12463Sjp161948#!/usr/perl5/bin/perl 20Sstevel@tonic-gate# 30Sstevel@tonic-gate# CA - wrapper around ca to make it easier to use ... basically ca requires 40Sstevel@tonic-gate# some setup stuff to be done before you can use it and this makes 50Sstevel@tonic-gate# things easier between now and when Eric is convinced to fix it :-) 60Sstevel@tonic-gate# 70Sstevel@tonic-gate# CA -newca ... will setup the right stuff 80Sstevel@tonic-gate# CA -newreq[-nodes] ... will generate a certificate request 90Sstevel@tonic-gate# CA -sign ... will sign the generated request and output 100Sstevel@tonic-gate# 110Sstevel@tonic-gate# At the end of that grab newreq.pem and newcert.pem (one has the key 120Sstevel@tonic-gate# and the other the certificate) and cat them together and that is what 130Sstevel@tonic-gate# you want/need ... I'll make even this a little cleaner later. 140Sstevel@tonic-gate# 150Sstevel@tonic-gate# 160Sstevel@tonic-gate# 12-Jan-96 tjh Added more things ... including CA -signcert which 170Sstevel@tonic-gate# converts a certificate to a request and then signs it. 180Sstevel@tonic-gate# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG 190Sstevel@tonic-gate# environment variable so this can be driven from 200Sstevel@tonic-gate# a script. 210Sstevel@tonic-gate# 25-Jul-96 eay Cleaned up filenames some more. 220Sstevel@tonic-gate# 11-Jun-96 eay Fixed a few filename missmatches. 230Sstevel@tonic-gate# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'. 240Sstevel@tonic-gate# 18-Apr-96 tjh Original hacking 250Sstevel@tonic-gate# 260Sstevel@tonic-gate# Tim Hudson 270Sstevel@tonic-gate# tjh@cryptsoft.com 280Sstevel@tonic-gate# 290Sstevel@tonic-gate 300Sstevel@tonic-gate# 27-Apr-98 snh Translation into perl, fix existing CA bug. 310Sstevel@tonic-gate# 320Sstevel@tonic-gate# 330Sstevel@tonic-gate# Steve Henson 340Sstevel@tonic-gate# shenson@bigfoot.com 350Sstevel@tonic-gate 360Sstevel@tonic-gate# default openssl.cnf file has setup as per the following 370Sstevel@tonic-gate# demoCA ... where everything is stored 380Sstevel@tonic-gate 392139Sjp161948my $openssl; 402139Sjp161948if(defined $ENV{OPENSSL}) { 412139Sjp161948 $openssl = $ENV{OPENSSL}; 422139Sjp161948} else { 432139Sjp161948 $openssl = "openssl"; 442139Sjp161948 $ENV{OPENSSL} = $openssl; 452139Sjp161948} 462139Sjp161948 470Sstevel@tonic-gate$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; 482139Sjp161948$DAYS="-days 365"; # 1 year 492139Sjp161948$CADAYS="-days 1095"; # 3 years 502139Sjp161948$REQ="$openssl req $SSLEAY_CONFIG"; 512139Sjp161948$CA="$openssl ca $SSLEAY_CONFIG"; 522139Sjp161948$VERIFY="$openssl verify"; 532139Sjp161948$X509="$openssl x509"; 542139Sjp161948$PKCS12="$openssl pkcs12"; 550Sstevel@tonic-gate 56*8192SJohn.Zolnowsky@Sun.COM$CATOP="/etc/openssl"; 570Sstevel@tonic-gate$CAKEY="cakey.pem"; 582139Sjp161948$CAREQ="careq.pem"; 590Sstevel@tonic-gate$CACERT="cacert.pem"; 600Sstevel@tonic-gate 610Sstevel@tonic-gate$DIRMODE = 0777; 620Sstevel@tonic-gate 630Sstevel@tonic-gate$RET = 0; 640Sstevel@tonic-gate 650Sstevel@tonic-gateforeach (@ARGV) { 660Sstevel@tonic-gate if ( /^(-\?|-h|-help)$/ ) { 670Sstevel@tonic-gate print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 680Sstevel@tonic-gate exit 0; 690Sstevel@tonic-gate } elsif (/^-newcert$/) { 700Sstevel@tonic-gate # create a certificate 712139Sjp161948 system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); 720Sstevel@tonic-gate $RET=$?; 732139Sjp161948 print "Certificate is in newcert.pem, private key is in newkey.pem\n" 740Sstevel@tonic-gate } elsif (/^-newreq$/) { 750Sstevel@tonic-gate # create a certificate request 762139Sjp161948 system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); 770Sstevel@tonic-gate $RET=$?; 782139Sjp161948 print "Request is in newreq.pem, private key is in newkey.pem\n"; 790Sstevel@tonic-gate } elsif (/^-newreq-nodes$/) { 800Sstevel@tonic-gate # create a certificate request 812139Sjp161948 system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); 820Sstevel@tonic-gate $RET=$?; 832139Sjp161948 print "Request is in newreq.pem, private key is in newkey.pem\n"; 840Sstevel@tonic-gate } elsif (/^-newca$/) { 850Sstevel@tonic-gate # if explicitly asked for or it doesn't exist then setup the 860Sstevel@tonic-gate # directory structure that Eric likes to manage things 870Sstevel@tonic-gate $NEW="1"; 880Sstevel@tonic-gate if ( "$NEW" || ! -f "${CATOP}/serial" ) { 890Sstevel@tonic-gate # create the directory hierarchy 900Sstevel@tonic-gate mkdir $CATOP, $DIRMODE; 910Sstevel@tonic-gate mkdir "${CATOP}/certs", $DIRMODE; 920Sstevel@tonic-gate mkdir "${CATOP}/crl", $DIRMODE ; 930Sstevel@tonic-gate mkdir "${CATOP}/newcerts", $DIRMODE; 940Sstevel@tonic-gate mkdir "${CATOP}/private", $DIRMODE; 950Sstevel@tonic-gate open OUT, ">${CATOP}/index.txt"; 960Sstevel@tonic-gate close OUT; 970Sstevel@tonic-gate } 980Sstevel@tonic-gate if ( ! -f "${CATOP}/private/$CAKEY" ) { 990Sstevel@tonic-gate print "CA certificate filename (or enter to create)\n"; 1000Sstevel@tonic-gate $FILE = <STDIN>; 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate chop $FILE; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate # ask user for existing CA certificate 1050Sstevel@tonic-gate if ($FILE) { 1060Sstevel@tonic-gate cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); 1070Sstevel@tonic-gate cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); 1080Sstevel@tonic-gate $RET=$?; 1090Sstevel@tonic-gate } else { 1100Sstevel@tonic-gate print "Making CA certificate ...\n"; 1112139Sjp161948 system ("$REQ -new -keyout " . 1122139Sjp161948 "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); 1132139Sjp161948 system ("$CA -create_serial " . 1142139Sjp161948 "-out ${CATOP}/$CACERT $CADAYS -batch " . 1152139Sjp161948 "-keyfile ${CATOP}/private/$CAKEY -selfsign " . 1162139Sjp161948 "-infiles ${CATOP}/$CAREQ "); 1170Sstevel@tonic-gate $RET=$?; 1180Sstevel@tonic-gate } 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate } elsif (/^-pkcs12$/) { 1210Sstevel@tonic-gate my $cname = $ARGV[1]; 1220Sstevel@tonic-gate $cname = "My Certificate" unless defined $cname; 1232139Sjp161948 system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . 1240Sstevel@tonic-gate "-certfile ${CATOP}/$CACERT -out newcert.p12 " . 1250Sstevel@tonic-gate "-export -name \"$cname\""); 1260Sstevel@tonic-gate $RET=$?; 1272139Sjp161948 print "PKCS #12 file is in newcert.p12\n"; 1280Sstevel@tonic-gate exit $RET; 1290Sstevel@tonic-gate } elsif (/^-xsign$/) { 1300Sstevel@tonic-gate system ("$CA -policy policy_anything -infiles newreq.pem"); 1310Sstevel@tonic-gate $RET=$?; 1320Sstevel@tonic-gate } elsif (/^(-sign|-signreq)$/) { 1330Sstevel@tonic-gate system ("$CA -policy policy_anything -out newcert.pem " . 1340Sstevel@tonic-gate "-infiles newreq.pem"); 1350Sstevel@tonic-gate $RET=$?; 1360Sstevel@tonic-gate print "Signed certificate is in newcert.pem\n"; 1370Sstevel@tonic-gate } elsif (/^(-signCA)$/) { 1380Sstevel@tonic-gate system ("$CA -policy policy_anything -out newcert.pem " . 1390Sstevel@tonic-gate "-extensions v3_ca -infiles newreq.pem"); 1400Sstevel@tonic-gate $RET=$?; 1410Sstevel@tonic-gate print "Signed CA certificate is in newcert.pem\n"; 1420Sstevel@tonic-gate } elsif (/^-signcert$/) { 1430Sstevel@tonic-gate system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . 1440Sstevel@tonic-gate "-out tmp.pem"); 1450Sstevel@tonic-gate system ("$CA -policy policy_anything -out newcert.pem " . 1460Sstevel@tonic-gate "-infiles tmp.pem"); 1470Sstevel@tonic-gate $RET = $?; 1480Sstevel@tonic-gate print "Signed certificate is in newcert.pem\n"; 1490Sstevel@tonic-gate } elsif (/^-verify$/) { 1500Sstevel@tonic-gate if (shift) { 1510Sstevel@tonic-gate foreach $j (@ARGV) { 1520Sstevel@tonic-gate system ("$VERIFY -CAfile $CATOP/$CACERT $j"); 1530Sstevel@tonic-gate $RET=$? if ($? != 0); 1540Sstevel@tonic-gate } 1550Sstevel@tonic-gate exit $RET; 1560Sstevel@tonic-gate } else { 1570Sstevel@tonic-gate system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); 1580Sstevel@tonic-gate $RET=$?; 1590Sstevel@tonic-gate exit 0; 1600Sstevel@tonic-gate } 1610Sstevel@tonic-gate } else { 1620Sstevel@tonic-gate print STDERR "Unknown arg $_\n"; 1630Sstevel@tonic-gate print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 1640Sstevel@tonic-gate exit 1; 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate} 1670Sstevel@tonic-gate 1680Sstevel@tonic-gateexit $RET; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gatesub cp_pem { 1710Sstevel@tonic-gatemy ($infile, $outfile, $bound) = @_; 1720Sstevel@tonic-gateopen IN, $infile; 1730Sstevel@tonic-gateopen OUT, ">$outfile"; 1740Sstevel@tonic-gatemy $flag = 0; 1750Sstevel@tonic-gatewhile (<IN>) { 1760Sstevel@tonic-gate $flag = 1 if (/^-----BEGIN.*$bound/) ; 1770Sstevel@tonic-gate print OUT $_ if ($flag); 1780Sstevel@tonic-gate if (/^-----END.*$bound/) { 1790Sstevel@tonic-gate close IN; 1800Sstevel@tonic-gate close OUT; 1810Sstevel@tonic-gate return; 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate} 1840Sstevel@tonic-gate} 1850Sstevel@tonic-gate 186