From 605fa68efaf2ebc891330ed1ae9e5053a2228c1e Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Fri, 27 Oct 2017 22:42:04 +0200
Subject: [PATCH] EVP_PKEY_asn1_add0(): Check that this method isn't already
 registered

No two public key ASN.1 methods with the same pkey_id can be
registered at the same time.

Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/4620)
---
 crypto/asn1/ameth_lib.c | 5 +++++
 crypto/evp/evp_err.c    | 3 +++
 include/openssl/evp.h   | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
index cfde49ab02..dca5affc90 100644
--- a/crypto/asn1/ameth_lib.c
+++ b/crypto/asn1/ameth_lib.c
@@ -176,6 +176,11 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
 
 int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
 {
+    if (pkey_asn1_find(ameth->pkey_id) != NULL) {
+        EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0,
+               EVP_R_PKEY_ASN1_METHOD_ALREADY_REGISTERED);
+        return 0;
+    }
     if (app_methods == NULL) {
         app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
         if (app_methods == NULL)
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index ab4b614026..f5b8635afd 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -49,6 +49,7 @@ static ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_FUNC(EVP_F_EVP_PBE_SCRYPT), "EVP_PBE_scrypt"},
     {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
     {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8), "EVP_PKEY2PKCS8"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_ASN1_ADD0), "EVP_PKEY_asn1_add0"},
     {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
     {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"},
     {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"},
@@ -142,6 +143,8 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
     {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
     {ERR_REASON(EVP_R_PARTIALLY_OVERLAPPING),
      "partially overlapping buffers"},
+    {ERR_REASON(EVP_R_PKEY_ASN1_METHOD_ALREADY_REGISTERED),
+     "pkey asn1 method already registered"},
     {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
     {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"},
     {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 41920fa77d..d2709eaedc 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1485,6 +1485,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_EVP_PBE_SCRYPT                             181
 # define EVP_F_EVP_PKCS82PKEY                             111
 # define EVP_F_EVP_PKEY2PKCS8                             113
+# define EVP_F_EVP_PKEY_ASN1_ADD0                         168
 # define EVP_F_EVP_PKEY_COPY_PARAMETERS                   103
 # define EVP_F_EVP_PKEY_CTX_CTRL                          137
 # define EVP_F_EVP_PKEY_CTX_CTRL_STR                      150
@@ -1569,6 +1570,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   150
 # define EVP_R_OPERATON_NOT_INITIALIZED                   151
 # define EVP_R_PARTIALLY_OVERLAPPING                      162
+# define EVP_R_PKEY_ASN1_METHOD_ALREADY_REGISTERED        164
 # define EVP_R_PRIVATE_KEY_DECODE_ERROR                   145
 # define EVP_R_PRIVATE_KEY_ENCODE_ERROR                   146
 # define EVP_R_PUBLIC_KEY_NOT_RSA                         106
-- 
2.25.1