Example in ILE C: Reading encrypted data from a file

See Code disclaimer information for information pertaining to code examples.

Refer to Scenario: Key Management and File Encryption Using the Cryptographic Services APIs for a description of this scenario.

Start of change
/*-------------------------------------------------------------------*/
/*                                                                   */
/* Sample C program:  Bill_Cus                                       */
/*                                                                   */
/*  COPYRIGHT      5722-SS1 (c) IBM Corp 2004, 2006                  */
/*                                                                   */
/*  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 programs.  All programs contained herein are            */
/*  provided to you "AS IS". THE IMPLIED WARRANTIES OF               */
/*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE         */
/*  EXPRESSLY DISCLAIMED. IBM provides no program services for       */
/*  these programs and files.                                        */
/*                                                                   */
/* Description:                                                      */
/*  This is a sample program to demonstrate use of the Cryptographic */
/*  Services APIs.  APIs demonstrated in this program are:           */
/*   Create Algorithm Context                                        */
/*   Create Key Context                                              */
/*   Decrypt Data                                                    */
/*   Destroy Key Context                                             */
/*   Destroy Algorithm Context                                       */
/*                                                                   */
/* Function:                                                         */
/*  For each record in the Customer Data file (CUSDTA), check the    */
/*  accounts receivable balance.  If there is a balance, decrypt the */
/*  customer's data and call Bill_Cus to create a bill.  The customer*/
/*  data is encrypted with a file key kept in the Customer Processing*/
/*  Information file (CUSPI).                                        */
/*                                                                   */
/*  Refer to the iSeries (TM) Information Center for a full          */
/*  description of this scenario.                                    */
/*                                                                   */
/* Use the following commands to compile this program:               */
/*   CRTCMOD MODULE(MY_LIB/BILL_CUS) SRCFILE(MY_LIB/MY_SRC)          */
/*   CRTSRVPGM SRVPGM(MY_LIB/BILL_CUS) +                             */
/*             MODULE(MY_LIB/BILL_CUS MY_LIB/CREATE_BILL) +          */
/*             BNDSRVPGM(QC3CTX QC3PRNG QC3DTADE)                    */
/*                                                                   */
/*-------------------------------------------------------------------*/
 
/*-------------------------------------------------------------------*/
/* Retrieve various structures/utilities.                            */
/*-------------------------------------------------------------------*/
 
#include <stdio.h>                    /* Standard I/O header         */
#include <stdlib.h>                   /* General utilities           */
#include <stddef.h>                   /* Standard definitions        */
#include <string.h>                   /* String handling utilities   */
#include <recio.h>                    /* Record I/O routines         */
#include <qusec.h>                    /* Error code structure        */
#include <qc3ctx.h>                   /* Hdr file for Context APIs   */
#include <qc3dtade.h>                 /* Hdr file for Decrypt Dta API*/

/*-------------------------------------------------------------------*/
/* The following structures were generated with GENCSRC.             */
/*-------------------------------------------------------------------*/
 
  #ifdef __cplusplus                                            
  #include <bcd.h>                                              
  #else                                                         
  #include <decimal.h>                                          
  #endif                                                        
  /* ------------------------------------------------------- *  
  // PHYSICAL FILE : MY_LIB/CUSPI                                
  // FILE LAST CHANGE DATE : 2004/02/11                         
  // RECORD FORMAT : CUSPIREC                                   
  // FORMAT LEVEL IDENTIFIER : 248C15A88E09C                    
   * ------------------------------------------------------- */ 
  typedef _Packed struct {                                                 
     char KEY[16];                         /* ENCRYPTION KEY */            
                                                                         
  #ifndef __cplusplus                                                      
     decimal( 8, 0) LASTCUS;                                               
  #else                                                                    
     _DecimalT< 8, 0> LASTCUS;             /* LAST CUSTOMER NUMBER */      
                                           /* BCD class SPECIFIED IN DDS */
  #endif                                                                   
  } CUSPIREC_both_t;                                           

  /* ------------------------------------------------------- *              
  // PHYSICAL FILE : MY_LIB/CUSDTA                                           
  // FILE LAST CHANGE DATE : 2004/02/11                                     
  // RECORD FORMAT : CUSDTAREC                                              
  // FORMAT LEVEL IDENTIFIER : 434C857F6F5B3                                
   * ------------------------------------------------------- */             
  typedef _Packed struct {                                                  
                                                                          
  #ifndef __cplusplus                                                       
     decimal( 8, 0) CUSNUM;                                                 
  #else                                                                     
     _DecimalT< 8, 0> CUSNUM;              /* CUSTOMER NUMBER */            
                                           /* BCD class SPECIFIED IN DDS */
  #endif                                                                    
     char IV[16];                          /* INITIALIZATION VECTOR */      
                                                                          
  #ifndef __cplusplus                                                       
     decimal(10, 2) ARBAL;                                                  
  #else                                                                     
     _DecimalT<10, 2> ARBAL;               /* ACCOUNTS RECEIVABLE BALANCE */
                                           /* BCD class SPECIFIED IN DDS */ 
  #endif                                                                    
     char ECUSDTA[80];                     /* ENCRYPTED CUSTOMER DATA */    
  } CUSDTAREC_both_t;                                          

/*-------------------------------------------------------------------*/
/* Function declarations                                             */
/*-------------------------------------------------------------------*/

                                      /* Create a bill               */
void Create_Bill(char *customerData, decimal(10, 2) balance);

/*-------------------------------------------------------------------*/
/* Start of mainline code.                                           */
/*-------------------------------------------------------------------*/

int Bill_Cus()
{
    
/*-------------------------------------------------------------------*/
/* Return codes                                                      */
/*-------------------------------------------------------------------*/
 
  int                   rtn;          /* Return code                 */
  #define               ERROR  -1
  #define               OK      0
 
/*-------------------------------------------------------------------*/
/* File handling variables                                           */
/*-------------------------------------------------------------------*/

  _RFILE               *cuspiPtr;     /* Pointer to CUSPI  file      */
  _RFILE               *cusdtaPtr;    /* Pointer to CUSDTA file      */
  CUSPIREC_both_t       cuspi;        /* CUSPI record                */
  CUSDTAREC_both_t      cusdta;       /* CUSDTA record               */
 
/*-------------------------------------------------------------------*/
/* Parameters needed by the Cryptographic Services APIs              */
/*-------------------------------------------------------------------*/
 
  Qus_EC_t              errCode;      /* Error code structure        */
  char                  csp;          /* Crypto service provider     */
  Qc3_Format_ALGD0200_T algD;         /* Block cipher alg description*/
  char                  AESctx[8];    /* AES alg context token       */
  int                   keySize;      /* Key size                    */
  char                  keyFormat;    /* Key format                  */
  int                   keyType;      /* Key type                    */
  char                  keyForm;      /* Key form                    */
  int                   keyStringLen; /* Length of key string        */
  Qc3_Format_KEYD0400_T kskey;        /* Key store structure         */
  char                  KEKctx[8];    /* KEK key context token       */
  char                  FKctx[8];     /* File key context token      */
  char                  pcusdta[80];  /* Plaintext customer data     */
  int                   cipherLen;    /* Length of ciphertext        */
  int                   plainLen;     /* Length of plaintext         */
  int                   rtnLen;       /* Return length               */
 
/*-------------------------------------------------------------------*/
/* Initializations                                                   */
/*-------------------------------------------------------------------*/
 
                                      /* Set to generate exceptions  */
  memset(&errCode, 0, sizeof(errCode));
                                      /* Use any crypto provider     */
  csp = Qc3_Any_CSP;

/*-------------------------------------------------------------------*/
/* Create an AES algorithm context for the key-encrypting key (KEK). */
/*-------------------------------------------------------------------*/
 
  memset(&algD, 0, sizeof(algD));     /* Init alg description to null*/
  algD.Block_Cipher_Alg = Qc3_AES;    /* Set AES algorithm           */
  algD.Block_Length = 16;             /* Block size is 16            */
  algD.Mode = Qc3_CBC;                /* Use cipher block chaining   */
  algD.Pad_Option = Qc3_No_Pad;       /* Do not pad                  */
                                      /* Create algorithm context    */
  Qc3CreateAlgorithmContext((unsigned char *)&algD,
      Qc3_Alg_Block_Cipher, AESctx, &errCode);
 
/*-------------------------------------------------------------------*/
/* Create a key context for the key-encrypting key (KEK).            */
/*-------------------------------------------------------------------*/

  keyFormat = Qc3_KSLabel_Struct;     /* Key format is keystore label*/
  keyStringLen = sizeof(kskey);       /* Length of key string        */
  keyType = Qc3_AES;                  /* Key type is AES             */
  keyForm = Qc3_Clear;                /* Key string is clear         */
  memset(&kskey, 0, sizeof(kskey));   /* Init name structure to null */
                                      /* Set key store file name     */
  memset(kskey.Key_Store, 0x40, sizeof(kskey.Key_Store));
  memcpy(kskey.Key_Store,"CUSKEYFILEMY_LIB", 16);
                                      /* Set key store label         */
  memset(kskey.Record_Label, 0x40, sizeof(kskey.Record_Label));
  memcpy(kskey.Record_Label, "CUSDTAKEK", 9);
                                      /* Create key context          */
  Qc3CreateKeyContext((char*)&kskey, &keyStringLen, &keyFormat, &keyType,
                      &keyForm, NULL, NULL, KEKctx, &errCode);
 
/*-------------------------------------------------------------------*/
/* Open Customer Processing Information file (CUSPI).                */
/* Read first record to obtain the encrypted file key.               */
/*-------------------------------------------------------------------*/
 
                                      /* Open CUSPI file             */
  if ((cuspiPtr = _Ropen("MY_LIB/CUSPI", "rr, arrseq=Y, riofb=N"))
       == NULL)
  {                                   /* If null ptr returned        */
                                      /* Send error message          */
    printf("Open of Customer Processing Information file (CUSPI) failed.");
    return ERROR;                     /* Return with error           */
  } 
                                      /* Read the first(only) record */
                                      /* to get encrypted file key.  */
  if ((_Rreadf(cuspiPtr, &cuspi, sizeof(cuspi), __DFT))->num_bytes
       == EOF)
  {                                   /* If record not found         */
                                      /* Send error message          */
    printf("Customer Processing Information (CUSPI) record missing.");
    _Rclose(cuspiPtr);                /* Close CUSPI file            */
    return ERROR;                     /* Return with error           */
  }
 
/*-------------------------------------------------------------------*/
/* Create a key context for the file key.                            */
/*-------------------------------------------------------------------*/

  keySize = sizeof(cuspi.KEY);        /* Key size                    */
  keyFormat = Qc3_Bin_String;         /* Key format is binary string */
  keyType = Qc3_AES;                  /* Key type is AES             */
  keyForm = Qc3_Encrypted;            /* Key is encrypted with a KEK */
                                      /* Create key context          */
  Qc3CreateKeyContext(cuspi.KEY, &keySize, &keyFormat, &keyType,
                      &keyForm, KEKctx, AESctx, FKctx, &errCode);

/*-------------------------------------------------------------------*/
/* Wipe out the encryptd file key value from program storage and     */
/* close the CUSPI file.                                             */
/*-------------------------------------------------------------------*/
 
                                      /* Wipe out encrypted file key */
  memset(cuspi.KEY, 0, sizeof(cuspi.KEY));
  _Rclose(cuspiPtr);                  /* Close CUSPI file            */
 
/*-------------------------------------------------------------------*/
/* Open Customer Data file.                                          */
/*-------------------------------------------------------------------*/
 
                                      /* Open CUSDTA file            */
  if ((cusdtaPtr = _Ropen("MY_LIB/CUSDTA", "rr, arrseq=Y, riofb=N"))
       == NULL)
  {                                   /* If null ptr returned        */
                                      /* Send error message          */
    printf("Open of CUSDTA file failed.");
    return ERROR;
  }

/*-------------------------------------------------------------------*/
/* Read each record of CUSDTA.                                       */
/*-------------------------------------------------------------------*/
 
                                      /* Read next record in file    */
                                      /* while not End-Of-File       */
  while ((_Rreadn(cusdtaPtr, &cusdta, sizeof(cusdta), __DFT))->num_bytes
          != EOF)
  {

/*-------------------------------------------------------------------*/
/* If accounts receivable balance > 0, decrypt customer data and     */
/* create a bill for the customer.                                   */
/*-------------------------------------------------------------------*/
 
    if (cusdta.ARBAL > 0)
    {
                                      /* Copy IV to alg description  */
      memcpy(algD.Init_Vector, cusdta.IV, 16);

                                      /* Decrypt customer data       */
      cipherLen = sizeof(cusdta.ECUSDTA);
      plainLen = sizeof(pcusdta);
      Qc3DecryptData(cusdta.ECUSDTA, &cipherLen,
                     (char*)&algD, Qc3_Alg_Block_Cipher,
                     FKctx,  Qc3_Key_Token,
                     &csp, NULL, pcusdta, &plainLen, &rtnLen,
                     &errCode);

                                      /* Create bill                 */
      Create_Bill(pcusdta, cusdta.ARBAL);
    }
  }

/*-------------------------------------------------------------------*/
/* Cleanup.                                                          */
/*-------------------------------------------------------------------*/
 
                                      /* Clear plaintext data        */
  memset(&pcusdta, 0, sizeof(pcusdta));
                                      /* Destroy file key context    */
  Qc3DestroyKeyContext(FKctx, &errCode);
                                      /* Destroy KEK context         */
  Qc3DestroyKeyContext(KEKctx, &errCode);
                                      /* Destroy the alg context     */
  Qc3DestroyAlgorithmContext(AESctx, &errCode);
                                      /* Close CUSDTA file           */
  _Rclose(cusdtaPtr);     
                                      /* Return successful           */
  return OK;

}

End of change



Top | Cryptographic Services APIs |APIs by category