
1: #!/usr/bin/perl 2: # 3: # CA - wrapper around ca to make it easier to use ... basically ca requires 4: # some setup stuff to be done before you can use it and this makes 5: # things easier between now and when Eric is convinced to fix it :-) 6: # 7: # CA -newca ... will setup the right stuff 8: # CA -newreq[-nodes] ... will generate a certificate request 9: # CA -sign ... will sign the generated request and output 10: # 11: # At the end of that grab newreq.pem and newcert.pem (one has the key 12: # and the other the certificate) and cat them together and that is what 13: # you want/need ... I'll make even this a little cleaner later. 14: # 15: # 16: # 12-Jan-96 tjh Added more things ... including CA -signcert which 17: # converts a certificate to a request and then signs it. 18: # 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG 19: # environment variable so this can be driven from 20: # a script. 21: # 25-Jul-96 eay Cleaned up filenames some more. 22: # 11-Jun-96 eay Fixed a few filename missmatches. 23: # 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'. 24: # 18-Apr-96 tjh Original hacking 25: # 26: # Tim Hudson 27: # tjh@cryptsoft.com 28: # 29: 30: # 27-Apr-98 snh Translation into perl, fix existing CA bug. 31: # 32: # 33: # Steve Henson 34: # shenson@bigfoot.com 35: 36: # default openssl.cnf file has setup as per the following 37: # demoCA ... where everything is stored 38: 39: my $openssl; 40: if(defined $ENV{OPENSSL}) { 41: $openssl = $ENV{OPENSSL}; 42: } else { 43: $openssl = "openssl"; 44: $ENV{OPENSSL} = $openssl; 45: } 46: 47: $SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; 48: $DAYS="-days 365"; # 1 year 49: $CADAYS="-days 1095"; # 3 years 50: $REQ="$openssl req $SSLEAY_CONFIG"; 51: $CA="$openssl ca $SSLEAY_CONFIG"; 52: $VERIFY="$openssl verify"; 53: $X509="$openssl x509"; 54: $PKCS12="$openssl pkcs12"; 55: 56: $CATOP="./demoCA"; 57: $CAKEY="cakey.pem"; 58: $CAREQ="careq.pem"; 59: $CACERT="cacert.pem"; 60: 61: $DIRMODE = 0777; 62: 63: $RET = 0; 64: 65: foreach (@ARGV) { 66: if ( /^(-\?|-h|-help)$/ ) { 67: print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 68: exit 0; 69: } elsif (/^-newcert$/) { 70: # create a certificate 71: system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); 72: $RET=$?; 73: print "Certificate is in newcert.pem, private key is in newkey.pem\n" 74: } elsif (/^-newreq$/) { 75: # create a certificate request 76: system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); 77: $RET=$?; 78: print "Request is in newreq.pem, private key is in newkey.pem\n"; 79: } elsif (/^-newreq-nodes$/) { 80: # create a certificate request 81: system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); 82: $RET=$?; 83: print "Request is in newreq.pem, private key is in newkey.pem\n"; 84: } elsif (/^-newca$/) { 85: # if explicitly asked for or it doesn't exist then setup the 86: # directory structure that Eric likes to manage things 87: $NEW="1"; 88: if ( "$NEW" || ! -f "${CATOP}/serial" ) { 89: # create the directory hierarchy 90: mkdir $CATOP, $DIRMODE; 91: mkdir "${CATOP}/certs", $DIRMODE; 92: mkdir "${CATOP}/crl", $DIRMODE ; 93: mkdir "${CATOP}/newcerts", $DIRMODE; 94: mkdir "${CATOP}/private", $DIRMODE; 95: open OUT, ">${CATOP}/index.txt"; 96: close OUT; 97: open OUT, ">${CATOP}/crlnumber"; 98: print OUT "01\n"; 99: close OUT; 100: } 101: if ( ! -f "${CATOP}/private/$CAKEY" ) { 102: print "CA certificate filename (or enter to create)\n"; 103: $FILE = <STDIN>; 104: 105: chop $FILE; 106: 107: # ask user for existing CA certificate 108: if ($FILE) { 109: cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); 110: cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); 111: $RET=$?; 112: } else { 113: print "Making CA certificate ...\n"; 114: system ("$REQ -new -keyout " . 115: "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); 116: system ("$CA -create_serial " . 117: "-out ${CATOP}/$CACERT $CADAYS -batch " . 118: "-keyfile ${CATOP}/private/$CAKEY -selfsign " . 119: "-extensions v3_ca " . 120: "-infiles ${CATOP}/$CAREQ "); 121: $RET=$?; 122: } 123: } 124: } elsif (/^-pkcs12$/) { 125: my $cname = $ARGV[1]; 126: $cname = "My Certificate" unless defined $cname; 127: system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . 128: "-certfile ${CATOP}/$CACERT -out newcert.p12 " . 129: "-export -name \"$cname\""); 130: $RET=$?; 131: print "PKCS #12 file is in newcert.p12\n"; 132: exit $RET; 133: } elsif (/^-xsign$/) { 134: system ("$CA -policy policy_anything -infiles newreq.pem"); 135: $RET=$?; 136: } elsif (/^(-sign|-signreq)$/) { 137: system ("$CA -policy policy_anything -out newcert.pem " . 138: "-infiles newreq.pem"); 139: $RET=$?; 140: print "Signed certificate is in newcert.pem\n"; 141: } elsif (/^(-signCA)$/) { 142: system ("$CA -policy policy_anything -out newcert.pem " . 143: "-extensions v3_ca -infiles newreq.pem"); 144: $RET=$?; 145: print "Signed CA certificate is in newcert.pem\n"; 146: } elsif (/^-signcert$/) { 147: system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . 148: "-out tmp.pem"); 149: system ("$CA -policy policy_anything -out newcert.pem " . 150: "-infiles tmp.pem"); 151: $RET = $?; 152: print "Signed certificate is in newcert.pem\n"; 153: } elsif (/^-verify$/) { 154: if (shift) { 155: foreach $j (@ARGV) { 156: system ("$VERIFY -CAfile $CATOP/$CACERT $j"); 157: $RET=$? if ($? != 0); 158: } 159: exit $RET; 160: } else { 161: system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); 162: $RET=$?; 163: exit 0; 164: } 165: } else { 166: print STDERR "Unknown arg $_\n"; 167: print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 168: exit 1; 169: } 170: } 171: 172: exit $RET; 173: 174: sub cp_pem { 175: my ($infile, $outfile, $bound) = @_; 176: open IN, $infile; 177: open OUT, ">$outfile"; 178: my $flag = 0; 179: while (<IN>) { 180: $flag = 1 if (/^-----BEGIN.*$bound/) ; 181: print OUT $_ if ($flag); 182: if (/^-----END.*$bound/) { 183: close IN; 184: close OUT; 185: return; 186: } 187: } 188: } 189: