Change this program example to suit your needs for generating a retained key pair for cloning master keys.
D************************************************************* D* GENRETAIN D* D* Sample program to generate a retained key to be used for D* master key cloning. 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: RETAINED_KEY_NAME D* D* Example: D* CALL PGM(GENRETAIN) PARM(TESTKEY) D* D* Use these commands to compile this program on the system: D* CRTRPGMOD MODULE(GENRETAIN) SRCFILE(SAMPLE) D* CRTPGM PGM(GENRETAIN) MODULE(GENRETAIN) D* BNDDIR(QCCA/QC6BNDDIR) D* D* Note: Authority to the CSNDPKG and CSNDPKB service programs D* in the QCCA library is assumed. D* D* The Common Cryptographic Architecture (CCA) verbs used are D* PKA_Key_Token_Build (CSNDPKB) and PKA_Key_Generate (CSNDPKG). 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 DTOKEN DS 2500 DTOKENARRAY 1 DIM(2500) D* ** Regeneration data DREGENDATA S 4 INZ(X'00000000') D* ** Transport key encrypting key DTRANSPORTKEK S 4 INZ(X'00000000') D* ** Generated keyid DGENKEY S 2500 D* ** Generated keyid length DGENKEYLEN S 9B 0 INZ(2500) D* ** Key name and length DKEYNAME S 64 DKEYNAMEL S 9B 0 INZ(64) D* ** Key structure for PKA Key Token Build DKEYSTRUCT DS DMODLEN 1 2B 0 DMODLENFLD 3 4B 0 DPUBEXPLEN 5 6B 0 DPRVEXPLEN 7 8B 0 DPUBEXP 9 12B 0 D* ** Null parms needed for CSNDPKB and CSNDPKG DZERO S 9B 0 INZ(0) DNULLPTR S * INZ(*NULL) D* ** Key structure length DKEYSTRUCTLEN S 9B 0 INZ(12) D* ** Data structure for aligning 2 bytes into D* ** a 2 bytes integer DLENSTRUCT DS 2 DMSB 1 1 DLSB 2 2 DLENGTH 1 2B 0 D* ** Private key section length DPRVSECLEN S 9B 0 D* ** Public key section length DPUBSECLEN S 9B 0 D* ** Index into Token array DINDEX S 9B 0 D* ** Declares for copying private key name DNAMEPTR1 S * DNAME1 S 64 BASED(NAMEPTR1) DNAMEPTR2 S * DNAME2 S 64 BASED(NAMEPTR2) D* ** Loop counter DI S 9B 0 D* ** File descriptor DFILED S 9B 0 D* ** File path and length DPATH S 80 INZ(*ALLX'00') DPATHLEN S 9B 0 D* ** Open flag - Create on open, open for writing, D* ** and clear if exists DOFLAG S 10I 0 INZ(X'4A') D* D********************************************************** D* Prototype for PKA_Key_Token_Build (CSNDPKB) D********************************************************** DCSNDPKB PR DRETCODE 9B 0 DRSNCODE 9B 0 DEXTDTALEN 9B 0 DEXTDTA 4 DRARRAYCT 9B 0 DRARRAY 16 DKEYSTRLEN 9B 0 DKEYSTR 10 DKEYNML 9B 0 DKEYNM 64 DRSRVLN1 9B 0 DRSRV1 * VALUE DRSRVLN2 9B 0 DRSRV2 * VALUE DRSRVLN3 9B 0 DRSRV3 * VALUE DRSRVLN4 9B 0 DRSRV4 * VALUE DRSRVLN5 9B 0 DRSRV5 * VALUE DTKNLEN 9B 0 DTKN 2500 OPTIONS(*VARSIZE) D* D********************************************************** D* Prototype for PKA_Key_Generate (CSNDPKG) D********************************************************** DCSNDPKG PR DRETCOD 9B 0 DRSNCOD 9B 0 DEXTDTALN 9B 0 DEXTDT 4 DRARRYCT 9B 0 DRARRY 16 DREGDTAL 9B 0 DREGDTA 20 OPTIONS(*VARSIZE) DSKTKNL 9B 0 DSKTKN 2500 OPTIONS(*VARSIZE) DTRNKEK 64 OPTIONS(*VARSIZE) DGENKEYL 9B 0 DGENKEY 2500 OPTIONS(*VARSIZE) 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 write() D********************************************************** D* value returned = number of bytes actually written, or -1 Dwrite PR 9B 0 EXTPROC('write') D* File descriptor returned from open() D 9B 0 VALUE D* Data to be written D 1200 OPTIONS(*VARSIZE) D* Length of data to write 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(4) CTDATA PERRCD(1) DMSGLENGTH S 9B 0 INZ(75) D DS DMSGTEXT 1 75 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 KEYNAMEPARM 50 C* *------------------------* C* * Initialize tokens to 0 * C* *------------------------* C MOVEL *ALLX'00' TOKEN C MOVEL *ALLX'00' GENKEY C* *------------------------* C* * Initialize key struct * C* *------------------------* C Z-ADD 1024 MODLEN C Z-ADD 0 MODLENFLD C Z-ADD 3 PUBEXPLEN C Z-ADD 0 PRVEXPLEN C EVAL PUBEXP = 65537 * 256 C* *------------------------* C* * Copy key name from parm* C* *------------------------* C MOVEL KEYNAMEPARM KEYNAME C* *------------------------------------* C* * Set the keywords in the rule array * C* *------------------------------------* C MOVEL 'RSA-PRIV' RULEARRAY C MOVE 'KEY-MGMT' RULEARRAY C Z-ADD 2 RULEARRAYCNT C************************************************************** C* Call PKA_Key_Token_Build SAPI C************************************************************** C CALLP CSNDPKB (RETURNCODE: C REASONCODE: C EXITDATALEN: C EXITDATA: C RULEARRAYCNT: C RULEARRAY: C KEYSTRUCTLEN: C KEYSTRUCT: C KEYNAMEL: C KEYNAME: C ZERO: C NULLPTR: C ZERO: C NULLPTR: C ZERO: C NULLPTR: C ZERO: C NULLPTR: C ZERO: C NULLPTR: C TOKENLEN: C TOKEN) C* *------------------------* C* * Check the return code * C* *------------------------* C RETURNCODE IFGT 0 C* *------------------------* C* * Send failure message * C* *------------------------* C MOVEL MSG(1) MSGTEXT C MOVE RETURNCODE FAILRETC C MOVE REASONCODE FAILRSNC C MOVEL 'CSNDPKB' SAPI C EXSR SNDMSG C RETURN C ENDIF C* C*------------------------------------------------------------* C* Build the certificate * C*------------------------------------------------------------* C* Get the private section length. The length is at position 11 C* of the token C EVAL MSB = TOKENARRAY(10+1) C EVAL LSB = TOKENARRAY(11+1) C MOVE LENGTH PRVSECLEN C* Get the public section length. The length is at position C* (11 + Private key section length). C EVAL MSB = TOKENARRAY(10 + PRVSECLEN + 1) C EVAL LSB = TOKENARRAY(11 + PRVSECLEN + 1) C MOVE LENGTH PUBSECLEN C* Calculate the certificate section length C* Cert Section length = Signature length (328) + C* EID section length (20) + C* Serial number length (12) + C* Info subsection header length (4) + C* Public Key section length + C* Cert section header length (4) C EVAL LENGTH = 328 + 20 + 12 + 4 + PUBSECLEN + 4 C* Fill Certificate section header C MOVE TOKENLEN INDEX C EVAL TOKENARRAY(INDEX +1) = X'40' C EVAL TOKENARRAY(INDEX +2) = X'00' C EVAL TOKENARRAY(INDEX +3) = MSB C EVAL TOKENARRAY(INDEX +4) = LSB C* Fill in public key subsection C EVAL TOKENARRAY(INDEX +5) = X'41' C ADD 5 INDEX C Z-ADD 1 I C* Copy the public key section of the token into the public key C* subsection of the certificate section. C I DOWLT PUBSECLEN C EVAL TOKENARRAY(INDEX + I) = C TOKENARRAY(PRVSECLEN + I + 8 + 1) C 1 ADD I I C ENDDO C EVAL INDEX = INDEX + PUBSECLEN - 1 C* Fill in Optional Information subsection header C Z-ADD 36 LENGTH C EVAL TOKENARRAY(INDEX +1) = X'42' C EVAL TOKENARRAY(INDEX +2) = X'00' C EVAL TOKENARRAY(INDEX +3) = MSB C EVAL TOKENARRAY(INDEX +4) = LSB C* Fill in Public Key Certficate EID C EVAL INDEX = INDEX + 4 C EVAL TOKENARRAY(INDEX +1) = X'51' C EVAL TOKENARRAY(INDEX +4) = X'14' C* Fill in Public Key Certficate Serial Number TLV C EVAL INDEX = INDEX + 20 C EVAL TOKENARRAY(INDEX +1) = X'52' C EVAL TOKENARRAY(INDEX +4) = X'0C' C* Fill in Signature Subsection C EVAL INDEX = INDEX + 12 C EVAL TOKENARRAY(INDEX +1) = X'45' C EVAL TOKENARRAY(INDEX +3) = X'01' C EVAL TOKENARRAY(INDEX +4) = X'48' C EVAL TOKENARRAY(INDEX +5) = X'01' C EVAL TOKENARRAY(INDEX +6) = X'01' C* Fill in private key name C EVAL INDEX = INDEX + 6 C EVAL NAMEPTR1 = %ADDR(TOKENARRAY(INDEX +1)) C EVAL NAMEPTR2 = C %ADDR(TOKENARRAY(PRVSECLEN+PUBSECLEN+12+1)) C MOVEL NAME2 NAME1 C* Adjust token length C EVAL LENGTH = INDEX + 64 + 258 C MOVE MSB TOKENARRAY(3) C MOVE LSB TOKENARRAY(4) C EVAL TOKENLEN = LENGTH C* *------------------------------------* C* * Set the keywords in the rule array * C* *------------------------------------* C MOVEL 'RETAIN ' RULEARRAY C MOVE 'CLONE ' RULEARRAY C Z-ADD 2 RULEARRAYCNT C C*------------------------------------------------------* C* Call PKA_Key_Generate SAPI * C*------------------------------------------------------* C CALLP CSNDPKG (RETURNCODE: C REASONCODE: C EXITDATALEN: C EXITDATA: C RULEARRAYCNT: C RULEARRAY: C ZERO: C REGENDATA: C TOKENLEN: C TOKEN: C TRANSPORTKEK: C GENKEYLEN: C GENKEY) C*-----------------------* C* Check the return code * C*-----------------------* C RETURNCODE IFGT 0 C* *----------------------* C* * Send failure message * C* *----------------------* C MOVEL MSG(1) MSGTEXT C MOVE RETURNCODE FAILRETC C MOVE REASONCODE FAILRSNC C MOVEL 'CSNDPKG' SAPI C EXSR SNDMSG C RETURN C ENDIF C* C* *----------------------* C* * Send success message * C* *----------------------* C MOVEL MSG(2) MSGTEXT C EXSR SNDMSG C* C*-------------------------------* C* Write certificate out to file * C*-------------------------------* C* ** Build path name C EVAL PATHLEN = %LEN(%TRIM(KEYNAMEPARM)) C PATHLEN SUBST KEYNAMEPARM:1 PATH C EVAL %SUBST(PATH:PATHLEN+1:4) = '.PUB' 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(3) MSGTEXT C EXSR SNDMSG C* C ELSE C* C* ** Open worked, write certificate out to file and close file C* C CALLP write (FILED: C GENKEY: C GENKEYLEN) C CALLP close (FILED) C* C* ** Send completion message C* C MOVEL MSG(4) MSGTEXT C EVAL %SUBST(MSGTEXT: 32: PATHLEN + 4) = C %SUBST(PATH: 1: PATHLEN + 4) 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 C* ** CSNDPKB failed with return/reason codes 9999/9999. The retained key was successfully created. The file could not be opened. The certificate was written to