From 3bf0c3fe31d5339524dae671064cc5fe9e4bda38 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 22 Jan 2018 19:03:37 +0100 Subject: [PATCH] Have EVP_PKEY_asn1_find_str() work more like EVP_PKEY_asn1_find() 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 (Merged from https://github.com/openssl/openssl/pull/5137) --- crypto/asn1/ameth_lib.c | 19 +++++++++++++++---- crypto/err/openssl.txt | 6 +++--- crypto/evp/evp_err.c | 6 +++--- include/openssl/evperr.h | 4 ++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index a40e20ed33..76512c6763 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -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); diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index b8ca452c8e..e98bd95938 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -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 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 6c1dc83c19..a43de74605 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -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), diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index a870e438dd..ff46657ef0 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -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 -- 2.34.1