Have EVP_PKEY_asn1_find_str() work more like EVP_PKEY_asn1_find()
authorRichard Levitte <levitte@openssl.org>
Mon, 22 Jan 2018 18:03:37 +0000 (19:03 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 23 Jan 2018 19:27:32 +0000 (20:27 +0100)
EVP_PKEY_asn1_find_str() would search through standard asn1 methods
first, then those added by the application, which EVP_PKEY_asn1_find()
worked the other way around.  Also, EVP_PKEY_asn1_find_str() didn't
handle aliases.

This change brings EVP_PKEY_asn1_find_str() closer to EVP_PKEY_asn1_find().

Fixes #5086

Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
(Merged from https://github.com/openssl/openssl/pull/5137)

crypto/asn1/ameth_lib.c
crypto/err/openssl.txt
crypto/evp/evp_err.c
include/openssl/evperr.h

index a40e20ed3322f5873ddd2de6d2bd584c71c3477d..76512c6763ef0494336d99b14620440030f42ab5 100644 (file)
@@ -104,7 +104,8 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
                                                    const char *str, int len)
 {
     int i;
-    const EVP_PKEY_ASN1_METHOD *ameth;
+    const EVP_PKEY_ASN1_METHOD *ameth = NULL;
+
     if (len == -1)
         len = strlen(str);
     if (pe) {
@@ -124,12 +125,12 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
 #endif
         *pe = NULL;
     }
-    for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
+    for (i = EVP_PKEY_asn1_get_count(); i-- > 0; ) {
         ameth = EVP_PKEY_asn1_get0(i);
         if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
             continue;
-        if (((int)strlen(ameth->pem_str) == len)
-            && (strncasecmp(ameth->pem_str, str, len) == 0))
+        if ((int)strlen(ameth->pem_str) == len
+            && strncasecmp(ameth->pem_str, str, len) == 0)
             return ameth;
     }
     return NULL;
@@ -137,11 +138,21 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
 
 int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
 {
+    EVP_PKEY_ASN1_METHOD tmp = { 0, };
+
     if (app_methods == NULL) {
         app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
         if (app_methods == NULL)
             return 0;
     }
+
+    tmp.pkey_id = ameth->pkey_id;
+    if (sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp) >= 0) {
+        EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0,
+               EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED);
+        return 0;
+    }
+
     if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
         return 0;
     sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
index b8ca452c8e0ec3bc0e8a853c37a6cc6cfb6a1bb7..e98bd959386836d5904095c0daa103ca42c89afd 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the OpenSSL license (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -2065,8 +2065,8 @@ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\
        operation not supported for this keytype
 EVP_R_OPERATON_NOT_INITIALIZED:151:operaton not initialized
 EVP_R_PARTIALLY_OVERLAPPING:162:partially overlapping buffers
-EVP_R_PKEY_ASN1_METHOD_ALREADY_REGISTERED:179:\
-       pkey asn1 method already registered
+EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\
+       pkey application asn1 method already registered
 EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error
 EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error
 EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
index 6c1dc83c1910c3dc690a8a0c7a867b1a8404f1b3..a43de746052789960ceef115b1951b5c16d5fd96 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -205,8 +205,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
     "operaton not initialized"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING),
     "partially overlapping buffers"},
-    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PKEY_ASN1_METHOD_ALREADY_REGISTERED),
-    "pkey asn1 method already registered"},
+    {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED),
+    "pkey application asn1 method already registered"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_DECODE_ERROR),
     "private key decode error"},
     {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR),
index a870e438dd6dfa27e6c76a8e412c7b8a81f11c42..ff46657ef0b4fa70a63d0ddb6464a53a627a9262 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -154,7 +154,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        179
+# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179
 # define EVP_R_PRIVATE_KEY_DECODE_ERROR                   145
 # define EVP_R_PRIVATE_KEY_ENCODE_ERROR                   146
 # define EVP_R_PUBLIC_KEY_NOT_RSA                         106