Change this program example to suit your needs for verifying a digital signature with your Cryptographic Coprocessor
/*---------------------------------------------------------------*/ /* Description: Verifies the digital signature of an IFS file */ /* produced by the SIGNFILE sample program. */ /* */ /* 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: Signed file */ /* File containing the signature */ /* Key label of the key to use */ /* */ /* Examples: */ /* CALL PGM(VERFILESIG) PARM('name_of_signed_file' + */ /* 'name_of_file_w_signature' + */ /* '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(VERFILESIG) SRCFILE(SAMPLE) SYSIFCOPT(*IFSIO)*/ /* CRTPGM PGM(SIGNFILE) MODULE(SIGNFILE) + */ /* BNDSRVPGM(QCCA/CSNDDSV QCCA/CSNBOWH) */ /* */ /* Note: authority to the CSNDDSV and CSNBOWH service programs */ /* in the QCCA library is assumed. */ /* */ /* Common Cryptographic Architecture (CCA) verbs used: */ /* Digital_Signature_Verify (CSNDDSV) */ /* 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_public_key_identifier_length = 64; char PKA_public_key_identifier[64]; long hash_length = 16L; char hash[128]; long signature_field_length; char signature_field[256]; char key_label[64]; FILE *file2verify; FILE *signature; int hash_return; if (argc < 2) { printf("Name of file to be verified is missing.\n"); return ERROR; } else if (argc < 3) { printf("Name of file containing the signature is missing.\n"); return ERROR; } else if (argc < 4) { printf("Key label for the key to be used for verification is missing.\n"); return ERROR; } if (strlen(argv[3]) > 64 ) { printf("Invalid Key Label. Key label longer than 64 bytes."); return ERROR; } else { memset(PKA_public_key_identifier, ' ', 64); memcpy(PKA_public_key_identifier, argv[3], strlen(argv[3])); } /* Open the file that is being verified. */ if ( (file2verify = 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, file2verify); /* Close the file. */ fclose(file2verify); if (hash_return != OK) { printf("Signature verification failed due to hash error.\n"); return ERROR; } else { signature = fopen(argv[2],"rb"); if (signature == NULL) { printf("Open of signature file %s failed.",argv[2]); printf("Signature was not verified."); return ERROR; } memset(signature_field, ' ', 256); fseek(signature, 0, SEEK_END); signature_field_length = ftell(signature); rewind(signature); fread(signature_field, 1, signature_field_length, signature); fclose(signature); /* Use CSNDDSV to verify the signature. */ CSNDDSV(&return_code, &reason_code, &exit_data_length, exit_data, &rule_array_count, (char *) rule_array, &PKA_public_key_identifier_length, PKA_public_key_identifier, &hash_length, hash, &signature_field_length, signature_field); } if (return_code != 0) { printf("Signature verification failed with return/reason code %ld/%ld", return_code, reason_code); return ERROR; } else { printf("Signature verification was successful."); printf("Return/Reason codes = %ld/%ld\n", return_code, reason_code); } } 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; } }