Avoid EVP_PKEY_set_type in EVP_PKEY_new_raw_*_key

These are effectively just APIs for creating Ed25519 and X25519 keys. We
may want to rethink this a bit later, but for now let's just do this.

Bug: 497
Change-Id: I01ae06fa86af96da993fd41611472838475bf094
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/67128
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/evp/evp.c b/crypto/evp/evp.c
index babf709..c8dcb50 100644
--- a/crypto/evp/evp.c
+++ b/crypto/evp/evp.c
@@ -372,16 +372,26 @@
 
 EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused,
                                        const uint8_t *in, size_t len) {
-  EVP_PKEY *ret = EVP_PKEY_new();
-  if (ret == NULL ||
-      !EVP_PKEY_set_type(ret, type)) {
-    goto err;
+  // To avoid pulling in all key types, look for specifically the key types that
+  // support |set_priv_raw|.
+  const EVP_PKEY_ASN1_METHOD *method;
+  switch (type) {
+    case EVP_PKEY_X25519:
+      method = &x25519_asn1_meth;
+      break;
+    case EVP_PKEY_ED25519:
+      method = &ed25519_asn1_meth;
+      break;
+    default:
+      OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+      return 0;
   }
 
-  if (ret->ameth->set_priv_raw == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+  EVP_PKEY *ret = EVP_PKEY_new();
+  if (ret == NULL) {
     goto err;
   }
+  evp_pkey_set_method(ret, method);
 
   if (!ret->ameth->set_priv_raw(ret, in, len)) {
     goto err;
@@ -396,16 +406,26 @@
 
 EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused,
                                       const uint8_t *in, size_t len) {
-  EVP_PKEY *ret = EVP_PKEY_new();
-  if (ret == NULL ||
-      !EVP_PKEY_set_type(ret, type)) {
-    goto err;
+  // To avoid pulling in all key types, look for specifically the key types that
+  // support |set_pub_raw|.
+  const EVP_PKEY_ASN1_METHOD *method;
+  switch (type) {
+    case EVP_PKEY_X25519:
+      method = &x25519_asn1_meth;
+      break;
+    case EVP_PKEY_ED25519:
+      method = &ed25519_asn1_meth;
+      break;
+    default:
+      OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
+      return 0;
   }
 
-  if (ret->ameth->set_pub_raw == NULL) {
-    OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+  EVP_PKEY *ret = EVP_PKEY_new();
+  if (ret == NULL) {
     goto err;
   }
+  evp_pkey_set_method(ret, method);
 
   if (!ret->ameth->set_pub_raw(ret, in, len)) {
     goto err;
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index 6468386..dac6986 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -1216,3 +1216,11 @@
   EXPECT_FALSE(EVP_PKEY_copy_parameters(rsa.get(), p256.get()));
   EXPECT_EQ(EVP_PKEY_RSA, EVP_PKEY_id(rsa.get()));
 }
+
+TEST(EVPExtraTest, RawKeyUnsupported) {
+  static const uint8_t kKey[] = {1, 2, 3, 4};
+  EXPECT_FALSE(
+      EVP_PKEY_new_raw_public_key(EVP_PKEY_RSA, nullptr, kKey, sizeof(kKey)));
+  EXPECT_FALSE(
+      EVP_PKEY_new_raw_private_key(EVP_PKEY_RSA, nullptr, kKey, sizeof(kKey)));
+}