Change this program example to suit your needs for signing a file with your Cryptographic Coprocessor.
If you choose to use this program example, change it to suit your specific needs. For security reasons, IBM® recommends that you individualize these program examples rather than using the default values provided.
/*---------------------------------------------------------------*/ /* Description: Digitally signs a streams file. */ /* */ /* COPYRIGHT 5769-SS1 (c) IBM Corp 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 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. */ /* */ /* Parameters: File to be signed */ /* File to contain signature */ /* Key label of key to use */ /* */ /* Examples: */ /* CALL PGM(SIGNFILE) PARM('file_to_sign' 'file_to_hold_sign' */ /* 'key_label'); */ /* */ /* Note: The CCA verbs used in the this program are more fully */ /* described in the IBM CCA Basic Services Reference */ /* and Guide (SC31-8609) publication. */ /* */ /* Note: This program assumes the card you want to use is */ /* already identified either by defaulting to the CRP01 */ /* device or has been 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. */ /* */ /* Use the following commands to compile this program: */ /* ADDLIBLE LIB(QCCA) */ /* CRTCMOD MODULE(SIGNFILE) SRCFILE(SAMPLE) SYSIFCOPT(*IFSIO) */ /* CRTPGM PGM(SIGNFILE) MODULE(SIGNFILE) */ /* BNDSRVPGM(QCCA/CSNDDSG QCCA/CSNBOWH) */ /* */ /* Note: authority to the CSNDDSG and CSNBOWH service programs */ /* in the QCCA library is assumed. */ /* */ /* Common Cryptographic Architecture (CCA) verbs used: */ /* Digital_Signature_Generate (CSNDDSG) */ /* One_Way_Hash (CSNBOWH) */ /*---------------------------------------------------------------*/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "csucincl.h" /* header file for CCA Cryptographic Service Provider */ /*-----------------------------------------------------------*/ /* standard return codes */ /*-----------------------------------------------------------*/ #define ERROR -1 #define OK 0 int hash_file(long h_len, char h_out[128], FILE *t_in); int main(int argc, char *argv[]) { /*-----------------------------------------------------------*/ /* standard CCA parameters */ /*-----------------------------------------------------------*/ long return_code; long reason_code; long exit_data_length = 0L; char exit_data[2]; long rule_array_count = 0L; char rule_array[1][8]; /*-----------------------------------------------------------*/ /* parameters unique to this sample program */ /*-----------------------------------------------------------*/ long PKA_private_key_identifier_length = 64; char PKA_private_key_identifier[64]; long hash_length = 16L; char hash[128]; long signature_field_length = 128L; long signature_bit_length = 0L; char signature_field[256]; char key_label[64]; long key_token_length = 2500L; char key_token[2500]; FILE *file2sign; FILE *signature; int hash_return; if (argc < 2) { printf("Name of file to be signed is missing."); return ERROR; } else if (argc < 3) { printf("Name of file where the signature should "); printf("be written is missing."); return ERROR; } else if (argc < 4) { printf("Key label for the key to be used for signing is missing."); return ERROR; } if ( (strlen(argv[3])) > 64 ) { printf("Invalid Key Label. Key label longer than 64."); return ERROR; } else { memset(PKA_private_key_identifier, ' ', 64); memcpy(PKA_private_key_identifier, argv[3],strlen(argv[3])); } /* Open the file that is being signed. */ if ( (file2sign = fopen(argv[1],"rb")) == NULL) { printf("Opening of file %s failed.",argv[1]); return ERROR; } /* Obtain a hash value for the file. */ hash_return = hash_file(hash_length, hash, file2sign); /* Close the file. */ fclose(file2sign); if (hash_return != OK) { printf("Signature generation failed due to hash error.\n"); } else { /* Use CSNDDSG to generate the signature. */ CSNDDSG(&return_code, &reason_code, &exit_data_length, exit_data, &rule_array_count, (char *) rule_array, &PKA_private_key_identifier_length, PKA_private_key_identifier, &hash_length, hash, &signature_field_length, &signature_bit_length, signature_field); } if (return_code != 0) { printf("Signature generation failed with return/reason code %ld/%ld", return_code, reason_code); return ERROR; } else { printf("Signature generation was successful."); printf("Return/Reason codes = %ld/%ld\n", return_code, reason_code); printf("Signature has length = %ld\n",signature_field_length); signature = fopen(argv[2],"wb"); if (signature == NULL) { printf("Open of file %s failed.",argv[2]); printf("Signature was not saved."); return ERROR; } fwrite(signature_field, 1, signature_field_length, signature); fclose(signature); printf("Signature was saved successfully in %s.", argv[2]); return OK; } } int hash_file(long h_len, char h_out[128], FILE *t_in) { /*-----------------------------------------------------------*/ /* standard CCA parameters */ /*-----------------------------------------------------------*/ long return_code; long reason_code; long exit_data_length = 0; char exit_data[2]; long rule_array_count = 2; char rule_array[2][8]; /*-----------------------------------------------------------*/ /* parameters unique to this function */ /*-----------------------------------------------------------*/ long text_length; char text[1024]; long chaining_vector_length = 128; char chaining_vector[128]; long file_length; fseek(t_in, 0, SEEK_END); file_length = ftell(t_in); rewind(t_in); text_length = fread(text, 1, 1024, t_in); memcpy(rule_array[0], "MD5 ", 8); if (file_length <= 1024) { memcpy(rule_array[1], "ONLY ", 8); } else { memcpy(rule_array[1], "FIRST ", 8); } while (file_length > 0) { CSNBOWH(&return_code, &reason_code, &exit_data_length, exit_data, &rule_array_count, (char *) rule_array, &text_length, text, &chaining_vector_length, chaining_vector, &h_len, h_out); if (return_code != 0) break; printf("Hash iteration worked.\n"); file_length -= text_length; if (file_length > 0) { text_length = fread(text, 1, 1024, t_in); if (file_length <= 1024) { memcpy(rule_array[1], "LAST ", 8); } else { memcpy(rule_array[1], "MIDDLE ", 8); } } } if (return_code != 0) { printf("Hash function failed with return/reason code %ld/%ld\n", return_code, reason_code); return ERROR; } else { printf("Hash completed successfully.\n"); printf("hash length = %ld\n", h_len); printf("hash = %.32s\n\n", h_out); return OK; } }