Change this program example to suit your needs for registering a hash of a public key certificate.
D************************************************************* D* REGHASH D* D* Sample program to register the hash of a CCA public key D* certificate. D* D* D* COPYRIGHT 5769-SS1 (C) IBM CORP. 2000, 2000 D* D* This material contains programming source code for your D* consideration. These example has not been thoroughly D* tested under all conditions. IBM, therefore, cannot D* guarantee or imply reliability, serviceability, or function D* of these programs. All programs contained herein are D* provided to you "AS IS". THE IMPLIED WARRANTIES OF D* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D* ARE EXPRESSLY DISCLAIMED. IBM provides no program services for D* these programs and files. D* D* D* Note: Input format is more fully described in Chapter 2 of D* IBM CCA Basic Services Reference and Guide D* (SC31-8609) publication. D* D* Parameters: Stream file containing public key certificate D* D* Example: D* CALL PGM(REGHASH) PARM(CERTFILE) D* D* Use these commands to compile this program on the system: D* CRTRPGMOD MODULE(REGHASH) SRCFILE(SAMPLE) D* CRTPGM PGM(REGHASH) MODULE(REGHASH) D* BNDDIR(QCCA/QC6BNDDIR) D* D* Note: Authority to the CSNDPKH and CSNBOWH service programs D* in the QCCA library is assumed. D* D* The Common Cryptographic Architecture (CCA) verbs used are D* PKA_Public_Key_Hash_Register (CSNDPKH) and One_Way_Hash C* (CSNBOWH). D* D************************************************************** D*-------------------------------------------------------- D* Declare variables used by CCA SAPI calls D*-------------------------------------------------------- D* ** Return code DRETURNCODE S 9B 0 D* ** Reason code DREASONCODE S 9B 0 D* ** Exit data length DEXITDATALEN S 9B 0 D* ** Exit data DEXITDATA S 4 D* ** Rule array count DRULEARRAYCNT S 9B 0 D* ** Rule array DRULEARRAY S 16 D* ** Token length DTOKENLEN S 9B 0 INZ(2500) D* ** Token and array for subscripting token DTOKEN DS 2500 DTOKENARRAY 1 DIM(2500) D* ** Chaining vector length DCHAINVCTLEN S 9B 0 INZ(128) D* ** Chaining vector DCHAINVCT S 128 D* ** Hash length DHASHLEN S 9B 0 INZ(20) D* ** Hash DHASH S 20 D* ** Text length DTXTLENGTH S 9B 0 D* ** Name of retained key DNAME S 64 D* ** Structure used for aligning 2 bytes into a D* ** 2 byte integer. DLENSTRUCT DS 2 DMSB 1 1 DLSB 2 2 DLENGTH 1 2B 0 D* D* ** Certificate section length DCRTSECLEN S 9B 0 D* ** Public key section length DPUBSECLEN S 9B 0 D* ** Index into PKA key token DTKNINDEX S 9B 0 D* ** Index into PKA key token DTMPINDEX S 9B 0 D* ** File descriptor DFILED S 9B 0 D* ** File path and path length DPATH S 80 INZ(*ALLX'00') DPATHLEN S 9B 0 D* ** Open Flag - Open for Read only DOFLAG S 10I 0 INZ(1) D* D********************************************************** D* Prototype for PKA_Public_Key_Hash_Register (CSNDPKH) D********************************************************** DCSNDPKH PR DRETCOD 9B 0 DRSNCOD 9B 0 DEXTDTALN 9B 0 DEXTDT 4 DRARRYCT 9B 0 DRARRY 16 DKYNAM 64 DHSHL 9B 0 DHSH 20 OPTIONS(*VARSIZE) D* D********************************************************** D* Prototype for One_Way_Hash (CSNBOWH) D********************************************************** DCSNBOWH PR DRETCOD 9B 0 DRSNCOD 9B 0 DEXTDTALN 9B 0 DEXTDT 4 DRARRYCT 9B 0 DRARRY 16 DTXTLEN 9B 0 DTXT 500 OPTIONS(*VARSIZE) DCHNVCTLEN 9B 0 DCHNVCT 128 DHSHLEN 9B 0 DHSH 20 D* D* D********************************************************** D* Prototype for open() D********************************************************** D* value returned = file descriptor (OK), -1 (error) Dopen PR 9B 0 EXTPROC('open') D* path name of file to be opened. D 128 OPTIONS(*VARSIZE) D* Open flags D 9B 0 VALUE D* (OPTIONAL) mode - access rights D 10U 0 VALUE OPTIONS(*NOPASS) D* (OPTIONAL) codepage D 10U 0 VALUE OPTIONS(*NOPASS) D* D********************************************************************* D* Prototype for read() D********************************************************** D* value returned = number of bytes actually read, or -1 Dread PR 9B 0 EXTPROC('read') D* File descriptor returned from open() D 9B 0 VALUE D* Input buffer D 2500 OPTIONS(*VARSIZE) D* Length of data to be read D 9B 0 VALUE D* D********************************************************************* D* Prototype for close() D********************************************************************* D* value returned = 0 (OK), or -1 Dclose PR 9B 0 EXTPROC('close') D* File descriptor returned from open() D 9B 0 VALUE D* D*------------------------------------------------------------- D* ** Declares for sending messages to the D* ** job log using the QMHSNDPM API D*------------------------------------------------------------- DMSG S 75 DIM(6) CTDATA PERRCD(1) DMSGLENGTH S 9B 0 INZ(75) D DS DMSGTEXT 1 80 DSAPI 1 7 DFAILRETC 41 44 DFAILRSNC 46 49 DMESSAGEID S 7 INZ(' ') DMESSAGEFILE S 21 INZ(' ') DMSGKEY S 4 INZ(' ') DMSGTYPE S 10 INZ('*INFO ') DSTACKENTRY S 10 INZ('* ') DSTACKCOUNTER S 9B 0 INZ(2) DERRCODE DS DBYTESIN 1 4B 0 INZ(0) DBYTESOUT 5 8B 0 INZ(0) C* C************************************************************** C* START OF PROGRAM * C* * C *ENTRY PLIST C PARM FILEPARM 50 C************************************************************** C* Open certificate file C************************************************************** C* *---------------------* C* ** Build path name * C* *---------------------* C EVAL PATHLEN = %LEN(%TRIM(FILEPARM)) C PATHLEN SUBST FILEPARM:1 PATH C* *---------------------* C* * Open the file * C* *---------------------* C EVAL FILED = open(PATH: OFLAG) C* *----------------------* C* * Check if open worked * C* *----------------------* C FILED IFEQ -1 C* *------------------------------------* C* * Open failed, send an error message * C* *------------------------------------* C MOVEL MSG(1) MSGTEXT C EXSR SNDMSG C RETURN C* C ENDIF C* *--------------------------------------------------* C* * Open worked, read certificate and close the file * C* *--------------------------------------------------* C EVAL TOKENLEN = read(FILED: TOKEN: TOKENLEN) C CALLP close (FILED) C* C* *--------------------------------------* C* * Check if read operation was OK * C* *--------------------------------------* C TOKENLEN IFEQ -1 C MOVEL MSG(2) MSGTEXT C EXSR SNDMSG C RETURN C ENDIF C* C* *--------------------------------------* C* * Check if certificate length is valid * C* * The length bytes start at position 3 * C* *--------------------------------------* C EVAL MSB = TOKENARRAY(3) C EVAL LSB = TOKENARRAY(4) C LENGTH IFLT TOKENLEN C* *-----------------------------------* C* * Certificate length is not valid * C* *-----------------------------------* C MOVEL MSG(3) MSGTEXT C EXSR SNDMSG C RETURN C ENDIF C* C************************************************************** C* Find the certificate in the token C* C* The layout of the token is C* C* - Token header - 8 bytes - including 2 length bytes C* - Public key section - length bytes at position 3 (11 overall) C* - Private key name - 68 bytes C* - Certificate section C* C* Note: 1 is added because RPG arrays start at 1. C************************************************************** C EVAL MSB = TOKENARRAY(11) C EVAL LSB = TOKENARRAY(12) C EVAL PUBSECLEN = LENGTH C EVAL TKNINDEX = PUBSECLEN + 68 + 8 + 1 C* C* *-----------------------------------------* C* * Determine length of certificate section * C* * Length bytes are at position 2 of the * C* * section. C* *-----------------------------------------* C EVAL MSB = TOKENARRAY(TKNINDEX + 2) C EVAL LSB = TOKENARRAY(TKNINDEX + 3) C EVAL CRTSECLEN = LENGTH C EVAL TMPINDEX = TKNINDEX + 4 C* C* *-----------------------------------------------------* C* * Parse each subsection of the certificate until the * C* * signature subsection is found or the end is reached.* C* * (Identifier for signature subsection is Hex 45.) * C* *-----------------------------------------------------* C DOW (TOKENARRAY(TMPINDEX) <> X'45') AND C (TMPINDEX < TKNINDEX + CRTSECLEN) C EVAL MSB = TOKENARRAY(TMPINDEX + 2) C EVAL LSB = TOKENARRAY(TMPINDEX + 3) C TMPINDEX ADD LENGTH TMPINDEX C ENDDO C* C* *----------------------------------------------------* C* * Check if no signature was found before the end of * C* * the certificate section. * C* *----------------------------------------------------* C IF TOKENARRAY(TMPINDEX) <> X'45' C MOVEL MSG(4) MSGTEXT C EXSR SNDMSG C RETURN C ENDIF C* C************************************************************** C* Hash the certificate C************************************************************** C* *------------------------------------------* C* * Calculate the length to hash * C* *------------------------------------------* C EVAL TXTLENGTH = TMPINDEX - TKNINDEX + 70 C* *------------------------------------------* C* * Set the keywords in the rule array * C* *------------------------------------------* C MOVEL 'SHA-1 ' RULEARRAY C Z-ADD 1 RULEARRAYCNT C* *-------------------------* C* * Call One Way Hash SAPI * C* *-------------------------* C CALLP CSNBOWH (RETURNCODE: C REASONCODE: C EXITDATALEN: C EXITDATA: C RULEARRAYCNT: C RULEARRAY: C TXTLENGTH: C TOKENARRAY(TKNINDEX): C CHAINVCTLEN: C CHAINVCT: C HASHLEN: C HASH) C* *------------------------* C* * Check the return code * C* *------------------------* C RETURNCODE IFGT 0 C* *-----------------------* C* * Send failure message * C* *-----------------------* C MOVEL MSG(5) MSGTEXT C MOVE RETURNCODE FAILRETC C MOVE REASONCODE FAILRSNC C MOVEL 'CSNBOWH' SAPI C EXSR SNDMSG C RETURN C ENDIF C* C************************************************************** C* Register the certificate hash C************************************************************** C* *------------------------------------------* C* * Set the keywords in the rule array * C* *------------------------------------------* C MOVEL 'SHA-1 ' RULEARRAY C MOVE 'CLONE ' RULEARRAY C Z-ADD 2 RULEARRAYCNT C* *------------------------------------------* C* * Build the key name (FILENAME.RETAINED) * C* *------------------------------------------* C EVAL %SUBST(NAME: 1: PATHLEN) = C %SUBST(PATH: 1: PATHLEN) C EVAL %SUBST(NAME:PATHLEN+1:9) = '.RETAINED' C* *-----------------------------------* C* * Call PKA Public Key Hash Register * C* *-----------------------------------* C CALLP CSNDPKH (RETURNCODE: C REASONCODE: C EXITDATALEN: C EXITDATA: C RULEARRAYCNT: C RULEARRAY: C NAME: C HASHLEN: C HASH) C* *------------------------* C* * Check the return code * C* *------------------------* C RETURNCODE IFGT 0 C* *-----------------------* C* * Send failure message * C* *-----------------------* C MOVEL MSG(5) MSGTEXT C MOVE RETURNCODE FAILRETC C MOVE REASONCODE FAILRSNC C MOVEL 'CSNDPKH' SAPI C EXSR SNDMSG C ELSE C* *-----------------------* C* * Send success message * C* *-----------------------* C MOVEL MSG(6) MSGTEXT C EVAL %SUBST(MSGTEXT: 41: PATHLEN + 9) = C %SUBST(NAME: 1: PATHLEN + 9) C EXSR SNDMSG C ENDIF C* C SETON LR C* C************************************************************** C* Subroutine to send a message C************************************************************** C SNDMSG BEGSR C CALL 'QMHSNDPM' C PARM MESSAGEID C PARM MESSAGEFILE C PARM MSGTEXT C PARM MSGLENGTH C PARM MSGTYPE C PARM STACKENTRY C PARM STACKCOUNTER C PARM MSGKEY C PARM ERRCODE C ENDSR ** The file could not be opened. There was an error reading from the file. The length of the certificate is not valid. The certificate is not valid. CSNBOWH failed with return/reason codes 9999/9999. The hash was successfully registered as