$!----------------------------------------------------------------------------- $! CREATE_SERVER_CERT.COM $! $! Create our own server certificate! $! This procedure is very "quick-and-dirty", use with that in mind! $! $! P1 must specify the server certificate file name $! P2 optionally specified the configuration file (defaults to DEFAULT.CNF) $! $! WASD VMS Web Services, Copyright (C) 1996-2015 Mark G.Daniel. $! This program comes with ABSOLUTELY NO WARRANTY. $! This is free software, and you are welcome to redistribute it under the $! conditions of the GNU GENERAL PUBLIC LICENSE, version 3, or later version. $! http://www.gnu.org/licenses/gpl.txt $! $! 18-JAN-2015 MGD use sha256 when generating request $! 04-APR-2010 MGD OpenSSL v1.0.0 use OPENSSL_CONF instead of -config $! 01-OCT-2003 MGD minor refinements $! 08-JAN-2003 MGD OPENSSL-0_9_7 $! 20-MAY-2001 MGD optional non-embedded private key password $! 07-APR-2001 MGD OPENSSL-0_9_6A $! 25-SEP-2000 MGD OPENSSL-0_9_6 $! 05-MAR-2000 MGD OPENSSL-0_9_5 $! 17-AUG-1999 MGD refinement (OPENSSL-0_9_4) $! 04-JUN-1999 MGD OPENSSL-0_9_3 (adapted from earlier procedures) $!----------------------------------------------------------------------------- $! $ if f$type(validDays) .eqs. "" then validDays = 1825 !(5*365 == five years!) $ if f$type(rsaKeySize) .eqs. "" then rsaKeySize = 2048 !(bits) $ if f$type(configFileName) .eqs. "" then configFileName = f$edit(P2,"lowercase") $! $ certDir = "[.CERT]" $ workDir = "[.CERT.WORK]" $ if configFileName .eqs. "" then configFileName = "default.cnf" $ configFileName = configFileName - ".cnf" + ".cnf" $! $ say = "write sys$output" $ tt = f$trnlnm("SYS$COMMAND","LNM$PROCESS",,"EXECUTIVE") $ say "" $! $ if P1 .eqs. "" $ then $ type sys$input ****************************** * CERTIFICATE NAME MISSING * ****************************** P1 must be the name of the certificate file (e.g. "MINE"). $ exit $ endif $ certFileName = f$edit(P1,"lowercase") - ".pem" + ".pem" $ if f$search("''certDir'''certFileName'") .nes. "" $ then $ type sys$input ***************************** * CERTIFICATE FILE EXISTS * ***************************** A certificate file using this name already exists! Using the same name will create a new file with a higher version number. $ read sys$command response /prompt="Continue? [N]: " $ say "" $ if .not. response then exit $ endif $! $ on error then goto serverError $ procedure = f$environment("procedure") - "000000." $ newDefault = f$parse(procedure,,,"device") + f$parse(procedure,,,"directory") $ prevDefault = f$environment("default") $ set default 'newDefault' $! $ @FIND_SSL $! $ @CREATE_SUPPORT_FILES $! $ type sys$input ********************************* * GENERATE SERVER CERTIFICATE * ********************************* A server certificate identifies a particular end-service. Its value as a guarantee of identity is founded in the authority of the organization that issues the certificate (the CA). It is the certificate specified to the server at startup. The server uses this certificate to establish its identity during the initial phase of the SSL protocol exchange. Each server should have a unique certificate. It is also common practice for a group of associated servers to share a 'wildcard' certificate (e.g. *.org.domain). $ read sys$command response /prompt="Continue? [N]: " $ say "" $ if .not. response then exit $! $ type sys$input ************************* * CERTIFICATE REQUEST * ************************* When prompted for: "Enter PEM pass phrase:" use "12345", or your own *secret* password. $ set noon $ define /user sys$input sys$command $!(^Y during password entry leaves the terminal kaput!) $ set nocontrol=y $ define /user openssl_conf 'configFileName' $ openSSL req -newkey rsa:'rsaKeySize' -verify -new -sha256 - -config 'configFileName' - -outform PEM -out 'workDir'TMPREQ.PEM - -keyout 'workDir'TMPKEY1.PEM $ set control=y $ set on $! $ type sys$input ************************** * CA SIGNS CERTIFICATE * ************************** When prompted for: "Enter pass phrase for sys$disk:[.cert]_cacert.pem:" supply the CA password, which should be "testing" if using the default WASD CA files. Note: the pass phrase is case-sensitive. $ set noon $ define /user sys$input sys$command $ set nocontrol=y $ define /user openssl_conf 'configFileName' $ openSSL ca -days 'validDays' -policy policy_anything - -config 'configFileName' - -outdir 'workDir' -out 'workDir'TMPCERT.PEM - -infiles 'workDir'TMPREQ.PEM $ set control=y $ set on $! $!(errors extrapolated from [.INCLUDE.OPENSSL]TXT_DB.H) $ type sys$input **************************************** * CHECK ABOVE FOR SUCCESSFUL SIGNING * **************************************** Indication of success: "Data Base Updated" These errors: "failed to update database TXT_DB error number 1" memory allocation failure number 2" index entry already exists number 3" index entry out-of-range number 4" no such index entry number 5" insert index entry clash (or other obvious error) Number 2 indicates this certificate's Distinguished Name (DN) is not unique. None of the fields is different to an existing certificate in the database. $ response = "" $ read sys$command response /prompt="Successful? [N]: " $ say "" $ if .not. response then goto serverCleanup $! $ type sys$input ******************************************* * PROVIDE EMBEDDED PRIVATE KEY PASSWORD * ******************************************* Private key password can be embedded with the private key (covenient) or provided manually at each server startup (secure but much less convenient). $ response = "Y" $ read sys$command line /prompt="Embed private key password? [Y]: " $ say "" $ if response .eqs. "" then response = "Y" $! $ if response $ then $! $ type sys$input When prompted for: "Enter PEM pass phrase:" use "12345", or your own *secret* password $ set noon $ define /user sys$input sys$command $ set nocontrol=y $ define /user openssl_conf 'configFileName' $ openSSl rsa -in 'workDir'TMPKEY1.PEM -out 'workDir'TMPKEY2.PEM $ rename 'workDir'TMPKEY2.PEM 'workDir'TMPKEY1.PEM;0 $ set control=y $ set on $! $ endif $! $!(append key to certificate as final file) $ copy 'workDir'TMPCERT.PEM,'workDir'TMPKEY1.PEM 'certDir''certFileName' $ define /user sys$output nl: $ define /user sys$error nl: $ set prot=w 'certDir''certFileName' $! $ type sys$input ********************* * C O M P L E T E * ********************* $ say "New server certificate is " + f$search("''certDir'''certFileName'") $ say "" $! $ goto serverCleanup $! $serverError: $ type sys$input *************** * E R R O R * *************** $! $ serverCleanup: $ define /user sys$output nl: $ define /user sys$error nl: $ delete 'workDir'*.PEM;* $ define /user sys$output nl: $ define /user sys$error nl: $ set prot=w 'certDir'*.*;* $ set prot=w 'workDir'*.*;* $ purge /nolog /keep=1 'workDir'SERIAL.*,'workDir'INDEX.*,'workDir'RAND.* $ if f$type(RANDFILE) .nes. "" then delete/symbol/global RANDFILE $! $ set default 'prevDefault' $! $!-----------------------------------------------------------------------------