Change this program example to suit your needs for generating a retained key pair for cloning master keys
/*-------------------------------------------------------------------*/ /* GENRETAIN */ /* */ /* Sample program to generate a retained key to be used for */ /* master key cloning. */ /* */ /* COPYRIGHT 5769-SS1 (C) IBM CORP. 1999, 1999 */ /* */ /* This material contains programming source code for your */ /* consideration. These examples have not been thoroughly */ /* tested under all conditions. IBM, therefore, cannot */ /* guarantee or imply reliability, serviceability, or function */ /* of these program. All programs contained herein are */ /* provided to you "AS IS". THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* ARE EXPRESSLY DISCLAIMED. IBM provides no program services for */ /* these programs and files. */ /* */ /* */ /* Note: Input format is more fully described in Chapter 2 of */ /* IBM CCA Basic Services Reference and Guide */ /* (SC31-8609) publication. */ /* */ /* Parameters: RETAINED_KEY_NAME */ /* */ /* Example: */ /* CALL PGM(GENRETAIN) PARM(TESTKEY) */ /* */ /* */ /* Note: This program assumes the card with the profile is */ /* already identified either by defaulting to the CRP01 */ /* device or by being explicitly named using the */ /* Cryptographic_Resource_Allocate verb. Also this */ /* device must be varied on and you must be authorized */ /* to use this device description. */ /* */ /* The Common Cryptographic Architecture (CCA) verbs used are */ /* PKA_Key_Token_Build (CSNDPKB) and PKA_Key_Generate (CSNDPKG). */ /* */ /* Use these commands to compile this program on the system: */ /* ADDLIBLE LIB(QCCA) */ /* CRTCMOD MODULE(GENRETAIN) SRCFILE(SAMPLE) */ /* CRTPGM PGM(GENRETAIN) MODULE(GENRETAIN) */ /* BNDDIR(QCCA/QC6BNDDIR) */ /* */ /* Note: Authority to the CSNDPKG and CSNDPKB service programs */ /* in the QCCA library is assumed. */ /* */ /*-------------------------------------------------------------------*/ #include <stdio.h> #include <string.h> #include "csucincl.h" int main(int argc, char *argv[]) { /*------------------------------------------------------------------*/ /* Declares for CCA parameters */ /*------------------------------------------------------------------*/ long return_code = 0; long reason_code = 0; long exit_data_length = 0; char exit_data[4]; char rule_array[24]; long rule_array_count; long token_len = 2500; char token[2500]; char regen_data[4]; char transport_key_id[4]; struct { short modlen; short modlenfld; short pubexplen; short prvexplen; long pubexp; } key_struct; /* Key structure for PKA Key Token Build */ long key_struct_length; long zero = 0; /*------------------------------------------------------------------*/ /* Declares for working with a PKA token */ /*------------------------------------------------------------------*/ long pub_sec_len; /* Public section length */ long prv_sec_len; /* Private section length */ long cert_sec_len; /* Certificate section length */ long info_subsec_len; /* Information subsection length */ long offset; /* Offset into token */ long tempOffset; /* (Another) Offset into token */ long tempLength; /* Length variable */ long tempLen1, tempLen2; /* temporary length variables */ char pub_token[2500]; long pub_token_len; long name_len; char name[64]; int i; /* Loop counter */ FILE *fp; /* File pointer */ if (argc < 2) /* Check the number of parameters passed */ { printf("Need to enter a private key name\n"); return 1; } memset(token,0,2500); /* Initialize token to 0 */ memcpy((void*)rule_array,"RSA-PRIVKEY-MGMT",16); /* Set rule array */ rule_array_count = 2; memset(name,' ', 64); /* Copy key name parameter */ memcpy(name, argv[1], strlen(argv[1])); name_len = 64; /*---------------------------*/ /* Initialize key structure */ /*---------------------------*/ memset((void*)&key_struct, 0, sizeof(key_struct)); key_struct.modlen = 1024; /* Modulus length is 1024 */ key_struct.pubexplen = 3; key_struct.pubexp = 0x01000100; /* Public exponent is 65537 */ key_struct_length = sizeof(key_struct); /*****************************************/ /* Call PKA_Key_Token_Build SAPI */ /*****************************************/ CSNDPKB( &return_code, &reason_code, &exit_data_length, exit_data, &rule_array_count, rule_array, &key_struct_length, (unsigned char *)&key_struct, &name_len, name, &zero, /* 1 */ NULL, &zero, /* 2 */ NULL, &zero, /* 3 */ NULL, &zero, /* 4 */ NULL, &zero, /* 5 */ NULL, &token_len, token); if (return_code != 0) { printf("PKA Key Token Build Failed : return code %d : reason code %d\n", return_code, reason_code); return 1; } /**************************************************************/ /* Build certificate */ /**************************************************************/ /* Determine length of token from length */ /* bytes at offset 2 and 3. */ token_len = ((256 * token[2]) + token[3]); /* Determine length of private key */ /* section from length bytes at offset */ /* 10. */ prv_sec_len = ((256 * token[10]) + token[11]); /* Determine length of public key section*/ /* section from length bytes at offset */ /* 10 + private section length */ pub_sec_len = ((256 * token[prv_sec_len + 10]) + token[prv_sec_len + 11]); /* Calculate the signature section length*/ cert_sec_len = 328 + /* from the signature subsection length, */ 20 + /* EID subsection length, */ 12 + /* Serial number subsection length, */ 4 + /* Information subsection header length, */ pub_sec_len + /* Public key subsection length, */ 4; /* and the certificate section hdr length*/ offset = token_len; /* Offset for additions to token */ /* Fill in certicate section header */ tempLen1 = cert_sec_len; tempLen1 >>= 8; token[offset++] = 0x40; token[offset++] = 0x00; token[offset++] = tempLen1; token[offset++] = cert_sec_len; /* Fill in public key subsection */ token[offset++] = 0x41; for (i = 1 ; i < pub_sec_len ; i ++) { /* Copy public key to certificate */ token[offset++] = token[prv_sec_len +(i+8)]; } /* Fill Optional Information Subsection Header */ info_subsec_len = 20 + /* Length of EID section */ 12 + /* Length of serial number section */ 4; /* Length of Info subsection header */ tempLen1 = info_subsec_len; tempLen1 >>= 8; token[offset++] = 0x42; token[offset++] = 0x00; token[offset++] = tempLen1; token[offset++] = info_subsec_len; /* Fill in Public Key Certficate EID subsection */ token[offset++] = 0x51; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x14; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; /* Public key Certificate Serial Number TLV */ token[offset++] = 0x52; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x0c; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; token[offset++] = 0x00; /* Fill in Signature Subsection */ token[offset++] = 0x45; token[offset++] = 0x00; token[offset++] = 0x01; token[offset++] = 0x48; token[offset++] = 0x01; token[offset++] = 0x01; for (i = 0 ; i < 64 ;i++) { /* Copy private key name out of private key name section */ /* into certificate */ token[offset++] = token[prv_sec_len + pub_sec_len + 12 + i]; } token_len = offset + 258; /* add 258 to allow for digtal sig. */ token[3] = token_len; /* Set new token length */ token[2] = token_len >> 8; /******************************************************************/ /* Generate Retained key using PKA token with certificate */ /******************************************************************/ memcpy((void*)rule_array,"RETAIN CLONE ",16); rule_array_count = 2; memset(pub_token,0,2500); pub_token_len = 2500; memset(transport_key_id,0,4); /*****************************************/ /* Call PKA_Key_Generate SAPI */ /*****************************************/ CSNDPKG( &return_code, &reason_code, &exit_data_length, exit_data, &rule_array_count, rule_array, &zero, /* regenerated data length */ regen_data, &token_len, token, transport_key_id, &pub_token_len, pub_token); if (return_code != 0) { printf("PKA Key Generate Failed : return code %d :reason code %d\n", return_code, reason_code); return 1; } /******************************************************************/ /* Write public key token out to file */ /******************************************************************/ /* Append ".PUB" to key name */ memcpy((void*)&name[strlen(argv[1])],".PUB",5); fp = fopen(name,"wb"); /* Open the file */ if (!fp) { printf("File open failed\n"); } else { fwrite(pub_token,pub_token_len,1,fp); /* Write token to file */ fclose(fp); /* Close the file */ printf("Public token written to file %s.\n",name); } name[strlen(argv[1])] = 0; /* Convert name to string */ printf("Private key %s is retained in the hardware\n",name); return 0; }