Home | History | Annotate | Download | only in apps
      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 (at] cryptsoft.com
     28 #
     29 
     30 # 27-Apr-98 snh    Translation into perl, fix existing CA bug.
     31 #
     32 #
     33 # Steve Henson
     34 # shenson (at] 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 
    190