static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype) { const char *ecstr; unsigned char *priv = NULL, *pub = NULL; size_t privlen = 0, publen = 0; int ret = 0; const EC_GROUP *group; if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) { publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL); if (publen == 0) goto err; } if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) { privlen = EC_KEY_priv2buf(x, &priv); if (privlen == 0) goto err; } if (ktype == EC_KEY_PRINT_PRIVATE) ecstr = "Private-Key"; else if (ktype == EC_KEY_PRINT_PUBLIC) ecstr = "Public-Key"; else ecstr = "ECDSA-Parameters"; if (!BIO_indent(bp, off, 128)) goto err; if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, EC_GROUP_order_bits(group)) <= 0) goto err; if (privlen != 0) { if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0) goto err; if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0) goto err; } if (publen != 0) { if (BIO_printf(bp, "%*spub:\n", off, "") <= 0) goto err; if (ASN1_buf_print(bp, pub, publen, off + 4) == 0) goto err; } if (!ECPKParameters_print(bp, group, off)) goto err; ret = 1; err: if (!ret) ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB); OPENSSL_clear_free(priv, privlen); OPENSSL_free(pub); return ret; }
static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { case ASN1_PKEY_CTRL_PKCS7_SIGN: if (arg1 == 0) { int snid, hnid; X509_ALGOR *alg1, *alg2; PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) return -1; hnid = OBJ_obj2nid(alg1->algorithm); if (hnid == NID_undef) return -1; if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) return -1; X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_SIGN: if (arg1 == 0) { int snid, hnid; X509_ALGOR *alg1, *alg2; CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) return -1; hnid = OBJ_obj2nid(alg1->algorithm); if (hnid == NID_undef) return -1; if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) return -1; X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; case ASN1_PKEY_CTRL_CMS_ENVELOPE: if (arg1 == 1) return ecdh_cms_decrypt(arg2); else if (arg1 == 0) return ecdh_cms_encrypt(arg2); return -2; case ASN1_PKEY_CTRL_CMS_RI_TYPE: *(int *)arg2 = CMS_RECIPINFO_AGREE; return 1; #endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_sha256; return 2; case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL); case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey), POINT_CONVERSION_UNCOMPRESSED, arg2, NULL); default: return -2; } }
/*- * This function hijacks the RNG to feed it the chosen ECDSA key and nonce. * The ECDSA KATs are from: * - the X9.62 draft (4) * - NIST CAVP (720) * * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG. * NB: This is not how applications should use ECDSA; this is only for testing. * * Tests the library can successfully: * - generate public keys that matches those KATs * - create ECDSA signatures that match those KATs * - accept those signatures as valid */ static int x9_62_tests(int n) { int nid, md_nid, ret = 0; const char *r_in = NULL, *s_in = NULL, *tbs = NULL; unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dgst_len = 0; long q_len, msg_len = 0; size_t p_len; EVP_MD_CTX *mctx = NULL; EC_KEY *key = NULL; ECDSA_SIG *signature = NULL; BIGNUM *r = NULL, *s = NULL; BIGNUM *kinv = NULL, *rp = NULL; const BIGNUM *sig_r = NULL, *sig_s = NULL; nid = ecdsa_cavs_kats[n].nid; md_nid = ecdsa_cavs_kats[n].md_nid; r_in = ecdsa_cavs_kats[n].r; s_in = ecdsa_cavs_kats[n].s; tbs = ecdsa_cavs_kats[n].msg; numbers[0] = ecdsa_cavs_kats[n].d; numbers[1] = ecdsa_cavs_kats[n].k; TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid)); if (!TEST_ptr(mctx = EVP_MD_CTX_new()) /* get the message digest */ || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len)) || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL)) || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len)) || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len)) /* create the key */ || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid)) /* load KAT variables */ || !TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()) || !TEST_true(BN_hex2bn(&r, r_in)) || !TEST_true(BN_hex2bn(&s, s_in)) /* swap the RNG source */ || !TEST_true(change_rand())) goto err; /* public key must match KAT */ use_fake = 1; if (!TEST_true(EC_KEY_generate_key(key)) || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED, &pbuf, NULL)) || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len)) || !TEST_int_eq(q_len, p_len) || !TEST_mem_eq(qbuf, q_len, pbuf, p_len)) goto err; /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */ use_fake = 1; if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)) || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len, kinv, rp, key)) /* verify the signature */ || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1)) goto err; /* compare the created signature with the expected signature */ ECDSA_SIG_get0(signature, &sig_r, &sig_s); if (!TEST_BN_eq(sig_r, r) || !TEST_BN_eq(sig_s, s)) goto err; ret = 1; err: /* restore the RNG source */ if (!TEST_true(restore_rand())) ret = 0; OPENSSL_free(message); OPENSSL_free(pbuf); OPENSSL_free(qbuf); EC_KEY_free(key); ECDSA_SIG_free(signature); BN_free(r); BN_free(s); EVP_MD_CTX_free(mctx); BN_clear_free(kinv); BN_clear_free(rp); return ret; }