Example: ILE C program for installing a master key share

Change this program example to suit your needs for installing a master key share.

Note: Read the Code license and disclaimer information for important legal information.
/*-------------------------------------------------------------------*/
/* PUTSHARE                                                          */
/*                                                                   */
/* Sample program to install a master key share as part of the       */
/* master key cloning process.                                       */
/*                                                                   */
/*  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: Share number                                          */
/*             Name of share receiver private key                    */
/*             Name of certifying key                                */
/*             Stream file containing sender certificate             */
/*                                                                   */
/*                                                                   */
/* Example:                                                          */
/*   CALL PGM(PUTSHARE) PARM(2 RECVR SAKEY SNDR.PUB)                 */
/*                                                                   */
/*                                                                   */
/* 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 is         */
/* Master_Key_Distribution (CSUAMKD).                                */
/*                                                                   */
/* Use these commands to compile this program on the system:         */
/* ADDLIBLE LIB(QCCA)                                                */
/* CRTCMOD MODULE(PUTSHARE)  SRCFILE(SAMPLE)                         */
/* CRTPGM  PGM(PUTSHARE)   MODULE(PUTSHARE)                          */
/*         BNDDIR(QCCA/QC6BNDDIR)                                    */
/*                                                                   */
/* Note: Authority to the CSUAMKD service program                    */
/*       in the QCCA library is assumed.                             */
/*                                                                   */
/*-------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "csucincl.h"
#include "decimal.h"

extern void QDCXLATE(decimal(5,0), char *, char*, char *);
#pragma linkage (QDCXLATE, OS, nowiden)

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];
 long cloneInfoKeyLength = 500;
 unsigned char cloneInfoKey[500];
 long cloneInfoLength = 400;
 unsigned char cloneInfo[400];
 long shareIdx;
 char name[64];
 char SAname[64];
 /*------------------------------------------------------------------*/
 /* 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 cloneShare[] = "cloneShare00";  /* Base cloning share filename */
 long count;                /* Number of bytes read in from file     */
 decimal(15,5) shareParm;   /* Packed 15 5 var used for converting   */
                            /* from packed 15 5 to binary.  Numeric  */
                            /* parms on system are passed as dec 15 5*/
 FILE *fp;                  /* File pointer                          */

 if (argc < 5)              /* Check number of parameters passed in  */
  {
   printf("Need Share index, Receiver name, SA name, and cert\n");
   return 1;
  }

                            /* Convert the packed decimal 15 5 parm  */
                            /* to binary.                            */
 memcpy(&shareParm,argv[1],sizeof(shareParm));
 shareIdx = shareParm;
 memset(name,' ',64);       /* Copy the Private key name parm to a   */
 memcpy(name,argv[2],strlen(argv[2]));  /* 64 byte space padded var. */
 memset(SAname,' ',64);     /* Copy the Share Admin name parm to a   */
 memcpy(SAname,argv[3],strlen(argv[3]));/* 64 byte space padded var. */

 fp = fopen(argv[4],"rb");  /* Open the file containing the token    */
 if (!fp)
  {
   printf("File %s not found.\n",argv[4]);
   return 1;
  }

 memset(token,0,2500);      /* Read the token from the file          */
 count = fread(token,1,2500,fp);

 fclose(fp);                /* Close the file                        */

                            /* Determine length of token from length */
                            /* bytes at offset 2 and 3.              */
 token_len = ((256 * token[2]) + token[3]);
 if (count < token_len)     /* Check if whole token was read in      */
  {
   printf("Incomplete token in file\n");
   return 1;
  }

 /************************************************************/
 /* Find the certificate offset in the token                 */
 /*                                                          */
 /* The layout of the token is                               */
 /*                                                          */
 /* - Token header - 8 bytes - including 2 length bytes      */
 /* - Public key section - length bytes at offset 10 overall */
 /* - Private key name - 68 bytes                            */
 /* - Certificate section                                    */
 /*                                                          */
 /************************************************************/
 pub_sec_len = ((256 * token[10]) + token[11]);

 offset = pub_sec_len + 68 + 8; /* Set offset to certiicate section */

                                 /* Determine certificate section    */
                                 /* length from the length bytes at  */
                                 /* offset 2 of the section.         */
 cert_sec_len = ((256 * token[offset + 2]) + token[offset + 3]);

 /**********************************************/
 /* Open and read the clone file               */
 /**********************************************/
                                 /* Build path name from the base    */
                                 /* file name and the index          */
 if (shareIdx < 9) cloneShare[11] = '0' + shareIdx;
 else
   {
    cloneShare[10] = '1';
    cloneShare[11] = '0' + shareIdx - 10;
   }

 fp = fopen(cloneShare,"rb");  /* Open the file with the share       */
 if (!fp)
  {
   printf("Clone share file %s not found.\n",cloneShare);
   return 1;
  }
                            /* Read in the length of the KEK         */
  count = fread((char*)&cloneInfoKeyLength,1,4,fp);

  if (count < 4)            /* Check if there was an error           */
   {
    printf("Clone share file %s contains invalid data.\n",
            cloneShare);
    fclose(fp);
    return 1;
   }
                            /* Read in the Key encrypting key        */
  count = fread((char*)cloneInfoKey,1,cloneInfoKeyLength,fp);

  if (count < cloneInfoKeyLength)  /* Check for an error reading     */
   {
    printf("Clone share file %s contains invalid data.\n",
            cloneShare);
    fclose(fp);
    return 1;
   }

                            /* Read in the length of the clone info  */
  count = fread((char*)&cloneInfoLength,1,4,fp);


  if (count < 4)            /* Check for an error                    */
   {
    printf("Clone share file %s contains invalid data.\n",
            cloneShare);
    fclose(fp);
    return 1;
   }

                            /* Read in the clone info                */
  count = fread((char*)cloneInfo,1,cloneInfoLength,fp);

  if (count < cloneInfoLength)  /* Check for an error                */
   {
    printf("Clone share file %s contains invalid data.\n",
            cloneShare);
    fclose(fp);
    return 1;
   }

  fclose(fp);               /* Close the file                        */

 /**************************************************************/
 /* Install the share                                          */
 /**************************************************************/
 memcpy((void*)rule_array,"INSTALL ",8);  /* Set rule array          */
 rule_array_count = 1;

 CSUAMKD( &return_code, &reason_code, &exit_data_length,
          exit_data,
          &rule_array_count,
          (unsigned char*)rule_array,
          &shareIdx,
          name,
          SAname,
          &cert_sec_len,
          &token[offset],
          &cloneInfoKeyLength,
          cloneInfoKey,
          &cloneInfoLength,
          cloneInfo);

 if (return_code > 4 )
  {
   printf("Master Key Distribution Failed : return reason %d/%d\n",
           return_code, reason_code);
   return 1;
  }
 else
  {
   printf("Master Key share %d successfully installed.\n",shareIdx);
   printf("Return reason codes %d/%d\n",return_code, reason_code);
   return 0;
  }

}