/* Creates a term which can be parsed by get_rsa_private_key(). This is a list of plain integer binaries (not mpints). */ static ERL_NIF_TERM put_rsa_private_key(ErlNifEnv* env, const RSA *rsa) { ERL_NIF_TERM result[8]; const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; /* Return at least [E,N,D] */ n = NULL; e = NULL; d = NULL; RSA_get0_key(rsa, &n, &e, &d); result[0] = bin_from_bn(env, e); // Exponent E result[1] = bin_from_bn(env, n); // Modulus N = p*q result[2] = bin_from_bn(env, d); // Exponent D /* Check whether the optional additional parameters are available */ p = NULL; q = NULL; RSA_get0_factors(rsa, &p, &q); dmp1 = NULL; dmq1 = NULL; iqmp = NULL; RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if (p && q && dmp1 && dmq1 && iqmp) { result[3] = bin_from_bn(env, p); // Factor p result[4] = bin_from_bn(env, q); // Factor q result[5] = bin_from_bn(env, dmp1); // D mod (p-1) result[6] = bin_from_bn(env, dmq1); // D mod (q-1) result[7] = bin_from_bn(env, iqmp); // (1/q) mod p return enif_make_list_from_array(env, result, 8); } else { return enif_make_list_from_array(env, result, 3); } }
static LUA_FUNCTION(openssl_rsa_parse) { const BIGNUM *n = NULL, *e = NULL, *d = NULL; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); lua_newtable(L); lua_pushinteger(L, RSA_size(rsa)); lua_setfield(L, -2, "size"); lua_pushinteger(L, RSA_bits(rsa)); lua_setfield(L, -2, "bits"); OPENSSL_PKEY_GET_BN(n, n); OPENSSL_PKEY_GET_BN(e, e); OPENSSL_PKEY_GET_BN(d, d); OPENSSL_PKEY_GET_BN(p, p); OPENSSL_PKEY_GET_BN(q, q); OPENSSL_PKEY_GET_BN(dmp1, dmp1); OPENSSL_PKEY_GET_BN(dmq1, dmq1); OPENSSL_PKEY_GET_BN(iqmp, iqmp); return 1; }
static int test_fips1864_keygen_kat(void) { int ret = 0; RSA *key = NULL; BN_CTX *ctx = NULL; BIGNUM *e, *Xp, *Xp1, *Xp2, *Xq, *Xq1, *Xq2; BIGNUM *p1, *p2, *q1, *q2; BIGNUM *p1_exp, *p2_exp, *q1_exp, *q2_exp; BIGNUM *p_exp, *q_exp, *n_exp, *d_exp; const BIGNUM *p, *q, *n, *d, *e2; if (!(TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new()))) goto err; BN_CTX_start(ctx); e = bn_load(ctx, cav_e, sizeof(cav_e)); Xp = bn_load(ctx, cav_Xp, sizeof(cav_Xp)); Xp1 = bn_load(ctx, cav_Xp1, sizeof(cav_Xp1)); Xp2 = bn_load(ctx, cav_Xp2, sizeof(cav_Xp2)); Xq = bn_load(ctx, cav_Xq, sizeof(cav_Xq)); Xq1 = bn_load(ctx, cav_Xq1, sizeof(cav_Xq1)); Xq2 = bn_load(ctx, cav_Xq2, sizeof(cav_Xq2)); p1_exp = bn_load(ctx, cav_p1, sizeof(cav_p1)); p2_exp = bn_load(ctx, cav_p2, sizeof(cav_p2)); q1_exp = bn_load(ctx, cav_q1, sizeof(cav_q1)); q2_exp = bn_load(ctx, cav_q2, sizeof(cav_q2)); p_exp = bn_load(ctx, cav_p, sizeof(cav_p)); q_exp = bn_load(ctx, cav_q, sizeof(cav_q)); n_exp = bn_load(ctx, cav_n, sizeof(cav_n)); d_exp = bn_load(ctx, cav_d, sizeof(cav_d)); p1 = BN_CTX_get(ctx); p2 = BN_CTX_get(ctx); q1 = BN_CTX_get(ctx); q2 = BN_CTX_get(ctx); ret = TEST_ptr(q2) && TEST_true(rsa_fips186_4_gen_prob_primes(key, p1, p2, NULL, Xp, Xp1, Xp2, q1, q2, NULL, Xq, Xq1, Xq2, 2048, e, ctx, NULL)) && TEST_true(rsa_sp800_56b_derive_params_from_pq(key, 2048, e, ctx)) && TEST_BN_eq(p1_exp, p1) && TEST_BN_eq(p2_exp, p2) && TEST_BN_eq(q1_exp, q1) && TEST_BN_eq(q2_exp, q2); if (!ret) goto err; RSA_get0_key(key, &n, &e2, &d); RSA_get0_factors(key, &p, &q); ret = TEST_BN_eq(e, e2) && TEST_BN_eq(p_exp, p) && TEST_BN_eq(q_exp, q) && TEST_BN_eq(n_exp, n) && TEST_BN_eq(d_exp, d); err: RSA_free(key); BN_CTX_end(ctx); BN_CTX_free(ctx); return ret; }
void _cjose_jwk_rsa_get_factors(RSA *rsa, BIGNUM **p, BIGNUM **q) { #if (CJOSE_OPENSSL_11X) RSA_get0_factors(rsa, (const BIGNUM **)p, (const BIGNUM **)q); #else *p=rsa->p; *q=rsa->q; #endif }
int ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) { const BIGNUM *rsa_p, *rsa_q, *rsa_d; BIGNUM *aux = NULL, *d_consttime = NULL; BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL; BN_CTX *ctx = NULL; int r; if (key == NULL || key->rsa == NULL || sshkey_type_plain(key->type) != KEY_RSA) return SSH_ERR_INVALID_ARGUMENT; RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); if ((ctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((aux = BN_new()) == NULL || (rsa_dmq1 = BN_new()) == NULL || (rsa_dmp1 = BN_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((d_consttime = BN_dup(rsa_d)) == NULL || (rsa_iqmp = BN_dup(iqmp)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } BN_set_flags(aux, BN_FLG_CONSTTIME); BN_set_flags(d_consttime, BN_FLG_CONSTTIME); if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) || (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) || (BN_sub(aux, rsa_p, BN_value_one()) == 0) || (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */ /* success */ r = 0; out: BN_clear_free(aux); BN_clear_free(d_consttime); BN_clear_free(rsa_dmp1); BN_clear_free(rsa_dmq1); BN_clear_free(rsa_iqmp); BN_CTX_free(ctx); return r; }
static void write_rsa(unsigned char **out, RSA *rsa, int ispub) { int nbyte, hnbyte; BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1; nbyte = RSA_size(rsa); hnbyte = (RSA_bits(rsa) + 15) >> 4; RSA_get0_key(rsa, &e, &n, &d); write_lebn(out, e, 4); write_lebn(out, n, -1); if (ispub) return; RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); write_lebn(out, p, hnbyte); write_lebn(out, q, hnbyte); write_lebn(out, dmp1, hnbyte); write_lebn(out, dmq1, hnbyte); write_lebn(out, iqmp, hnbyte); write_lebn(out, d, nbyte); }
static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) { int nbyte, hnbyte, bitlen; BIGNUM *e; RSA_get0_key(rsa, &e, NULL, NULL); if (BN_num_bits(e) > 32) goto badkey; bitlen = RSA_bits(rsa); nbyte = RSA_size(rsa); hnbyte = (bitlen + 15) >> 4; if (ispub) { *pmagic = MS_RSA1MAGIC; return bitlen; } else { BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1; *pmagic = MS_RSA2MAGIC; /* * For private key each component must fit within nbyte or hnbyte. */ RSA_get0_key(rsa, NULL, NULL, &d); if (BN_num_bytes(d) > nbyte) goto badkey; RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if ((BN_num_bytes(iqmp) > hnbyte) || (BN_num_bytes(p) > hnbyte) || (BN_num_bytes(q) > hnbyte) || (BN_num_bytes(dmp1) > hnbyte) || (BN_num_bytes(dmq1) > hnbyte)) goto badkey; } return bitlen; badkey: PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); return 0; }
/* * Store private key */ static int pkcs11_store_key(PKCS11_TOKEN *token, EVP_PKEY *pk, unsigned int type, char *label, unsigned char *id, size_t id_len, PKCS11_KEY ** ret_key) { PKCS11_SLOT *slot = TOKEN2SLOT(token); PKCS11_CTX *ctx = TOKEN2CTX(token); PKCS11_SLOT_private *spriv = PRIVSLOT(slot); CK_OBJECT_HANDLE object; CK_ATTRIBUTE attrs[32]; unsigned int n = 0; int rv; const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q; /* First, make sure we have a session */ if (!spriv->haveSession && PKCS11_open_session(slot, 1)) return -1; /* Now build the key attrs */ pkcs11_addattr_int(attrs + n++, CKA_CLASS, type); if (label) pkcs11_addattr_s(attrs + n++, CKA_LABEL, label); if (id && id_len) pkcs11_addattr(attrs + n++, CKA_ID, id, id_len); pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bool(attrs + n++, CKA_PRIVATE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SENSITIVE, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_DECRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_SIGN, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_UNWRAP, TRUE); } else { /* CKO_PUBLIC_KEY */ pkcs11_addattr_bool(attrs + n++, CKA_ENCRYPT, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_VERIFY, TRUE); pkcs11_addattr_bool(attrs + n++, CKA_WRAP, TRUE); } #if OPENSSL_VERSION_NUMBER >= 0x10100003L if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA) { RSA *rsa = EVP_PKEY_get1_RSA(pk); #else if (pk->type == EVP_PKEY_RSA) { RSA *rsa = pk->pkey.rsa; #endif pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA); #if OPENSSL_VERSION_NUMBER >= 0x10100005L RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); RSA_get0_factors(rsa, &rsa_p, &rsa_q); #else rsa_n=rsa->n; rsa_e=rsa->e; rsa_d=rsa->d; rsa_p=rsa->p; rsa_q=rsa->q; #endif pkcs11_addattr_bn(attrs + n++, CKA_MODULUS, rsa_n); pkcs11_addattr_bn(attrs + n++, CKA_PUBLIC_EXPONENT, rsa_e); if (type == CKO_PRIVATE_KEY) { pkcs11_addattr_bn(attrs + n++, CKA_PRIVATE_EXPONENT, rsa_d); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_1, rsa_p); pkcs11_addattr_bn(attrs + n++, CKA_PRIME_2, rsa_q); } } else { pkcs11_zap_attrs(attrs, n); PKCS11err(type == CKO_PRIVATE_KEY ? PKCS11_F_PKCS11_STORE_PRIVATE_KEY : PKCS11_F_PKCS11_STORE_PUBLIC_KEY, PKCS11_NOT_SUPPORTED); return -1; } /* Now call the pkcs11 module to create the object */ rv = CRYPTOKI_call(ctx, C_CreateObject(spriv->session, attrs, n, &object)); /* Zap all memory allocated when building the template */ pkcs11_zap_attrs(attrs, n); CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, rv); /* Gobble the key object */ return pkcs11_init_key(ctx, token, spriv->session, object, type, ret_key); } /* * Get the key type */ int pkcs11_get_key_type(PKCS11_KEY *key) { PKCS11_KEY_private *kpriv = PRIVKEY(key); return kpriv->ops->type; }
static int build_decrypt_op_buf(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaCyRsaDecryptOpData ** dec_op_data, CpaFlatBuffer ** output_buffer, int alloc_pad) { int rsa_len = 0; CpaCyRsaPrivateKey *cpa_prv_key = NULL; const BIGNUM *p = NULL; const BIGNUM *q = NULL; const BIGNUM *dmp1 = NULL; const BIGNUM *dmq1 = NULL; const BIGNUM *iqmp = NULL; DEBUG("- Started\n"); RSA_get0_factors((const RSA*)rsa, &p, &q); RSA_get0_crt_params((const RSA*)rsa, &dmp1, &dmq1, &iqmp); if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL) { WARN("Either p %p, q %p, dmp1 %p, dmq1 %p, iqmp %p are NULL\n", p, q, dmp1, dmq1, iqmp); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_IQMP_NULL); return 0; } /* Padding check */ if ((padding != RSA_NO_PADDING) && (padding != RSA_PKCS1_PADDING)) { WARN("Unknown Padding %d\n", padding); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PADDING_UNKNOWN); return 0; } cpa_prv_key = (CpaCyRsaPrivateKey *) OPENSSL_zalloc(sizeof(CpaCyRsaPrivateKey)); if (NULL == cpa_prv_key) { WARN("Failed to allocate cpa_prv_key\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PRIV_KEY_MALLOC_FAILURE); return 0; } DEBUG("flen =%d, padding = %d \n", flen, padding); /* output signature should have same length as RSA(128) */ rsa_len = RSA_size(rsa); /* output and input data MUST allocate memory for sign process */ /* memory allocation for DecOpdata[IN] */ *dec_op_data = OPENSSL_zalloc(sizeof(CpaCyRsaDecryptOpData)); if (NULL == *dec_op_data) { WARN("Failed to allocate dec_op_data\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_DEC_OP_DATA_MALLOC_FAILURE); OPENSSL_free(cpa_prv_key); return 0; } /* Setup the DecOpData structure */ (*dec_op_data)->pRecipientPrivateKey = cpa_prv_key; cpa_prv_key->version = CPA_CY_RSA_VERSION_TWO_PRIME; /* Setup the private key rep type 2 structure */ cpa_prv_key->privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2; if (qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime1P, p) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime2Q, q) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent1Dp, dmp1) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent2Dq, dmq1) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.coefficientQInv, iqmp) != 1) { WARN("Failed to convert privateKeyRep2 elements to flatbuffer\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE); return 0; } if (alloc_pad) { (*dec_op_data)->inputData.pData = qat_alloc_pad((Cpa8U *) from, flen, rsa_len, 1); } else { (*dec_op_data)->inputData.pData = (Cpa8U *) copyAllocPinnedMemory((void *)from, flen, __FILE__, __LINE__); } if (NULL == (*dec_op_data)->inputData.pData) { WARN("Failed to allocate (*dec_op_data)->inputData.pData\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_INPUT_DATA_MALLOC_FAILURE); return 0; } if (alloc_pad) (*dec_op_data)->inputData.dataLenInBytes = rsa_len; else (*dec_op_data)->inputData.dataLenInBytes = flen; *output_buffer = OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (NULL == *output_buffer) { WARN("Failed to allocate output_buffer\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_OUTPUT_BUF_MALLOC_FAILURE); return 0; } /* * Memory allocation for DecOpdata[IN] the size of outputBuffer * should big enough to contain RSA_size */ (*output_buffer)->pData = (Cpa8U *) qaeCryptoMemAlloc(rsa_len, __FILE__, __LINE__); if (NULL == (*output_buffer)->pData) { WARN("Failed to allocate output_buffer->pData\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE); return 0; } (*output_buffer)->dataLenInBytes = rsa_len; DEBUG("- Finished\n"); return 1; }
void sshkey_file_tests(void) { struct sshkey *k1, *k2; struct sshbuf *buf, *pw; BIGNUM *a, *b, *c; char *cp; const BIGNUM *n, *p, *q, *g, *pub_key, *priv_key; TEST_START("load passphrase"); pw = load_text_file("pw"); TEST_DONE(); TEST_START("parse RSA from private"); buf = load_file("rsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("rsa_1.param.n"); b = load_bignum("rsa_1.param.p"); c = load_bignum("rsa_1.param.q"); RSA_get0_key(k1->rsa, &n, NULL, NULL); RSA_get0_factors(k1->rsa, &p, &q); ASSERT_BIGNUM_EQ(n, a); ASSERT_BIGNUM_EQ(p, b); ASSERT_BIGNUM_EQ(q, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse RSA from private w/ passphrase"); buf = load_file("rsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse RSA from new-format"); buf = load_file("rsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse RSA from new-format w/ passphrase"); buf = load_file("rsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load RSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_RSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("RSA key hex fingerprint"); buf = load_text_file("rsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("RSA cert hex fingerprint"); buf = load_text_file("rsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("RSA key bubblebabble fingerprint"); buf = load_text_file("rsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); TEST_START("parse DSA from private"); buf = load_file("dsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("dsa_1.param.g"); b = load_bignum("dsa_1.param.priv"); c = load_bignum("dsa_1.param.pub"); DSA_get0_pqg(k1->dsa, NULL, NULL, &g); DSA_get0_key(k1->dsa, &pub_key, &priv_key); ASSERT_BIGNUM_EQ(g, a); ASSERT_BIGNUM_EQ(priv_key, b); ASSERT_BIGNUM_EQ(pub_key, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse DSA from private w/ passphrase"); buf = load_file("dsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse DSA from new-format"); buf = load_file("dsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse DSA from new-format w/ passphrase"); buf = load_file("dsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load DSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load DSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("dsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_DSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("DSA key hex fingerprint"); buf = load_text_file("dsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("DSA cert hex fingerprint"); buf = load_text_file("dsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("DSA key bubblebabble fingerprint"); buf = load_text_file("dsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #ifdef OPENSSL_HAS_ECC TEST_START("parse ECDSA from private"); buf = load_file("ecdsa_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); buf = load_text_file("ecdsa_1.param.curve"); ASSERT_STRING_EQ((const char *)sshbuf_ptr(buf), OBJ_nid2sn(k1->ecdsa_nid)); sshbuf_free(buf); a = load_bignum("ecdsa_1.param.priv"); b = load_bignum("ecdsa_1.param.pub"); c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, NULL, NULL); ASSERT_PTR_NE(c, NULL); ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); ASSERT_BIGNUM_EQ(b, c); BN_free(a); BN_free(b); BN_free(c); TEST_DONE(); TEST_START("parse ECDSA from private w/ passphrase"); buf = load_file("ecdsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse ECDSA from new-format"); buf = load_file("ecdsa_n"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("parse ECDSA from new-format w/ passphrase"); buf = load_file("ecdsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load ECDSA from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load ECDSA cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ecdsa_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_ECDSA_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("ECDSA key hex fingerprint"); buf = load_text_file("ecdsa_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("ECDSA cert hex fingerprint"); buf = load_text_file("ecdsa_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("ECDSA key bubblebabble fingerprint"); buf = load_text_file("ecdsa_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); #endif /* OPENSSL_HAS_ECC */ TEST_START("parse Ed25519 from private"); buf = load_file("ed25519_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); ASSERT_INT_EQ(k1->type, KEY_ED25519); /* XXX check key contents */ TEST_DONE(); TEST_START("parse Ed25519 from private w/ passphrase"); buf = load_file("ed25519_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load Ed25519 from public"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), &k2, NULL), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); sshkey_free(k2); TEST_DONE(); TEST_START("load Ed25519 cert"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("ed25519_1"), &k2), 0); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(k2->type, KEY_ED25519_CERT); ASSERT_INT_EQ(sshkey_equal(k1, k2), 0); ASSERT_INT_EQ(sshkey_equal_public(k1, k2), 1); TEST_DONE(); TEST_START("Ed25519 key hex fingerprint"); buf = load_text_file("ed25519_1.fp"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); TEST_START("Ed25519 cert hex fingerprint"); buf = load_text_file("ed25519_1-cert.fp"); cp = sshkey_fingerprint(k2, SSH_DIGEST_SHA256, SSH_FP_BASE64); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); sshkey_free(k2); TEST_DONE(); TEST_START("Ed25519 key bubblebabble fingerprint"); buf = load_text_file("ed25519_1.fp.bb"); cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); free(cp); TEST_DONE(); sshkey_free(k1); sshbuf_free(pw); }
int RSA_get_RSAPRIVATEKEYBLOB(RSA *rsa, RSAPRIVATEKEYBLOB *blob) { const BIGNUM *n; const BIGNUM *e; const BIGNUM *d; const BIGNUM *p; const BIGNUM *q; const BIGNUM *dmp1; const BIGNUM *dmq1; const BIGNUM *iqmp; if (!rsa || !blob) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (RSA_bits(rsa) > sizeof(blob->Modulus) * 8 || RSA_bits(rsa) % 8 != 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if (!n || !e || !d) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } memset(blob, 0, sizeof(RSAPRIVATEKEYBLOB)); blob->AlgID = SGD_RSA; blob->BitLen = RSA_bits(rsa); if (BN_bn2bin(n, blob->Modulus + sizeof(blob->Modulus) - BN_num_bytes(n)) <= 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (BN_bn2bin(e, blob->PublicExponent + sizeof(blob->PublicExponent) - BN_num_bytes(e)) <= 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (BN_bn2bin(d, blob->PrivateExponent + sizeof(blob->PrivateExponent) - BN_num_bytes(d)) <= 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (p && BN_bn2bin(p, blob->Prime1 + sizeof(blob->Prime1) - BN_num_bytes(p)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (q && BN_bn2bin(q, blob->Prime2 + sizeof(blob->Prime2) - BN_num_bytes(q)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (dmp1 && BN_bn2bin(dmp1, blob->Prime1Exponent + sizeof(blob->Prime1Exponent) - BN_num_bytes(dmp1)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (dmq1 && BN_bn2bin(dmq1, blob->Prime2Exponent + sizeof(blob->Prime2Exponent) - BN_num_bytes(dmq1)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (iqmp && BN_bn2bin(iqmp, blob->Coefficient + sizeof(blob->Coefficient) - BN_num_bytes(iqmp)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } return 1; }
int lws_x509_jwk_privkey_pem(struct lws_jwk *jwk, void *pem, size_t len, const char *passphrase) { BIO* bio = BIO_new(BIO_s_mem()); BIGNUM *mpi, *dummy[6]; EVP_PKEY *pkey = NULL; EC_KEY *ecpriv = NULL; RSA *rsapriv = NULL; const BIGNUM *cmpi; int n, m, ret = -1; BIO_write(bio, pem, len); PEM_read_bio_PrivateKey(bio, &pkey, lws_x509_jwk_privkey_pem_pp_cb, (void *)passphrase); BIO_free(bio); lws_explicit_bzero((void *)pem, len); if (!pkey) { lwsl_err("%s: unable to parse PEM privkey\n", __func__); lws_tls_err_describe(); return -1; } /* confirm the key type matches the existing jwk situation */ switch (jwk->kty) { case LWS_GENCRYPTO_KTY_EC: if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) { lwsl_err("%s: jwk is EC but privkey isn't\n", __func__); goto bail; } ecpriv = EVP_PKEY_get1_EC_KEY(pkey); if (!ecpriv) { lwsl_notice("%s: missing EC key\n", __func__); goto bail; } cmpi = EC_KEY_get0_private_key(ecpriv); /* quick size check first */ n = BN_num_bytes(cmpi); if (jwk->e[LWS_GENCRYPTO_EC_KEYEL_Y].len != (uint32_t)n) { lwsl_err("%s: jwk key size doesn't match\n", __func__); goto bail1; } /* TODO.. check public curve / group + point */ jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len = n; jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf = lws_malloc(n, "ec"); if (!jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf) goto bail1; m = BN_bn2binpad(cmpi, jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf, jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len); if (m != BN_num_bytes(cmpi)) goto bail1; break; case LWS_GENCRYPTO_KTY_RSA: if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_RSA) { lwsl_err("%s: RSA jwk, non-RSA privkey\n", __func__); goto bail; } rsapriv = EVP_PKEY_get1_RSA(pkey); if (!rsapriv) { lwsl_notice("%s: missing RSA key\n", __func__); goto bail; } #if defined(LWS_HAVE_RSA_SET0_KEY) RSA_get0_key(rsapriv, (const BIGNUM **)&dummy[0], /* n */ (const BIGNUM **)&dummy[1], /* e */ (const BIGNUM **)&mpi); /* d */ RSA_get0_factors(rsapriv, (const BIGNUM **)&dummy[4], /* p */ (const BIGNUM **)&dummy[5]); /* q */ #else dummy[0] = rsapriv->n; dummy[1] = rsapriv->e; dummy[4] = rsapriv->p; dummy[5] = rsapriv->q; mpi = rsapriv->d; #endif /* quick size check first */ n = BN_num_bytes(mpi); if (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len != (uint32_t)n) { lwsl_err("%s: jwk key size doesn't match\n", __func__); goto bail1; } /* then check that n & e match what we got from the cert */ dummy[2] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].buf, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len, NULL); dummy[3] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].buf, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].len, NULL); m = BN_cmp(dummy[2], dummy[0]) | BN_cmp(dummy[3], dummy[1]); BN_clear_free(dummy[2]); BN_clear_free(dummy[3]); if (m) { lwsl_err("%s: privkey doesn't match jwk pubkey\n", __func__); goto bail1; } /* accept d from the PEM privkey into the JWK */ jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].len = n; jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf = lws_malloc(n, "privjk"); if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf) goto bail1; BN_bn2bin(mpi, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf); /* accept p and q from the PEM privkey into the JWK */ jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].len = BN_num_bytes(dummy[4]); jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf = lws_malloc(n, "privjk"); if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf) { lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf); goto bail1; } BN_bn2bin(dummy[4], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf); jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].len = BN_num_bytes(dummy[5]); jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf = lws_malloc(n, "privjk"); if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf) { lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf); lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf); goto bail1; } BN_bn2bin(dummy[5], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf); break; default: lwsl_err("%s: JWK has unknown kty %d\n", __func__, jwk->kty); return -1; } ret = 0; bail1: if (jwk->kty == LWS_GENCRYPTO_KTY_EC) EC_KEY_free(ecpriv); else RSA_free(rsapriv); bail: EVP_PKEY_free(pkey); return ret; }
static isc_boolean_t opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { int status; RSA *rsa1 = NULL, *rsa2 = NULL; const BIGNUM *n1 = NULL, *n2 = NULL; const BIGNUM *e1 = NULL, *e2 = NULL; const BIGNUM *d1 = NULL, *d2 = NULL; const BIGNUM *p1 = NULL, *p2 = NULL; const BIGNUM *q1 = NULL, *q2 = NULL; #if USE_EVP EVP_PKEY *pkey1, *pkey2; #endif #if USE_EVP pkey1 = key1->keydata.pkey; pkey2 = key2->keydata.pkey; /* * The pkey reference will keep these around after * the RSA_free() call. */ if (pkey1 != NULL) { rsa1 = EVP_PKEY_get1_RSA(pkey1); RSA_free(rsa1); } if (pkey2 != NULL) { rsa2 = EVP_PKEY_get1_RSA(pkey2); RSA_free(rsa2); } #else rsa1 = key1->keydata.rsa; rsa2 = key2->keydata.rsa; #endif if (rsa1 == NULL && rsa2 == NULL) return (ISC_TRUE); else if (rsa1 == NULL || rsa2 == NULL) return (ISC_FALSE); RSA_get0_key(rsa1, &n1, &e1, &d1); RSA_get0_key(rsa2, &n2, &e2, &d2); status = BN_cmp(n1, n2) || BN_cmp(e1, e2); if (status != 0) return (ISC_FALSE); #if USE_EVP if (RSA_test_flags(rsa1, RSA_FLAG_EXT_PKEY) != 0 || RSA_test_flags(rsa2, RSA_FLAG_EXT_PKEY) != 0) { if (RSA_test_flags(rsa1, RSA_FLAG_EXT_PKEY) == 0 || RSA_test_flags(rsa2, RSA_FLAG_EXT_PKEY) == 0) return (ISC_FALSE); /* * Can't compare private parameters, BTW does it make sense? */ return (ISC_TRUE); } #endif if (d1 != NULL || d2 != NULL) { if (d1 == NULL || d2 == NULL) return (ISC_FALSE); RSA_get0_factors(rsa1, &p1, &q1); RSA_get0_factors(rsa2, &p2, &q2); status = BN_cmp(d1, d2) || BN_cmp(p1, p1) || BN_cmp(q1, q2); if (status != 0) return (ISC_FALSE); } return (ISC_TRUE); }
static isc_result_t opensslrsa_tofile(const dst_key_t *key, const char *directory) { int i; RSA *rsa; dst_private_t priv; unsigned char *bufs[8]; isc_result_t result; const BIGNUM *n = NULL, *e = NULL, *d = NULL; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; #if USE_EVP if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); if (rsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); #else if (key->keydata.rsa == NULL) return (DST_R_NULLKEY); rsa = key->keydata.rsa; #endif memset(bufs, 0, sizeof(bufs)); RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if (key->external) { priv.nelements = 0; result = dst__privstruct_writefile(key, &priv, directory); goto fail; } for (i = 0; i < 8; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(n)); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = BN_num_bytes(n); BN_bn2bin(n, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = BN_num_bytes(e); BN_bn2bin(e, bufs[i]); priv.elements[i].data = bufs[i]; i++; if (d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = BN_num_bytes(d); BN_bn2bin(d, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = BN_num_bytes(p); BN_bn2bin(p, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = BN_num_bytes(q); BN_bn2bin(q, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = BN_num_bytes(dmp1); BN_bn2bin(dmp1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = BN_num_bytes(dmq1); BN_bn2bin(dmq1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = BN_num_bytes(iqmp); BN_bn2bin(iqmp, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = (unsigned short)strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = (unsigned short)strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: #if USE_EVP RSA_free(rsa); #endif for (i = 0; i < 8; i++) { if (bufs[i] == NULL) break; isc_mem_put(key->mctx, bufs[i], BN_num_bytes(n)); } return (result); }
/** 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; }