EVP_PKEY: null-check EVP_PKEY_ASN1_METHOD before using

Most interesting things that can be done with an EVP_PKEY require
`ameth` to be non-NULL. It's only ever NULL for a default initialized
empty object which will have id EVP_PKEY_NONE, but since we return these
from EVP_PKEY_new(), we should avoid crashing when trying to use them.

Bug: 42290409
Change-Id: I31894f0377aaed8cc97fbde9d3e59fe86a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/93629
Reviewed-by: David Benjamin <davidben@google.com>
Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/crypto/evp/evp.cc b/crypto/evp/evp.cc
index 7581c39..aab4de7 100644
--- a/crypto/evp/evp.cc
+++ b/crypto/evp/evp.cc
@@ -288,7 +288,7 @@
                                  size_t *out_len) {
   auto *impl = FromOpaque(pkey);
 
-  if (impl->ameth->get_priv_raw == nullptr) {
+  if (impl->ameth == nullptr || impl->ameth->get_priv_raw == nullptr) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return 0;
   }
@@ -300,7 +300,7 @@
                               size_t *out_len) {
   auto *impl = FromOpaque(pkey);
 
-  if (impl->ameth->get_priv_seed == nullptr) {
+  if (impl->ameth == nullptr || impl->ameth->get_priv_seed == nullptr) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return 0;
   }
@@ -312,7 +312,7 @@
                                 size_t *out_len) {
   auto *impl = FromOpaque(pkey);
 
-  if (impl->ameth->get_pub_raw == nullptr) {
+  if (impl->ameth == nullptr || impl->ameth->get_pub_raw == nullptr) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return 0;
   }
@@ -385,7 +385,7 @@
                                    size_t len) {
   auto *impl = FromOpaque(pkey);
 
-  if (impl->ameth->set1_tls_encodedpoint == nullptr) {
+  if (impl->ameth == nullptr || impl->ameth->set1_tls_encodedpoint == nullptr) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return 0;
   }
@@ -396,7 +396,7 @@
 size_t EVP_PKEY_get1_tls_encodedpoint(const EVP_PKEY *pkey, uint8_t **out_ptr) {
   auto *impl = FromOpaque(pkey);
 
-  if (impl->ameth->get1_tls_encodedpoint == nullptr) {
+  if (impl->ameth == nullptr || impl->ameth->get1_tls_encodedpoint == nullptr) {
     OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
     return 0;
   }
diff --git a/crypto/evp/evp_extra_test.cc b/crypto/evp/evp_extra_test.cc
index dcd3f95..d78c82e 100644
--- a/crypto/evp/evp_extra_test.cc
+++ b/crypto/evp/evp_extra_test.cc
@@ -1416,6 +1416,37 @@
   EXPECT_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_NONE);
 }
 
+// An empty key shouldn't crash on operations.
+TEST(EVPExtraTest, EmptyKey) {
+  UniquePtr<EVP_PKEY> empty(EVP_PKEY_new());
+  ASSERT_TRUE(empty);
+
+  EXPECT_FALSE(EVP_PKEY_is_opaque(empty.get()));
+  EXPECT_FALSE(EVP_PKEY_eq(empty.get(), empty.get()));
+  EXPECT_TRUE(EVP_PKEY_parameters_eq(empty.get(), empty.get()));
+  EXPECT_FALSE(EVP_PKEY_missing_parameters(empty.get()));
+  EXPECT_EQ(EVP_PKEY_size(empty.get()), 0);
+  EXPECT_EQ(EVP_PKEY_bits(empty.get()), 0);
+  EXPECT_EQ(EVP_PKEY_id(empty.get()), EVP_PKEY_NONE);
+
+  EXPECT_EQ(EVP_PKEY_get_raw_private_key(empty.get(), nullptr, nullptr), 0);
+  EXPECT_TRUE(ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP,
+                          EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE));
+  EXPECT_EQ(EVP_PKEY_get_private_seed(empty.get(), nullptr, nullptr), 0);
+  EXPECT_TRUE(ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP,
+                          EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE));
+  EXPECT_EQ(EVP_PKEY_get_raw_public_key(empty.get(), nullptr, nullptr), 0);
+  EXPECT_TRUE(ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP,
+                          EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE));
+
+  EXPECT_EQ(EVP_PKEY_get1_tls_encodedpoint(empty.get(), nullptr), 0u);
+  EXPECT_TRUE(ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP,
+                          EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE));
+  EXPECT_EQ(EVP_PKEY_set1_tls_encodedpoint(empty.get(), nullptr, 0u), 0);
+  EXPECT_TRUE(ErrorEquals(ERR_peek_last_error(), ERR_LIB_EVP,
+                          EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE));
+}
+
 // Due to an OpenSSL API flaw, it is possible to make a half-empty X25519 key.
 // Using a key in this state is a caller error, but we gracefully handle this
 // case.