summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/asn1/ameth_lib.c139
1 files changed, 52 insertions, 87 deletions
diff --git a/src/lib/libcrypto/asn1/ameth_lib.c b/src/lib/libcrypto/asn1/ameth_lib.c
index 82bfa77390..cca1dcce7d 100644
--- a/src/lib/libcrypto/asn1/ameth_lib.c
+++ b/src/lib/libcrypto/asn1/ameth_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ameth_lib.c,v 1.27 2022/11/09 16:14:15 jsing Exp $ */ 1/* $OpenBSD: ameth_lib.c,v 1.28 2022/11/09 18:17:16 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -81,127 +81,89 @@ extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
81extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; 81extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
82extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; 82extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth;
83 83
84/* Keep this sorted in type order !! */ 84static const EVP_PKEY_ASN1_METHOD *asn1_methods[] = {
85static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { 85 &cmac_asn1_meth,
86#ifndef OPENSSL_NO_RSA
87 &rsa_asn1_meths[0],
88 &rsa_asn1_meths[1],
89#endif
90#ifndef OPENSSL_NO_DH
91 &dh_asn1_meth, 86 &dh_asn1_meth,
92#endif
93#ifndef OPENSSL_NO_DSA
94 &dsa_asn1_meths[0], 87 &dsa_asn1_meths[0],
95 &dsa_asn1_meths[1], 88 &dsa_asn1_meths[1],
96 &dsa_asn1_meths[2], 89 &dsa_asn1_meths[2],
97 &dsa_asn1_meths[3], 90 &dsa_asn1_meths[3],
98 &dsa_asn1_meths[4], 91 &dsa_asn1_meths[4],
99#endif
100#ifndef OPENSSL_NO_EC
101 &eckey_asn1_meth, 92 &eckey_asn1_meth,
102#endif
103#ifndef OPENSSL_NO_GOST
104 &gostr01_asn1_meths[0],
105 &gostimit_asn1_meth, 93 &gostimit_asn1_meth,
106#endif 94 &gostr01_asn1_meths[0],
107 &hmac_asn1_meth,
108 &cmac_asn1_meth,
109#ifndef OPENSSL_NO_RSA
110 &rsa_pss_asn1_meth,
111#endif
112#ifndef OPENSSL_NO_GOST
113 &gostr01_asn1_meths[1], 95 &gostr01_asn1_meths[1],
114 &gostr01_asn1_meths[2], 96 &gostr01_asn1_meths[2],
115#endif 97 &hmac_asn1_meth,
98 &rsa_asn1_meths[0],
99 &rsa_asn1_meths[1],
100 &rsa_pss_asn1_meth,
116}; 101};
117 102
118typedef int sk_cmp_fn_type(const char * const *a, const char * const *b); 103static const size_t asn1_methods_count =
119DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD) 104 sizeof(asn1_methods) / sizeof(asn1_methods[0]);
120static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
121
122static int ameth_cmp_BSEARCH_CMP_FN(const void *, const void *);
123static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *, const EVP_PKEY_ASN1_METHOD * const *);
124static const EVP_PKEY_ASN1_METHOD * *OBJ_bsearch_ameth(const EVP_PKEY_ASN1_METHOD * *key, const EVP_PKEY_ASN1_METHOD * const *base, int num);
125 105
126static int 106DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
127ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a, 107static STACK_OF(EVP_PKEY_ASN1_METHOD) *asn1_app_methods = NULL;
128 const EVP_PKEY_ASN1_METHOD * const *b)
129{
130 return ((*a)->pkey_id - (*b)->pkey_id);
131}
132
133
134static int
135ameth_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
136{
137 const EVP_PKEY_ASN1_METHOD * const *a = a_;
138 const EVP_PKEY_ASN1_METHOD * const *b = b_;
139 return ameth_cmp(a, b);
140}
141
142static const EVP_PKEY_ASN1_METHOD * *
143OBJ_bsearch_ameth(const EVP_PKEY_ASN1_METHOD * *key, const EVP_PKEY_ASN1_METHOD * const *base, int num)
144{
145 return (const EVP_PKEY_ASN1_METHOD * *)OBJ_bsearch_(key, base, num, sizeof(const EVP_PKEY_ASN1_METHOD *),
146 ameth_cmp_BSEARCH_CMP_FN);
147}
148 108
149int 109int
150EVP_PKEY_asn1_get_count(void) 110EVP_PKEY_asn1_get_count(void)
151{ 111{
152 int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); 112 int num = asn1_methods_count;
153 if (app_methods) 113
154 num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); 114 if (asn1_app_methods != NULL)
115 num += sk_EVP_PKEY_ASN1_METHOD_num(asn1_app_methods);
116
155 return num; 117 return num;
156} 118}
157 119
158const EVP_PKEY_ASN1_METHOD * 120const EVP_PKEY_ASN1_METHOD *
159EVP_PKEY_asn1_get0(int idx) 121EVP_PKEY_asn1_get0(int idx)
160{ 122{
161 int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); 123 int num = asn1_methods_count;
124
162 if (idx < 0) 125 if (idx < 0)
163 return NULL; 126 return NULL;
164 if (idx < num) 127 if (idx < num)
165 return standard_methods[idx]; 128 return asn1_methods[idx];
129
166 idx -= num; 130 idx -= num;
167 return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); 131
132 return sk_EVP_PKEY_ASN1_METHOD_value(asn1_app_methods, idx);
168} 133}
169 134
170static const EVP_PKEY_ASN1_METHOD * 135static const EVP_PKEY_ASN1_METHOD *
171pkey_asn1_find(int type) 136pkey_asn1_find(int pkey_id)
172{ 137{
173 EVP_PKEY_ASN1_METHOD tmp; 138 const EVP_PKEY_ASN1_METHOD *ameth;
174 const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; 139 int i;
175 tmp.pkey_id = type; 140
176 if (app_methods) { 141 for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) {
177 int idx; 142 ameth = EVP_PKEY_asn1_get0(i);
178 idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); 143 if (ameth->pkey_id == pkey_id)
179 if (idx >= 0) 144 return ameth;
180 return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
181 } 145 }
182 ret = OBJ_bsearch_ameth(&t, standard_methods, 146
183 sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *)); 147 return NULL;
184 if (!ret || !*ret)
185 return NULL;
186 return *ret;
187} 148}
188 149
189/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL 150/*
151 * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
190 * also search through engines and set *pe to a functional reference 152 * also search through engines and set *pe to a functional reference
191 * to the engine implementing 'type' or NULL if no engine implements 153 * to the engine implementing 'type' or NULL if no engine implements
192 * it. 154 * it.
193 */ 155 */
194
195const EVP_PKEY_ASN1_METHOD * 156const EVP_PKEY_ASN1_METHOD *
196EVP_PKEY_asn1_find(ENGINE **pe, int type) 157EVP_PKEY_asn1_find(ENGINE **pe, int type)
197{ 158{
198 const EVP_PKEY_ASN1_METHOD *t; 159 const EVP_PKEY_ASN1_METHOD *mp;
199 160
200 for (;;) { 161 for (;;) {
201 t = pkey_asn1_find(type); 162 if ((mp = pkey_asn1_find(type)) == NULL)
202 if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) 163 break;
164 if ((mp->pkey_flags & ASN1_PKEY_ALIAS) == 0)
203 break; 165 break;
204 type = t->pkey_base_id; 166 type = mp->pkey_base_id;
205 } 167 }
206 if (pe) { 168 if (pe) {
207#ifndef OPENSSL_NO_ENGINE 169#ifndef OPENSSL_NO_ENGINE
@@ -215,14 +177,15 @@ EVP_PKEY_asn1_find(ENGINE **pe, int type)
215#endif 177#endif
216 *pe = NULL; 178 *pe = NULL;
217 } 179 }
218 return t; 180 return mp;
219} 181}
220 182
221const EVP_PKEY_ASN1_METHOD * 183const EVP_PKEY_ASN1_METHOD *
222EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len) 184EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len)
223{ 185{
224 int i;
225 const EVP_PKEY_ASN1_METHOD *ameth; 186 const EVP_PKEY_ASN1_METHOD *ameth;
187 int i;
188
226 if (len == -1) 189 if (len == -1)
227 len = strlen(str); 190 len = strlen(str);
228 if (pe) { 191 if (pe) {
@@ -242,7 +205,7 @@ EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len)
242#endif 205#endif
243 *pe = NULL; 206 *pe = NULL;
244 } 207 }
245 for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { 208 for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) {
246 ameth = EVP_PKEY_asn1_get0(i); 209 ameth = EVP_PKEY_asn1_get0(i);
247 if (ameth->pkey_flags & ASN1_PKEY_ALIAS) 210 if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
248 continue; 211 continue;
@@ -256,14 +219,15 @@ EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len)
256int 219int
257EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) 220EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
258{ 221{
259 if (app_methods == NULL) { 222 if (asn1_app_methods == NULL) {
260 app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); 223 asn1_app_methods = sk_EVP_PKEY_ASN1_METHOD_new(NULL);
261 if (!app_methods) 224 if (asn1_app_methods == NULL)
262 return 0; 225 return 0;
263 } 226 }
264 if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) 227
228 if (!sk_EVP_PKEY_ASN1_METHOD_push(asn1_app_methods, ameth))
265 return 0; 229 return 0;
266 sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); 230
267 return 1; 231 return 1;
268} 232}
269 233
@@ -273,8 +237,9 @@ EVP_PKEY_asn1_add_alias(int to, int from)
273 EVP_PKEY_ASN1_METHOD *ameth; 237 EVP_PKEY_ASN1_METHOD *ameth;
274 238
275 ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); 239 ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
276 if (!ameth) 240 if (ameth == NULL)
277 return 0; 241 return 0;
242
278 ameth->pkey_base_id = to; 243 ameth->pkey_base_id = to;
279 if (!EVP_PKEY_asn1_add0(ameth)) { 244 if (!EVP_PKEY_asn1_add0(ameth)) {
280 EVP_PKEY_asn1_free(ameth); 245 EVP_PKEY_asn1_free(ameth);