PKI_RSA_KEY * _pki_pkcs11_rsakey_new( PKI_KEYPARAMS *kp, URL *url, PKCS11_HANDLER *lib, void *driver) { PKI_RSA_KEY *ret = NULL; CK_OBJECT_HANDLE *handler_pubkey = NULL; CK_OBJECT_HANDLE *handler_privkey = NULL; CK_ATTRIBUTE privTemp[32]; CK_ATTRIBUTE pubTemp[32]; CK_RV rv; CK_MECHANISM * RSA_MECH_PTR = NULL; CK_ULONG i = 0; CK_ULONG n = 0; CK_ULONG bits = 0; size_t label_len = 0; unsigned char *data = NULL; CK_BYTE *esp = NULL; CK_ULONG size = 0; BIGNUM *bn = NULL; BIGNUM *id_num = NULL; char *id = NULL; int id_len = 8; int idx = 0; if ( !url || !url->addr ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return ( NULL ); } label_len = strlen( url->addr ); /* Check the min size for the key */ if ( kp ) { if( kp->bits < PKI_RSA_KEY_MIN_SIZE ) { PKI_ERROR(PKI_ERR_X509_KEYPAIR_SIZE_SHORT, NULL); } else { bits = (CK_ULONG) kp->bits; } } else { bits = PKI_RSA_KEY_DEFAULT_SIZE; } // Look for a supported key generation mechanism for (idx = 0; idx < RSA_MECH_LIST_SIZE; idx++) { // Checks if the mechanism is supported if (HSM_PKCS11_check_mechanism(lib, RSA_MECH_LIST[idx].mechanism) == PKI_OK) { // Set the pointer to the supported mechanism RSA_MECH_PTR = &RSA_MECH_LIST[idx]; // Debugging Information PKI_DEBUG("Found RSA KEY GEN MECHANISM 0x%8.8X", RSA_MECH_LIST[idx].mechanism); // Breaks out of the loop break; } else { // Let's provide debug information for not-supported mechs PKI_DEBUG("RSA KEY GEN MECHANISM 0x%8.8X not supported", RSA_MECH_LIST[idx].mechanism); } } // If no key gen algors are supported, abort if (RSA_MECH_PTR == NULL) { PKI_ERROR(PKI_ERR_HSM_KEYPAIR_GENERATE, "No KeyGen Mechanisms supported!"); return NULL; } PKI_DEBUG("BITS FOR KEY GENERATION %lu (def: %lu)", bits, PKI_RSA_KEY_DEFAULT_SIZE); if (kp && kp->rsa.exponent > 3) { // TO be Implemented } else { if( BN_hex2bn(&bn, "10001") == 0 ) { PKI_log_debug("ERROR, can not convert 10001 to BIGNUM"); return ( NULL ); } } if( url->path != NULL ) { if((BN_hex2bn(&id_num, url->path )) == 0 ) { PKI_log_debug("ERROR, can not convert %s to BIGNUM", url->path ); return ( NULL ); } if((id_len = BN_num_bytes(id_num)) < 0 ) { if ( bn ) BN_free ( bn ); if ( id_num ) BN_free ( id_num ); return ( NULL ); } id = PKI_Malloc ( (size_t ) id_len ); BN_bn2bin( id_num, (unsigned char *) id ); } else { id_len = 10; if((id = PKI_Malloc ( (size_t) id_len )) == NULL ) { if ( bn ) BN_free ( bn ); return ( NULL ); } if( RAND_bytes( (unsigned char *) id, id_len) == 0 ) { PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not generate RAND bytes"); if( bn ) BN_free ( bn ); return ( NULL ); } } PKI_DEBUG("Setting the Bits to %lu", bits); /* Setting Attributes for the public Key Template */ n = 0; //HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PUBLIC_KEY, &pubTemp[n++]); //HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &pubTemp[n++]); HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &pubTemp[n++]); HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &pubTemp[n++]); HSM_PKCS11_set_attr_bool( CKA_ENCRYPT, CK_TRUE, &pubTemp[n++]); HSM_PKCS11_set_attr_bool( CKA_VERIFY, CK_TRUE, &pubTemp[n++]); HSM_PKCS11_set_attr_bool( CKA_WRAP, CK_TRUE, &pubTemp[n++]); HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &pubTemp[n++]); HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &pubTemp[n++]); HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &pubTemp[n++]); /* Setting Attributes for the private Key Template */ i = 0; //HSM_PKCS11_set_attr_int( CKA_CLASS, CKO_PRIVATE_KEY, &privTemp[i++]); //HSM_PKCS11_set_attr_int( CKA_KEY_TYPE, CKK_RSA, &privTemp[i++]); //HSM_PKCS11_set_attr_int( CKA_MODULUS_BITS, bits, &privTemp[i++]); HSM_PKCS11_set_attr_bool( CKA_TOKEN, CK_TRUE, &privTemp[i++]); HSM_PKCS11_set_attr_bool( CKA_PRIVATE, CK_TRUE, &privTemp[i++]); HSM_PKCS11_set_attr_bool( CKA_SENSITIVE, CK_TRUE, &privTemp[i++]); HSM_PKCS11_set_attr_bool( CKA_DECRYPT, CK_TRUE, &privTemp[i++]); HSM_PKCS11_set_attr_bool( CKA_SIGN, CK_TRUE, &privTemp[i++]); // HSM_PKCS11_set_attr_bool( CKA_NEVER_EXTRACTABLE, CK_TRUE, // &privTemp[i++]); // HSM_PKCS11_set_attr_bool( CKA_EXTRACTABLE, CK_FALSE, &privTemp[i++]); HSM_PKCS11_set_attr_bool( CKA_UNWRAP, CK_TRUE, &privTemp[i++]); // HSM_PKCS11_set_attr_bn(CKA_PUBLIC_EXPONENT, bn, &privTemp[i++]); HSM_PKCS11_set_attr_sn(CKA_LABEL, url->addr, label_len, &privTemp[i++]); HSM_PKCS11_set_attr_sn(CKA_ID, id, (size_t) id_len, &privTemp[i++]); /* Allocate the handlers for pub and priv keys */ handler_pubkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( sizeof( CK_OBJECT_HANDLE )); handler_privkey = (CK_OBJECT_HANDLE *) PKI_Malloc ( sizeof( CK_OBJECT_HANDLE )); if( !handler_pubkey || !handler_privkey ) { if ( bn ) BN_free ( bn ); if ( esp ) PKI_Free ( esp ); return ( NULL ); } PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Generating a new Key ... "); rv = lib->callbacks->C_GenerateKeyPair ( lib->session, RSA_MECH_PTR, pubTemp, n, privTemp, i, handler_pubkey, handler_privkey); if( rv != CKR_OK ) { if ( rv == CKR_MECHANISM_INVALID ) { PKI_log_err("HSM_PKCS11_KEYPAIR_new()::RSA Algorithm " "is not supported by the Token" ); } else { PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed with " "code 0x%8.8X", rv ); }; if ( bn ) BN_free ( bn ); if ( esp ) PKI_Free ( esp ); return ( NULL ); } /* Clean up the Memory we are not using anymore */ if ( bn ) BN_free ( bn ); if ( esp ) PKI_Free ( esp ); /* Generate a new RSA container */ if((ret = RSA_new()) == NULL ) { goto err; }; if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session, CKA_PUBLIC_EXPONENT, (void **) &data, &size, lib ) != PKI_OK ) { goto err; }; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL RSA_set0_key(ret, NULL, BN_bin2bn( data, (int) size, NULL), NULL); #else ret->e = BN_bin2bn( data, (int) size, NULL ); #endif PKI_Free ( data ); data = NULL; if( HSM_PKCS11_get_attribute ( handler_pubkey, &lib->session, CKA_MODULUS, (void **) &data, &size, lib ) != PKI_OK ) { goto err; }; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL RSA_set0_key(ret, BN_bin2bn(data, (int) size, NULL), NULL, NULL); #else ret->n = BN_bin2bn( data, (int) size, NULL ); #endif PKI_Free ( data ); data = NULL; /* Let's get the Attributes from the Keypair and store into the key's pointer */ RSA_set_method( ret, HSM_PKCS11_get_rsa_method()); #ifdef RSA_FLAG_SIGN_VER # if OPENSSL_VERSION_NUMBER >= 0x1010000fL RSA_set_flags( ret, RSA_FLAG_SIGN_VER); # else ret->flags |= RSA_FLAG_SIGN_VER; # endif #endif /* Push the priv and pub key handlers to the rsa->ex_data */ RSA_set_ex_data( ret, KEYPAIR_DRIVER_HANDLER_IDX, driver ); RSA_set_ex_data( ret, KEYPAIR_PRIVKEY_HANDLER_IDX, handler_privkey ); RSA_set_ex_data( ret, KEYPAIR_PUBKEY_HANDLER_IDX, handler_pubkey ); /* Cleanup the memory for Templates */ HSM_PKCS11_clean_template ( pubTemp, (int) n ); HSM_PKCS11_clean_template ( privTemp, (int) i ); /* Let's return the RSA_KEY infrastructure */ return (ret); err: if( ret ) RSA_free ((RSA *) ret ); if ( handler_pubkey ) { if((rv = lib->callbacks->C_DestroyObject( lib->session, *handler_pubkey )) != CKR_OK ) { PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed to delete " "pubkey object"); }; PKI_Free ( handler_pubkey ); } if( handler_privkey ) { if((rv = lib->callbacks->C_DestroyObject( lib->session, *handler_privkey)) != CKR_OK ) { PKI_log_debug ("HSM_PKCS11_KEYPAIR_new()::Failed to delete " "privkey object"); }; PKI_Free ( handler_privkey ); } PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Key material DELETED!"); return ( NULL ); }
int main(int argc, char *argv[]) { int err = 0; int v; RSA *key; unsigned char ptext[256]; unsigned char ctext[256]; static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; unsigned char ctext_ex[256]; int plen; int clen = 0; int num; int n; CRYPTO_set_mem_debug(1); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */ plen = sizeof(ptext_ex) - 1; for (v = 0; v < 6; v++) { key = RSA_new(); switch (v % 3) { case 0: clen = key1(key, ctext_ex); break; case 1: clen = key2(key, ctext_ex); break; case 2: clen = key3(key, ctext_ex); break; } if (v / 3 >= 1) RSA_set_flags(key, RSA_FLAG_NO_CONSTTIME); num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING); if (num != clen) { printf("PKCS#1 v1.5 encryption failed!\n"); err = 1; goto oaep; } num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("PKCS#1 v1.5 decryption failed!\n"); err = 1; } else printf("PKCS #1 v1.5 encryption/decryption ok\n"); oaep: ERR_clear_error(); num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_OAEP_PADDING); if (num == -1 && pad_unknown()) { printf("No OAEP support\n"); goto next; } if (num != clen) { printf("OAEP encryption failed!\n"); err = 1; goto next; } num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("OAEP decryption (encrypted data) failed!\n"); err = 1; } else if (memcmp(ctext, ctext_ex, num) == 0) printf("OAEP test vector %d passed!\n", v); /* * Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT). Try * decrypting ctext_ex */ num = RSA_private_decrypt(clen, ctext_ex, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { printf("OAEP decryption (test vector data) failed!\n"); err = 1; } else printf("OAEP encryption/decryption ok\n"); /* Try decrypting corrupted ciphertexts. */ for (n = 0; n < clen; ++n) { ctext[n] ^= 1; num = RSA_private_decrypt(clen, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num > 0) { printf("Corrupt data decrypted!\n"); err = 1; break; } ctext[n] ^= 1; } /* Test truncated ciphertexts, as well as negative length. */ for (n = -1; n < clen; ++n) { num = RSA_private_decrypt(n, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING); if (num > 0) { printf("Truncated data decrypted!\n"); err = 1; break; } } next: RSA_free(key); } #ifndef OPENSSL_NO_CRYPTO_MDEBUG if (CRYPTO_mem_leaks_fp(stderr) <= 0) err = 1; #endif return err; }