/*
- * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <openssl/x509.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
-#include <openssl/cms.h>
#include <openssl/asn1t.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
int nid;
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
- ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
return 0;
}
if (EC_GROUP_get_asn1_flag(group)
if (asn1obj == NULL || OBJ_length(asn1obj) == 0) {
ASN1_OBJECT_free(asn1obj);
- ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_OID);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_OID);
return 0;
}
*ppval = asn1obj;
pstr->length = i2d_ECParameters(ec_key, &pstr->data);
if (pstr->length <= 0) {
ASN1_STRING_free(pstr);
- ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
*ppval = pstr;
int penclen;
if (!eckey_param2type(&ptype, &pval, ec_key)) {
- ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
penclen = i2o_ECPublicKey(ec_key, NULL);
return 0;
}
-static EC_KEY *eckey_type2param(int ptype, const void *pval,
- OPENSSL_CTX *libctx, const char *propq)
-{
- EC_KEY *eckey = NULL;
- EC_GROUP *group = NULL;
-
- if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) {
- ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
- goto ecerr;
- }
-
- if (ptype == V_ASN1_SEQUENCE) {
- const ASN1_STRING *pstr = pval;
- const unsigned char *pm = pstr->data;
- int pmlen = pstr->length;
-
-
- if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) {
- ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
- goto ecerr;
- }
- } else if (ptype == V_ASN1_OBJECT) {
- const ASN1_OBJECT *poid = pval;
-
- /*
- * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
- */
-
- group = EC_GROUP_new_by_curve_name_ex(libctx, propq, OBJ_obj2nid(poid));
- if (group == NULL)
- goto ecerr;
- EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
- if (EC_KEY_set_group(eckey, group) == 0)
- goto ecerr;
- EC_GROUP_free(group);
- } else {
- ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
- goto ecerr;
- }
-
- return eckey;
-
- ecerr:
- EC_KEY_free(eckey);
- EC_GROUP_free(group);
- return NULL;
-}
-
static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
{
const unsigned char *p = NULL;
- const void *pval;
- int ptype, pklen;
+ int pklen;
EC_KEY *eckey = NULL;
X509_ALGOR *palg;
- OPENSSL_CTX *libctx = NULL;
+ OSSL_LIB_CTX *libctx = NULL;
const char *propq = NULL;
- if (!X509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)
+ if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey)
|| !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
return 0;
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- eckey = eckey_type2param(ptype, pval, libctx, propq);
+ eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq);
if (!eckey)
return 0;
/* We have parameters now set public key */
if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
- ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
goto ecerr;
}
}
static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
- OPENSSL_CTX *libctx, const char *propq)
+ OSSL_LIB_CTX *libctx, const char *propq)
{
- const unsigned char *p = NULL;
- const void *pval;
- int ptype, pklen;
- EC_KEY *eckey = NULL;
- const X509_ALGOR *palg;
-
- if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
- return 0;
- X509_ALGOR_get0(NULL, &ptype, &pval, palg);
-
- eckey = eckey_type2param(ptype, pval, libctx, propq);
- if (eckey == NULL)
- goto err;
+ int ret = 0;
+ EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq);
- /* We have parameters now set private key */
- if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
- ECerr(0, EC_R_DECODE_ERROR);
- goto err;
+ if (eckey != NULL) {
+ ret = 1;
+ EVP_PKEY_assign_EC_KEY(pkey, eckey);
}
- EVP_PKEY_assign_EC_KEY(pkey, eckey);
- return 1;
-
- err:
- EC_KEY_free(eckey);
- return 0;
+ return ret;
}
static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
unsigned int old_flags;
if (!eckey_param2type(&ptype, &pval, &ec_key)) {
- ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
+ ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR);
return 0;
}
eplen = i2d_ECPrivateKey(&ec_key, NULL);
if (!eplen) {
- ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 0;
}
ep = OPENSSL_malloc(eplen);
if (ep == NULL) {
- ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
return 0;
}
p = ep;
if (!i2d_ECPrivateKey(&ec_key, &p)) {
OPENSSL_free(ep);
- ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
return 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);
+ ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ret = 1;
err:
if (!ret)
- ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
+ ERR_raise(ERR_LIB_EC, 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_RI_TYPE:
- *(int *)arg2 = CMS_RECIPINFO_AGREE;
- return 1;
-#endif
-
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
/* For SM2, the only valid digest-alg is SM3 */
return 1;
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
- return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
+ /* We should only be here if we have a legacy key */
+ if (!ossl_assert(evp_pkey_is_legacy(pkey)))
+ return 0;
+ return EC_KEY_oct2key(evp_pkey_get0_EC_KEY_int(pkey), arg2, arg1, NULL);
case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
default:
return -2;
-
}
-
}
static int ec_pkey_check(const EVP_PKEY *pkey)
/* stay consistent to what EVP_PKEY_check demands */
if (eckey->priv_key == NULL) {
- ECerr(EC_F_EC_PKEY_CHECK, EC_R_MISSING_PRIVATE_KEY);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY);
return 0;
}
/* stay consistent to what EVP_PKEY_check demands */
if (eckey->group == NULL) {
- ECerr(EC_F_EC_PKEY_PARAM_CHECK, EC_R_MISSING_PARAMETERS);
+ ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS);
return 0;
}
static
int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
- EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
+ EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx,
const char *propq)
{
const EC_KEY *eckey = NULL;
BN_CTX_start(bnctx);
/* export the domain parameters */
- if (!ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
+ if (!ossl_ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
goto err;
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
return 0;
}
- if (!ec_group_fromdata(ec, params)
- || !ec_key_otherparams_fromdata(ec, params)
- || !ec_key_fromdata(ec, params, 1)
+ if (!ossl_ec_group_fromdata(ec, params)
+ || !ossl_ec_key_otherparams_fromdata(ec, params)
+ || !ossl_ec_key_fromdata(ec, params, 1)
|| !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
EC_KEY_free(ec);
return 0;
return 1;
}
-const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
+static int ec_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
+{
+ EC_KEY *eckey = from->pkey.ec;
+ EC_KEY *dupkey = NULL;
+ int ret;
+
+ if (eckey != NULL) {
+ dupkey = EC_KEY_dup(eckey);
+ if (dupkey == NULL)
+ return 0;
+ } else {
+ /* necessary to properly copy empty SM2 keys */
+ return EVP_PKEY_set_type(to, from->type);
+ }
+
+ ret = EVP_PKEY_assign_EC_KEY(to, dupkey);
+ if (!ret)
+ EC_KEY_free(dupkey);
+ return ret;
+}
+
+const EVP_PKEY_ASN1_METHOD ossl_eckey_asn1_meth = {
EVP_PKEY_EC,
EVP_PKEY_EC,
0,
ec_pkey_dirty_cnt,
ec_pkey_export_to,
ec_pkey_import_from,
+ ec_pkey_copy,
eckey_priv_decode_ex
};
#if !defined(OPENSSL_NO_SM2)
-const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
+const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth = {
EVP_PKEY_SM2,
EVP_PKEY_EC,
ASN1_PKEY_ALIAS