#!/usr/bin/perl -w # This expects input of the form: # type filenameprefix commonname emailaddress password # user path/joeuser Joe User joeuser@org.com 8gfBl@#9 # host path/twizzle twizzle.org.com joeuser@org.com # # Fiields are separated by tabs. Users have passwords but # hosts do not. use strict; my($ca_pass_file) = "capassfile.txt"; # This is necessary because if you do this with large input files, # your machine will run out of randomness. print STDERR "Running find to get randomness.\n"; my(@files) = grep(!/\'/, (`find /Users/ian/src`)); chomp @files; print STDERR "Validating.\n"; my(@lines); # Input validation pass while(<>) { chomp; my($type,$filename,$commonname,$email,$password) = split /\t/; if(not ($type eq 'user' or $type eq 'host')) { die "Error in input: first field should be type, either 'user' or 'host'."; } my $input_file = "$filename.txt"; my $key_file = "$filename.key"; my $req_file = "$filename.req"; my $cert_file = "$filename.crt"; if(-e $key_file) { die "Key file exists: '$key_file'"; } if(-e $req_file) { die "Request file exists: '$req_file'"; } if(-e $cert_file) { die "Certificate file exists: '$cert_file'"; } # How to validate common name? # Stronger validation of email addresses? # See: http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html # see also perlfaq9 if(not $email =~ /^[\w.-]+\@(?:[\w-]+\.)+\w+$/) { die "Invalid email address: '$email'"; } if($type eq 'user' and $password eq '') { die "User can't have null password."; } if($type eq 'host' and $password ne '') { die "Host must have null password."; } push @lines, $_; } print STDERR "Running.\n"; foreach (@lines) { chomp; my($type,$filename,$commonname,$email,$password) = split /\t/; my $input_file = "$filename.txt"; my $key_file = "$filename.key"; my $req_file = "$filename.req"; my $cert_file = "$filename.crt"; my $pass_file = "$filename.pass"; # create input file open FF, ">$input_file" or die "Can't open '$input_file': $!"; print FF "\n\n\n\n\n\n$commonname\n$email\n"; close FF; # make the reqs and keys my $files = "'".$files[int(rand($#files))]."':'".$files[int(rand($#files))]."':'".$files[int(rand($#files))]."'"; if($type eq 'user') { # create password file open FF, ">$pass_file" or die "Can't open '$pass_file': $!"; print FF "$password\n"; close FF; &docmd("openssl req -newkey rsa:1024 -keyout $key_file -passout file:$pass_file -config openssl.cnf -out $req_file -rand $files < $input_file"); unlink($pass_file) or die "Can't delete '$pass_file': $!"; } else { &docmd("openssl req -newkey rsa:1024 -keyout $key_file -nodes -config openssl.cnf -out $req_file -rand $files < $input_file"); } &docmd("openssl ca -config openssl.cnf -passin file:$ca_pass_file -batch -out $cert_file -infiles $req_file"); } sub docmd { my($cmd) = @_; print "$cmd\n"; print `$cmd`; }