159191Skris#!/usr/local/bin/perl 259191Skris# 359191Skris# CA - wrapper around ca to make it easier to use ... basically ca requires 459191Skris# some setup stuff to be done before you can use it and this makes 559191Skris# things easier between now and when Eric is convinced to fix it :-) 659191Skris# 759191Skris# CA -newca ... will setup the right stuff 8109998Smarkm# CA -newreq[-nodes] ... will generate a certificate request 959191Skris# CA -sign ... will sign the generated request and output 1059191Skris# 1159191Skris# At the end of that grab newreq.pem and newcert.pem (one has the key 1259191Skris# and the other the certificate) and cat them together and that is what 1359191Skris# you want/need ... I'll make even this a little cleaner later. 1459191Skris# 1559191Skris# 1659191Skris# 12-Jan-96 tjh Added more things ... including CA -signcert which 1759191Skris# converts a certificate to a request and then signs it. 1859191Skris# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG 1959191Skris# environment variable so this can be driven from 2059191Skris# a script. 2159191Skris# 25-Jul-96 eay Cleaned up filenames some more. 2259191Skris# 11-Jun-96 eay Fixed a few filename missmatches. 2359191Skris# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'. 2459191Skris# 18-Apr-96 tjh Original hacking 2559191Skris# 2659191Skris# Tim Hudson 2759191Skris# tjh@cryptsoft.com 2859191Skris# 2959191Skris 3059191Skris# 27-Apr-98 snh Translation into perl, fix existing CA bug. 3159191Skris# 3259191Skris# 3359191Skris# Steve Henson 3459191Skris# shenson@bigfoot.com 3559191Skris 3659191Skris# default openssl.cnf file has setup as per the following 3759191Skris# demoCA ... where everything is stored 3859191Skris 39160814Ssimonmy $openssl; 40160814Ssimonif(defined $ENV{OPENSSL}) { 41160814Ssimon $openssl = $ENV{OPENSSL}; 42160814Ssimon} else { 43160814Ssimon $openssl = "openssl"; 44160814Ssimon $ENV{OPENSSL} = $openssl; 45160814Ssimon} 46160814Ssimon 4768651Skris$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; 48160814Ssimon$DAYS="-days 365"; # 1 year 49160814Ssimon$CADAYS="-days 1095"; # 3 years 50160814Ssimon$REQ="$openssl req $SSLEAY_CONFIG"; 51160814Ssimon$CA="$openssl ca $SSLEAY_CONFIG"; 52160814Ssimon$VERIFY="$openssl verify"; 53160814Ssimon$X509="$openssl x509"; 54160814Ssimon$PKCS12="$openssl pkcs12"; 5559191Skris 5659191Skris$CATOP="./demoCA"; 5759191Skris$CAKEY="cakey.pem"; 58160814Ssimon$CAREQ="careq.pem"; 5959191Skris$CACERT="cacert.pem"; 6059191Skris 6159191Skris$DIRMODE = 0777; 6259191Skris 6359191Skris$RET = 0; 6459191Skris 6559191Skrisforeach (@ARGV) { 6659191Skris if ( /^(-\?|-h|-help)$/ ) { 67109998Smarkm print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 6859191Skris exit 0; 6959191Skris } elsif (/^-newcert$/) { 7059191Skris # create a certificate 71160814Ssimon system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); 7259191Skris $RET=$?; 73160814Ssimon print "Certificate is in newcert.pem, private key is in newkey.pem\n" 7459191Skris } elsif (/^-newreq$/) { 7559191Skris # create a certificate request 76160814Ssimon system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); 7759191Skris $RET=$?; 78160814Ssimon print "Request is in newreq.pem, private key is in newkey.pem\n"; 79109998Smarkm } elsif (/^-newreq-nodes$/) { 80109998Smarkm # create a certificate request 81160814Ssimon system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); 82109998Smarkm $RET=$?; 83160814Ssimon print "Request is in newreq.pem, private key is in newkey.pem\n"; 8459191Skris } elsif (/^-newca$/) { 8559191Skris # if explicitly asked for or it doesn't exist then setup the 8659191Skris # directory structure that Eric likes to manage things 8759191Skris $NEW="1"; 8859191Skris if ( "$NEW" || ! -f "${CATOP}/serial" ) { 8959191Skris # create the directory hierarchy 9059191Skris mkdir $CATOP, $DIRMODE; 9159191Skris mkdir "${CATOP}/certs", $DIRMODE; 9259191Skris mkdir "${CATOP}/crl", $DIRMODE ; 9359191Skris mkdir "${CATOP}/newcerts", $DIRMODE; 9459191Skris mkdir "${CATOP}/private", $DIRMODE; 9559191Skris open OUT, ">${CATOP}/index.txt"; 9659191Skris close OUT; 97160814Ssimon open OUT, ">${CATOP}/crlnumber"; 98160814Ssimon print OUT "01\n"; 99160814Ssimon close OUT; 10059191Skris } 10159191Skris if ( ! -f "${CATOP}/private/$CAKEY" ) { 10259191Skris print "CA certificate filename (or enter to create)\n"; 10359191Skris $FILE = <STDIN>; 10459191Skris 10559191Skris chop $FILE; 10659191Skris 10759191Skris # ask user for existing CA certificate 10859191Skris if ($FILE) { 10959191Skris cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); 11059191Skris cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); 11159191Skris $RET=$?; 11259191Skris } else { 11359191Skris print "Making CA certificate ...\n"; 114160814Ssimon system ("$REQ -new -keyout " . 115160814Ssimon "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); 116160814Ssimon system ("$CA -create_serial " . 117160814Ssimon "-out ${CATOP}/$CACERT $CADAYS -batch " . 118160814Ssimon "-keyfile ${CATOP}/private/$CAKEY -selfsign " . 119160814Ssimon "-extensions v3_ca " . 120160814Ssimon "-infiles ${CATOP}/$CAREQ "); 12159191Skris $RET=$?; 12259191Skris } 12359191Skris } 12459191Skris } elsif (/^-pkcs12$/) { 12559191Skris my $cname = $ARGV[1]; 12659191Skris $cname = "My Certificate" unless defined $cname; 127160814Ssimon system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . 12859191Skris "-certfile ${CATOP}/$CACERT -out newcert.p12 " . 12959191Skris "-export -name \"$cname\""); 13059191Skris $RET=$?; 131160814Ssimon print "PKCS #12 file is in newcert.p12\n"; 13259191Skris exit $RET; 13359191Skris } elsif (/^-xsign$/) { 13459191Skris system ("$CA -policy policy_anything -infiles newreq.pem"); 13559191Skris $RET=$?; 13659191Skris } elsif (/^(-sign|-signreq)$/) { 13759191Skris system ("$CA -policy policy_anything -out newcert.pem " . 13859191Skris "-infiles newreq.pem"); 13959191Skris $RET=$?; 14059191Skris print "Signed certificate is in newcert.pem\n"; 14168651Skris } elsif (/^(-signCA)$/) { 14268651Skris system ("$CA -policy policy_anything -out newcert.pem " . 14368651Skris "-extensions v3_ca -infiles newreq.pem"); 14468651Skris $RET=$?; 14568651Skris print "Signed CA certificate is in newcert.pem\n"; 14659191Skris } elsif (/^-signcert$/) { 14759191Skris system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . 14859191Skris "-out tmp.pem"); 14959191Skris system ("$CA -policy policy_anything -out newcert.pem " . 15059191Skris "-infiles tmp.pem"); 15159191Skris $RET = $?; 15259191Skris print "Signed certificate is in newcert.pem\n"; 15359191Skris } elsif (/^-verify$/) { 15459191Skris if (shift) { 15559191Skris foreach $j (@ARGV) { 15659191Skris system ("$VERIFY -CAfile $CATOP/$CACERT $j"); 15759191Skris $RET=$? if ($? != 0); 15859191Skris } 15959191Skris exit $RET; 16059191Skris } else { 16159191Skris system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); 16259191Skris $RET=$?; 16359191Skris exit 0; 16459191Skris } 16559191Skris } else { 16659191Skris print STDERR "Unknown arg $_\n"; 167109998Smarkm print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 16859191Skris exit 1; 16959191Skris } 17059191Skris} 17159191Skris 17259191Skrisexit $RET; 17359191Skris 17459191Skrissub cp_pem { 17559191Skrismy ($infile, $outfile, $bound) = @_; 17659191Skrisopen IN, $infile; 17759191Skrisopen OUT, ">$outfile"; 17859191Skrismy $flag = 0; 17959191Skriswhile (<IN>) { 18059191Skris $flag = 1 if (/^-----BEGIN.*$bound/) ; 18159191Skris print OUT $_ if ($flag); 18259191Skris if (/^-----END.*$bound/) { 18359191Skris close IN; 18459191Skris close OUT; 18559191Skris return; 18659191Skris } 18759191Skris} 18859191Skris} 18959191Skris 190