STDMETHODIMP CBECC::put_Parameter(VARIANT newVal) { if (newVal.vt == VT_UI1 || newVal.vt == VT_I2 || newVal.vt == VT_I4 || newVal.vt == VT_R4 || newVal.vt == VT_R8) { int nid = varGetNumber(newVal, 409); free(); m_pECC = EC_KEY_new_by_curve_name(nid); if(m_pECC == NULL) return E_INVALIDARG; } else { CBVarPtr varPtr; HRESULT hr = varPtr.Attach(newVal); if(FAILED(hr))return hr; free(); m_pECC = d2i_ECParameters((EC_KEY**)&m_pECC, (const BYTE**)&varPtr.m_pData, varPtr.m_nSize); if(m_pECC == NULL)return E_INVALIDARG; } return S_OK; }
static EC_KEY *eckey_type2param(int ptype, void *pval) { EC_KEY *eckey = NULL; if (ptype == V_ASN1_SEQUENCE) { ASN1_STRING *pstr = pval; const uint8_t *pm = pstr->data; int pmlen = pstr->length; eckey = d2i_ECParameters(NULL, &pm, pmlen); if (eckey == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } } else if (ptype == V_ASN1_OBJECT) { ASN1_OBJECT *poid = pval; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid(poid)); if (eckey == NULL) { goto err; } } else { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } return eckey; err: if (eckey) { EC_KEY_free(eckey); } return NULL; }
static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) { EC_KEY *eckey; if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); return 0; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; }
static EC_KEY *pkcs11_get_ec(PKCS11_KEY *key) { EC_KEY *ec, *found_params = NULL, *found_point = NULL; CK_BYTE *params, *point; size_t params_len = 0, point_len = 0; PKCS11_KEY *pubkey; ec = EC_KEY_new(); if (ec == NULL) return NULL; /* For OpenSSL req we need at least the * EC_KEY_get0_group(ec_key)) to return the group. * Continue even if it fails, as the sign operation does not need * it if the PKCS#11 module or the hardware can figure this out */ if (!key_getattr_alloc(key, CKA_EC_PARAMS, ¶ms, ¶ms_len)) { const unsigned char *a = params; /* Convert to OpenSSL parmas */ found_params = d2i_ECParameters(&ec, &a, (long)params_len); OPENSSL_free(params); } /* Now retrieve the point */ pubkey = key->isPrivate ? pkcs11_find_key_from_key(key) : key; if (pubkey == NULL) return ec; if (!key_getattr_alloc(pubkey, CKA_EC_POINT, &point, &point_len)) { const unsigned char *a; ASN1_OCTET_STRING *os; /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ a = point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)point_len); if (os) { a = os->data; found_point = o2i_ECPublicKey(&ec, &a, os->length); ASN1_STRING_free(os); } if (found_point == NULL) { /* Workaround for broken PKCS#11 modules */ a = point; found_point = o2i_ECPublicKey(&ec, &a, point_len); } OPENSSL_free(point); } /* A public keys requires both the params and the point to be present */ if (!key->isPrivate && (found_params == NULL || found_point == NULL)) { EC_KEY_free(ec); return NULL; } return ec; }
static int eckey_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { EC_KEY *eckey; if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); return 0; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; }
static EC_KEY *eckey_type2param(int ptype, void *pval) { EC_KEY *eckey = NULL; if (ptype == V_ASN1_SEQUENCE) { ASN1_STRING *pstr = pval; const unsigned char *pm = NULL; int pmlen; pm = pstr->data; pmlen = pstr->length; if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); goto ecerr; } } else if (ptype == V_ASN1_OBJECT) { ASN1_OBJECT *poid = pval; EC_GROUP *group; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ if ((eckey = EC_KEY_new()) == NULL) { ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); goto ecerr; } group = EC_GROUP_new_by_curve_name(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: if (eckey) EC_KEY_free(eckey); return NULL; }
EC_KEY * ECParameters_dup(EC_KEY *key) { unsigned char *p = NULL; EC_KEY *k = NULL; int len; if (key == NULL) return (NULL); if ((len = i2d_ECParameters(key, &p)) > 0) k = d2i_ECParameters(NULL, (const unsigned char **)&p, len); return (k); }
/* Retrieve EC parameters from key into ec * return nonzero on error */ static int pkcs11_get_params(EC_KEY *ec, PKCS11_KEY *key) { CK_BYTE *params; size_t params_len = 0; const unsigned char *a; int rv; if (key_getattr_alloc(key, CKA_EC_PARAMS, ¶ms, ¶ms_len)) return -1; a = params; rv = d2i_ECParameters(&ec, &a, (long)params_len) == NULL; OPENSSL_free(params); return rv; }
static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor) { EC_KEY *ec_key = NULL; int ptype; void *pval; const unsigned char *p; X509_ALGOR_get0(NULL, &ptype, &pval, algor); if (ptype == V_ASN1_SEQUENCE) { ASN1_OCTET_STRING *pstr = (ASN1_OCTET_STRING *)pval; p = pstr->data; if (!(ec_key = d2i_ECParameters(NULL, &p, pstr->length))) { CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB); return NULL; } } else if (ptype == V_ASN1_OBJECT) { ASN1_OBJECT *poid = (ASN1_OBJECT *)pval; EC_GROUP *group; if (!(ec_key = EC_KEY_new())) { CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_MALLOC_FAILURE); return NULL; } if (!(group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)))) { EC_KEY_free(ec_key); CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB); return NULL; } EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); if (!EC_KEY_set_group(ec_key, group)) { EC_GROUP_free(group); EC_KEY_free(ec_key); CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB); return NULL; } EC_GROUP_free(group); } else { CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, CPK_R_BAD_DATA); return NULL; } return ec_key; }
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) { EVP_PKEY *ret=NULL; long j; int type; const unsigned char *p; #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) const unsigned char *cp; X509_ALGOR *a; #endif if (key == NULL) goto err; if (key->pkey != NULL) { CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); return(key->pkey); } if (key->public_key == NULL) goto err; type=OBJ_obj2nid(key->algor->algorithm); if ((ret = EVP_PKEY_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } ret->type = EVP_PKEY_type(type); /* the parameters must be extracted before the public key (ECDSA!) */ #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) a=key->algor; #endif if (0) ; #ifndef OPENSSL_NO_DSA else if (ret->type == EVP_PKEY_DSA) { if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { if ((ret->pkey.dsa = DSA_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } ret->pkey.dsa->write_params=0; cp=p=a->parameter->value.sequence->data; j=a->parameter->value.sequence->length; if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j)) goto err; } ret->save_parameters=1; } #endif #ifndef OPENSSL_NO_EC else if (ret->type == EVP_PKEY_EC) { if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { /* type == V_ASN1_SEQUENCE => we have explicit parameters * (e.g. parameters in the X9_62_EC_PARAMETERS-structure ) */ if ((ret->pkey.ec= EC_KEY_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } cp = p = a->parameter->value.sequence->data; j = a->parameter->value.sequence->length; if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j)) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB); goto err; } } else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT)) { /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ EC_KEY *ec_key; EC_GROUP *group; if (ret->pkey.ec == NULL) ret->pkey.ec = EC_KEY_new(); ec_key = ret->pkey.ec; if (ec_key == NULL) goto err; group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); if (group == NULL) goto err; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_set_group(ec_key, group) == 0) goto err; EC_GROUP_free(group); } /* the case implicitlyCA is currently not implemented */ ret->save_parameters = 1; } #endif p=key->public_key->data; j=key->public_key->length; if (!d2i_PublicKey(type, &ret, &p, (long)j)) { X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); goto err; } key->pkey = ret; CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); return(ret); err: if (ret != NULL) EVP_PKEY_free(ret); return(NULL); }
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsa = NULL; ASN1_TYPE *t1, *t2; ASN1_INTEGER *privkey; STACK_OF(ASN1_TYPE) *ndsa = NULL; #endif #ifndef OPENSSL_NO_EC EC_KEY *eckey = NULL; const unsigned char *p_tmp; #endif #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) ASN1_TYPE *param = NULL; BN_CTX *ctx = NULL; int plen; #endif X509_ALGOR *a; const unsigned char *p; const unsigned char *cp; int pkeylen; int nid; char obj_tmp[80]; if(p8->pkey->type == V_ASN1_OCTET_STRING) { p8->broken = PKCS8_OK; p = p8->pkey->value.octet_string->data; pkeylen = p8->pkey->value.octet_string->length; } else { p8->broken = PKCS8_NO_OCTET; p = p8->pkey->value.sequence->data; pkeylen = p8->pkey->value.sequence->length; } if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } a = p8->pkeyalg; nid = OBJ_obj2nid(a->algorithm); switch(nid) { #ifndef OPENSSL_NO_RSA case NID_rsaEncryption: cp = p; if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); return NULL; } EVP_PKEY_assign_RSA (pkey, rsa); break; #endif #ifndef OPENSSL_NO_DSA case NID_dsa: /* PKCS#8 DSA is weird: you just get a private key integer * and parameters in the AlgorithmIdentifier the pubkey must * be recalculated. */ /* Check for broken DSA PKCS#8, UGH! */ if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, d2i_ASN1_TYPE, ASN1_TYPE_free))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(sk_ASN1_TYPE_num(ndsa) != 2 ) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* Handle Two broken types: * SEQUENCE {parameters, priv_key} * SEQUENCE {pub_key, priv_key} */ t1 = sk_ASN1_TYPE_value(ndsa, 0); t2 = sk_ASN1_TYPE_value(ndsa, 1); if(t1->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_EMBEDDED_PARAM; param = t1; } else if(a->parameter->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_NS_DB; param = a->parameter; } else { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(t2->type != V_ASN1_INTEGER) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } privkey = t2->value.integer; } else { if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } param = p8->pkeyalg->parameter; } if (!param || (param->type != V_ASN1_SEQUENCE)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); goto dsaerr; } /* Calculate public key (ouch!) */ if (!(dsa->pub_key = BN_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free (ctx); if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); else ASN1_INTEGER_free(privkey); break; dsaerr: BN_CTX_free (ctx); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); EVP_PKEY_free(pkey); return NULL; break; #endif #ifndef OPENSSL_NO_EC case NID_X9_62_id_ecPublicKey: p_tmp = p; /* extract the ec parameters */ param = p8->pkeyalg->parameter; if (!param || ((param->type != V_ASN1_SEQUENCE) && (param->type != V_ASN1_OBJECT))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } if (param->type == V_ASN1_SEQUENCE) { cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(eckey = d2i_ECParameters(NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } } else { EC_GROUP *group; cp = p = param->value.object->data; plen = param->value.object->length; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ if ((eckey = EC_KEY_new()) == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); goto ecerr; } group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); 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); } /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } /* calculate public key (if necessary) */ if (EC_KEY_get0_public_key(eckey) == NULL) { const BIGNUM *priv_key; const EC_GROUP *group; EC_POINT *pub_key; /* the public key was not included in the SEC1 private * key => calculate the public key */ group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); if (ctx) BN_CTX_free(ctx); break; ecerr: if (ctx) BN_CTX_free(ctx); if (eckey) EC_KEY_free(eckey); if (pkey) EVP_PKEY_free(pkey); return NULL; #endif default: EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); ERR_add_error_data(2, "TYPE=", obj_tmp); EVP_PKEY_free (pkey); return NULL; } return pkey; }
static int test_EVP_PKEY_check(int i) { int ret = 0; const unsigned char *p; EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_EC EC_KEY *eckey = NULL; #endif EVP_PKEY_CTX *ctx = NULL; EVP_PKEY_CTX *ctx2 = NULL; const APK_DATA *ak = &keycheckdata[i]; const unsigned char *input = ak->kder; size_t input_len = ak->size; int expected_id = ak->evptype; int expected_check = ak->check; int expected_pub_check = ak->pub_check; int expected_param_check = ak->param_check; int type = ak->type; BIO *pubkey = NULL; p = input; switch (type) { case 0: if (!TEST_ptr(pkey = d2i_AutoPrivateKey(NULL, &p, input_len)) || !TEST_ptr_eq(p, input + input_len) || !TEST_int_eq(EVP_PKEY_id(pkey), expected_id)) goto done; break; #ifndef OPENSSL_NO_EC case 1: if (!TEST_ptr(pubkey = BIO_new_mem_buf(input, input_len)) || !TEST_ptr(eckey = d2i_EC_PUBKEY_bio(pubkey, NULL)) || !TEST_ptr(pkey = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))) goto done; break; case 2: if (!TEST_ptr(eckey = d2i_ECParameters(NULL, &p, input_len)) || !TEST_ptr_eq(p, input + input_len) || !TEST_ptr(pkey = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))) goto done; break; #endif default: return 0; } if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; if (!TEST_int_eq(EVP_PKEY_check(ctx), expected_check)) goto done; if (!TEST_int_eq(EVP_PKEY_public_check(ctx), expected_pub_check)) goto done; if (!TEST_int_eq(EVP_PKEY_param_check(ctx), expected_param_check)) goto done; ctx2 = EVP_PKEY_CTX_new_id(0xdefaced, NULL); /* assign the pkey directly, as an internal test */ EVP_PKEY_up_ref(pkey); ctx2->pkey = pkey; if (!TEST_int_eq(EVP_PKEY_check(ctx2), 0xbeef)) goto done; if (!TEST_int_eq(EVP_PKEY_public_check(ctx2), 0xbeef)) goto done; if (!TEST_int_eq(EVP_PKEY_param_check(ctx2), 0xbeef)) goto done; ret = 1; done: EVP_PKEY_CTX_free(ctx); EVP_PKEY_CTX_free(ctx2); EVP_PKEY_free(pkey); BIO_free(pubkey); return ret; }
/* * Get EC key material and stash pointer in ex_data * Note we get called twice, once for private key, and once for public * We need to get the EC_PARAMS and EC_POINT into both, * as lib11 dates from RSA only where all the pub key components * were also part of the private key. With EC the point * is not in the private key, and the params may or may not be. * */ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY * key) { EVP_PKEY *pk; EC_KEY * ec = NULL; CK_RV ckrv; size_t ec_paramslen = 0; CK_BYTE * ec_params = NULL; size_t ec_pointlen = 0; CK_BYTE * ec_point = NULL; PKCS11_KEY * pubkey; ASN1_OCTET_STRING *os=NULL; pk = EVP_PKEY_new(); if (pk == NULL) return NULL; ec = EC_KEY_new(); if (ec == NULL) { EVP_PKEY_free(pk); return NULL; } EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */ /* For Openssl req we need at least the * EC_KEY_get0_group(ec_key)) to return the group. * Even if it fails will continue as a sign only does not need * need this if the pkcs11 or card can figure this out. */ if (key_getattr_var(key, CKA_EC_PARAMS, NULL, &ec_paramslen) == CKR_OK && ec_paramslen > 0) { ec_params = OPENSSL_malloc(ec_paramslen); if (ec_params) { ckrv = key_getattr_var(key, CKA_EC_PARAMS, ec_params, &ec_paramslen); if (ckrv == CKR_OK) { const unsigned char * a = ec_params; /* convert to OpenSSL parmas */ d2i_ECParameters(&ec, &a, (long) ec_paramslen); } } } /* Now get the ec_point */ pubkey = key->isPrivate ? PKCS11_find_key_from_key(key) : key; if (pubkey) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen); if (ckrv == CKR_OK && ec_pointlen > 0) { ec_point = OPENSSL_malloc(ec_pointlen); if (ec_point) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, ec_point, &ec_pointlen); if (ckrv == CKR_OK) { /* PKCS#11 returns ASN1 octstring*/ const unsigned char * a; /* we have asn1 octet string, need to strip off 04 len */ a = ec_point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long) ec_pointlen); if (os) { a = os->data; o2i_ECPublicKey(&ec, &a, os->length); } /* EC_KEY_print_fp(stderr, ec, 5); */ } } } } /* If the key is not extractable, create a key object * that will use the card's functions to sign & decrypt */ if (os) ASN1_STRING_free(os); if (ec_point) OPENSSL_free(ec_point); if (ec_params) OPENSSL_free(ec_params); if (key->isPrivate) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L EC_KEY_set_method(ec, PKCS11_get_ec_key_method()); #else ECDSA_set_method(ec, PKCS11_get_ecdsa_method()); /* TODO: Retrieve the ECDSA private key object attributes instead, * unless the key has the "sensitive" attribute set */ #endif } /* TODO: Extract the ECDSA private key instead, if the key * is marked as extractable (and not private?) */ #if OPENSSL_VERSION_NUMBER >= 0x10100002L EC_KEY_set_ex_data(ec,ec_key_ex_index, key); #else ECDSA_set_ex_data(ec, ecdsa_ex_index, key); #endif EC_KEY_free(ec); /* drops our reference to it */ return pk; }