static int test_check_private_key(void) { int ret = 0; BIGNUM *n = NULL, *d = NULL, *e = NULL; RSA *key = NULL; ret = TEST_ptr(key = RSA_new()) /* check NULL pointers fail */ && TEST_false(rsa_sp800_56b_check_private(key)) /* load private key */ && TEST_ptr(n = bn_load_new(cav_n, sizeof(cav_n))) && TEST_ptr(d = bn_load_new(cav_d, sizeof(cav_d))) && TEST_ptr(e = bn_load_new(cav_e, sizeof(cav_e))) && TEST_true(RSA_set0_key(key, n, e, d)); if (!ret) { BN_free(n); BN_free(e); BN_free(d); goto end; } /* check d is in range */ ret = TEST_true(rsa_sp800_56b_check_private(key)) /* check d is too low */ && TEST_true(BN_set_word(d, 0)) && TEST_false(rsa_sp800_56b_check_private(key)) /* check d is too high */ && TEST_ptr(BN_copy(d, n)) && TEST_false(rsa_sp800_56b_check_private(key)); end: RSA_free(key); return ret; }
static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) { if (key->evp_pkey) { /* We've already constructed it, so just reuse it */ return 1; } /* Create the RSA key */ RSA *rsa = RSA_new(); if (!rsa) return 0; if (!RSA_set0_key(rsa, key->n, key->e, NULL)) { RSA_free(rsa); return 0; } /* Create an EVP_PKEY container to abstract the key-type. */ key->evp_pkey = EVP_PKEY_new(); if (!key->evp_pkey) { RSA_free(rsa); return 0; } /* Assign the RSA key to the EVP_PKEY structure. This will take over memory management of the RSA key */ if (!EVP_PKEY_assign_RSA(key->evp_pkey, rsa)) { EVP_PKEY_free(key->evp_pkey); key->evp_pkey = NULL; RSA_free(rsa); } return 1; }
/* * Get RSA key material */ static RSA *pkcs11_get_rsa(PKCS11_KEY *key) { RSA *rsa; PKCS11_KEY *keys = NULL; unsigned int i, count = 0; BIGNUM *rsa_n=NULL, *rsa_e=NULL; rsa = RSA_new(); if (rsa == NULL) return NULL; /* Retrieve the modulus and the public exponent */ if (key_getattr_bn(key, CKA_MODULUS, &rsa_n) || key_getattr_bn(key, CKA_PUBLIC_EXPONENT, &rsa_e)) goto failure; if (!BN_is_zero(rsa_e)) /* The public exponent was retrieved */ goto success; BN_clear_free(rsa_e); rsa_e = NULL; /* The public exponent was not found in the private key: * retrieve it from the corresponding public key */ if (!PKCS11_enumerate_public_keys(KEY2TOKEN(key), &keys, &count)) { for(i = 0; i < count; i++) { BIGNUM *pubmod; if (key_getattr_bn(&keys[i], CKA_MODULUS, &pubmod)) continue; /* Failed to retrieve the modulus */ if (BN_cmp(rsa_n, pubmod) == 0) { /* The key was found */ BN_clear_free(pubmod); if (key_getattr_bn(&keys[i], CKA_PUBLIC_EXPONENT, &rsa_e)) continue; /* Failed to retrieve the public exponent */ goto success; } else { BN_clear_free(pubmod); } } } /* Last resort: use the most common default */ rsa_e = BN_new(); if (rsa_e && BN_set_word(rsa_e, RSA_F4)) goto success; failure: RSA_free(rsa); return NULL; success: #if OPENSSL_VERSION_NUMBER >= 0x10100005L RSA_set0_key(rsa, rsa_n, rsa_e, NULL); #else rsa->n=rsa_n; rsa->e=rsa_e; #endif return rsa; }
static int test_check_private_exponent(void) { int ret = 0; RSA *key = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *q = NULL, *e = NULL, *d = NULL, *n = NULL; ret = TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new()) && TEST_ptr(p = BN_new()) && TEST_ptr(q = BN_new()) /* lcm(15-1,17-1) = 14*16 / 2 = 112 */ && TEST_true(BN_set_word(p, 15)) && TEST_true(BN_set_word(q, 17)) && TEST_true(RSA_set0_factors(key, p, q)); if (!ret) { BN_free(p); BN_free(q); goto end; } ret = TEST_ptr(e = BN_new()) && TEST_ptr(d = BN_new()) && TEST_ptr(n = BN_new()) && TEST_true(BN_set_word(e, 5)) && TEST_true(BN_set_word(d, 157)) && TEST_true(BN_set_word(n, 15*17)) && TEST_true(RSA_set0_key(key, n, e, d)); if (!ret) { BN_free(e); BN_free(d); BN_free(n); goto end; } /* fails since d >= lcm(p-1, q-1) */ ret = TEST_false(rsa_check_private_exponent(key, 8, ctx)) && TEST_true(BN_set_word(d, 45)) /* d is correct size and 1 = e.d mod lcm(p-1, q-1) */ && TEST_true(rsa_check_private_exponent(key, 8, ctx)) /* d is too small compared to nbits */ && TEST_false(rsa_check_private_exponent(key, 16, ctx)) /* d is too small compared to nbits */ && TEST_true(BN_set_word(d, 16)) && TEST_false(rsa_check_private_exponent(key, 8, ctx)) /* fail if 1 != e.d mod lcm(p-1, q-1) */ && TEST_true(BN_set_word(d, 46)) && TEST_false(rsa_check_private_exponent(key, 8, ctx)); end: RSA_free(key); BN_CTX_free(ctx); return ret; }
/* * Returns VAL_NO_ERROR on success, other values on failure */ static int rsamd5_parse_public_key(const u_char *buf, size_t buflen, RSA * rsa) { int index = 0; const u_char *cp; u_int16_t exp_len = 0x0000; BIGNUM *bn_exp; BIGNUM *bn_mod; if (!rsa || buflen == 0) return VAL_BAD_ARGUMENT; cp = buf; if (buf[index] == 0) { if (buflen < 3) return VAL_BAD_ARGUMENT; index += 1; cp = (buf + index); VAL_GET16(exp_len, cp); index += 2; } else { exp_len += buf[index]; index += 1; } if (exp_len > buflen - index) { return VAL_BAD_ARGUMENT; } /* * Extract the exponent */ bn_exp = BN_bin2bn(buf + index, exp_len, NULL); index += exp_len; if (buflen <= index) { return VAL_BAD_ARGUMENT; } /* * Extract the modulus */ bn_mod = BN_bin2bn(buf + index, buflen - index, NULL); RSA_set0_key(rsa, bn_mod, bn_exp, NULL); return VAL_NO_ERROR; /* success */ }
static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int bitlen, int ispub) { const unsigned char *pin = *in; EVP_PKEY *ret = NULL; BIGNUM *e = NULL, *n = NULL, *d = NULL; RSA *rsa = NULL; unsigned int nbyte, hnbyte; nbyte = (bitlen + 7) >> 3; hnbyte = (bitlen + 15) >> 4; rsa = RSA_new(); ret = EVP_PKEY_new(); if (rsa == NULL || ret == NULL) goto memerr; e = BN_new(); if (e == NULL) goto memerr; if (!BN_set_word(e, read_ledword(&pin))) goto memerr; if (!read_lebn(&pin, nbyte, &n)) goto memerr; if (!ispub) { BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; if (!read_lebn(&pin, hnbyte, &p)) goto memerr; if (!read_lebn(&pin, hnbyte, &q)) goto memerr; if (!read_lebn(&pin, hnbyte, &dmp1)) goto memerr; if (!read_lebn(&pin, hnbyte, &dmq1)) goto memerr; if (!read_lebn(&pin, hnbyte, &iqmp)) goto memerr; if (!read_lebn(&pin, nbyte, &d)) goto memerr; RSA_set0_factors(rsa, p, q); RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp); } RSA_set0_key(rsa, e, n, d); EVP_PKEY_set1_RSA(ret, rsa); RSA_free(rsa); *in = pin; return ret; memerr: PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); RSA_free(rsa); EVP_PKEY_free(ret); return NULL; }
Private(base::const_byte_span nBytes, base::const_byte_span eBytes) : _rsa(RSA_new()) { if (_rsa) { auto n = openssl::BigNum(nBytes).takeRaw(); auto e = openssl::BigNum(eBytes).takeRaw(); auto valid = (n != nullptr) && (e != nullptr); // We still pass both values to RSA_set0_key() so that even // if only one of them is valid RSA would take ownership of it. if (!RSA_set0_key(_rsa, n, e, nullptr) || !valid) { RSA_free(base::take(_rsa)); } else { computeFingerprint(); } } }
int RSA_set_RSAPUBLICKEYBLOB(RSA *rsa, const RSAPUBLICKEYBLOB *blob) { int ret = 0; BIGNUM *n = NULL; BIGNUM *e = NULL; if (!rsa || !blob) { GMAPIerr(GMAPI_F_RSA_SET_RSAPUBLICKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if ((blob->BitLen < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) || (blob->BitLen > sizeof(blob->Modulus) * 8) || (blob->BitLen % 8 != 0)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPUBLICKEYBLOB, GMAPI_R_INVALID_RSA_KEY_LENGTH); return 0; } if (!(n = BN_bin2bn(blob->Modulus, sizeof(blob->Modulus), NULL))) { GMAPIerr(GMAPI_F_RSA_SET_RSAPUBLICKEYBLOB, GMAPI_R_INVALID_RSA_PUBLIC_KEY); goto end; } if (!(e = BN_bin2bn(blob->PublicExponent, sizeof(blob->PublicExponent), NULL))) { GMAPIerr(GMAPI_F_RSA_SET_RSAPUBLICKEYBLOB, GMAPI_R_INVALID_RSA_PUBLIC_KEY); goto end; } if (!RSA_set0_key(rsa, n, e, NULL)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPUBLICKEYBLOB, GMAPI_R_INVALID_RSA_PUBLIC_KEY); goto end; } n = NULL; e = NULL; ret = 1; end: BN_free(n); BN_free(e); return ret; }
int get_rsa_public_key(ErlNifEnv* env, ERL_NIF_TERM key, RSA *rsa) { /* key=[E,N] */ ERL_NIF_TERM head, tail; BIGNUM *e, *n; if (!enif_get_list_cell(env, key, &head, &tail) || !get_bn_from_bin(env, head, &e) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &n) || !enif_is_empty_list(env, tail)) { return 0; } (void) RSA_set0_key(rsa, n, e, NULL); return 1; }
int main(int argc, char **argv) { RSA *keypair = RSA_new(); BIGNUM *n = BN_new(); BIGNUM *e = BN_new(); if(argc != 3) { printf("Usage : %s <n> <e>\n", argv[0]); return 1; } BN_dec2bn(&n, argv[1]); BN_dec2bn(&e, argv[2]); RSA_set0_key(keypair, n, e, NULL); PEM_write_RSAPublicKey(stdout, keypair); RSA_free(keypair); return 0; }
/** * Get IFD (Terminal) private key data passing the three * arguments (modulus, public and private exponent). * * @param card pointer to card driver structure * @param ifd_privkey where to store IFD private key * @param modulus the byte array used as the modulus of the key * @param modulus_len the length of the modulus * @param public_exponent the byte array for the public exponent * @param public_exponent_len the length of the public exponent * @param private_exponent the byte array for the private exponent * @param private_exponent_len the length of the private exponent * @return SC_SUCCESS if ok; else error code */ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, u8 * modulus, int modulus_len, u8 * public_exponent, int public_exponent_len, u8 * private_exponent, int private_exponent_len) { RSA *ifd_rsa=NULL; BIGNUM *ifd_rsa_n, *ifd_rsa_e, *ifd_rsa_d = NULL; int res=SC_SUCCESS; LOG_FUNC_CALLED(card->ctx); /* compose ifd_private key with data provided in Annex 3 of DNIe Manual */ *ifd_privkey = EVP_PKEY_new(); ifd_rsa = RSA_new(); if (!*ifd_privkey || !ifd_rsa) { sc_log(card->ctx, "Cannot create data for IFD private key"); return SC_ERROR_OUT_OF_MEMORY; } ifd_rsa_n = BN_bin2bn(ifd_modulus, sizeof(ifd_modulus), NULL); ifd_rsa_e = BN_bin2bn(ifd_public_exponent, sizeof(ifd_public_exponent), NULL); ifd_rsa_d = BN_bin2bn(ifd_private_exponent, sizeof(ifd_private_exponent), NULL); if (RSA_set0_key(ifd_rsa, ifd_rsa_n, ifd_rsa_e, ifd_rsa_d) != 1) { BN_free(ifd_rsa_n); BN_free(ifd_rsa_e); BN_free(ifd_rsa_d); RSA_free(ifd_rsa); EVP_PKEY_free(*ifd_privkey); sc_log(card->ctx, "Cannot set RSA values for IFD private key"); return SC_ERROR_INTERNAL; } res = EVP_PKEY_assign_RSA(*ifd_privkey, ifd_rsa); if (!res) { if (*ifd_privkey) EVP_PKEY_free(*ifd_privkey); /* implies ifd_rsa free() */ sc_log(card->ctx, "Cannot compose IFD private key"); return SC_ERROR_INTERNAL; } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); }
static int test_check_public_key(void) { int ret = 0; BIGNUM *n = NULL, *e = NULL; RSA *key = NULL; ret = TEST_ptr(key = RSA_new()) /* check NULL pointers fail */ && TEST_false(rsa_sp800_56b_check_public(key)) /* load public key */ && TEST_ptr(e = bn_load_new(cav_e, sizeof(cav_e))) && TEST_ptr(n = bn_load_new(cav_n, sizeof(cav_n))) && TEST_true(RSA_set0_key(key, n, e, NULL)); if (!ret) { BN_free(e); BN_free(n); goto end; } /* check public key is valid */ ret = TEST_true(rsa_sp800_56b_check_public(key)) /* check fail if n is even */ && TEST_true(BN_add_word(n, 1)) && TEST_false(rsa_sp800_56b_check_public(key)) && TEST_true(BN_sub_word(n, 1)) /* check fail if n is wrong number of bits */ && TEST_true(BN_lshift1(n, n)) && TEST_false(rsa_sp800_56b_check_public(key)) && TEST_true(BN_rshift1(n, n)) /* test odd exponent fails */ && TEST_true(BN_add_word(e, 1)) && TEST_false(rsa_sp800_56b_check_public(key)) && TEST_true(BN_sub_word(e, 1)) /* modulus fails composite check */ && TEST_true(BN_add_word(n, 2)) && TEST_false(rsa_sp800_56b_check_public(key)); end: RSA_free(key); return ret; }
/** * Retrieve Root CA public key. * * Just returns (as local SM authentication) static data * @param card Pointer to card driver structure * @param root_ca_key pointer to resulting returned key * @return SC_SUCCESS if ok; else error code */ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) { int res=SC_SUCCESS; RSA *root_ca_rsa=NULL; BIGNUM *root_ca_rsa_n, *root_ca_rsa_e; LOG_FUNC_CALLED(card->ctx); /* compose root_ca_public key with data provided by Dnie Manual */ *root_ca_key = EVP_PKEY_new(); root_ca_rsa = RSA_new(); if (!*root_ca_key || !root_ca_rsa) { sc_log(card->ctx, "Cannot create data for root CA public key"); return SC_ERROR_OUT_OF_MEMORY; } root_ca_rsa_n = BN_bin2bn(icc_root_ca_modulus, sizeof(icc_root_ca_modulus), NULL); root_ca_rsa_e = BN_bin2bn(icc_root_ca_public_exponent, sizeof(icc_root_ca_public_exponent), NULL); if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) { BN_free(root_ca_rsa_n); BN_free(root_ca_rsa_e); if (*root_ca_key) EVP_PKEY_free(*root_ca_key); if (root_ca_rsa) RSA_free(root_ca_rsa); sc_log(card->ctx, "Cannot set RSA valuses for CA public key"); return SC_ERROR_INTERNAL; } res = EVP_PKEY_assign_RSA(*root_ca_key, root_ca_rsa); if (!res) { if (*root_ca_key) EVP_PKEY_free(*root_ca_key); /*implies root_ca_rsa free() */ sc_log(card->ctx, "Cannot compose root CA public key"); return SC_ERROR_INTERNAL; } LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); }
static isc_result_t rsa_check(RSA *rsa, RSA *pub) { const BIGNUM *n1 = NULL, *n2 = NULL; const BIGNUM *e1 = NULL, *e2 = NULL; BIGNUM *n = NULL, *e = NULL; /* * Public parameters should be the same but if they are not set * copy them from the public key. */ RSA_get0_key(rsa, &n1, &e1, NULL); if (pub != NULL) { RSA_get0_key(pub, &n2, &e2, NULL); if (n1 != NULL) { if (BN_cmp(n1, n2) != 0) return (DST_R_INVALIDPRIVATEKEY); } else { n = BN_dup(n2); } if (e1 != NULL) { if (BN_cmp(e1, e2) != 0) return (DST_R_INVALIDPRIVATEKEY); } else { e = BN_dup(e2); } if (RSA_set0_key(rsa, n, e, NULL) == 0) { if (n != NULL) BN_free(n); if (e != NULL) BN_free(e); } } RSA_get0_key(rsa, &n1, &e1, NULL); if (n1 == NULL || e1 == NULL) return (DST_R_INVALIDPRIVATEKEY); return (ISC_R_SUCCESS); }
int get_rsa_private_key(ErlNifEnv* env, ERL_NIF_TERM key, RSA *rsa) { /* key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C] */ ERL_NIF_TERM head, tail; BIGNUM *e, *n, *d; BIGNUM *p, *q; BIGNUM *dmp1, *dmq1, *iqmp; if (!enif_get_list_cell(env, key, &head, &tail) || !get_bn_from_bin(env, head, &e) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &n) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &d)) { return 0; } (void) RSA_set0_key(rsa, n, e, d); if (enif_is_empty_list(env, tail)) { return 1; } if (!enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &p) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &q) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &dmp1) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &dmq1) || !enif_get_list_cell(env, tail, &head, &tail) || !get_bn_from_bin(env, head, &iqmp) || !enif_is_empty_list(env, tail)) { return 0; } (void) RSA_set0_factors(rsa, p, q); (void) RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp); return 1; }
bool _cjose_jwk_rsa_set(RSA *rsa, uint8_t *n, size_t n_len, uint8_t *e, size_t e_len, uint8_t *d, size_t d_len) { BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; // RSA_set0_key doesn't work without each of those on the first call! if ((n == NULL) || (n_len <= 0) || (e == NULL) || (e_len <= 0)) return false; if (n && n_len > 0) rsa_n = BN_bin2bn(n, n_len, NULL); if (e && e_len > 0) rsa_e = BN_bin2bn(e, e_len, NULL); if (d && d_len > 0) rsa_d = BN_bin2bn(d, d_len, NULL); #if (CJOSE_OPENSSL_11X) return RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d) == 1; #else rsa->n = rsa_n; rsa->e = rsa_e; rsa->d = rsa_d; return true; #endif }
sgx_status_t sgx_rsa3072_verify(const uint8_t *p_data, uint32_t data_size, const sgx_rsa3072_public_key_t *p_public, const sgx_rsa3072_signature_t *p_signature, sgx_rsa_result_t *p_result) { if ((p_data == NULL) || (data_size < 1) || (p_public == NULL) || (p_signature == NULL) || (p_result == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } *p_result = SGX_RSA_INVALID_SIGNATURE; sgx_status_t retval = SGX_ERROR_UNEXPECTED; int verified = 0; RSA *pub_rsa_key = NULL; EVP_PKEY *pub_pkey = NULL; BIGNUM *n = NULL; BIGNUM *e = NULL; const EVP_MD* sha256_md = NULL; EVP_MD_CTX *ctx = NULL; CLEAR_OPENSSL_ERROR_QUEUE; do { // converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM // n = BN_lebin2bn((const unsigned char *)p_public->mod, sizeof(p_public->mod), 0); if (n == NULL) { break; } // converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM // e = BN_lebin2bn((const unsigned char *)p_public->exp, sizeof(p_public->exp), 0); if (e == NULL) { break; } // allocates and initializes an RSA key structure // pub_rsa_key = RSA_new(); if (pub_rsa_key == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // sets the modulus and public exp values of the RSA key // if (RSA_set0_key(pub_rsa_key, n, e, NULL) != 1) { BN_clear_free(n); BN_clear_free(e); break; } // allocates an empty EVP_PKEY structure // pub_pkey = EVP_PKEY_new(); if (pub_pkey == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed // if (EVP_PKEY_assign_RSA(pub_pkey, pub_rsa_key) != 1) { RSA_free(pub_rsa_key); break; } // allocates, initializes and returns a digest context // ctx = EVP_MD_CTX_new(); if (ctx == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // return EVP_MD structures for SHA256 digest algorithm */ // sha256_md = EVP_sha256(); if (sha256_md == NULL) { break; } // sets up verification context ctx to use digest type // if (EVP_DigestVerifyInit(ctx, NULL, sha256_md, NULL, pub_pkey) <= 0) { break; } // hashes data_size bytes of data at p_data into the verification context ctx. // this function can be called several times on the same ctx to hash additional data // if (EVP_DigestVerifyUpdate(ctx, (const void *)p_data, data_size) <= 0) { break; } // verifies the data in ctx against the signature in p_signature of length SGX_RSA3072_KEY_SIZE // verified = EVP_DigestVerifyFinal(ctx, (const unsigned char *)p_signature, SGX_RSA3072_KEY_SIZE); if (verified) { *p_result = SGX_RSA_VALID; } else if (verified != 0) { break; } retval = SGX_SUCCESS; } while (0); if (retval != SGX_SUCCESS) { GET_LAST_OPENSSL_ERROR; } if (ctx) EVP_MD_CTX_free(ctx); if (pub_pkey) { EVP_PKEY_free(pub_pkey); pub_rsa_key = NULL; n = NULL; e = NULL; } if (pub_rsa_key) { RSA_free(pub_rsa_key); n = NULL; e = NULL; } if (n) BN_clear_free(n); if (e) BN_clear_free(e); return retval; }
static isc_result_t opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; unsigned int length; #if USE_EVP EVP_PKEY *pkey; #endif BIGNUM *e = NULL, *n = NULL; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); length = r.length; rsa = RSA_new(); if (rsa == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); SET_FLAGS(rsa); if (r.length < 1) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base; isc_region_consume(&r, 1); if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = (*r.base) << 8; isc_region_consume(&r, 1); e_bytes += *r.base; isc_region_consume(&r, 1); } if (r.length < e_bytes) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e = BN_bin2bn(r.base, e_bytes, NULL); isc_region_consume(&r, e_bytes); n = BN_bin2bn(r.base, r.length, NULL); if (RSA_set0_key(rsa, n, e, NULL) == 0) { if (n != NULL) BN_free(n); if (e != NULL) BN_free(e); RSA_free(rsa); return (ISC_R_NOMEMORY); } key->key_size = BN_num_bits(n); isc_buffer_forward(data, length); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) { RSA_free(rsa); return (ISC_R_NOMEMORY); } if (!EVP_PKEY_set1_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); RSA_free(rsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); }
/** Sets the tag-designated key component into the established RSA context. This function sets the tag-designated RSA key component into the established RSA context from the user-specified non-negative integer (octet string format represented in RSA PKCS#1). If BigNumber is NULL, then the specified key component in RSA context is cleared. If RsaContext is NULL, then return FALSE. @param[in, out] RsaContext Pointer to RSA context being set. @param[in] KeyTag Tag of RSA key component being set. @param[in] BigNumber Pointer to octet integer buffer. If NULL, then the specified key component in RSA context is cleared. @param[in] BnSize Size of big number buffer in bytes. If BigNumber is NULL, then it is ignored. @retval TRUE RSA key component was set successfully. @retval FALSE Invalid RSA key component tag. **/ BOOLEAN EFIAPI RsaSetKey ( IN OUT VOID *RsaContext, IN RSA_KEY_TAG KeyTag, IN CONST UINT8 *BigNumber, IN UINTN BnSize ) { RSA *RsaKey; BIGNUM *BnN; BIGNUM *BnE; BIGNUM *BnD; BIGNUM *BnP; BIGNUM *BnQ; BIGNUM *BnDp; BIGNUM *BnDq; BIGNUM *BnQInv; // // Check input parameters. // if (RsaContext == NULL || BnSize > INT_MAX) { return FALSE; } BnN = NULL; BnE = NULL; BnD = NULL; BnP = NULL; BnQ = NULL; BnDp = NULL; BnDq = NULL; BnQInv = NULL; // // Retrieve the components from RSA object. // RsaKey = (RSA *) RsaContext; RSA_get0_key (RsaKey, (const BIGNUM **)&BnN, (const BIGNUM **)&BnE, (const BIGNUM **)&BnD); RSA_get0_factors (RsaKey, (const BIGNUM **)&BnP, (const BIGNUM **)&BnQ); RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnDp, (const BIGNUM **)&BnDq, (const BIGNUM **)&BnQInv); // // Set RSA Key Components by converting octet string to OpenSSL BN representation. // NOTE: For RSA public key (used in signature verification), only public components // (N, e) are needed. // switch (KeyTag) { // // RSA Public Modulus (N), Public Exponent (e) and Private Exponent (d) // case RsaKeyN: case RsaKeyE: case RsaKeyD: if (BnN == NULL) { BnN = BN_new (); } if (BnE == NULL) { BnE = BN_new (); } if (BnD == NULL) { BnD = BN_new (); } if ((BnN == NULL) || (BnE == NULL) || (BnD == NULL)) { return FALSE; } switch (KeyTag) { case RsaKeyN: BnN = BN_bin2bn (BigNumber, (UINT32)BnSize, BnN); break; case RsaKeyE: BnE = BN_bin2bn (BigNumber, (UINT32)BnSize, BnE); break; case RsaKeyD: BnD = BN_bin2bn (BigNumber, (UINT32)BnSize, BnD); break; default: return FALSE; } if (RSA_set0_key (RsaKey, BN_dup(BnN), BN_dup(BnE), BN_dup(BnD)) == 0) { return FALSE; } break; // // RSA Secret Prime Factor of Modulus (p and q) // case RsaKeyP: case RsaKeyQ: if (BnP == NULL) { BnP = BN_new (); } if (BnQ == NULL) { BnQ = BN_new (); } if ((BnP == NULL) || (BnQ == NULL)) { return FALSE; } switch (KeyTag) { case RsaKeyP: BnP = BN_bin2bn (BigNumber, (UINT32)BnSize, BnP); break; case RsaKeyQ: BnQ = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQ); break; default: return FALSE; } if (RSA_set0_factors (RsaKey, BN_dup(BnP), BN_dup(BnQ)) == 0) { return FALSE; } break; // // p's CRT Exponent (== d mod (p - 1)), q's CRT Exponent (== d mod (q - 1)), // and CRT Coefficient (== 1/q mod p) // case RsaKeyDp: case RsaKeyDq: case RsaKeyQInv: if (BnDp == NULL) { BnDp = BN_new (); } if (BnDq == NULL) { BnDq = BN_new (); } if (BnQInv == NULL) { BnQInv = BN_new (); } if ((BnDp == NULL) || (BnDq == NULL) || (BnQInv == NULL)) { return FALSE; } switch (KeyTag) { case RsaKeyDp: BnDp = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDp); break; case RsaKeyDq: BnDq = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDq); break; case RsaKeyQInv: BnQInv = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQInv); break; default: return FALSE; } if (RSA_set0_crt_params (RsaKey, BN_dup(BnDp), BN_dup(BnDq), BN_dup(BnQInv)) == 0) { return FALSE; } break; default: return FALSE; } return TRUE; }
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, const unsigned char *edata, unsigned long elen, const unsigned char *ndata, unsigned long nlen, const unsigned char *ddata, unsigned long dlen, const unsigned char *pdata, unsigned long plen, const unsigned char *qdata, unsigned long qlen, const unsigned char *e1data, unsigned long e1len, const unsigned char *e2data, unsigned long e2len, const unsigned char *coeffdata, unsigned long coefflen) { BIGNUM * e; BIGNUM * n; BIGNUM * d = 0; BIGNUM * p = 0; BIGNUM * q = 0; BIGNUM * dmp1 = 0; BIGNUM * dmq1 = 0; BIGNUM * iqmp = 0; e = BN_new(); BN_bin2bn(edata, elen, e); n = BN_new(); BN_bin2bn(ndata, nlen, n); if(ddata) { d = BN_new(); BN_bin2bn(ddata, dlen, d); p = BN_new(); BN_bin2bn(pdata, plen, p); q = BN_new(); BN_bin2bn(qdata, qlen, q); dmp1 = BN_new(); BN_bin2bn(e1data, e1len, dmp1); dmq1 = BN_new(); BN_bin2bn(e2data, e2len, dmq1); iqmp = BN_new(); BN_bin2bn(coeffdata, coefflen, iqmp); } *rsa = RSA_new(); #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_key(*rsa, n, e, d); #else (*rsa)->e = e; (*rsa)->n = n; #endif #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_factors(*rsa, p, q); #else (*rsa)->p = p; (*rsa)->q = q; #endif #ifdef HAVE_OPAQUE_STRUCTS RSA_set0_crt_params(*rsa, dmp1, dmq1, iqmp); #else (*rsa)->dmp1 = dmp1; (*rsa)->dmq1 = dmq1; (*rsa)->iqmp = iqmp; #endif return 0; }
static isc_result_t opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; RSA *rsa = NULL, *pubrsa = NULL; #ifdef USE_ENGINE ENGINE *ep = NULL; const BIGNUM *ex = NULL; #endif isc_mem_t *mctx = key->mctx; const char *engine = NULL, *label = NULL; #if defined(USE_ENGINE) || USE_EVP EVP_PKEY *pkey = NULL; #endif BIGNUM *n = NULL, *e = NULL, *d = NULL; BIGNUM *p = NULL, *q = NULL; BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) goto err; if (key->external) { if (priv.nelements != 0) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pub == NULL) DST_RET(DST_R_INVALIDPRIVATEKEY); key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); } #if USE_EVP if (pub != NULL && pub->keydata.pkey != NULL) pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); #else if (pub != NULL && pub->keydata.rsa != NULL) { pubrsa = pub->keydata.rsa; pub->keydata.rsa = NULL; } #endif for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: engine = (char *)priv.elements[i].data; break; case TAG_RSA_LABEL: label = (char *)priv.elements[i].data; break; default: break; } } /* * Is this key is stored in a HSM? * See if we can fetch it. */ if (label != NULL) { #ifdef USE_ENGINE if (engine == NULL) DST_RET(DST_R_NOENGINE); ep = dst__openssl_getengine(engine); if (ep == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(ep, label, NULL, NULL); if (pkey == NULL) DST_RET(dst__openssl_toresult2( "ENGINE_load_private_key", ISC_R_NOTFOUND)); key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); RSA_get0_key(rsa, NULL, &ex, NULL); if (BN_num_bits(ex) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; EVP_PKEY_free(pkey); #endif dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); #else DST_RET(DST_R_NOENGINE); #endif } rsa = RSA_new(); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); SET_FLAGS(rsa); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET(ISC_R_NOMEMORY); if (!EVP_PKEY_set1_RSA(pkey, rsa)) DST_RET(ISC_R_FAILURE); key->keydata.pkey = pkey; #else key->keydata.rsa = rsa; #endif for (i = 0; i < priv.nelements; i++) { BIGNUM *bn; switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: continue; case TAG_RSA_LABEL: continue; default: bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, NULL); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); switch (priv.elements[i].tag) { case TAG_RSA_MODULUS: n = bn; break; case TAG_RSA_PUBLICEXPONENT: e = bn; break; case TAG_RSA_PRIVATEEXPONENT: d = bn; break; case TAG_RSA_PRIME1: p = bn; break; case TAG_RSA_PRIME2: q = bn; break; case TAG_RSA_EXPONENT1: dmp1 = bn; break; case TAG_RSA_EXPONENT2: dmq1 = bn; break; case TAG_RSA_COEFFICIENT: iqmp = bn; break; } } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); if (RSA_set0_key(rsa, n, e, d) == 0) { if (n != NULL) BN_free(n); if (e != NULL) BN_free(e); if (d != NULL) BN_free(d); } if (RSA_set0_factors(rsa, p, q) == 0) { if (p != NULL) BN_free(p); if (q != NULL) BN_free(q); } if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0) { if (dmp1 != NULL) BN_free(dmp1); if (dmq1 != NULL) BN_free(dmq1); if (iqmp != NULL) BN_free(iqmp); } if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS) DST_RET(ISC_R_RANGE); key->key_size = BN_num_bits(n); if (pubrsa != NULL) RSA_free(pubrsa); #if USE_EVP RSA_free(rsa); #endif return (ISC_R_SUCCESS); err: #if USE_EVP if (pkey != NULL) EVP_PKEY_free(pkey); #endif if (rsa != NULL) RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); key->keydata.generic = NULL; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); }
static int test_invalid_keypair(void) { int ret = 0; RSA *key = NULL; BN_CTX *ctx = NULL; BIGNUM *p = NULL, *q = NULL, *n = NULL, *e = NULL, *d = NULL; ret = TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new()) /* NULL parameters */ && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) /* load key */ && TEST_ptr(p = bn_load_new(cav_p, sizeof(cav_p))) && TEST_ptr(q = bn_load_new(cav_q, sizeof(cav_q))) && TEST_true(RSA_set0_factors(key, p, q)); if (!ret) { BN_free(p); BN_free(q); goto end; } ret = TEST_ptr(e = bn_load_new(cav_e, sizeof(cav_e))) && TEST_ptr(n = bn_load_new(cav_n, sizeof(cav_n))) && TEST_ptr(d = bn_load_new(cav_d, sizeof(cav_d))) && TEST_true(RSA_set0_key(key, n, e, d)); if (!ret) { BN_free(e); BN_free(n); BN_free(d); goto end; } /* bad strength/key size */ ret = TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 100, 2048)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 112, 1024)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 128, 2048)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, 140, 3072)) /* mismatching exponent */ && TEST_false(rsa_sp800_56b_check_keypair(key, BN_value_one(), -1, 2048)) /* bad exponent */ && TEST_true(BN_add_word(e, 1)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_sub_word(e, 1)) /* mismatch between bits and modulus */ && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 3072)) && TEST_true(rsa_sp800_56b_check_keypair(key, e, 112, 2048)) /* check n == pq failure */ && TEST_true(BN_add_word(n, 1)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_sub_word(n, 1)) /* check p */ && TEST_true(BN_sub_word(p, 2)) && TEST_true(BN_mul(n, p, q, ctx)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_add_word(p, 2)) && TEST_true(BN_mul(n, p, q, ctx)) /* check q */ && TEST_true(BN_sub_word(q, 2)) && TEST_true(BN_mul(n, p, q, ctx)) && TEST_false(rsa_sp800_56b_check_keypair(key, NULL, -1, 2048)) && TEST_true(BN_add_word(q, 2)) && TEST_true(BN_mul(n, p, q, ctx)); end: RSA_free(key); BN_CTX_free(ctx); return ret; }
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 RSA_set_RSAPRIVATEKEYBLOB(RSA *rsa, const RSAPRIVATEKEYBLOB *blob) { int ret = 0; BIGNUM *n = NULL; BIGNUM *e = NULL; BIGNUM *d = NULL; BIGNUM *p = NULL; BIGNUM *q = NULL; BIGNUM *dmp1 = NULL; BIGNUM *dmq1 = NULL; BIGNUM *iqmp = NULL; if (!rsa || !blob) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (blob->AlgID != SGD_RSA) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_ALGOR); return 0; } if (blob->BitLen < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS || blob->BitLen > sizeof(blob->Modulus) * 8 || blob->BitLen % 8 != 0 || blob->BitLen % 16 != 0) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (!(n = BN_bin2bn(blob->Modulus, sizeof(blob->Modulus), NULL)) || !(e = BN_bin2bn(blob->PublicExponent, sizeof(blob->PublicExponent), NULL)) || !(d = BN_bin2bn(blob->PrivateExponent, sizeof(blob->PrivateExponent), NULL)) || !(p = BN_bin2bn(blob->Prime1, sizeof(blob->Prime1), NULL)) || !(q = BN_bin2bn(blob->Prime2, sizeof(blob->Prime2), NULL)) || !(dmp1 = BN_bin2bn(blob->Prime1Exponent, sizeof(blob->Prime1Exponent), NULL)) || !(dmq1 = BN_bin2bn(blob->Prime2Exponent, sizeof(blob->Prime2Exponent), NULL)) || !(iqmp = BN_bin2bn(blob->Coefficient, sizeof(blob->Coefficient), NULL))) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, ERR_R_BN_LIB); goto end; } if (!RSA_set0_key(rsa, n, e, d)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } n = NULL; e = NULL; d = NULL; if (!RSA_set0_factors(rsa, p, q)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } p = NULL; q = NULL; if (!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) { GMAPIerr(GMAPI_F_RSA_SET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); goto end; } dmp1 = NULL; dmq1 = NULL; iqmp = NULL; ret = 1; end: BN_free(n); BN_free(e); BN_free(d); BN_free(p); BN_free(q); BN_free(dmp1); BN_free(dmq1); BN_free(iqmp); return ret; }
static int key2048p3(RSA *key) { /* C90 requires string should <= 509 bytes */ static const unsigned char n[] = "\x92\x60\xd0\x75\x0a\xe1\x17\xee\xe5\x5c\x3f\x3d\xea\xba\x74\x91" "\x75\x21\xa2\x62\xee\x76\x00\x7c\xdf\x8a\x56\x75\x5a\xd7\x3a\x15" "\x98\xa1\x40\x84\x10\xa0\x14\x34\xc3\xf5\xbc\x54\xa8\x8b\x57\xfa" "\x19\xfc\x43\x28\xda\xea\x07\x50\xa4\xc4\x4e\x88\xcf\xf3\xb2\x38" "\x26\x21\xb8\x0f\x67\x04\x64\x43\x3e\x43\x36\xe6\xd0\x03\xe8\xcd" "\x65\xbf\xf2\x11\xda\x14\x4b\x88\x29\x1c\x22\x59\xa0\x0a\x72\xb7" "\x11\xc1\x16\xef\x76\x86\xe8\xfe\xe3\x4e\x4d\x93\x3c\x86\x81\x87" "\xbd\xc2\x6f\x7b\xe0\x71\x49\x3c\x86\xf7\xa5\x94\x1c\x35\x10\x80" "\x6a\xd6\x7b\x0f\x94\xd8\x8f\x5c\xf5\xc0\x2a\x09\x28\x21\xd8\x62" "\x6e\x89\x32\xb6\x5c\x5b\xd8\xc9\x20\x49\xc2\x10\x93\x2b\x7a\xfa" "\x7a\xc5\x9c\x0e\x88\x6a\xe5\xc1\xed\xb0\x0d\x8c\xe2\xc5\x76\x33" "\xdb\x26\xbd\x66\x39\xbf\xf7\x3c\xee\x82\xbe\x92\x75\xc4\x02\xb4" "\xcf\x2a\x43\x88\xda\x8c\xf8\xc6\x4e\xef\xe1\xc5\xa0\xf5\xab\x80" "\x57\xc3\x9f\xa5\xc0\x58\x9c\x3e\x25\x3f\x09\x60\x33\x23\x00\xf9" "\x4b\xea\x44\x87\x7b\x58\x8e\x1e\xdb\xde\x97\xcf\x23\x60\x72\x7a" "\x09\xb7\x75\x26\x2d\x7e\xe5\x52\xb3\x31\x9b\x92\x66\xf0\x5a\x25"; static const unsigned char e[] = "\x01\x00\x01"; static const unsigned char d[] = "\x6a\x7d\xf2\xca\x63\xea\xd4\xdd\xa1\x91\xd6\x14\xb6\xb3\x85\xe0" "\xd9\x05\x6a\x3d\x6d\x5c\xfe\x07\xdb\x1d\xaa\xbe\xe0\x22\xdb\x08" "\x21\x2d\x97\x61\x3d\x33\x28\xe0\x26\x7c\x9d\xd2\x3d\x78\x7a\xbd" "\xe2\xaf\xcb\x30\x6a\xeb\x7d\xfc\xe6\x92\x46\xcc\x73\xf5\xc8\x7f" "\xdf\x06\x03\x01\x79\xa2\x11\x4b\x76\x7d\xb1\xf0\x83\xff\x84\x1c" "\x02\x5d\x7d\xc0\x0c\xd8\x24\x35\xb9\xa9\x0f\x69\x53\x69\xe9\x4d" "\xf2\x3d\x2c\xe4\x58\xbc\x3b\x32\x83\xad\x8b\xba\x2b\x8f\xa1\xba" "\x62\xe2\xdc\xe9\xac\xcf\xf3\x79\x9a\xae\x7c\x84\x00\x16\xf3\xba" "\x8e\x00\x48\xc0\xb6\xcc\x43\x39\xaf\x71\x61\x00\x3a\x5b\xeb\x86" "\x4a\x01\x64\xb2\xc1\xc9\x23\x7b\x64\xbc\x87\x55\x69\x94\x35\x1b" "\x27\x50\x6c\x33\xd4\xbc\xdf\xce\x0f\x9c\x49\x1a\x7d\x6b\x06\x28" "\xc7\xc8\x52\xbe\x4f\x0a\x9c\x31\x32\xb2\xed\x3a\x2c\x88\x81\xe9" "\xaa\xb0\x7e\x20\xe1\x7d\xeb\x07\x46\x91\xbe\x67\x77\x76\xa7\x8b" "\x5c\x50\x2e\x05\xd9\xbd\xde\x72\x12\x6b\x37\x38\x69\x5e\x2d\xd1" "\xa0\xa9\x8a\x14\x24\x7c\x65\xd8\xa7\xee\x79\x43\x2a\x09\x2c\xb0" "\x72\x1a\x12\xdf\x79\x8e\x44\xf7\xcf\xce\x0c\x49\x81\x47\xa9\xb1"; static const unsigned char p[] = "\x06\x77\xcd\xd5\x46\x9b\xc1\xd5\x58\x00\x81\xe2\xf3\x0a\x36\xb1" "\x6e\x29\x89\xd5\x2f\x31\x5f\x92\x22\x3b\x9b\x75\x30\x82\xfa\xc5" "\xf5\xde\x8a\x36\xdb\xc6\xe5\x8f\xef\x14\x37\xd6\x00\xf9\xab\x90" "\x9b\x5d\x57\x4c\xf5\x1f\x77\xc4\xbb\x8b\xdd\x9b\x67\x11\x45\xb2" "\x64\xe8\xac\xa8\x03\x0f\x16\x0d\x5d\x2d\x53\x07\x23\xfb\x62\x0d" "\xe6\x16\xd3\x23\xe8\xb3"; static const unsigned char q[] = "\x06\x66\x9a\x70\x53\xd6\x72\x74\xfd\xea\x45\xc3\xc0\x17\xae\xde" "\x79\x17\xae\x79\xde\xfc\x0e\xf7\xa4\x3a\x8c\x43\x8f\xc7\x8a\xa2" "\x2c\x51\xc4\xd0\x72\x89\x73\x5c\x61\xbe\xfd\x54\x3f\x92\x65\xde" "\x4d\x65\x71\x70\xf6\xf2\xe5\x98\xb9\x0f\xd1\x0b\xe6\x95\x09\x4a" "\x7a\xdf\xf3\x10\x16\xd0\x60\xfc\xa5\x10\x34\x97\x37\x6f\x0a\xd5" "\x5d\x8f\xd4\xc3\xa0\x5b"; static const unsigned char dmp1[] = "\x05\x7c\x9e\x1c\xbd\x90\x25\xe7\x40\x86\xf5\xa8\x3b\x7a\x3f\x99" "\x56\x95\x60\x3a\x7b\x95\x4b\xb8\xa0\xd7\xa5\xf1\xcc\xdc\x5f\xb5" "\x8c\xf4\x62\x95\x54\xed\x2e\x12\x62\xc2\xe8\xf6\xde\xce\xed\x8e" "\x77\x6d\xc0\x40\x25\x74\xb3\x5a\x2d\xaa\xe1\xac\x11\xcb\xe2\x2f" "\x0a\x51\x23\x1e\x47\xb2\x05\x88\x02\xb2\x0f\x4b\xf0\x67\x30\xf0" "\x0f\x6e\xef\x5f\xf7\xe7"; static const unsigned char dmq1[] = "\x01\xa5\x6b\xbc\xcd\xe3\x0e\x46\xc6\x72\xf5\x04\x56\x28\x01\x22" "\x58\x74\x5d\xbc\x1c\x3c\x29\x41\x49\x6c\x81\x5c\x72\xe2\xf7\xe5" "\xa3\x8e\x58\x16\xe0\x0e\x37\xac\x1f\xbb\x75\xfd\xaf\xe7\xdf\xe9" "\x1f\x70\xa2\x8f\x52\x03\xc0\x46\xd9\xf9\x96\x63\x00\x27\x7e\x5f" "\x38\x60\xd6\x6b\x61\xe2\xaf\xbe\xea\x58\xd3\x9d\xbc\x75\x03\x8d" "\x42\x65\xd6\x6b\x85\x97"; static const unsigned char iqmp[] = "\x03\xa1\x8b\x80\xe4\xd8\x87\x25\x17\x5d\xcc\x8d\xa9\x8a\x22\x2b" "\x6c\x15\x34\x6f\x80\xcc\x1c\x44\x04\x68\xbc\x03\xcd\x95\xbb\x69" "\x37\x61\x48\xb4\x23\x13\x08\x16\x54\x6a\xa1\x7c\xf5\xd4\x3a\xe1" "\x4f\xa4\x0c\xf5\xaf\x80\x85\x27\x06\x0d\x70\xc0\xc5\x19\x28\xfe" "\xee\x8e\x86\x21\x98\x8a\x37\xb7\xe5\x30\x25\x70\x93\x51\x2d\x49" "\x85\x56\xb3\x0c\x2b\x96"; static const unsigned char ex_prime[] = "\x03\x89\x22\xa0\xb7\x3a\x91\xcb\x5e\x0c\xfd\x73\xde\xa7\x38\xa9" "\x47\x43\xd6\x02\xbf\x2a\xb9\x3c\x48\xf3\x06\xd6\x58\x35\x50\x56" "\x16\x5c\x34\x9b\x61\x87\xc8\xaa\x0a\x5d\x8a\x0a\xcd\x9c\x41\xd9" "\x96\x24\xe0\xa9\x9b\x26\xb7\xa8\x08\xc9\xea\xdc\xa7\x15\xfb\x62" "\xa0\x2d\x90\xe6\xa7\x55\x6e\xc6\x6c\xff\xd6\x10\x6d\xfa\x2e\x04" "\x50\xec\x5c\x66\xe4\x05"; static const unsigned char ex_exponent[] = "\x02\x0a\xcd\xc3\x82\xd2\x03\xb0\x31\xac\xd3\x20\x80\x34\x9a\x57" "\xbc\x60\x04\x57\x25\xd0\x29\x9a\x16\x90\xb9\x1c\x49\x6a\xd1\xf2" "\x47\x8c\x0e\x9e\xc9\x20\xc2\xd8\xe4\x8f\xce\xd2\x1a\x9c\xec\xb4" "\x1f\x33\x41\xc8\xf5\x62\xd1\xa5\xef\x1d\xa1\xd8\xbd\x71\xc6\xf7" "\xda\x89\x37\x2e\xe2\xec\x47\xc5\xb8\xe3\xb4\xe3\x5c\x82\xaa\xdd" "\xb7\x58\x2e\xaf\x07\x79"; static const unsigned char ex_coefficient[] = "\x00\x9c\x09\x88\x9b\xc8\x57\x08\x69\x69\xab\x2d\x9e\x29\x1c\x3c" "\x6d\x59\x33\x12\x0d\x2b\x09\x2e\xaf\x01\x2c\x27\x01\xfc\xbd\x26" "\x13\xf9\x2d\x09\x22\x4e\x49\x11\x03\x82\x88\x87\xf4\x43\x1d\xac" "\xca\xec\x86\xf7\x23\xf1\x64\xf3\xf5\x81\xf0\x37\x36\xcf\x67\xff" "\x1a\xff\x7a\xc7\xf9\xf9\x67\x2d\xa0\x9d\x61\xf8\xf6\x47\x5c\x2f" "\xe7\x66\xe8\x3c\x3a\xe8"; BIGNUM **pris = NULL, **exps = NULL, **coeffs = NULL; int rv = 256; /* public key length */ if (!TEST_int_eq(RSA_set0_key(key, BN_bin2bn(n, sizeof(n) - 1, NULL), BN_bin2bn(e, sizeof(e) - 1, NULL), BN_bin2bn(d, sizeof(d) - 1, NULL)), 1)) goto err; if (!TEST_int_eq(RSA_set0_factors(key, BN_bin2bn(p, sizeof(p) - 1, NULL), BN_bin2bn(q, sizeof(q) - 1, NULL)), 1)) goto err; if (!TEST_int_eq(RSA_set0_crt_params(key, BN_bin2bn(dmp1, sizeof(dmp1) - 1, NULL), BN_bin2bn(dmq1, sizeof(dmq1) - 1, NULL), BN_bin2bn(iqmp, sizeof(iqmp) - 1, NULL)), 1)) return 0; pris = OPENSSL_zalloc(sizeof(BIGNUM *)); exps = OPENSSL_zalloc(sizeof(BIGNUM *)); coeffs = OPENSSL_zalloc(sizeof(BIGNUM *)); if (!TEST_ptr(pris) || !TEST_ptr(exps) || !TEST_ptr(coeffs)) goto err; pris[0] = BN_bin2bn(ex_prime, sizeof(ex_prime) - 1, NULL); exps[0] = BN_bin2bn(ex_exponent, sizeof(ex_exponent) - 1, NULL); coeffs[0] = BN_bin2bn(ex_coefficient, sizeof(ex_coefficient) - 1, NULL); if (!TEST_ptr(pris[0]) || !TEST_ptr(exps[0]) || !TEST_ptr(coeffs[0])) goto err; if (!TEST_true(RSA_set0_multi_prime_params(key, pris, exps, coeffs, NUM_EXTRA_PRIMES))) goto err; ret: OPENSSL_free(pris); OPENSSL_free(exps); OPENSSL_free(coeffs); return rv; err: if (pris != NULL) BN_free(pris[0]); if (exps != NULL) BN_free(exps[0]); if (coeffs != NULL) BN_free(coeffs[0]); rv = 0; goto ret; }
static EVP_PKEY *ssh2_line_to_key(char *line) { EVP_PKEY *key; RSA *rsa; BIGNUM *rsa_e, *rsa_n; unsigned char decoded[OPENSSH_LINE_MAX]; int len; char *b, *c; int i; /* find the mime-blob */ b = line; if (!b) return NULL; /* find the first whitespace */ while (*b && *b != ' ') b++; /* skip that whitespace */ b++; /* find the end of the blob / comment */ for (c = b; *c && *c != ' ' && 'c' != '\t' && *c != '\r' && *c != '\n'; c++) ; *c = 0; /* decode binary data */ if (sc_base64_decode(b, decoded, OPENSSH_LINE_MAX) < 0) return NULL; i = 0; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* now: key_from_blob */ if (strncmp((char *)&decoded[i], "ssh-rsa", 7) != 0) return NULL; i += len; /* to prevent access beyond 'decoded' array, index 'i' must be always checked */ if ( i + 4 > OPENSSH_LINE_MAX ) return NULL; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; if ( i + len > OPENSSH_LINE_MAX ) return NULL; /* get bignum */ rsa_e = BN_bin2bn(decoded + i, len, NULL); i += len; if ( i + 4 > OPENSSH_LINE_MAX ) return NULL; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; if ( i + len > OPENSSH_LINE_MAX ) return NULL; /* get bignum */ rsa_n = BN_bin2bn(decoded + i, len, NULL); key = EVP_PKEY_new(); rsa = RSA_new(); /* set e and n */ if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { EVP_PKEY_free(key); RSA_free(rsa); return NULL; } EVP_PKEY_assign_RSA(key, rsa); return key; }
RSA * sldns_key_buf2rsa_raw(unsigned char* key, size_t len) { uint16_t offset; uint16_t exp; uint16_t int16; RSA *rsa; BIGNUM *modulus; BIGNUM *exponent; if (len == 0) return NULL; if (key[0] == 0) { if(len < 3) return NULL; memmove(&int16, key+1, 2); exp = ntohs(int16); offset = 3; } else { exp = key[0]; offset = 1; } /* key length at least one */ if(len < (size_t)offset + exp + 1) return NULL; /* Exponent */ exponent = BN_new(); if(!exponent) return NULL; (void) BN_bin2bn(key+offset, (int)exp, exponent); offset += exp; /* Modulus */ modulus = BN_new(); if(!modulus) { BN_free(exponent); return NULL; } /* length of the buffer must match the key length! */ (void) BN_bin2bn(key+offset, (int)(len - offset), modulus); rsa = RSA_new(); if(!rsa) { BN_free(exponent); BN_free(modulus); return NULL; } #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) #ifndef S_SPLINT_S rsa->n = modulus; rsa->e = exponent; #endif /* splint */ #else /* OPENSSL_VERSION_NUMBER */ if (!RSA_set0_key(rsa, modulus, exponent, NULL)) { BN_free(exponent); BN_free(modulus); RSA_free(rsa); return NULL; } #endif return rsa; }
int AuthenticateAgent(AgentConnection *conn, bool trust_key) { char sendbuffer[CF_EXPANDSIZE], in[CF_BUFSIZE], *out, *decrypted_cchall; BIGNUM *nonce_challenge, *bn = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; int encrypted_len, nonce_len = 0, len, session_size; bool need_to_implicitly_trust_server; char enterprise_field = 'c'; if (PRIVKEY == NULL || PUBKEY == NULL) { Log(LOG_LEVEL_ERR, "No public/private key pair is loaded," " please create one using cf-key"); return false; } enterprise_field = CfEnterpriseOptions(); session_size = CfSessionKeySize(enterprise_field); /* Generate a random challenge to authenticate the server */ nonce_challenge = BN_new(); if (nonce_challenge == NULL) { Log(LOG_LEVEL_ERR, "Cannot allocate BIGNUM structure for server challenge"); return false; } BN_rand(nonce_challenge, CF_NONCELEN, 0, 0); nonce_len = BN_bn2mpi(nonce_challenge, in); if (FIPS_MODE) { HashString(in, nonce_len, digest, CF_DEFAULT_DIGEST); } else { HashString(in, nonce_len, digest, HASH_METHOD_MD5); } /* We assume that the server bound to the remote socket is the official one i.e. = root's */ /* Ask the server to send us the public key if we don't have it. */ RSA *server_pubkey = HavePublicKeyByIP(conn->username, conn->remoteip); if (server_pubkey) { need_to_implicitly_trust_server = false; encrypted_len = RSA_size(server_pubkey); } else { need_to_implicitly_trust_server = true; encrypted_len = nonce_len; } // Server pubkey is what we want to has as a unique ID snprintf(sendbuffer, sizeof(sendbuffer), "SAUTH %c %d %d %c", need_to_implicitly_trust_server ? 'n': 'y', encrypted_len, nonce_len, enterprise_field); out = xmalloc(encrypted_len); if (server_pubkey != NULL) { if (RSA_public_encrypt(nonce_len, in, out, server_pubkey, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Public encryption failed. (RSA_public_encrypt: %s)", CryptoLastErrorString()); free(out); RSA_free(server_pubkey); return false; } memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, out, encrypted_len); } else { memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, in, nonce_len); } /* proposition C1 - Send challenge / nonce */ SendTransaction(conn->conn_info, sendbuffer, CF_RSA_PROTO_OFFSET + encrypted_len, CF_DONE); BN_free(bn); BN_free(nonce_challenge); free(out); /*Send the public key - we don't know if server has it */ /* proposition C2 */ const BIGNUM *pubkey_n, *pubkey_e; RSA_get0_key(PUBKEY, &pubkey_n, &pubkey_e, NULL); memset(sendbuffer, 0, CF_EXPANDSIZE); len = BN_bn2mpi(pubkey_n, sendbuffer); SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE); /* No need to encrypt the public key ... */ /* proposition C3 */ memset(sendbuffer, 0, CF_EXPANDSIZE); len = BN_bn2mpi(pubkey_e, sendbuffer); SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE); /* check reply about public key - server can break conn_info here */ /* proposition S1 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, in, NULL) == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction broken off (1). (ReceiveTransaction: %s)", GetErrorStr()); RSA_free(server_pubkey); return false; } if (BadProtoReply(in)) { Log(LOG_LEVEL_ERR, "Bad protocol reply: %s", in); RSA_free(server_pubkey); return false; } /* Get challenge response - should be CF_DEFAULT_DIGEST of challenge */ /* proposition S2 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, in, NULL) == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction broken off (2). (ReceiveTransaction: %s)", GetErrorStr()); RSA_free(server_pubkey); return false; } /* Check if challenge reply was correct */ if ((HashesMatch(digest, in, CF_DEFAULT_DIGEST)) || (HashesMatch(digest, in, HASH_METHOD_MD5))) // Legacy { if (need_to_implicitly_trust_server == false) { /* The IP was found in lastseen. */ Log(LOG_LEVEL_VERBOSE, ".....................[.h.a.i.l.]................................."); Log(LOG_LEVEL_VERBOSE, "Strong authentication of server '%s' connection confirmed", conn->this_server); } else /* IP was not found in lastseen */ { if (trust_key) { Log(LOG_LEVEL_VERBOSE, "Trusting server identity, promise to accept key from '%s' = '%s'", conn->this_server, conn->remoteip); } else { Log(LOG_LEVEL_ERR, "Not authorized to trust public key of server '%s' (trustkey = false)", conn->this_server); RSA_free(server_pubkey); return false; } } } else { Log(LOG_LEVEL_ERR, "Challenge response from server '%s/%s' was incorrect", conn->this_server, conn->remoteip); RSA_free(server_pubkey); return false; } /* Receive counter challenge from server */ /* proposition S3 */ memset(in, 0, CF_BUFSIZE); encrypted_len = ReceiveTransaction(conn->conn_info, in, NULL); if (encrypted_len == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction sent illegal cipher length"); RSA_free(server_pubkey); return false; } decrypted_cchall = xmalloc(encrypted_len); if (RSA_private_decrypt(encrypted_len, in, decrypted_cchall, PRIVKEY, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Private decrypt failed, abandoning. (RSA_private_decrypt: %s)", CryptoLastErrorString()); RSA_free(server_pubkey); return false; } /* proposition C4 */ if (FIPS_MODE) { HashString(decrypted_cchall, nonce_len, digest, CF_DEFAULT_DIGEST); } else { HashString(decrypted_cchall, nonce_len, digest, HASH_METHOD_MD5); } if (FIPS_MODE) { SendTransaction(conn->conn_info, digest, CF_DEFAULT_DIGEST_LEN, CF_DONE); } else { SendTransaction(conn->conn_info, digest, CF_MD5_LEN, CF_DONE); } free(decrypted_cchall); /* If we don't have the server's public key, it will be sent */ if (server_pubkey == NULL) { RSA *newkey = RSA_new(); Log(LOG_LEVEL_VERBOSE, "Collecting public key from server!"); /* proposition S4 - conditional */ if ((len = ReceiveTransaction(conn->conn_info, in, NULL)) == -1) { Log(LOG_LEVEL_ERR, "Protocol error in RSA authentation from IP '%s'", conn->this_server); return false; } BIGNUM *newkey_n, *newkey_e; if ((newkey_n = BN_mpi2bn(in, len, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Private key decrypt failed. (BN_mpi2bn: %s)", CryptoLastErrorString()); RSA_free(newkey); return false; } /* proposition S5 - conditional */ if ((len = ReceiveTransaction(conn->conn_info, in, NULL)) == -1) { Log(LOG_LEVEL_INFO, "Protocol error in RSA authentation from IP '%s'", conn->this_server); BN_clear_free(newkey_n); RSA_free(newkey); return false; } if ((newkey_e = BN_mpi2bn(in, len, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Public key decrypt failed. (BN_mpi2bn: %s)", CryptoLastErrorString()); BN_clear_free(newkey_n); RSA_free(newkey); return false; } if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { Log(LOG_LEVEL_ERR, "Failed to set RSA key: %s", TLSErrorString(ERR_get_error())); BN_clear_free(newkey_e); BN_clear_free(newkey_n); RSA_free(newkey); return false; } server_pubkey = RSAPublicKey_dup(newkey); RSA_free(newkey); } assert(server_pubkey != NULL); /* proposition C5 */ if (!SetSessionKey(conn)) { Log(LOG_LEVEL_ERR, "Unable to set session key"); return false; } if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "A random session key could not be established"); RSA_free(server_pubkey); return false; } encrypted_len = RSA_size(server_pubkey); out = xmalloc(encrypted_len); if (RSA_public_encrypt(session_size, conn->session_key, out, server_pubkey, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Public encryption failed. (RSA_public_encrypt: %s)", CryptoLastErrorString()); free(out); RSA_free(server_pubkey); return false; } SendTransaction(conn->conn_info, out, encrypted_len, CF_DONE); Key *key = KeyNew(server_pubkey, CF_DEFAULT_DIGEST); conn->conn_info->remote_key = key; Log(LOG_LEVEL_VERBOSE, "Public key identity of host '%s' is: %s", conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key)); SavePublicKey(conn->username, KeyPrintableHash(conn->conn_info->remote_key), server_pubkey); unsigned int length = 0; LastSaw(conn->remoteip, KeyBinaryHash(conn->conn_info->remote_key, &length), LAST_SEEN_ROLE_CONNECT); free(out); return true; }
static EVP_PKEY *ssh1_line_to_key(char *line) { EVP_PKEY *key; RSA *rsa; char *b, *e, *m, *c; BIGNUM *rsa_e, *rsa_n; key = EVP_PKEY_new(); if (!key) return NULL; rsa = RSA_new(); if (!rsa) goto err; /* first digitstring: the bits */ b = line; /* second digitstring: the exponent */ /* skip all digits */ for (e = b; *e >= '0' && *e <= '0'; e++) ; /* must be a whitespace */ if (*e != ' ' && *e != '\t') return NULL; /* cut the string in two part */ *e = 0; e++; /* skip more whitespace */ while (*e == ' ' || *e == '\t') e++; /* third digitstring: the modulus */ /* skip all digits */ for (m = e; *m >= '0' && *m <= '0'; m++) ; /* must be a whitespace */ if (*m != ' ' && *m != '\t') return NULL; /* cut the string in two part */ *m = 0; m++; /* skip more whitespace */ while (*m == ' ' || *m == '\t') m++; /* look for a comment after the modulus */ for (c = m; *c >= '0' && *c <= '0'; c++) ; /* could be a whitespace or end of line */ if (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\r' && *c != 0) return NULL; if (*c == ' ' || *c == '\t') { *c = 0; c++; /* skip more whitespace */ while (*c == ' ' || *c == '\t') c++; if (*c && *c != '\r' && *c != '\n') { /* we have a comment */ } else { c = NULL; } } else { *c = 0; c = NULL; } /* ok, now we have b e m pointing to pure digit * null terminated strings and maybe c pointing to a comment */ BN_dec2bn(&rsa_e, e); BN_dec2bn(&rsa_n, m); if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) goto err; EVP_PKEY_assign_RSA(key, rsa); return key; err: EVP_PKEY_free(key); return NULL; }
sgx_status_t sgx_rsa3072_sign(const uint8_t * p_data, uint32_t data_size, const sgx_rsa3072_key_t * p_key, sgx_rsa3072_signature_t * p_signature) { if ((p_data == NULL) || (data_size < 1) || (p_key == NULL) || (p_signature == NULL)) { return SGX_ERROR_INVALID_PARAMETER; } sgx_status_t retval = SGX_ERROR_UNEXPECTED; RSA *priv_rsa_key = NULL; EVP_PKEY* priv_pkey = NULL; BIGNUM *n = NULL; BIGNUM *d = NULL; BIGNUM *e = NULL; EVP_MD_CTX* ctx = NULL; const EVP_MD* sha256_md = NULL; size_t siglen = SGX_RSA3072_KEY_SIZE; int ret = 0; CLEAR_OPENSSL_ERROR_QUEUE; do { // converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM // n = BN_lebin2bn((const unsigned char *)p_key->mod, sizeof(p_key->mod), 0); if (n == NULL) { break; } // converts the private exp value of rsa key, represented as positive integer in little-endian into a BIGNUM // d = BN_lebin2bn((const unsigned char *)p_key->d, sizeof(p_key->d), 0); if (d == NULL) { break; } // converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM // e = BN_lebin2bn((const unsigned char *)p_key->e, sizeof(p_key->e), 0); if (e == NULL) { break; } // allocates and initializes an RSA key structure // priv_rsa_key = RSA_new(); if (priv_rsa_key == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // sets the modulus, private exp and public exp values of the RSA key // if (RSA_set0_key(priv_rsa_key, n, e, d) != 1) { BN_clear_free(n); BN_clear_free(d); BN_clear_free(e); break; } // allocates an empty EVP_PKEY structure // priv_pkey = EVP_PKEY_new(); if (priv_pkey == NULL) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed // if (EVP_PKEY_assign_RSA(priv_pkey, priv_rsa_key) != 1) { RSA_free(priv_rsa_key); break; } // allocates, initializes and returns a digest context // ctx = EVP_MD_CTX_new(); if (NULL == ctx) { retval = SGX_ERROR_OUT_OF_MEMORY; break; } // return EVP_MD structures for SHA256 digest algorithm */ // sha256_md = EVP_sha256(); if (sha256_md == NULL) { break; } // sets up signing context ctx to use digest type // if (EVP_DigestSignInit(ctx, NULL, sha256_md, NULL, priv_pkey) <= 0) { break; } // hashes data_size bytes of data at p_data into the signature context ctx // if (EVP_DigestSignUpdate(ctx, (const void *)p_data, data_size) <= 0) { break; } // signs the data in ctx places the signature in p_signature. // ret = EVP_DigestSignFinal(ctx, (unsigned char *)p_signature, &siglen);//fails if (ret <= 0) { break; } // validates the signature size // if (SGX_RSA3072_KEY_SIZE != siglen) { break; } retval = SGX_SUCCESS; } while (0); if (retval != SGX_SUCCESS) { GET_LAST_OPENSSL_ERROR; } if (ctx) EVP_MD_CTX_free(ctx); if (priv_pkey) { EVP_PKEY_free(priv_pkey); priv_rsa_key = NULL; n = NULL; d = NULL; e = NULL; } if (priv_rsa_key) { RSA_free(priv_rsa_key); n = NULL; d = NULL; e = NULL; } if (n) BN_clear_free(n); if (d) BN_clear_free(d); if (e) BN_clear_free(e); return retval; }