Ejemplo n.º 1
0
/* Tests loading a bad key in PKCS8 format */
static int test_EVP_PKCS82PKEY(void)
{
    int ret = 0;
    const unsigned char *derp = kExampleBadECKeyDER;
    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
    EVP_PKEY *pkey = NULL;

    p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER));

    if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) {
        fprintf(stderr, "Failed to parse key\n");
        goto done;
    }

    pkey = EVP_PKCS82PKEY(p8inf);
    if (pkey) {
        fprintf(stderr, "Imported invalid EC key\n");
        goto done;
    }

    ret = 1;

 done:
    PKCS8_PRIV_KEY_INFO_free(p8inf);
    EVP_PKEY_free(pkey);

    return ret;
}
Ejemplo n.º 2
0
static int openssl_import_keypair(const keymaster_device_t* dev,
        const uint8_t* key, const size_t key_length,
        uint8_t** key_blob, size_t* key_blob_length) {
    int response = -1;

    if (key == NULL) {
        ALOGW("input key == NULL");
        return -1;
    } else if (key_blob == NULL || key_blob_length == NULL) {
        ALOGW("output key blob or length == NULL");
        return -1;
    }

    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
    if (pkcs8.get() == NULL) {
        logOpenSSLError("openssl_import_keypair");
        return -1;
    }

    /* assign to EVP */
    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
    if (pkey.get() == NULL) {
        logOpenSSLError("openssl_import_keypair");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(pkcs8);

    if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
        return -1;
    }

    return 0;
}
Ejemplo n.º 3
0
TEST_F(KeymasterTest, ImportKeyPair_EC_Success) {
    uint8_t* key_blob;
    size_t key_blob_length;

    ASSERT_EQ(0,
            sDevice->import_keypair(sDevice, TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1),
                    &key_blob, &key_blob_length))
            << "Should successfully import an EC key";
    UniqueKey key(&sDevice, key_blob, key_blob_length);

    uint8_t* x509_data;
    size_t x509_data_length;
    ASSERT_EQ(0,
            sDevice->get_keypair_public(sDevice, key_blob, key_blob_length,
                    &x509_data, &x509_data_length))
            << "Should be able to retrieve EC public key successfully";
    UniqueBlob x509_blob(x509_data, x509_data_length);

    const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get());
    Unique_EVP_PKEY actual(d2i_PUBKEY((EVP_PKEY**) NULL, &tmp,
            static_cast<long>(x509_blob.length())));

    ASSERT_EQ(EVP_PKEY_type(actual.get()->type), EVP_PKEY_EC)
            << "Generated key type should be of type EC";

    const unsigned char *expectedTmp = static_cast<const unsigned char*>(TEST_EC_KEY_1);
    Unique_PKCS8_PRIV_KEY_INFO expectedPkcs8(
            d2i_PKCS8_PRIV_KEY_INFO((PKCS8_PRIV_KEY_INFO**) NULL, &expectedTmp,
                    sizeof(TEST_EC_KEY_1)));

    Unique_EVP_PKEY expected(EVP_PKCS82PKEY(expectedPkcs8.get()));

    ASSERT_EQ(1, EVP_PKEY_cmp(expected.get(), actual.get()))
            << "Expected and actual keys should match";
}
Ejemplo n.º 4
0
/* Tests loading a bad key in PKCS8 format */
static int test_EVP_PKCS82PKEY(void)
{
    int ret = 0;
    const unsigned char *derp = kExampleBadECKeyDER;
    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
    EVP_PKEY *pkey = NULL;

    if (!TEST_ptr(p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp,
                                              sizeof(kExampleBadECKeyDER))))
        goto done;

    if (!TEST_ptr_eq(derp,
                     kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)))
        goto done;

    if (!TEST_ptr_null(pkey = EVP_PKCS82PKEY(p8inf)))
        goto done;

    ret = 1;

 done:
    PKCS8_PRIV_KEY_INFO_free(p8inf);
    EVP_PKEY_free(pkey);

    return ret;
}
__attribute__((visibility("default"))) int openssl_import_keypair(const keymaster0_device_t*,
                                                                  const uint8_t* key,
                                                                  const size_t key_length,
                                                                  uint8_t** key_blob,
                                                                  size_t* key_blob_length) {
    if (key == NULL) {
        ALOGW("input key == NULL");
        return -1;
    } else if (key_blob == NULL || key_blob_length == NULL) {
        ALOGW("output key blob or length == NULL");
        return -1;
    }

    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
    if (pkcs8.get() == NULL) {
        logOpenSSLError("openssl_import_keypair");
        return -1;
    }

    /* assign to EVP */
    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
    if (pkey.get() == NULL) {
        logOpenSSLError("openssl_import_keypair");
        return -1;
    }

    if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
        return -1;
    }

    return 0;
}
Ejemplo n.º 6
0
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
                         long len) {
  EVP_PKEY *ret;

  if (out == NULL || *out == NULL) {
    ret = EVP_PKEY_new();
    if (ret == NULL) {
      OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB);
      return NULL;
    }
  } else {
    ret = *out;
  }

  if (!EVP_PKEY_set_type(ret, type)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
    goto err;
  }

  const uint8_t *in = *inp;
  if (!ret->ameth->old_priv_decode ||
      !ret->ameth->old_priv_decode(ret, &in, len)) {
    if (ret->ameth->priv_decode) {
      /* Reset |in| in case |old_priv_decode| advanced it on error. */
      in = *inp;
      PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &in, len);
      if (!p8) {
        goto err;
      }
      EVP_PKEY_free(ret);
      ret = EVP_PKCS82PKEY(p8);
      PKCS8_PRIV_KEY_INFO_free(p8);
      if (ret == NULL) {
        goto err;
      }
    } else {
      OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
      goto err;
    }
  }

  if (out != NULL) {
    *out = ret;
  }
  *inp = in;
  return ret;

err:
  if (out == NULL || *out != ret) {
    EVP_PKEY_free(ret);
  }
  return NULL;
}
Ejemplo n.º 7
0
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
                             long length)
{
    STACK_OF(ASN1_TYPE) *inkey;
    const unsigned char *p;
    int keytype;
    p = *pp;
    /*
     * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
     * analyzing it we can determine the passed structure: this assumes the
     * input is surrounded by an ASN1 SEQUENCE.
     */
    inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
    p = *pp;
    /*
     * Since we only need to discern "traditional format" RSA and DSA keys we
     * can just count the elements.
     */
    if (sk_ASN1_TYPE_num(inkey) == 6)
        keytype = EVP_PKEY_DSA;
    else if (sk_ASN1_TYPE_num(inkey) == 4)
        keytype = EVP_PKEY_EC;
    else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
                                              * traditional format */
        PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
        EVP_PKEY *ret;

        sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
        if (!p8) {
            ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
                    ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
            return NULL;
        }
        ret = EVP_PKCS82PKEY(p8);
        PKCS8_PRIV_KEY_INFO_free(p8);
        if (ret == NULL)
            return NULL;
        *pp = p;
        if (a) {
            *a = ret;
        }
        return ret;
    } else
        keytype = EVP_PKEY_RSA;
    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
    return d2i_PrivateKey(keytype, a, pp, length);
}
Ejemplo n.º 8
0
// Decode from PKCS#8 BER
bool OSSLECPrivateKey::PKCS8Decode(const ByteString& ber)
{
	int len = ber.size();
	if (len <= 0) return false;
	const unsigned char* priv = ber.const_byte_str();
	PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &priv, len);
	if (p8 == NULL) return false;
	EVP_PKEY* pkey = EVP_PKCS82PKEY(p8);
	PKCS8_PRIV_KEY_INFO_free(p8);
	if (pkey == NULL) return false;
	EC_KEY* key = EVP_PKEY_get1_EC_KEY(pkey);
	EVP_PKEY_free(pkey);
	if (key == NULL) return false;
	setFromOSSL(key);
	EC_KEY_free(key);
	return true;
}
Ejemplo n.º 9
0
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
  STACK_OF(ASN1_TYPE) *inkey;
  const uint8_t *p;
  int keytype;
  p = *inp;

  /* Dirty trick: read in the ASN1 data into out STACK_OF(ASN1_TYPE):
   * by analyzing it we can determine the passed structure: this
   * assumes the input is surrounded by an ASN1 SEQUENCE. */
  inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, len);
  /* Since we only need to discern "traditional format" RSA and DSA
   * keys we can just count the elements. */
  if (sk_ASN1_TYPE_num(inkey) == 6) {
    keytype = EVP_PKEY_DSA;
  } else if (sk_ASN1_TYPE_num(inkey) == 4) {
    keytype = EVP_PKEY_EC;
  } else if (sk_ASN1_TYPE_num(inkey) == 3) {
    /* This seems to be PKCS8, not traditional format */
    p = *inp;
    PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
    EVP_PKEY *ret;

    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
    if (!p8) {
      OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
      return NULL;
    }
    ret = EVP_PKCS82PKEY(p8);
    PKCS8_PRIV_KEY_INFO_free(p8);
    if (ret == NULL) {
      return NULL;
    }

    *inp = p;
    if (out) {
      *out = ret;
    }
    return ret;
  } else {
    keytype = EVP_PKEY_RSA;
  }

  sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
  return d2i_PrivateKey(keytype, out, inp, len);
}
/* static */
Key* Key::ImportKey(const AuthorizationSet& key_description, keymaster_key_format_t key_format,
                    const uint8_t* key_data, size_t key_data_length, const Logger& logger,
                    keymaster_error_t* error) {
    *error = KM_ERROR_OK;

    if (key_data == NULL || key_data_length <= 0) {
        *error = KM_ERROR_INVALID_KEY_BLOB;
        return NULL;
    }

    if (key_format != KM_KEY_FORMAT_PKCS8) {
        *error = KM_ERROR_UNSUPPORTED_KEY_FORMAT;
        return NULL;
    }

    UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8(
        d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_data_length));
    if (pkcs8.get() == NULL) {
        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
        return NULL;
    }

    UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKCS82PKEY(pkcs8.get()));
    if (pkey.get() == NULL) {
        *error = KM_ERROR_INVALID_KEY_BLOB;
        return NULL;
    }

    UniquePtr<Key> key;
    switch (EVP_PKEY_type(pkey->type)) {
    case EVP_PKEY_RSA:
        return RsaKey::ImportKey(key_description, pkey.get(), logger, error);
    case EVP_PKEY_DSA:
        return DsaKey::ImportKey(key_description, pkey.get(), logger, error);
    case EVP_PKEY_EC:
        return EcdsaKey::ImportKey(key_description, pkey.get(), logger, error);
    default:
        *error = KM_ERROR_UNSUPPORTED_ALGORITHM;
        return NULL;
    }

    *error = KM_ERROR_UNIMPLEMENTED;
    return NULL;
}
Ejemplo n.º 11
0
EVP_PKEY *
PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
{
	char *nm = NULL;
	const unsigned char *p = NULL;
	unsigned char *data = NULL;
	long len;
	int slen;
	EVP_PKEY *ret = NULL;

	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY,
	    bp, cb, u))
		return NULL;
	p = data;

	if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
		if (!p8inf)
			goto p8err;
		ret = EVP_PKCS82PKEY(p8inf);
		if (x) {
			EVP_PKEY_free(*x);
			*x = ret;
		}
		PKCS8_PRIV_KEY_INFO_free(p8inf);
	} else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		X509_SIG *p8;
		int klen;
		char psbuf[PEM_BUFSIZE];
		p8 = d2i_X509_SIG(NULL, &p, len);
		if (!p8)
			goto p8err;
		if (cb)
			klen = cb(psbuf, PEM_BUFSIZE, 0, u);
		else
			klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
		if (klen <= 0) {
			PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,
			    PEM_R_BAD_PASSWORD_READ);
			X509_SIG_free(p8);
			goto err;
		}
		p8inf = PKCS8_decrypt(p8, psbuf, klen);
		X509_SIG_free(p8);
		if (!p8inf)
			goto p8err;
		ret = EVP_PKCS82PKEY(p8inf);
		if (x) {
			EVP_PKEY_free(*x);
			*x = ret;
		}
		PKCS8_PRIV_KEY_INFO_free(p8inf);
	} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
		const EVP_PKEY_ASN1_METHOD *ameth;
		ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
		if (!ameth || !ameth->old_priv_decode)
			goto p8err;
		ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
	}

p8err:
	if (ret == NULL)
		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
err:
	free(nm);
	OPENSSL_cleanse(data, len);
	free(data);
	return (ret);
}
Ejemplo n.º 12
0
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
	{
	char *nm=NULL;
	const unsigned char *p=NULL;
	unsigned char *data=NULL;
	long len;
	EVP_PKEY *ret=NULL;

	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
		return NULL;
	p = data;

	if (strcmp(nm,PEM_STRING_RSA) == 0)
		ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len);
	else if (strcmp(nm,PEM_STRING_DSA) == 0)
		ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len);
	else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0)
		ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len);
	else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
		if(!p8inf) goto p8err;
		ret = EVP_PKCS82PKEY(p8inf);
		if(x) {
			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
			*x = ret;
		}
		PKCS8_PRIV_KEY_INFO_free(p8inf);
	} else if (strcmp(nm,PEM_STRING_PKCS8) == 0) {
		PKCS8_PRIV_KEY_INFO *p8inf;
		X509_SIG *p8;
		int klen;
		char psbuf[PEM_BUFSIZE];
		p8 = d2i_X509_SIG(NULL, &p, len);
		if(!p8) goto p8err;
		if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
		else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u);
		if (klen <= 0) {
			PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,
					PEM_R_BAD_PASSWORD_READ);
			X509_SIG_free(p8);
			goto err;
		}
		p8inf = PKCS8_decrypt(p8, psbuf, klen);
		X509_SIG_free(p8);
		if(!p8inf) goto p8err;
		ret = EVP_PKCS82PKEY(p8inf);
		if(x) {
			if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
			*x = ret;
		}
		PKCS8_PRIV_KEY_INFO_free(p8inf);
	}
p8err:
	if (ret == NULL)
		PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
err:
	OPENSSL_free(nm);
	OPENSSL_cleanse(data, len);
	OPENSSL_free(data);
	return(ret);
	}
Ejemplo n.º 13
0
static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
                                              const char *pem_header,
                                              const unsigned char *blob,
                                              size_t len, void **pctx,
                                              int *matchcount,
                                              const UI_METHOD *ui_method,
                                              void *ui_data)
{
    OSSL_STORE_INFO *store_info = NULL;
    EVP_PKEY *pkey = NULL;
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;

    if (pem_name != NULL) {
        if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) {
            PKCS8_PRIV_KEY_INFO *p8inf =
                d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len);

            *matchcount = 1;
            if (p8inf != NULL)
                pkey = EVP_PKCS82PKEY(p8inf);
            PKCS8_PRIV_KEY_INFO_free(p8inf);
        } else {
            int slen;

            if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
                && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
                                                   slen)) != NULL) {
                *matchcount = 1;
                pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
            }
        }
    } else {
        int i;

        for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
            EVP_PKEY *tmp_pkey = NULL;
            const unsigned char *tmp_blob = blob;

            ameth = EVP_PKEY_asn1_get0(i);
            if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
                continue;

            tmp_pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &tmp_blob, len);
            if (tmp_pkey != NULL) {
                if (pkey != NULL)
                    EVP_PKEY_free(tmp_pkey);
                else
                    pkey = tmp_pkey;
                (*matchcount)++;
            }
        }

        if (*matchcount > 1) {
            EVP_PKEY_free(pkey);
            pkey = NULL;
        }
    }
    if (pkey == NULL)
        /* No match */
        return NULL;

    store_info = OSSL_STORE_INFO_new_PKEY(pkey);
    if (store_info == NULL)
        EVP_PKEY_free(pkey);

    return store_info;
}
Ejemplo n.º 14
0
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
                                  void *u)
{
    char *nm = NULL;
    const unsigned char *p = NULL;
    unsigned char *data = NULL;
    long len;
    EVP_PKEY *ret = NULL;

    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
        return NULL;
    p = data;

    if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
        PKCS8_PRIV_KEY_INFO *p8inf;
        p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
        if (!p8inf)
            goto p8err;
        ret = EVP_PKCS82PKEY(p8inf);
        if (x) {
            if (*x)
                EVP_PKEY_free((EVP_PKEY *)*x);
            *x = ret;
        }
        PKCS8_PRIV_KEY_INFO_free(p8inf);
    } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
        PKCS8_PRIV_KEY_INFO *p8inf;
        X509_SIG *p8;
        int klen;
        char psbuf[PEM_BUFSIZE];
        p8 = d2i_X509_SIG(NULL, &p, len);
        if (!p8)
            goto p8err;

        klen = 0;
        if (!cb)
            cb = PEM_def_callback;
        klen = cb(psbuf, PEM_BUFSIZE, 0, u);
        if (klen <= 0) {
            OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
            X509_SIG_free(p8);
            goto err;
        }
        p8inf = PKCS8_decrypt(p8, psbuf, klen);
        X509_SIG_free(p8);
        OPENSSL_cleanse(psbuf, klen);
        if (!p8inf)
            goto p8err;
        ret = EVP_PKCS82PKEY(p8inf);
        if (x) {
            if (*x)
                EVP_PKEY_free((EVP_PKEY *)*x);
            *x = ret;
        }
        PKCS8_PRIV_KEY_INFO_free(p8inf);
    } else if (strcmp(nm, PEM_STRING_RSA) == 0) {
        /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the
         * standalone format. This and the cases below probably should not
         * accept PKCS#8. */
        ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len);
    } else if (strcmp(nm, PEM_STRING_EC) == 0) {
        ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len);
    } else if (strcmp(nm, PEM_STRING_DSA) == 0) {
        ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len);
    }
 p8err:
    if (ret == NULL)
        OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);

 err:
    OPENSSL_free(nm);
    OPENSSL_cleanse(data, len);
    OPENSSL_free(data);
    return (ret);
}
Ejemplo n.º 15
-1
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
                         long length)
{
    EVP_PKEY *ret;
    const unsigned char *p = *pp;

    if ((a == NULL) || (*a == NULL)) {
        if ((ret = EVP_PKEY_new()) == NULL) {
            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
            return (NULL);
        }
    } else {
        ret = *a;
#ifndef OPENSSL_NO_ENGINE
        if (ret->engine) {
            ENGINE_finish(ret->engine);
            ret->engine = NULL;
        }
#endif
    }

    if (!EVP_PKEY_set_type(ret, type)) {
        ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
        goto err;
    }

    if (!ret->ameth->old_priv_decode ||
        !ret->ameth->old_priv_decode(ret, &p, length)) {
        if (ret->ameth->priv_decode) {
            EVP_PKEY *tmp;
            PKCS8_PRIV_KEY_INFO *p8 = NULL;
            p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
            if (!p8)
                goto err;
            tmp = EVP_PKCS82PKEY(p8);
            PKCS8_PRIV_KEY_INFO_free(p8);
            if (tmp == NULL)
                goto err;
            EVP_PKEY_free(ret);
            ret = tmp;
        } else {
            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
            goto err;
        }
    }
    *pp = p;
    if (a != NULL)
        (*a) = ret;
    return (ret);
 err:
    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        EVP_PKEY_free(ret);
    return (NULL);
}