$! CA - wrapper around ca to make it easier to use ... basically ca requires $! some setup stuff to be done before you can use it and this makes $! things easier between now and when Eric is convinced to fix it :-) $! $! CA -newca ... will setup the right stuff $! CA -newreq ... will generate a certificate request $! CA -sign ... will sign the generated request and output $! $! At the end of that grab newreq.pem and newcert.pem (one has the key $! and the other the certificate) and cat them together and that is what $! you want/need ... I'll make even this a little cleaner later. $! $! $! 12-Jan-96 tjh Added more things ... including CA -signcert which $! converts a certificate to a request and then signs it. $! 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG $! environment variable so this can be driven from $! a script. $! 25-Jul-96 eay Cleaned up filenames some more. $! 11-Jun-96 eay Fixed a few filename missmatches. $! 03-May-96 eay Modified to use 'openssl cmd' instead of 'cmd'. $! 18-Apr-96 tjh Original hacking $! $! Tim Hudson $! tjh@cryptsoft.com $! $! $! default ssleay.cnf file has setup as per the following $! demoCA ... where everything is stored $ $ IF F$TYPE(OPENSSL_CONFIG) .EQS. "" THEN OPENSSL_CONFIG := SSL3$ROOT:[000000]OPENSSL-VMS.CNF $ DAYS = "-days 365" $ CADAYS = "-days 1095" ! 3 years $ REQ = "openssl req -config " + OPENSSL_CONFIG $ CA = "openssl ca -config " + OPENSSL_CONFIG $ VERIFY = "openssl verify" $ X509 = "openssl x509" $ PKCS12 = "openssl pkcs12" $ echo = "write sys$Output" $ RET = 0 $! $! 2010-12-20 SMS. $! Use a concealed logical name to reduce command line lengths, to $! avoid DCL errors on VAX: $! %DCL-W-TKNOVF, command element is too long - shorten $! (Path segments like "openssl-1_0_1-stable-SNAP-20101217" accumulate $! quickly.) $! $ CATOP = F$PARSE( F$ENVIRONMENT( "DEFAULT"), "[]")- "].;"+ ".demoCA.]" $ define /translation_attributes = concealed CATOP 'CATOP' $! $ on error then goto clean_up $ on control_y then goto clean_up $! $ CAKEY = "CATOP:[private]cakey.pem" $ CACERT = "CATOP:[000000]cacert.pem" $ CAREQ = "CATOP:[000000]careq.pem" $ CACRL = "CATOP:[crl]crl.pem" $ NEWKEY = "newkey.pem" $ NEWREQ = "newreq.pem" $ NEWCERT = "newcert.pem" $ NEWP12 = "newcert.p12" $ $ __INPUT := SYS$COMMAND $! $ i = 1 $opt_loop: $ $ prog_opt = F$EDIT(P'i',"lowercase") $ $ IF (prog_opt .EQS. "?" .OR. prog_opt .EQS. "-h" .OR. prog_opt .EQS. "-help") $ THEN $ echo "usage: CA.COM -newcert | -newreq | -newreq-nodes | -xsign | -sign | -signCA | -signcert | -crl | -newca" $ echo " CA.COM -pkcs12 [certname]" $ echo " CA.COM -verify certfile ..." $ echo " CA.COM -revoke certfile [reason]" $ ENDIF $ $ IF (prog_opt .EQS. "-input") $ THEN $! Get input from somewhere other than SYS$COMMAND $ i = i + 1 $ __INPUT = P'i $ i = i + 1 $ GOTO opt_loop $ ENDIF $ $ IF (prog_opt .EQS. "-newcert" ) $ THEN $! create a certificate $ 'REQ -new -x509 -keyout 'NEWKEY -out 'NEWCERT 'DAYS $ RET = $STATUS .AND. %x0003 $ IF (RET .EQ. 1) THEN echo "Cert is in ''NEWCERT', private key is in ''NEWKEY'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-precert" ) $ THEN $! create a pre-certificate $ 'REQ -x509 -precert -keyout 'NEWKEY -out 'NEWCERT 'DAYS $ RET = $STATUS .AND. %x0003 $ IF (RET .EQ. 1) THEN echo "Pre-cert is in ''NEWCERT', private key is in ''NEWKEY'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-newreq" ) $ THEN $! create a certificate request $ 'REQ -new -keyout 'NEWKEY -out 'NEWREQ 'DAYS $ RET = $STATUS .AND. %x0003 $ IF (RET .EQ. 1) THEN echo "Request is in ''NEWREQ', private key is in ''NEWKEY'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-newreq-nodes" ) $ THEN $! create a certificate request $ 'REQ -new -nodes -keyout 'NEWKEY -out 'NEWREQ 'DAYS $ RET = $STATUS .AND. %x0003 $ IF (RET .EQ. 1) THEN echo "Request is in ''NEWREQ', private key is in ''NEWKEY'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-newca") $ THEN $ IF (F$SEARCH( "CATOP:[000000]crlnumber.") .NES. "") THEN GOTO clean_up $! create the directory hierarchy $ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[000000] $ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[certs] $ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[crl] $ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[newcerts] $ CREATE /DIRECTORY /PROTECTION=OWNER:RWED CATOP:[private] $ $ OPEN /WRITE crln_file CATOP:[000000]crlnumber. $ WRITE crln_file "01" $ CLOSE crln_file $ APPEND /NEW_VERSION NL: CATOP:[000000]index.txt $ APPEND /NEW_VERSION NL: CATOP:[000000]index.txt-attr $ $! ask user for existing CA certificate $ READ '__INPUT FILE - /PROMPT="CA certificate filename (or enter to create): " $ IF (FILE .NES. "") .AND. (F$SEARCH(FILE) .NES. "") $ THEN $ call copy_pemfile 'FILE 'CAKEY "PRIVATE" $ call copy_pemfile 'FILE 'CACERT "CERTIFICATE" $ RET=1 $ ELSE $ echo "Making CA certificate ..." $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'REQ -new -keyout 'CAKEY -out 'CAREQ $ RET=$STATUS .AND. %x0003 $ IF (RET .EQ. 1) $ THEN $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'CA -create_serial -out 'CACERT 'CADAYS - -keyfile 'CAKEY -selfsign -extensions v3_ca $ RET=$STATUS .AND. %x0003 $ ENDIF $ ENDIF $ IF (RET .EQ. 1) THEN echo "CA certificate is in ''CACERT'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-pkcs12" ) $ THEN $ i = i + 1 $ cname = P'i $ IF (cname .EQS. "") THEN cname = "My certificate" $ 'PKCS12 -in 'NEWCERT -inkey 'NEWKEY - -certfile 'CACERT -out 'NEWP12 - -export -name "''cname'" $ RET=$STATUS .AND. %x0003 $ IF (RET .EQ. 1) THEN echo "PKCS #12 file is in ''NEWP12'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-xsign" ) $ THEN $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'CA -policy policy_anything -infiles 'NEWREQ $ RET=$STATUS .AND. %x0003 $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-sign" ) $ THEN $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'CA -policy policy_anything -out 'NEWCERT -infiles 'NEWREQ $ RET=$STATUS .AND. %x0003 $ IF (RET .EQ. 1) $ THEN $ type newcert.pem $ echo "Signed certificate is in ''NEWCERT'" $ ENDIF $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-signCA" ) $ THEN $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'CA -policy policy_anything -out 'NEWCERT - -extensions v3_ca -infiles 'NEWREQ $ RET=$STATUS .AND. %x0003 $ IF (RET .EQ. 1) $ THEN $ type newcert.pem $ echo "Signed CA certificate is in ''NEWCERT'" $ ENDIF $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-signcert" ) $ THEN $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'X509 -x509toreq -in 'NEWREQ -signkey 'NEWREQ -out tmp.pem $ RET=$STATUS .AND. %x0003 $ IF (RET .EQ. 1) $ THEN $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'CA -policy policy_anything -out 'NEWCERT -infiles tmp.pem $ RET=$STATUS .AND. %x0003 $ ENDIF $ IF (RET .EQ. 1) $ THEN $ type newcert.pem $ echo "Signed CA certificate is in ''NEWCERT'" $ ENDIF $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-verify" ) $ THEN $ first = i + 1 $ verify_opt_loop: $ i = i + 1 $ IF (i .GT. 8) GOTO clean_up $ IF (P'i .NES. "") $ THEN $ __tmp = P'i $ DEFINE /USER_MODE SYS$INPUT '__INPUT $ 'VERIFY "-CAfile" 'CACERT '__tmp $ tmp=$STATUS .AND. %x0003 $ IF (i .EQ. first .OR. tmp .NE. 1) THEN RET=tmp $ ENDIF $ GOTO verify_opt_loop $ ENDIF $ $ IF (prog_opt .EQS. "-crl" ) $ THEN $ 'CA -gencrl -out 'CACRL $ RET=$STATUS .AND. %x0003 $ IF (RET .EQ. 1) THEN echo "Generated CRL is in ''CACRL'" $ GOTO clean_up $ ENDIF $ $ IF (prog_opt .EQS. "-revoke" ) $ THEN $ i = i + 1 $ cname = P'i $ IF (cname .EQS. "") $ THEN $ echo "Certificate filename is required; reason optional." $ GOTO clean_up $ ENDIF $ i = i + 1 $ reason = P'i $ IF (reason .NES. "") $ THEN $ IF (reason .NES. "unspecified" - .AND. reason .NES. "keyCompromise" - .AND. reason .NES. "CACompromise" - .AND. reason .NES. "affiliationChanged" - .AND. reason .NES. "superseded" - .AND. reason .NES. "cessationOfOperation" - .AND. reason .NES. "certificateHold" - .AND. reason .NES. "removeFromCRL") $ THEN $ echo "Invalid CRL reason; must be one of:" $ echo " unspecified, keyCompromise, CACompromise," $ echo " affiliationChanged, superseded, cessationOfOperation" $ echo " certificateHold, removeFromCRL" $ GOTO clean_up $ ENDIF $ reason = " -crl_reason ''reason'" $ ENDIF $ 'CA -revoke "''cname'" 'reason $ RET=$STATUS .AND. %x0003 $ GOTO clean_up $ ENDIF $ $ echo "Unknown arg ''prog_opt'" $ echo "Use -help for help."; $ $ clean_up: $ $ IF (f$trnlnm( "CATOP", "LNM$PROCESS") .nes. "") then - deassign /process CATOP $ $ EXIT 'RET $ $ copy_pemfile: $ subroutine $ found = 0 $ beginpattern = "-----BEGIN " + P3 $ endpattern = "-----END " + P3 $ OPEN/READ pem P1 $ OPEN/WRITE out P2 $ read_loop: $ READ pem line /error=end_read_loop /end_of_file=end_read_loop $ IF (f$length(line) .NE. 0 - .AND. f$locate(beginpattern, line) .EQ. 0) THEN found = 1 $ IF (found .EQ. 1) WRITE out line $ IF (f$length(line) .NE. 0 - .AND. f$locate(endpattern, line) .EQ. 0) THEN GOTO end_read_loop $ GOTO read_loop $ end_read_loop: $ CLOSE pem $ CLOSE out $ exit $ endsubroutine