- EVP_PKEY *pkey = NULL;
-#ifndef OPENSSL_NO_RSA
- RSA *rsa = NULL;
-#endif
-#ifndef OPENSSL_NO_DSA
- DSA *dsa = NULL;
-#endif
-#ifndef OPENSSL_NO_ECDSA
- ECDSA *ecdsa = NULL;
-#endif
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
- ASN1_INTEGER *privkey;
- ASN1_TYPE *t1, *t2, *param = NULL;
- STACK_OF(ASN1_TYPE) *n_stack = NULL;
- BN_CTX *ctx = NULL;
- int plen;
-#endif
- X509_ALGOR *a;
- 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
-#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
- case NID_ecdsa_with_SHA1:
- case NID_dsa:
- /* PKCS#8 DSA/ECDSA is weird: you just get a private key integer
- * and parameters in the AlgorithmIdentifier the pubkey must
- * be recalculated.
- */
-
- /* Check for broken DSA/ECDSA PKCS#8, UGH! */
- if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
- {
- if(!(n_stack = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
- d2i_ASN1_TYPE,
- ASN1_TYPE_free)))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- if(sk_ASN1_TYPE_num(n_stack) != 2 )
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- /* Handle Two broken types:
- * SEQUENCE {parameters, priv_key}
- * SEQUENCE {pub_key, priv_key}
- */
-
- t1 = sk_ASN1_TYPE_value(n_stack, 0);
- t2 = sk_ASN1_TYPE_value(n_stack, 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 err;
- }
-
- if(t2->type != V_ASN1_INTEGER) {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- privkey = t2->value.integer;
- }
- else
- {
- if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen)))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- param = p8->pkeyalg->parameter;
- }
- if (!param || (param->type != V_ASN1_SEQUENCE))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- cp = p = param->value.sequence->data;
- plen = param->value.sequence->length;
- if (!(ctx = BN_CTX_new()))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (nid == NID_dsa)
- {
-#ifndef OPENSSL_NO_DSA
- if (!(dsa = d2i_DSAparams (NULL, &cp, plen)))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- /* 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 err;
- }
- /* Calculate public key (ouch!) */
- if (!(dsa->pub_key = BN_new()))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- 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 err;
- }
-
- EVP_PKEY_assign_DSA(pkey, dsa);
- BN_CTX_free(ctx);
- if(n_stack) sk_ASN1_TYPE_pop_free(n_stack, ASN1_TYPE_free);
- else ASN1_INTEGER_free(privkey);
-#else
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
- goto err;
-#endif
- }
- else /* nid == NID_ecdsa_with_SHA1 */
- {
-#ifndef OPENSSL_NO_ECDSA
- if ((ecdsa = d2i_ECDSAParameters(NULL, &cp, plen)) == NULL)
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- if ((ecdsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)) == NULL)
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
- goto err;
- }
- if ((ecdsa->pub_key = EC_POINT_new(ecdsa->group)) == NULL)
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
- goto err;
- }
- if (!EC_POINT_copy(ecdsa->pub_key, EC_GROUP_get0_generator(ecdsa->group)))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
- goto err;
- }
- if (!EC_POINT_mul(ecdsa->group, ecdsa->pub_key, ecdsa->priv_key,
- NULL, NULL, ctx))
- {
- EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
- goto err;
- }
-
- EVP_PKEY_assign_ECDSA(pkey, ecdsa);
- BN_CTX_free(ctx);
- if (n_stack) sk_ASN1_TYPE_pop_free(n_stack, ASN1_TYPE_free);
- else
- ASN1_INTEGER_free(privkey);
-#else
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
- goto err;
-#endif
- }
- break;
-err:
- if (ctx) BN_CTX_free(ctx);
- sk_ASN1_TYPE_pop_free(n_stack, ASN1_TYPE_free);
-#ifndef OPENSSL_NO_DSA
- if (dsa) DSA_free(dsa);
-#endif
-#ifndef OPENSSL_NO_ECDSA
- if (ecdsa) ECDSA_free(ecdsa);
-#endif
- if (pkey) EVP_PKEY_free(pkey);
- return NULL;
- break;
-#endif
- default:
- EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
- if (!a->algorithm) strcpy (obj_tmp, "NULL");
- 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;