File indexing completed on 2024-04-28 04:44:12
0001 #!/usr/bin/perl 0002 # 0003 # CA - wrapper around ca to make it easier to use ... basically ca requires 0004 # some setup stuff to be done before you can use it and this makes 0005 # things easier between now and when Eric is convinced to fix it :-) 0006 # 0007 # CA -newca ... will setup the right stuff 0008 # CA -newreq[-nodes] ... will generate a certificate request 0009 # CA -sign ... will sign the generated request and output 0010 # 0011 # At the end of that grab newreq.pem and newcert.pem (one has the key 0012 # and the other the certificate) and cat them together and that is what 0013 # you want/need ... I'll make even this a little cleaner later. 0014 # 0015 # 0016 # 12-Jan-96 tjh Added more things ... including CA -signcert which 0017 # converts a certificate to a request and then signs it. 0018 # 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG 0019 # environment variable so this can be driven from 0020 # a script. 0021 # 25-Jul-96 eay Cleaned up filenames some more. 0022 # 11-Jun-96 eay Fixed a few filename missmatches. 0023 # 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'. 0024 # 18-Apr-96 tjh Original hacking 0025 # 0026 # Tim Hudson 0027 # tjh@cryptsoft.com 0028 # 0029 0030 # 27-Apr-98 snh Translation into perl, fix existing CA bug. 0031 # 0032 # 0033 # Steve Henson 0034 # shenson@bigfoot.com 0035 0036 # default openssl.cnf file has setup as per the following 0037 # demoCA ... where everything is stored 0038 0039 my $openssl; 0040 if(defined $ENV{OPENSSL}) { 0041 $openssl = $ENV{OPENSSL}; 0042 } else { 0043 $openssl = "openssl"; 0044 $ENV{OPENSSL} = $openssl; 0045 } 0046 0047 #$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; 0048 $DAYS="-days 3650"; # 10 years 0049 $CADAYS="-days 2000"; # ~6 years 0050 $REQ="$openssl req -config ./openssl.cnf"; 0051 $CA="$openssl ca -config ./openssl.cnf"; 0052 $VERIFY="$openssl verify"; 0053 $X509="$openssl x509"; 0054 $PKCS12="$openssl pkcs12"; 0055 0056 $CATOP="./CA"; 0057 $CAKEY="cakey.pem"; 0058 $CAREQ="careq.pem"; 0059 $CACERT="cacert.pem"; 0060 0061 $DIRMODE = 0777; 0062 0063 $RET = 0; 0064 0065 foreach (@ARGV) { 0066 if ( /^(-\?|-h|-help)$/ ) { 0067 print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 0068 exit 0; 0069 } elsif (/^-newcert$/) { 0070 # create a certificate 0071 system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); 0072 $RET=$?; 0073 print "Certificate is in newcert.pem, private key is in newkey.pem\n" 0074 } elsif (/^-newreq$/) { 0075 # create a certificate request 0076 system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); 0077 $RET=$?; 0078 print "Request is in newreq.pem, private key is in newkey.pem\n"; 0079 } elsif (/^-newreq-nodes$/) { 0080 # create a certificate request 0081 system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); 0082 $RET=$?; 0083 print "Request is in newreq.pem, private key is in newkey.pem\n"; 0084 } elsif (/^-newca$/) { 0085 # if explicitly asked for or it doesn't exist then setup the 0086 # directory structure that Eric likes to manage things 0087 $NEW="1"; 0088 if ( "$NEW" || ! -f "${CATOP}/serial" ) { 0089 # create the directory hierarchy 0090 mkdir $CATOP, $DIRMODE; 0091 mkdir "${CATOP}/certs", $DIRMODE; 0092 mkdir "${CATOP}/crl", $DIRMODE ; 0093 mkdir "${CATOP}/newcerts", $DIRMODE; 0094 mkdir "${CATOP}/private", $DIRMODE; 0095 open OUT, ">${CATOP}/index.txt"; 0096 close OUT; 0097 open OUT, ">${CATOP}/crlnumber"; 0098 print OUT "01\n"; 0099 close OUT; 0100 } 0101 if ( ! -f "${CATOP}/private/$CAKEY" ) { 0102 print "CA certificate filename (or enter to create)\n"; 0103 $FILE = <STDIN>; 0104 0105 chop $FILE; 0106 0107 # ask user for existing CA certificate 0108 if ($FILE) { 0109 cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); 0110 cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); 0111 $RET=$?; 0112 } else { 0113 print "Making CA certificate ...\n"; 0114 system ("$REQ -new -keyout " . 0115 "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); 0116 system ("$CA -create_serial " . 0117 "-out ${CATOP}/$CACERT $CADAYS -batch " . 0118 "-keyfile ${CATOP}/private/$CAKEY -selfsign " . 0119 "-extensions v3_ca " . 0120 "-infiles ${CATOP}/$CAREQ "); 0121 $RET=$?; 0122 } 0123 } 0124 } elsif (/^-pkcs12$/) { 0125 my $cname = $ARGV[1]; 0126 $cname = "My Certificate" unless defined $cname; 0127 system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . 0128 "-certfile ${CATOP}/$CACERT -out newcert.p12 " . 0129 "-export -name \"$cname\""); 0130 $RET=$?; 0131 print "PKCS #12 file is in newcert.p12\n"; 0132 exit $RET; 0133 } elsif (/^-xsign$/) { 0134 system ("$CA -policy policy_anything -infiles newreq.pem"); 0135 $RET=$?; 0136 } elsif (/^(-sign|-signreq)$/) { 0137 system ("$CA -policy policy_anything -out newcert.pem " . 0138 "-infiles newreq.pem"); 0139 $RET=$?; 0140 print "Signed certificate is in newcert.pem\n"; 0141 } elsif (/^(-signCA)$/) { 0142 system ("$CA -policy policy_anything -out newcert.pem " . 0143 "-extensions v3_ca -infiles newreq.pem"); 0144 $RET=$?; 0145 print "Signed CA certificate is in newcert.pem\n"; 0146 } elsif (/^-signcert$/) { 0147 system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . 0148 "-out tmp.pem"); 0149 system ("$CA -policy policy_anything -out newcert.pem " . 0150 "-infiles tmp.pem"); 0151 $RET = $?; 0152 print "Signed certificate is in newcert.pem\n"; 0153 } elsif (/^-verify$/) { 0154 if (shift) { 0155 foreach $j (@ARGV) { 0156 system ("$VERIFY -CAfile $CATOP/$CACERT $j"); 0157 $RET=$? if ($? != 0); 0158 } 0159 exit $RET; 0160 } else { 0161 system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); 0162 $RET=$?; 0163 exit 0; 0164 } 0165 } else { 0166 print STDERR "Unknown arg $_\n"; 0167 print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; 0168 exit 1; 0169 } 0170 } 0171 0172 exit $RET; 0173 0174 sub cp_pem { 0175 my ($infile, $outfile, $bound) = @_; 0176 open IN, $infile; 0177 open OUT, ">$outfile"; 0178 my $flag = 0; 0179 while (<IN>) { 0180 $flag = 1 if (/^-----BEGIN.*$bound/) ; 0181 print OUT $_ if ($flag); 0182 if (/^-----END.*$bound/) { 0183 close IN; 0184 close OUT; 0185 return; 0186 } 0187 } 0188 } 0189