summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp/p_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/evp/p_lib.c')
-rw-r--r--src/lib/libcrypto/evp/p_lib.c394
1 files changed, 179 insertions, 215 deletions
diff --git a/src/lib/libcrypto/evp/p_lib.c b/src/lib/libcrypto/evp/p_lib.c
index 22155ecf62..1916c61699 100644
--- a/src/lib/libcrypto/evp/p_lib.c
+++ b/src/lib/libcrypto/evp/p_lib.c
@@ -74,66 +74,26 @@
74#include <openssl/dh.h> 74#include <openssl/dh.h>
75#endif 75#endif
76 76
77#ifndef OPENSSL_NO_ENGINE
78#include <openssl/engine.h>
79#endif
80
81#include "asn1_locl.h"
82
77static void EVP_PKEY_free_it(EVP_PKEY *x); 83static void EVP_PKEY_free_it(EVP_PKEY *x);
78 84
79int EVP_PKEY_bits(EVP_PKEY *pkey) 85int EVP_PKEY_bits(EVP_PKEY *pkey)
80 { 86 {
81 if (0) 87 if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
82 return 0; 88 return pkey->ameth->pkey_bits(pkey);
83#ifndef OPENSSL_NO_RSA 89 return 0;
84 else if (pkey->type == EVP_PKEY_RSA)
85 return(BN_num_bits(pkey->pkey.rsa->n));
86#endif
87#ifndef OPENSSL_NO_DSA
88 else if (pkey->type == EVP_PKEY_DSA)
89 return(BN_num_bits(pkey->pkey.dsa->p));
90#endif
91#ifndef OPENSSL_NO_EC
92 else if (pkey->type == EVP_PKEY_EC)
93 {
94 BIGNUM *order = BN_new();
95 const EC_GROUP *group;
96 int ret;
97
98 if (!order)
99 {
100 ERR_clear_error();
101 return 0;
102 }
103 group = EC_KEY_get0_group(pkey->pkey.ec);
104 if (!EC_GROUP_get_order(group, order, NULL))
105 {
106 ERR_clear_error();
107 return 0;
108 }
109
110 ret = BN_num_bits(order);
111 BN_free(order);
112 return ret;
113 }
114#endif
115 return(0);
116 } 90 }
117 91
118int EVP_PKEY_size(EVP_PKEY *pkey) 92int EVP_PKEY_size(EVP_PKEY *pkey)
119 { 93 {
120 if (pkey == NULL) 94 if (pkey && pkey->ameth && pkey->ameth->pkey_size)
121 return(0); 95 return pkey->ameth->pkey_size(pkey);
122#ifndef OPENSSL_NO_RSA 96 return 0;
123 if (pkey->type == EVP_PKEY_RSA)
124 return(RSA_size(pkey->pkey.rsa));
125 else
126#endif
127#ifndef OPENSSL_NO_DSA
128 if (pkey->type == EVP_PKEY_DSA)
129 return(DSA_size(pkey->pkey.dsa));
130#endif
131#ifndef OPENSSL_NO_ECDSA
132 if (pkey->type == EVP_PKEY_EC)
133 return(ECDSA_size(pkey->pkey.ec));
134#endif
135
136 return(0);
137 } 97 }
138 98
139int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) 99int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
@@ -174,88 +134,26 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
174 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS); 134 EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
175 goto err; 135 goto err;
176 } 136 }
177#ifndef OPENSSL_NO_DSA 137 if (from->ameth && from->ameth->param_copy)
178 if (to->type == EVP_PKEY_DSA) 138 return from->ameth->param_copy(to, from);
179 {
180 BIGNUM *a;
181
182 if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err;
183 if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p);
184 to->pkey.dsa->p=a;
185
186 if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err;
187 if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q);
188 to->pkey.dsa->q=a;
189
190 if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err;
191 if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g);
192 to->pkey.dsa->g=a;
193 }
194#endif
195#ifndef OPENSSL_NO_EC
196 if (to->type == EVP_PKEY_EC)
197 {
198 EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
199 if (group == NULL)
200 goto err;
201 if (EC_KEY_set_group(to->pkey.ec, group) == 0)
202 goto err;
203 EC_GROUP_free(group);
204 }
205#endif
206 return(1);
207err: 139err:
208 return(0); 140 return 0;
209 } 141 }
210 142
211int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) 143int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
212 { 144 {
213#ifndef OPENSSL_NO_DSA 145 if (pkey->ameth && pkey->ameth->param_missing)
214 if (pkey->type == EVP_PKEY_DSA) 146 return pkey->ameth->param_missing(pkey);
215 { 147 return 0;
216 DSA *dsa;
217
218 dsa=pkey->pkey.dsa;
219 if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
220 return(1);
221 }
222#endif
223#ifndef OPENSSL_NO_EC
224 if (pkey->type == EVP_PKEY_EC)
225 {
226 if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
227 return(1);
228 }
229#endif
230
231 return(0);
232 } 148 }
233 149
234int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 150int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
235 { 151 {
236#ifndef OPENSSL_NO_DSA 152 if (a->type != b->type)
237 if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA)) 153 return -1;
238 { 154 if (a->ameth && a->ameth->param_cmp)
239 if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || 155 return a->ameth->param_cmp(a, b);
240 BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || 156 return -2;
241 BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
242 return(0);
243 else
244 return(1);
245 }
246#endif
247#ifndef OPENSSL_NO_EC
248 if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC)
249 {
250 const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
251 *group_b = EC_KEY_get0_group(b->pkey.ec);
252 if (EC_GROUP_cmp(group_a, group_b, NULL))
253 return 0;
254 else
255 return 1;
256 }
257#endif
258 return(-1);
259 } 157 }
260 158
261int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 159int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
@@ -263,51 +161,22 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
263 if (a->type != b->type) 161 if (a->type != b->type)
264 return -1; 162 return -1;
265 163
266 if (EVP_PKEY_cmp_parameters(a, b) == 0) 164 if (a->ameth)
267 return 0;
268
269 switch (a->type)
270 { 165 {
271#ifndef OPENSSL_NO_RSA 166 int ret;
272 case EVP_PKEY_RSA: 167 /* Compare parameters if the algorithm has them */
273 if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 168 if (a->ameth->param_cmp)
274 || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
275 return 0;
276 break;
277#endif
278#ifndef OPENSSL_NO_DSA
279 case EVP_PKEY_DSA:
280 if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
281 return 0;
282 break;
283#endif
284#ifndef OPENSSL_NO_EC
285 case EVP_PKEY_EC:
286 {
287 int r;
288 const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
289 const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
290 *pb = EC_KEY_get0_public_key(b->pkey.ec);
291 r = EC_POINT_cmp(group, pa, pb, NULL);
292 if (r != 0)
293 { 169 {
294 if (r == 1) 170 ret = a->ameth->param_cmp(a, b);
295 return 0; 171 if (ret <= 0)
296 else 172 return ret;
297 return -2;
298 } 173 }
299 } 174
300 break; 175 if (a->ameth->pub_cmp)
301#endif 176 return a->ameth->pub_cmp(a, b);
302#ifndef OPENSSL_NO_DH
303 case EVP_PKEY_DH:
304 return -2;
305#endif
306 default:
307 return -2;
308 } 177 }
309 178
310 return 1; 179 return -2;
311 } 180 }
312 181
313EVP_PKEY *EVP_PKEY_new(void) 182EVP_PKEY *EVP_PKEY_new(void)
@@ -321,22 +190,87 @@ EVP_PKEY *EVP_PKEY_new(void)
321 return(NULL); 190 return(NULL);
322 } 191 }
323 ret->type=EVP_PKEY_NONE; 192 ret->type=EVP_PKEY_NONE;
193 ret->save_type=EVP_PKEY_NONE;
324 ret->references=1; 194 ret->references=1;
195 ret->ameth=NULL;
196 ret->engine=NULL;
325 ret->pkey.ptr=NULL; 197 ret->pkey.ptr=NULL;
326 ret->attributes=NULL; 198 ret->attributes=NULL;
327 ret->save_parameters=1; 199 ret->save_parameters=1;
328 return(ret); 200 return(ret);
329 } 201 }
330 202
331int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key) 203/* Setup a public key ASN1 method and ENGINE from a NID or a string.
204 * If pkey is NULL just return 1 or 0 if the algorithm exists.
205 */
206
207static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
332 { 208 {
333 if (pkey == NULL) return(0); 209 const EVP_PKEY_ASN1_METHOD *ameth;
334 if (pkey->pkey.ptr != NULL) 210 ENGINE *e = NULL;
335 EVP_PKEY_free_it(pkey); 211 if (pkey)
336 pkey->type=EVP_PKEY_type(type); 212 {
337 pkey->save_type=type; 213 if (pkey->pkey.ptr)
214 EVP_PKEY_free_it(pkey);
215 /* If key type matches and a method exists then this
216 * lookup has succeeded once so just indicate success.
217 */
218 if ((type == pkey->save_type) && pkey->ameth)
219 return 1;
220#ifndef OPENSSL_NO_ENGINE
221 /* If we have an ENGINE release it */
222 if (pkey->engine)
223 {
224 ENGINE_finish(pkey->engine);
225 pkey->engine = NULL;
226 }
227#endif
228 }
229 if (str)
230 ameth = EVP_PKEY_asn1_find_str(&e, str, len);
231 else
232 ameth = EVP_PKEY_asn1_find(&e, type);
233#ifndef OPENSSL_NO_ENGINE
234 if (!pkey && e)
235 ENGINE_finish(e);
236#endif
237 if (!ameth)
238 {
239 EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
240 return 0;
241 }
242 if (pkey)
243 {
244 pkey->ameth = ameth;
245 pkey->engine = e;
246
247 pkey->type = pkey->ameth->pkey_id;
248 pkey->save_type=type;
249 }
250 return 1;
251 }
252
253int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
254 {
255 return pkey_set_type(pkey, type, NULL, -1);
256 }
257
258int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
259 {
260 return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
261 }
262
263int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
264 {
265 if (!EVP_PKEY_set_type(pkey, type))
266 return 0;
338 pkey->pkey.ptr=key; 267 pkey->pkey.ptr=key;
339 return(key != NULL); 268 return (key != NULL);
269 }
270
271void *EVP_PKEY_get0(EVP_PKEY *pkey)
272 {
273 return pkey->pkey.ptr;
340 } 274 }
341 275
342#ifndef OPENSSL_NO_RSA 276#ifndef OPENSSL_NO_RSA
@@ -425,24 +359,29 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
425 359
426int EVP_PKEY_type(int type) 360int EVP_PKEY_type(int type)
427 { 361 {
428 switch (type) 362 int ret;
429 { 363 const EVP_PKEY_ASN1_METHOD *ameth;
430 case EVP_PKEY_RSA: 364 ENGINE *e;
431 case EVP_PKEY_RSA2: 365 ameth = EVP_PKEY_asn1_find(&e, type);
432 return(EVP_PKEY_RSA); 366 if (ameth)
433 case EVP_PKEY_DSA: 367 ret = ameth->pkey_id;
434 case EVP_PKEY_DSA1: 368 else
435 case EVP_PKEY_DSA2: 369 ret = NID_undef;
436 case EVP_PKEY_DSA3: 370#ifndef OPENSSL_NO_ENGINE
437 case EVP_PKEY_DSA4: 371 if (e)
438 return(EVP_PKEY_DSA); 372 ENGINE_finish(e);
439 case EVP_PKEY_DH: 373#endif
440 return(EVP_PKEY_DH); 374 return ret;
441 case EVP_PKEY_EC: 375 }
442 return(EVP_PKEY_EC); 376
443 default: 377int EVP_PKEY_id(const EVP_PKEY *pkey)
444 return(NID_undef); 378 {
445 } 379 return pkey->type;
380 }
381
382int EVP_PKEY_base_id(const EVP_PKEY *pkey)
383 {
384 return EVP_PKEY_type(pkey->type);
446 } 385 }
447 386
448void EVP_PKEY_free(EVP_PKEY *x) 387void EVP_PKEY_free(EVP_PKEY *x)
@@ -471,32 +410,57 @@ void EVP_PKEY_free(EVP_PKEY *x)
471 410
472static void EVP_PKEY_free_it(EVP_PKEY *x) 411static void EVP_PKEY_free_it(EVP_PKEY *x)
473 { 412 {
474 switch (x->type) 413 if (x->ameth && x->ameth->pkey_free)
414 x->ameth->pkey_free(x);
415#ifndef OPENSSL_NO_ENGINE
416 if (x->engine)
475 { 417 {
476#ifndef OPENSSL_NO_RSA 418 ENGINE_finish(x->engine);
477 case EVP_PKEY_RSA: 419 x->engine = NULL;
478 case EVP_PKEY_RSA2:
479 RSA_free(x->pkey.rsa);
480 break;
481#endif
482#ifndef OPENSSL_NO_DSA
483 case EVP_PKEY_DSA:
484 case EVP_PKEY_DSA2:
485 case EVP_PKEY_DSA3:
486 case EVP_PKEY_DSA4:
487 DSA_free(x->pkey.dsa);
488 break;
489#endif
490#ifndef OPENSSL_NO_EC
491 case EVP_PKEY_EC:
492 EC_KEY_free(x->pkey.ec);
493 break;
494#endif
495#ifndef OPENSSL_NO_DH
496 case EVP_PKEY_DH:
497 DH_free(x->pkey.dh);
498 break;
499#endif
500 } 420 }
421#endif
422 }
423
424static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
425 const char *kstr)
426 {
427 BIO_indent(out, indent, 128);
428 BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
429 kstr, OBJ_nid2ln(pkey->type));
430 return 1;
431 }
432
433int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
434 int indent, ASN1_PCTX *pctx)
435 {
436 if (pkey->ameth && pkey->ameth->pub_print)
437 return pkey->ameth->pub_print(out, pkey, indent, pctx);
438
439 return unsup_alg(out, pkey, indent, "Public Key");
440 }
441
442int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
443 int indent, ASN1_PCTX *pctx)
444 {
445 if (pkey->ameth && pkey->ameth->priv_print)
446 return pkey->ameth->priv_print(out, pkey, indent, pctx);
447
448 return unsup_alg(out, pkey, indent, "Private Key");
449 }
450
451int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
452 int indent, ASN1_PCTX *pctx)
453 {
454 if (pkey->ameth && pkey->ameth->param_print)
455 return pkey->ameth->param_print(out, pkey, indent, pctx);
456 return unsup_alg(out, pkey, indent, "Parameters");
457 }
458
459int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
460 {
461 if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
462 return -2;
463 return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
464 0, pnid);
501 } 465 }
502 466