|
/********************************************************************/
/* */
/* Sample program to call the one-way hash service to generate */
/* the SHA-1 hash of the input text and call digital signature */
/* generate with an RSA key using the ISO 9796 text formatting. The */
/* RSA key token is built from supplied data and imported for the */
/* signature generate service to use. */
/* */
/* INPUT: TEXT Message digest to be signed */
/* */
/* OUTPUT: SIGNATURE_LENGTH Length of the signature in bytes */
/* Written to a dataset. */
/* */
/* SIGNATURE Signature for hash. Written to a */
/* dataset. */
/* */
/********************************************************************/
DSIGEXP:PROCEDURE( TEXT ) OPTIONS( MAIN );
/* Declarations - Parameters */
DCL TEXT CHAR( 64 ) VARYING;
/* Declarations - API parameters */
DCL CHAINING_VECTOR_LENGTH FIXED BINARY( 31, 0 ) INIT( 128 );
DCL CHAINING_VECTOR CHAR( 128 );
DCL DUMMY_KEK CHAR( 64 );
DCL EXIT_DATA CHAR( 4 );
DCL EXIT_LEN FIXED BINARY( 31, 0 ) INIT( 0 );
DCL HASH CHAR( 20 );
DCL HASH_LENGTH FIXED BINARY( 31, 0 ) INIT( 20 );
DCL INTERNAL_PKA_TOKEN CHAR( 1024 );
DCL INTERNAL_PKA_TOKEN_LENGTH FIXED BINARY( 31, 0 );
DCL KEY_VALUE_STRUCTURE CHAR(139)
INIT(( '02000040000300408000000000000000'X ||
'01AE28DA4606D885EB7E0340D6BAAC51'X ||
'991C0CD0EAE835AFD9CFF3CD7E7EA741'X ||
'41DADD24A6331BEDF41A6626522CCF15'X ||
'767D167D01A16F970100010252BDAD42'X ||
'52BDAD425A8C6045D41AFAF746BEBD5F'X ||
'085D574FCD9C07F0B38C2C45017C2A1A'X ||
'B919ED2551350A76606BFA6AF2F1609A'X ||
'00A0A48DD719A55E9CA801'X ));
DCL KEY_VALUE_LENGTH FIXED BINARY( 31, 0 ) INIT( 139 );
DCL OWH_TEXT CHAR( 64 );
DCL PKA_KEY_TOKEN CHAR( 1024 );
DCL PKA_TOKEN_LENGTH FIXED BINARY( 31, 0 );
DCL PRIVATE_NAME CHAR( 64 ) INIT( 'PL1.EXAMPLE.FOR.APG' );
DCL PRIVATE_NAME_LENGTH FIXED BINARY( 31, 0 ) INIT( 0 );
DCL RETURN_CODE FIXED BINARY( 31, 0 ) INIT( 0 );
DCL REASON_CODE FIXED BINARY( 31, 0 ) INIT( 0 );
DCL RESERVED_FIELD_LENGTH FIXED BINARY( 31, 0 ) INIT( 0 );
DCL RESERVED_FIELD CHAR( 1 );
DCL RULE_ARY_CNT_DSG FIXED BINARY( 31, 0 ) INIT( 1 );
DCL RULE_ARY_CNT_PKB FIXED BINARY( 31, 0 ) INIT( 1 );
DCL RULE_ARY_CNT_PKI FIXED BINARY( 31, 0 ) INIT( 0 );
DCL RULE_ARY_CNT_OWH FIXED BINARY( 31, 0 ) INIT( 2 );
DCL RULE_ARY_DSG CHAR( 8 ) INIT( 'ISO-9796' );
DCL RULE_ARY_PKB CHAR( 8 ) INIT( 'RSA-PRIV' );
DCL RULE_ARY_PKI CHAR( 8 );
DCL RULE_ARY_OWH CHAR( 16 ) INIT( 'SHA-1 ONLY ' );
DCL SIGNATURE_LENGTH FIXED BINARY( 31, 0 );
DCL SIGNATURE CHAR( 128 );
DCL SIG_BIT_LENGTH FIXED BINARY( 31, 0 );
DCL TEXT_LENGTH FIXED BINARY( 31, 0 );
/* Declarations - Files and entry points */
DCL SYSPRINT FILE OUTPUT;
DCL SIGOUT FILE RECORD OUTPUT;
DCL CSNDPKB ENTRY EXTERNAL OPTIONS( ASM, INTER );
DCL CSNDPKI ENTRY EXTERNAL OPTIONS( ASM, INTER );
DCL CSNBOWH ENTRY EXTERNAL OPTIONS( ASM, INTER );
DCL CSNDDSG ENTRY EXTERNAL OPTIONS( ASM, INTER );
/* Declarations - Internal variables */
DCL DSG_HEADER CHAR( 32 )
INIT( '* DIGITAL SIGNATURE GENERATION *' );
DCL FILE_OUT_LINE CHAR( 128 );
DCL OWH_HEADER CHAR( 16 )
INIT( '* ONE WAY HASH *' );
DCL PKB_HEADER CHAR( 16 )
INIT( '* PKA TOKEN BUILD *' );
DCL PKI_HEADER CHAR( 16 )
INIT( '* PKA TOKEN IMPORT *' );
DCL RC_STRING CHAR( 14 ) INIT( 'RETURN CODE = ' );
DCL RS_STRING CHAR( 14 ) INIT( 'REASON CODE = ' );
DCL SIG_STRING CHAR( 12 ) INIT( 'SIGNATURE = ' );
DCL SIG_LEN_STRING CHAR( 26 ) INIT( 'SIGNATURE LENGTH(BYTES) = ' );
/* Declarations - Built-in functions */
DCL (SUBSTR, LENGTH) BUILTIN;
/********************************************************************/
/* Call one-way hash to get the SHA-1 hash of the text. */
/********************************************************************/
TEXT_LENGTH = LENGTH( TEXT );
OWH_TEXT = SUBSTR( TEXT, 1, TEXT_LENGTH );
CALL CSNBOWH( RETURN_CODE,
REASON_CODE,
EXIT_LEN,
EXIT_DATA,
RULE_ARY_CNT_OWH,
RULE_ARY_OWH,
TEXT_LENGTH,
OWH_TEXT,
CHAINING_VECTOR_LENGTH,
CHAINING_VECTOR,
HASH_LENGTH,
HASH );
PUT SKIP LIST( OWH_HEADER );
PUT SKIP LIST( RC_STRING || RETURN_CODE );
PUT SKIP LIST( RS_STRING || REASON_CODE );
/********************************************************************/
/* Create the PKA RSA private external token. */
/********************************************************************/
IF RETURN_CODE = 0 THEN
DO;
PKA_TOKEN_LENGTH = 1024;
CALL CSNDPKB( RETURN_CODE,
REASON_CODE,
EXIT_LEN,
EXIT_DATA,
RULE_ARY_CNT_PKB,
RULE_ARY_PKB,
KEY_VALUE_LENGTH,
KEY_VALUE_STRUCTURE,
PRIVATE_NAME_LENGTH,
PRIVATE_NAME,
RESERVED_FIELD_LENGTH,
RESERVED_FIELD,
RESERVED_FIELD_LENGTH,
RESERVED_FIELD,
RESERVED_FIELD_LENGTH,
RESERVED_FIELD,
RESERVED_FIELD_LENGTH,
RESERVED_FIELD,
RESERVED_FIELD_LENGTH,
RESERVED_FIELD,
PKA_TOKEN_LENGTH,
PKA_KEY_TOKEN );
PUT SKIP LIST( PKB_HEADER );
PUT SKIP LIST( RC_STRING || RETURN_CODE );
PUT SKIP LIST( RS_STRING || REASON_CODE );
END;
/********************************************************************/
/* Import the clear RSA private external token. */
/********************************************************************/
IF RETURN_CODE = 0 THEN
DO;
INTERNAL_PKA_TOKEN_LENGTH = 1024;
CALL CSNDPKI( RETURN_CODE,
REASON_CODE,
EXIT_LEN,
EXIT_DATA,
RULE_ARY_CNT_PKI,
RULE_ARY_PKI,
PKA_TOKEN_LENGTH,
PKA_KEY_TOKEN,
DUMMY_KEK,
INTERNAL_PKA_TOKEN_LENGTH,
INTERNAL_PKA_TOKEN );
PUT SKIP LIST( PKI_HEADER );
PUT SKIP LIST( RC_STRING || RETURN_CODE );
PUT SKIP LIST( RS_STRING || REASON_CODE );
END;
/********************************************************************/
/* Call digital signature generate. */
/********************************************************************/
IF RETURN_CODE = 0 THEN
DO;
SIGNATURE_LENGTH = 128;
CALL CSNDDSG( RETURN_CODE,
REASON_CODE,
EXIT_LEN,
EXIT_DATA,
RULE_ARY_CNT_DSG,
RULE_ARY_DSG,
INTERNAL_PKA_TOKEN_LENGTH,
INTERNAL_PKA_TOKEN,
HASH_LENGTH,
HASH,
SIGNATURE_LENGTH,
SIG_BIT_LENGTH,
SIGNATURE );
PUT SKIP LIST( DSG_HEADER );
PUT SKIP LIST( RC_STRING || RETURN_CODE );
PUT SKIP LIST( RS_STRING || REASON_CODE );
IF RETURN_CODE = 0 THEN
DO;
/****************************************************************/
/* Write the signature and its length to the output file. */
/****************************************************************/
FILE_OUT_LINE = SIG_LEN_STRING || SIGNATURE_LENGTH;
WRITE FILE(SIGOUT) FROM( FILE_OUT_LINE );
FILE_OUT_LINE = SIG_STRING || SIGNATURE;
WRITE FILE(SIGOUT) FROM( FILE_OUT_LINE );
END;
END;
END DSIGEXP;
|