static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p = NULL; const void *pval; int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); eckey = eckey_type2param(ptype, pval); if (!eckey) { ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); 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); goto ecerr; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; ecerr: EC_KEY_free(eckey); return 0; }
static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { 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); if (!eckey) goto ecliberr; /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); goto ecerr; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; ecliberr: ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); ecerr: EC_KEY_free(eckey); return 0; }
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) { BIO *mdbio = NULL; ASN1_OBJECT *digestoid; const EVP_MD *digest; X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); digest = EVP_get_digestbyobj(digestoid); if (!digest) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_UNKNOWN_DIGEST_ALGORIHM); goto err; } mdbio = BIO_new(BIO_f_md()); if (!mdbio || !BIO_set_md(mdbio, digest)) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); goto err; } return mdbio; err: if (mdbio) BIO_free(mdbio); return NULL; }
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg) { int nid; ASN1_OBJECT *mdoid; X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); nid = OBJ_obj2nid(mdoid); /* Look for digest type to match signature */ for (;;) { EVP_MD_CTX *mtmp; chain = BIO_find_type(chain, BIO_TYPE_MD); if (chain == NULL) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, CMS_R_NO_MATCHING_DIGEST); return 0; } BIO_get_md_ctx(chain, &mtmp); if (EVP_MD_CTX_type(mtmp) == nid /* * Workaround for broken implementations that use signature * algorithm OID instead of digest. */ || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) return EVP_MD_CTX_copy_ex(mctx, mtmp); chain = BIO_next(chain); } }
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p = NULL; void *pval; int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { return 0; } X509_ALGOR_get0(NULL, &ptype, &pval, palg); eckey = eckey_type2param(ptype, pval); if (!eckey) { OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, ERR_R_EC_LIB); return 0; } /* We have parameters now set public key */ if (!o2i_ECPublicKey(&eckey, &p, pklen)) { OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, EVP_R_DECODE_ERROR); goto err; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; err: if (eckey) { EC_KEY_free(eckey); } return 0; }
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *public_key = NULL; DSA *dsa = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype == V_ASN1_SEQUENCE) { pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) { DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); goto err; } } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { if (!(dsa = DSA_new())) { DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); goto err; } } else { DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); goto err; } if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); goto err; } if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); goto err; } ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DSA(pkey, dsa); return 1; err: if (public_key) ASN1_INTEGER_free(public_key); if (dsa) DSA_free(dsa); return 0; }
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *public_key = NULL; DSA *dsa = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { return 0; } X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype == V_ASN1_SEQUENCE) { pstr = pval; pm = pstr->data; pmlen = pstr->length; dsa = d2i_DSAparams(NULL, &pm, pmlen); if (dsa == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { dsa = DSA_new(); if (dsa == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } } else { OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR); goto err; } public_key = d2i_ASN1_INTEGER(NULL, &p, pklen); if (public_key == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL); if (dsa->pub_key == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_BN_DECODE_ERROR); goto err; } ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DSA(pkey, dsa); return 1; err: ASN1_INTEGER_free(public_key); DSA_free(dsa); return 0; }
/* Parses GOST algorithm parameters from X509_ALGOR and * modifies pkey setting NID and parameters */ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) { ASN1_OBJECT *palg_obj =NULL; int ptype = V_ASN1_UNDEF; int pkey_nid = NID_undef,param_nid = NID_undef; void *_pval; ASN1_STRING *pval = NULL; const unsigned char *p; GOST_KEY_PARAMS *gkp = NULL; X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); pval = _pval; if (ptype != V_ASN1_SEQUENCE) { GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, GOST_R_BAD_KEY_PARAMETERS_FORMAT); return 0; } p=pval->data; pkey_nid = OBJ_obj2nid(palg_obj); gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length); if (!gkp) { GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, GOST_R_BAD_PKEY_PARAMETERS_FORMAT); return 0; } param_nid = OBJ_obj2nid(gkp->key_params); GOST_KEY_PARAMS_free(gkp); EVP_PKEY_set_type(pkey,pkey_nid); switch (pkey_nid) { case NID_id_GostR3410_94: { DSA *dsa= EVP_PKEY_get0(pkey); if (!dsa) { dsa = DSA_new(); if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0; } if (!fill_GOST94_params(dsa,param_nid)) return 0; break; } case NID_id_GostR3410_2001: { EC_KEY *ec = EVP_PKEY_get0(pkey); if (!ec) { ec = EC_KEY_new(); if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0; } if (!fill_GOST2001_params(ec,param_nid)) return 0; } } return 1; }
static int dh_priv_decode (EVP_PKEY * pkey, PKCS8_PRIV_KEY_INFO * p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; DH *dh = NULL; if (!PKCS8_pkey_get0 (NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0 (NULL, &ptype, &pval, palg); if (ptype != V_ASN1_SEQUENCE) goto decerr; if (!(privkey = d2i_ASN1_INTEGER (NULL, &p, pklen))) goto decerr; pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dh = d2i_DHparams (NULL, &pm, pmlen))) goto decerr; /* We have parameters now set private key */ if (!(dh->priv_key = ASN1_INTEGER_to_BN (privkey, NULL))) { DHerr (DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); goto dherr; } /* Calculate public key */ if (!DH_generate_key (dh)) goto dherr; EVP_PKEY_assign_DH (pkey, dh); ASN1_INTEGER_free (privkey); return 1; decerr: DHerr (DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); dherr: DH_free (dh); return 0; }
static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *public_key = NULL; DH *dh = NULL; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype != V_ASN1_SEQUENCE) { DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); goto err; } pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) { DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); goto err; } if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen))) { DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); goto err; } /* We have parameters now set public key */ if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); goto err; } ASN1_INTEGER_free(public_key); EVP_PKEY_assign_DH(pkey, dh); return 1; err: if (public_key) ASN1_INTEGER_free(public_key); if (dh) DH_free(dh); return 0; }
static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) { ASN1_OBJECT *aoid; int atype; void *aval; ASN1_INTEGER *public_key = NULL; int rv = 0; EVP_PKEY *pkpeer = NULL, *pk = NULL; DH *dhpeer = NULL; const unsigned char *p; int plen; X509_ALGOR_get0(&aoid, &atype, &aval, alg); if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) goto err; /* Only absent parameters allowed in RFC XXXX */ if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) goto err; pk = EVP_PKEY_CTX_get0_pkey(pctx); if (!pk) goto err; if (pk->type != EVP_PKEY_DHX) goto err; /* Get parameters from parent key */ dhpeer = DHparams_dup(pk->pkey.dh); /* We have parameters now set public key */ plen = ASN1_STRING_length(pubkey); p = ASN1_STRING_data(pubkey); if (!p || !plen) goto err; if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) { DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR); goto err; } /* We have parameters now set public key */ if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) { DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR); goto err; } pkpeer = EVP_PKEY_new(); if (pkpeer == NULL) goto err; EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer); dhpeer = NULL; if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) rv = 1; err: ASN1_INTEGER_free(public_key); EVP_PKEY_free(pkpeer); DH_free(dhpeer); return rv; }
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) { ASN1_OBJECT *aoid; int atype; void *aval; int rv = 0; EVP_PKEY *pkpeer = NULL; EC_KEY *ecpeer = NULL; const unsigned char *p; int plen; X509_ALGOR_get0(&aoid, &atype, &aval, alg); if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) goto err; /* If absent parameters get group from main key */ if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { const EC_GROUP *grp; EVP_PKEY *pk; pk = EVP_PKEY_CTX_get0_pkey(pctx); if (!pk) goto err; grp = EC_KEY_get0_group(pk->pkey.ec); ecpeer = EC_KEY_new(); if (!ecpeer) goto err; if (!EC_KEY_set_group(ecpeer, grp)) goto err; } else { ecpeer = eckey_type2param(atype, aval); if (!ecpeer) goto err; } /* We have parameters now set public key */ plen = ASN1_STRING_length(pubkey); p = ASN1_STRING_data(pubkey); if (!p || !plen) goto err; if (!o2i_ECPublicKey(&ecpeer, &p, plen)) goto err; pkpeer = EVP_PKEY_new(); if (!pkpeer) goto err; EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) rv = 1; err: if (ecpeer) EC_KEY_free(ecpeer); if (pkpeer) EVP_PKEY_free(pkpeer); return rv; }
static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) { X509_ALGOR *palg = NULL; const unsigned char *pubkey_buf = NULL; const unsigned char *p; ASN1_OBJECT *palgobj = NULL; int pub_len; BIGNUM *X, *Y; ASN1_OCTET_STRING *octet = NULL; int len; int ret; int ptype = V_ASN1_UNDEF; ASN1_STRING *pval = NULL; if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub) == 0) return 0; (void)EVP_PKEY_assign_GOST(pk, NULL); X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg); if (ptype != V_ASN1_SEQUENCE) { GOSTerr(GOST_F_PUB_DECODE_GOST01, GOST_R_BAD_KEY_PARAMETERS_FORMAT); return 0; } p = pval->data; if (decode_gost01_algor_params(pk, &p, pval->length) == 0) return 0; octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); if (octet == NULL) { GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); return 0; } len = octet->length / 2; X = GOST_le2bn(octet->data, len, NULL); Y = GOST_le2bn(octet->data + len, len, NULL); ASN1_OCTET_STRING_free(octet); ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); if (ret == 0) GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); BN_free(X); BN_free(Y); return ret; }
BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms) { CMS_CompressedData *cd; const ASN1_OBJECT *compoid; if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) { CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); return NULL; } cd = cms->d.compressedData; X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm); if (OBJ_obj2nid(compoid) != NID_zlib_compression) { CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); return NULL; } return BIO_new(BIO_f_zlib()); }
static int openssl_xalgor_tostring(lua_State* L) { int type; void* val; ASN1_OBJECT *obj; X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); X509_ALGOR_get0(&obj, &type, &val, alg); if (obj != NULL) { luaL_Buffer B; luaL_buffinit(L, &B); luaL_addsize(&B, OBJ_obj2txt(luaL_prepbuffer(&B), LUAL_BUFFERSIZE, obj, 0)); luaL_pushresult(&B); return 1; } return 0; }
static int openssl_xalgor_get(lua_State* L) { int type; void* val; ASN1_OBJECT *obj; X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); X509_ALGOR_get0(&obj, &type, &val, alg); if (obj != NULL) PUSH_OBJECT(OBJ_dup(obj), "openssl.asn1_object"); else lua_pushnil(L); if (type == V_ASN1_UNDEF) lua_pushnil(L); else PUSH_OBJECT(ASN1_STRING_dup(val), "openssl.asn1_string"); return 2; }
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; }
/* Decode any parameters and set them in RSA structure */ static int rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) { const ASN1_OBJECT *algoid; const void *algp; int algptype; X509_ALGOR_get0(&algoid, &algptype, &algp, alg); if (OBJ_obj2nid(algoid) == EVP_PKEY_RSA) return 1; if (algptype == V_ASN1_UNDEF) return 1; if (algptype != V_ASN1_SEQUENCE) { RSAerr(RSA_F_RSA_PARAM_DECODE, RSA_R_INVALID_PSS_PARAMETERS); return 0; } rsa->pss = rsa_pss_decode(alg); if (rsa->pss == NULL) return 0; return 1; }
static DSA *X509_ALGOR_get1_DSA(X509_ALGOR *algor) { DSA *dsa = NULL; int ptype; void *pval; ASN1_OCTET_STRING *pstr; const unsigned char *p; X509_ALGOR_get0(NULL, &ptype, &pval, algor); if (ptype != V_ASN1_SEQUENCE) { CPKerr(CPK_F_X509_ALGOR_GET1_DSA, CPK_R_BAD_DATA); return NULL; } pstr = (ASN1_OCTET_STRING *)pval; p = pstr->data; if (!(dsa = d2i_DSAparams(NULL, &p, pstr->length))) { CPKerr(CPK_F_X509_ALGOR_GET1_DSA, ERR_R_DSA_LIB); return NULL; } return dsa; }
static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *sigalg, ASN1_BIT_STRING *str, EVP_PKEY *pkey) { const ASN1_OBJECT *obj; int ptype; int nid; /* Sanity check: make sure it is ED25519/ED448 with absent parameters */ X509_ALGOR_get0(&obj, &ptype, NULL, sigalg); nid = OBJ_obj2nid(obj); if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) { ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING); return 0; } if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey)) return 0; return 2; }
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p = NULL; void *pval; int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { return 0; } X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype != V_ASN1_OBJECT) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return 0; } eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid((ASN1_OBJECT *)pval)); if (eckey == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); return 0; } /* We have parameters now set public key */ if (!o2i_ECPublicKey(&eckey, &p, pklen)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; err: if (eckey) { EC_KEY_free(eckey); } return 0; }
static int openssl_xalgor_get(lua_State* L) { int type; void* val; ASN1_OBJECT *obj; X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); X509_ALGOR_get0(&obj, &type, &val, alg); if (obj != NULL) { openssl_push_asn1object(L, obj); } else lua_pushnil(L); if (type == V_ASN1_UNDEF) lua_pushnil(L); else { PUSH_ASN1_STRING(L, val); } return 2; }
static int dh_cms_encrypt(CMS_RecipientInfo *ri) { EVP_PKEY_CTX *pctx; EVP_PKEY *pkey; EVP_CIPHER_CTX *ctx; int keylen; X509_ALGOR *talg, *wrap_alg = NULL; ASN1_OBJECT *aoid; ASN1_BIT_STRING *pubkey; ASN1_STRING *wrap_str; ASN1_OCTET_STRING *ukm; unsigned char *penc = NULL, *dukm = NULL; int penclen; size_t dukmlen = 0; int rv = 0; int kdf_type, wrap_nid; const EVP_MD *kdf_md; pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!pctx) return 0; /* Get ephemeral key */ pkey = EVP_PKEY_CTX_get0_pkey(pctx); if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, NULL, NULL, NULL)) goto err; X509_ALGOR_get0(&aoid, NULL, NULL, talg); /* Is everything uninitialised? */ if (aoid == OBJ_nid2obj(NID_undef)) { ASN1_INTEGER *pubk; pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); if (!pubk) goto err; /* Set the key */ penclen = i2d_ASN1_INTEGER(pubk, &penc); ASN1_INTEGER_free(pubk); if (penclen <= 0) goto err; ASN1_STRING_set0(pubkey, penc, penclen); pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; penc = NULL; X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), V_ASN1_UNDEF, NULL); } /* See if custom paraneters set */ kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); if (kdf_type <= 0) goto err; if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) goto err; if (kdf_type == EVP_PKEY_DH_KDF_NONE) { kdf_type = EVP_PKEY_DH_KDF_X9_42; if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) goto err; } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) /* Unknown KDF */ goto err; if (kdf_md == NULL) { /* Only SHA1 supported */ kdf_md = EVP_sha1(); if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) goto err; } else if (EVP_MD_type(kdf_md) != NID_sha1) /* Unsupported digest */ goto err; if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) goto err; /* Get wrap NID */ ctx = CMS_RecipientInfo_kari_get0_ctx(ri); wrap_nid = EVP_CIPHER_CTX_type(ctx); if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) goto err; keylen = EVP_CIPHER_CTX_key_length(ctx); /* Package wrap algorithm in an AlgorithmIdentifier */ wrap_alg = X509_ALGOR_new(); if (!wrap_alg) goto err; wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); wrap_alg->parameter = ASN1_TYPE_new(); if (!wrap_alg->parameter) goto err; if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) goto err; if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { ASN1_TYPE_free(wrap_alg->parameter); wrap_alg->parameter = NULL; } if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) goto err; if (ukm) { dukmlen = ASN1_STRING_length(ukm); dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); if (!dukm) goto err; } if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) goto err; dukm = NULL; /* * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter * of another AlgorithmIdentifier. */ penc = NULL; penclen = i2d_X509_ALGOR(wrap_alg, &penc); if (!penc || !penclen) goto err; wrap_str = ASN1_STRING_new(); if (!wrap_str) goto err; ASN1_STRING_set0(wrap_str, penc, penclen); penc = NULL; X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), V_ASN1_SEQUENCE, wrap_str); rv = 1; err: if (penc) OPENSSL_free(penc); if (wrap_alg) X509_ALGOR_free(wrap_alg); return rv; }
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) { CMS_SignedData *sd; CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; if(!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); if (!si) goto merr; X509_check_purpose(signer, -1, -1); CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); si->pkey = pk; si->signer = signer; if (flags & CMS_USE_KEYID) { si->version = 3; if (sd->version < 3) sd->version = 3; type = CMS_SIGNERINFO_KEYIDENTIFIER; } else { type = CMS_SIGNERINFO_ISSUER_SERIAL; si->version = 1; } if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */ if (md == NULL) md = EVP_sha1(); /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } cms_DigestAlgorithm_set(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { ASN1_OBJECT *aoid; alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) break; } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { alg = X509_ALGOR_new(); if (!alg) goto merr; cms_DigestAlgorithm_set(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); goto merr; } } /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, * hard code algorithm parameters. */ switch (pk->type) { case EVP_PKEY_RSA: X509_ALGOR_set0(si->signatureAlgorithm, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); break; case EVP_PKEY_DSA: X509_ALGOR_set0(si->signatureAlgorithm, OBJ_nid2obj(NID_dsaWithSHA1), V_ASN1_UNDEF, 0); break; case EVP_PKEY_EC: X509_ALGOR_set0(si->signatureAlgorithm, OBJ_nid2obj(NID_ecdsa_with_SHA1), V_ASN1_UNDEF, 0); break; default: CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } if (!(flags & CMS_NOATTR)) { /* Initialialize signed attributes strutucture so other * attributes such as signing time etc are added later * even if we add none here. */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); if (!si->signedAttrs) goto merr; } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); if (!i) goto merr; } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si)) goto err; } } if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) goto merr; } if (!sd->signerInfos) sd->signerInfos = sk_CMS_SignerInfo_new_null(); if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) goto merr; return si; merr: CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); err: if (si) M_ASN1_free_of(si, CMS_SignerInfo); return NULL; }
static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; BN_CTX *ctx = NULL; STACK_OF(ASN1_TYPE) *ndsa = NULL; DSA *dsa = NULL; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); /* Check for broken DSA PKCS#8, UGH! */ if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { ASN1_TYPE *t1, *t2; if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) goto decerr; if (sk_ASN1_TYPE_num(ndsa) != 2) goto decerr; /* 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; pval = t1->value.ptr; } else if (ptype == V_ASN1_SEQUENCE) p8->broken = PKCS8_NS_DB; else goto decerr; if (t2->type != V_ASN1_INTEGER) goto decerr; privkey = t2->value.integer; } else { const unsigned char *q = p; if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen))) goto decerr; if (privkey->type == V_ASN1_NEG_INTEGER) { p8->broken = PKCS8_NEG_PRIVKEY; ASN1_INTEGER_free(privkey); if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen))) goto decerr; } if (ptype != V_ASN1_SEQUENCE) goto decerr; } pstr = pval; pm = pstr->data; pmlen = pstr->length; if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) goto decerr; /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR); goto dsaerr; } /* Calculate public key */ if (!(dsa->pub_key = BN_new())) { DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_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); return 1; decerr: DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); dsaerr: BN_CTX_free (ctx); if (privkey) ASN1_INTEGER_free(privkey); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); return 0; }
static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { RSA_PKEY_CTX *rctx = ctx->data; switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { if (!check_padding_md(rctx->md, p1)) return 0; if (p1 == RSA_PKCS1_PSS_PADDING) { if (!(ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } if (p1 == RSA_PKCS1_OAEP_PADDING) { if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) goto bad_pad; if (!rctx->md) rctx->md = EVP_sha1(); } rctx->pad_mode = p1; return 1; } bad_pad: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return -2; case EVP_PKEY_CTRL_GET_RSA_PADDING: *(int *)p2 = rctx->pad_mode; return 1; case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) *(int *)p2 = rctx->saltlen; else { if (p1 < -2) return -2; rctx->saltlen = p1; } return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 256) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); return -2; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (!p2) return -2; rctx->pub_exp = p2; return 1; case EVP_PKEY_CTRL_MD: if (!check_padding_md(p2, rctx->pad_mode)) return 0; rctx->md = p2; return 1; case EVP_PKEY_CTRL_RSA_MGF1_MD: case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); return -2; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { if (rctx->mgf1md) *(const EVP_MD **)p2 = rctx->mgf1md; else *(const EVP_MD **)p2 = rctx->md; } else rctx->mgf1md = p2; return 1; case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: return 1; #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_DECRYPT: { X509_ALGOR *alg = NULL; ASN1_OBJECT *encalg = NULL; if (p2) CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg); if (alg) X509_ALGOR_get0(&encalg, NULL, NULL, alg); if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep) rctx->pad_mode = RSA_PKCS1_OAEP_PADDING; } case EVP_PKEY_CTRL_CMS_ENCRYPT: case EVP_PKEY_CTRL_CMS_SIGN: return 1; #endif case EVP_PKEY_CTRL_PEER_KEY: RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; default: return -2; } }
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) { CMS_SignedData *sd; CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; if (!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); if (!si) goto merr; /* Call for side-effect of computing hash and caching extensions */ X509_check_purpose(signer, -1, -1); X509_up_ref(signer); EVP_PKEY_up_ref(pk); si->pkey = pk; si->signer = signer; si->mctx = EVP_MD_CTX_new(); si->pctx = NULL; if (si->mctx == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); goto err; } if (flags & CMS_USE_KEYID) { si->version = 3; if (sd->version < 3) sd->version = 3; type = CMS_SIGNERINFO_KEYIDENTIFIER; } else { type = CMS_SIGNERINFO_ISSUER_SERIAL; si->version = 1; } if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; if (md == NULL) { int def_nid; if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) goto err; md = EVP_get_digestbynid(def_nid); if (md == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); goto err; } } if (!md) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); goto err; } X509_ALGOR_set_md(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { const ASN1_OBJECT *aoid; alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) break; } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { alg = X509_ALGOR_new(); if (alg == NULL) goto merr; X509_ALGOR_set_md(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); goto merr; } } if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) goto err; if (!(flags & CMS_NOATTR)) { /* * Initialize signed attributes structure so other attributes * such as signing time etc are added later even if we add none here. */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); if (!si->signedAttrs) goto merr; } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); if (!i) goto merr; } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && !CMS_SignerInfo_sign(si)) goto err; } } if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) goto merr; } if (flags & CMS_KEY_PARAM) { if (flags & CMS_NOATTR) { si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); if (si->pctx == NULL) goto err; if (EVP_PKEY_sign_init(si->pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) goto err; } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0) goto err; } if (!sd->signerInfos) sd->signerInfos = sk_CMS_SignerInfo_new_null(); if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) goto merr; return si; merr: CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(si, CMS_SignerInfo); return NULL; }
static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p = NULL; void *pval; int ptype, pklen; EC_KEY *eckey = NULL; 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); if (!eckey) goto ecliberr; /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { ECerr(EC_F_ECKEY_PRIV_DECODE, EC_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) { ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; ecliberr: ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); ecerr: if (eckey) EC_KEY_free(eckey); return 0; }
static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const uint8_t *p, *pm; int pklen, pmlen; int ptype; void *pval; ASN1_STRING *pstr; X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; BN_CTX *ctx = NULL; /* In PKCS#8 DSA: you just get a private key integer and parameters in the * AlgorithmIdentifier the pubkey must be recalculated. */ STACK_OF(ASN1_TYPE) *ndsa = NULL; DSA *dsa = NULL; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) { return 0; } X509_ALGOR_get0(NULL, &ptype, &pval, palg); /* Check for broken DSA PKCS#8, UGH! */ if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { ASN1_TYPE *t1, *t2; ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen); if (ndsa == NULL) { goto decerr; } if (sk_ASN1_TYPE_num(ndsa) != 2) { goto decerr; } /* 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; pval = t1->value.ptr; } else if (ptype == V_ASN1_SEQUENCE) { p8->broken = PKCS8_NS_DB; } else { goto decerr; } if (t2->type != V_ASN1_INTEGER) { goto decerr; } privkey = t2->value.integer; } else { const uint8_t *q = p; privkey = d2i_ASN1_INTEGER(NULL, &p, pklen); if (privkey == NULL) { goto decerr; } if (privkey->type == V_ASN1_NEG_INTEGER) { p8->broken = PKCS8_NEG_PRIVKEY; ASN1_INTEGER_free(privkey); privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen); if (privkey == NULL) { goto decerr; } } if (ptype != V_ASN1_SEQUENCE) { goto decerr; } } pstr = pval; pm = pstr->data; pmlen = pstr->length; dsa = d2i_DSAparams(NULL, &pm, pmlen); if (dsa == NULL) { goto decerr; } /* We have parameters. Now set private key */ dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL); if (dsa->priv_key == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN); goto dsaerr; } /* Calculate public key. */ dsa->pub_key = BN_new(); if (dsa->pub_key == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto dsaerr; } ctx = BN_CTX_new(); if (ctx == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free(ctx); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); ASN1_INTEGER_free(privkey); return 1; decerr: OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); dsaerr: BN_CTX_free(ctx); ASN1_INTEGER_free(privkey); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); return 0; }
static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p, *pm; int pklen, pmlen; int ptype; const void *pval; const ASN1_STRING *pstr; const X509_ALGOR *palg; ASN1_INTEGER *privkey = NULL; BN_CTX *ctx = NULL; DSA *dsa = NULL; int ret = 0; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) goto decerr; if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) goto decerr; pstr = pval; pm = pstr->data; pmlen = pstr->length; if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) goto decerr; /* We have parameters now set private key */ if ((dsa->priv_key = BN_secure_new()) == NULL || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) { DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); goto dsaerr; } /* Calculate public key */ if ((dsa->pub_key = BN_new()) == NULL) { DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); goto dsaerr; } if ((ctx = BN_CTX_new()) == NULL) { DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); goto dsaerr; } BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); ret = 1; goto done; decerr: DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR); dsaerr: DSA_free(dsa); done: BN_CTX_free(ctx); ASN1_STRING_clear_free(privkey); return ret; }