static int rsaGenerateComponents( CRYPT_PKCINFO_RSA *rsaKeyInfo, const int keySizeBits ) { CONTEXT_INFO staticContextInfo; PKC_INFO contextData, *pkcInfo = &contextData; int length, status; assert( isWritePtr( rsaKeyInfo, sizeof( CRYPT_PKCINFO_RSA ) ) ); REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \ keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) ); /* Clear return value */ cryptInitComponents( rsaKeyInfo, FALSE ); /* Generate the key components */ status = generateKeyComponents( &staticContextInfo, &contextData, getRSACapability(), keySizeBits ); if( cryptStatusError( status ) ) return( status ); /* Extract the newly-generated key components for the caller to use */ rsaKeyInfo->nLen = BN_num_bits( &pkcInfo->rsaParam_n ); length = BN_bn2bin( &pkcInfo->rsaParam_n, rsaKeyInfo->n ); ENSURES( length == bitsToBytes( rsaKeyInfo->nLen ) ); rsaKeyInfo->eLen = BN_num_bits( &pkcInfo->rsaParam_e ); length = BN_bn2bin( &pkcInfo->rsaParam_e, rsaKeyInfo->e ); ENSURES( length == bitsToBytes( rsaKeyInfo->eLen ) ); rsaKeyInfo->pLen = BN_num_bits( &pkcInfo->rsaParam_p ); length = BN_bn2bin( &pkcInfo->rsaParam_p, rsaKeyInfo->p ); ENSURES( length == bitsToBytes( rsaKeyInfo->pLen ) ); rsaKeyInfo->qLen = BN_num_bits( &pkcInfo->rsaParam_q ); length = BN_bn2bin( &pkcInfo->rsaParam_q, rsaKeyInfo->q ); ENSURES( length == bitsToBytes( rsaKeyInfo->qLen ) ); rsaKeyInfo->e1Len = BN_num_bits( &pkcInfo->rsaParam_exponent1 ); length = BN_bn2bin( &pkcInfo->rsaParam_exponent1, rsaKeyInfo->e1 ); ENSURES( length == bitsToBytes( rsaKeyInfo->e1Len ) ); rsaKeyInfo->e2Len = BN_num_bits( &pkcInfo->rsaParam_exponent2 ); length = BN_bn2bin( &pkcInfo->rsaParam_exponent2, rsaKeyInfo->e2 ); ENSURES( length == bitsToBytes( rsaKeyInfo->e2Len ) ); rsaKeyInfo->uLen = BN_num_bits( &pkcInfo->rsaParam_u ); length = BN_bn2bin( &pkcInfo->rsaParam_u, rsaKeyInfo->u ); ENSURES( length == bitsToBytes( rsaKeyInfo->uLen ) ); staticDestroyContext( &staticContextInfo ); return( status ); }
int main( int argc, char *argv[] ) { int n; FILE *f; char *buf[8]; char *outFile; char *keyFile; char *certFile; char *certData; char *label; char *secret; struct stat st; int usage; RSA *key; EVP_PKEY *evp; CRYPT_KEYSET keyset; CRYPT_CONTEXT pKey; CRYPT_PKCINFO_RSA rsa; CRYPT_CERTIFICATE cert; CRYPT_KEYOPT_TYPE opt; if ( argc != 6 ) { fprintf( stderr, "Syntax: %s <key> <cert> <out> <label> <secret>\n", argv[0] ); exit( -1 ); } keyFile = argv[1]; certFile = argv[2]; outFile = argv[3]; label = argv[4]; secret = argv[5]; if ( ( f = fopen( keyFile, "r" ) ) == NULL || ( evp = PEM_read_PrivateKey( f, NULL, NULL, NULL ) ) == NULL || ( key = EVP_PKEY_get1_RSA( evp ) ) == NULL ) { fprintf( stderr, "Couldn't load private key from '%s'\n", keyFile ); if ( f ) { ERR_print_errors_fp( stderr ); fclose( f ); } if ( evp ) EVP_PKEY_free( evp ); exit( -1 ); } if ( ( f = fopen( certFile, "r" ) ) == NULL || fstat( fileno( f ), &st ) < 0 || ( certData = malloc( st.st_size ) ) == NULL || fread( certData, 1, st.st_size, f ) < st.st_size ) { fprintf( stderr, "Couldn't load certificate from '%s'\n", certFile ); if ( f ) fclose( f ); free( certData ); exit( -1 ); } /* Should we create a keyset, or append to an existing one? */ opt = CRYPT_KEYOPT_CREATE; f = fopen( outFile, "r" ); if ( f != NULL ) { opt = CRYPT_KEYOPT_NONE; fclose( f ); } cryptInit(); cryptInitComponents( &rsa, CRYPT_KEYTYPE_PRIVATE ); if ( ( buf[0] = malloc( BN_num_bytes( key->n ) ) ) != NULL && ( buf[1] = malloc( BN_num_bytes( key->e ) ) ) != NULL && ( buf[2] = malloc( BN_num_bytes( key->d ) ) ) != NULL && ( buf[3] = malloc( BN_num_bytes( key->p ) ) ) != NULL && ( buf[4] = malloc( BN_num_bytes( key->q ) ) ) != NULL && ( buf[5] = malloc( BN_num_bytes( key->iqmp ) ) ) != NULL && ( buf[6] = malloc( BN_num_bytes( key->dmp1 ) ) ) != NULL && ( buf[7] = malloc( BN_num_bytes( key->dmq1 ) ) ) != NULL ) { int i; BN_bn2bin( key->n, buf[0] ); BN_bn2bin( key->e, buf[1] ); BN_bn2bin( key->d, buf[2] ); BN_bn2bin( key->p, buf[3] ); BN_bn2bin( key->q, buf[4] ); BN_bn2bin( key->iqmp, buf[5] ); BN_bn2bin( key->dmp1, buf[6] ); BN_bn2bin( key->dmq1, buf[7] ); cryptSetComponent( (&rsa)->n, buf[0], BN_num_bits( key->n ) ); cryptSetComponent( (&rsa)->e, buf[1], BN_num_bits( key->e ) ); cryptSetComponent( (&rsa)->d, buf[2], BN_num_bits( key->d ) ); cryptSetComponent( (&rsa)->p, buf[3], BN_num_bits( key->p ) ); cryptSetComponent( (&rsa)->q, buf[4], BN_num_bits( key->q ) ); cryptSetComponent( (&rsa)->u, buf[5], BN_num_bits( key->iqmp ) ); cryptSetComponent( (&rsa)->e1, buf[6], BN_num_bits( key->dmp1 ) ); cryptSetComponent( (&rsa)->e2, buf[7], BN_num_bits( key->dmq1 ) ); i = 0; while ( i < 8 ) free( buf[i++] ); } else { fprintf( stderr, "Couldn't initialise PKCINFO_RSA data.\n" ); exit( -1 ); } n = cryptCreateContext( &pKey, CRYPT_UNUSED, CRYPT_ALGO_RSA ); check( n, pKey, "cryptCreateContext" ); n = cryptSetAttributeString( pKey, CRYPT_CTXINFO_LABEL, label, strlen( label ) ); check( n, pKey, "cryptSetAttributeString(LABEL)" ); n = cryptSetAttributeString( pKey, CRYPT_CTXINFO_KEY_COMPONENTS, &rsa, sizeof( CRYPT_PKCINFO_RSA ) ); check( n, pKey, "cryptSetAttributeString(KEY_COMPONENTS)" ); n = cryptImportCert( certData, st.st_size, CRYPT_UNUSED, &cert ); check( n, cert, "cryptImportCert" ); n = cryptGetAttribute( cert, CRYPT_CERTINFO_KEYUSAGE, &usage ); if ( n != CRYPT_OK ) { fprintf( stderr, "Warning: The certificate specifies no KEYUSAGE.\n" "Cryptlib may not permit its use. See " "<http://toroid.org/ams/pemtrans>.\n" ); } n = cryptKeysetOpen( &keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, outFile, opt ); check( n, keyset, "cryptKeysetOpen" ); n = cryptAddPrivateKey( keyset, pKey, secret ); check( n, keyset, "cryptAddPrivateKey" ); n = cryptAddPublicKey( keyset, cert ); check( n, keyset, "cryptAddPublicKey" ); cryptKeysetClose( keyset ); cryptDestroyComponents( &rsa ); cryptDestroyContext( pKey ); cryptDestroyCert( cert ); exit( 0 ); }
static int dlpGenerateComponents( CRYPT_PKCINFO_DLP *dlpKeyInfo, const int keySizeBits, const CRYPT_ALGO_TYPE cryptAlgo ) { CONTEXT_INFO staticContextInfo; PKC_INFO contextData, *pkcInfo = &contextData; int length, status; assert( isWritePtr( dlpKeyInfo, sizeof( CRYPT_PKCINFO_DLP ) ) ); REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \ keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) ); REQUIRES( cryptAlgo == CRYPT_ALGO_DH || \ cryptAlgo == CRYPT_ALGO_DSA || \ cryptAlgo == CRYPT_ALGO_ELGAMAL ); /* Clear return value */ cryptInitComponents( dlpKeyInfo, FALSE ); /* Generate the key components */ switch( cryptAlgo ) { #ifdef USE_DH case CRYPT_ALGO_DH: status = generateKeyComponents( &staticContextInfo, &contextData, getDHCapability(), keySizeBits ); break; #endif /* USE_DH */ #ifdef USE_DSA case CRYPT_ALGO_DSA: status = generateKeyComponents( &staticContextInfo, &contextData, getDSACapability(), keySizeBits ); break; #endif /* USE_DSA */ #ifdef USE_ELGAMAL case CRYPT_ALGO_ELGAMAL: status = generateKeyComponents( &staticContextInfo, &contextData, getElgamalCapability(), keySizeBits ); break; #endif /* USE_ELGAMAL */ default: retIntError(); } if( cryptStatusError( status ) ) return( status ); /* Extract the newly-generated key components for the caller to use */ dlpKeyInfo->pLen = BN_num_bits( &pkcInfo->dlpParam_p ); length = BN_bn2bin( &pkcInfo->dlpParam_p, dlpKeyInfo->p ); ENSURES( length == bitsToBytes( dlpKeyInfo->pLen ) ); dlpKeyInfo->gLen = BN_num_bits( &pkcInfo->dlpParam_g ); length = BN_bn2bin( &pkcInfo->dlpParam_g, dlpKeyInfo->g ); ENSURES( length == bitsToBytes( dlpKeyInfo->gLen ) ); dlpKeyInfo->qLen = BN_num_bits( &pkcInfo->dlpParam_q ); length = BN_bn2bin( &pkcInfo->dlpParam_q, dlpKeyInfo->q ); ENSURES( length == bitsToBytes( dlpKeyInfo->qLen ) ); dlpKeyInfo->yLen = BN_num_bits( &pkcInfo->dlpParam_y ); length = BN_bn2bin( &pkcInfo->dlpParam_y, dlpKeyInfo->y ); ENSURES( length == bitsToBytes( dlpKeyInfo->yLen ) ); dlpKeyInfo->xLen = BN_num_bits( &pkcInfo->dlpParam_x ); length = BN_bn2bin( &pkcInfo->dlpParam_x, dlpKeyInfo->x ); ENSURES( length == bitsToBytes( dlpKeyInfo->xLen ) ); staticDestroyContext( &staticContextInfo ); return( status ); }