Branch data Line data Source code
1 : : /* crypto/evp/p_lib.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : #include <stdio.h>
60 : : #include "cryptlib.h"
61 : : #include <openssl/bn.h>
62 : : #include <openssl/err.h>
63 : : #include <openssl/objects.h>
64 : : #include <openssl/evp.h>
65 : : #include <openssl/asn1_mac.h>
66 : : #include <openssl/x509.h>
67 : : #ifndef OPENSSL_NO_RSA
68 : : #include <openssl/rsa.h>
69 : : #endif
70 : : #ifndef OPENSSL_NO_DSA
71 : : #include <openssl/dsa.h>
72 : : #endif
73 : : #ifndef OPENSSL_NO_DH
74 : : #include <openssl/dh.h>
75 : : #endif
76 : :
77 : : #ifndef OPENSSL_NO_ENGINE
78 : : #include <openssl/engine.h>
79 : : #endif
80 : :
81 : : #include "asn1_locl.h"
82 : :
83 : : static void EVP_PKEY_free_it(EVP_PKEY *x);
84 : :
85 : 3 : int EVP_PKEY_bits(EVP_PKEY *pkey)
86 : : {
87 [ + - ][ + - ]: 3 : if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
[ + - ]
88 : 3 : return pkey->ameth->pkey_bits(pkey);
89 : : return 0;
90 : : }
91 : :
92 : 2634 : int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
93 : : {
94 [ + - ]: 2634 : if (pkey == NULL)
95 : : return 0;
96 [ + - ][ + - ]: 2634 : if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
97 : : return -2;
98 : 2634 : return pkey->ameth->pkey_security_bits(pkey);
99 : : }
100 : :
101 : 7568 : int EVP_PKEY_size(EVP_PKEY *pkey)
102 : : {
103 [ + - ][ + - ]: 7568 : if (pkey && pkey->ameth && pkey->ameth->pkey_size)
[ + - ]
104 : 7568 : return pkey->ameth->pkey_size(pkey);
105 : : return 0;
106 : : }
107 : :
108 : 1 : int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
109 : : {
110 : : #ifndef OPENSSL_NO_DSA
111 [ - + ]: 1 : if (pkey->type == EVP_PKEY_DSA)
112 : : {
113 : 0 : int ret=pkey->save_parameters;
114 : :
115 [ # # ]: 0 : if (mode >= 0)
116 : 0 : pkey->save_parameters=mode;
117 : 0 : return(ret);
118 : : }
119 : : #endif
120 : : #ifndef OPENSSL_NO_EC
121 [ - + ]: 1 : if (pkey->type == EVP_PKEY_EC)
122 : : {
123 : 0 : int ret = pkey->save_parameters;
124 : :
125 [ # # ]: 0 : if (mode >= 0)
126 : 0 : pkey->save_parameters = mode;
127 : 0 : return(ret);
128 : : }
129 : : #endif
130 : : return(0);
131 : : }
132 : :
133 : 1047 : int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
134 : : {
135 [ - + ]: 1047 : if (to->type != from->type)
136 : : {
137 : 0 : EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES);
138 : 0 : goto err;
139 : : }
140 : :
141 [ - + ]: 1047 : if (EVP_PKEY_missing_parameters(from))
142 : : {
143 : 0 : EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
144 : 0 : goto err;
145 : : }
146 [ + - ][ + + ]: 1047 : if (from->ameth && from->ameth->param_copy)
147 : 5 : return from->ameth->param_copy(to, from);
148 : : err:
149 : : return 0;
150 : : }
151 : :
152 : 4354 : int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
153 : : {
154 [ + - ][ + + ]: 4354 : if (pkey->ameth && pkey->ameth->param_missing)
155 : 56 : return pkey->ameth->param_missing(pkey);
156 : : return 0;
157 : : }
158 : :
159 : 8 : int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
160 : : {
161 [ + - ]: 8 : if (a->type != b->type)
162 : : return -1;
163 [ + - ][ + - ]: 8 : if (a->ameth && a->ameth->param_cmp)
164 : 8 : return a->ameth->param_cmp(a, b);
165 : : return -2;
166 : : }
167 : :
168 : 1131 : int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
169 : : {
170 [ + - ]: 1131 : if (a->type != b->type)
171 : : return -1;
172 : :
173 [ + - ]: 1131 : if (a->ameth)
174 : : {
175 : : int ret;
176 : : /* Compare parameters if the algorithm has them */
177 [ + + ]: 1131 : if (a->ameth->param_cmp)
178 : : {
179 : 37 : ret = a->ameth->param_cmp(a, b);
180 [ + - ]: 37 : if (ret <= 0)
181 : : return ret;
182 : : }
183 : :
184 [ + - ]: 1131 : if (a->ameth->pub_cmp)
185 : 1131 : return a->ameth->pub_cmp(a, b);
186 : : }
187 : :
188 : : return -2;
189 : : }
190 : :
191 : 21887 : EVP_PKEY *EVP_PKEY_new(void)
192 : : {
193 : : EVP_PKEY *ret;
194 : :
195 : 21887 : ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
196 [ - + ]: 21887 : if (ret == NULL)
197 : : {
198 : 0 : EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE);
199 : 0 : return(NULL);
200 : : }
201 : 21887 : ret->type=EVP_PKEY_NONE;
202 : 21887 : ret->save_type=EVP_PKEY_NONE;
203 : 21887 : ret->references=1;
204 : 21887 : ret->ameth=NULL;
205 : 21887 : ret->engine=NULL;
206 : 21887 : ret->pkey.ptr=NULL;
207 : 21887 : ret->attributes=NULL;
208 : 21887 : ret->save_parameters=1;
209 : 21887 : return(ret);
210 : : }
211 : :
212 : : /* Setup a public key ASN1 method and ENGINE from a NID or a string.
213 : : * If pkey is NULL just return 1 or 0 if the algorithm exists.
214 : : */
215 : :
216 : 26779 : static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
217 : : {
218 : : const EVP_PKEY_ASN1_METHOD *ameth;
219 : 26779 : ENGINE *e = NULL;
220 [ + - ]: 26779 : if (pkey)
221 : : {
222 [ - + ]: 26779 : if (pkey->pkey.ptr)
223 : 0 : EVP_PKEY_free_it(pkey);
224 : : /* If key type matches and a method exists then this
225 : : * lookup has succeeded once so just indicate success.
226 : : */
227 [ + + ][ - + ]: 26779 : if ((type == pkey->save_type) && pkey->ameth)
228 : : return 1;
229 : : #ifndef OPENSSL_NO_ENGINE
230 : : /* If we have an ENGINE release it */
231 [ - + ]: 21889 : if (pkey->engine)
232 : : {
233 : 0 : ENGINE_finish(pkey->engine);
234 : 0 : pkey->engine = NULL;
235 : : }
236 : : #endif
237 : : }
238 [ - + ]: 21889 : if (str)
239 : 0 : ameth = EVP_PKEY_asn1_find_str(&e, str, len);
240 : : else
241 : 21889 : ameth = EVP_PKEY_asn1_find(&e, type);
242 : : #ifndef OPENSSL_NO_ENGINE
243 [ - + ][ # # ]: 21889 : if (!pkey && e)
244 : 0 : ENGINE_finish(e);
245 : : #endif
246 [ - + ]: 21889 : if (!ameth)
247 : : {
248 : 0 : EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
249 : 0 : return 0;
250 : : }
251 [ + - ]: 21889 : if (pkey)
252 : : {
253 : 21889 : pkey->ameth = ameth;
254 : 21889 : pkey->engine = e;
255 : :
256 : 21889 : pkey->type = pkey->ameth->pkey_id;
257 : 21889 : pkey->save_type=type;
258 : : }
259 : : return 1;
260 : : }
261 : :
262 : 26779 : int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
263 : : {
264 : 26779 : return pkey_set_type(pkey, type, NULL, -1);
265 : : }
266 : :
267 : 0 : int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
268 : : {
269 : 0 : return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
270 : : }
271 : :
272 : 21887 : int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
273 : : {
274 [ + - ]: 21887 : if (!EVP_PKEY_set_type(pkey, type))
275 : : return 0;
276 : 21887 : pkey->pkey.ptr=key;
277 : 21887 : return (key != NULL);
278 : : }
279 : :
280 : 7 : void *EVP_PKEY_get0(EVP_PKEY *pkey)
281 : : {
282 : 7 : return pkey->pkey.ptr;
283 : : }
284 : :
285 : : #ifndef OPENSSL_NO_RSA
286 : 0 : int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
287 : : {
288 : 0 : int ret = EVP_PKEY_assign_RSA(pkey, key);
289 [ # # ]: 0 : if(ret)
290 : 0 : RSA_up_ref(key);
291 : 0 : return ret;
292 : : }
293 : :
294 : 6 : RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
295 : : {
296 [ - + ]: 6 : if(pkey->type != EVP_PKEY_RSA) {
297 : 0 : EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
298 : 0 : return NULL;
299 : : }
300 : 6 : RSA_up_ref(pkey->pkey.rsa);
301 : 6 : return pkey->pkey.rsa;
302 : : }
303 : : #endif
304 : :
305 : : #ifndef OPENSSL_NO_DSA
306 : 2 : int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
307 : : {
308 : 2 : int ret = EVP_PKEY_assign_DSA(pkey, key);
309 [ + - ]: 2 : if(ret)
310 : 2 : DSA_up_ref(key);
311 : 2 : return ret;
312 : : }
313 : :
314 : 0 : DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
315 : : {
316 [ # # ]: 0 : if(pkey->type != EVP_PKEY_DSA) {
317 : 0 : EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
318 : 0 : return NULL;
319 : : }
320 : 0 : DSA_up_ref(pkey->pkey.dsa);
321 : 0 : return pkey->pkey.dsa;
322 : : }
323 : : #endif
324 : :
325 : : #ifndef OPENSSL_NO_EC
326 : :
327 : 3 : int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
328 : : {
329 : 3 : int ret = EVP_PKEY_assign_EC_KEY(pkey,key);
330 [ + - ]: 3 : if (ret)
331 : 3 : EC_KEY_up_ref(key);
332 : 3 : return ret;
333 : : }
334 : :
335 : 0 : EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
336 : : {
337 [ # # ]: 0 : if (pkey->type != EVP_PKEY_EC)
338 : : {
339 : 0 : EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
340 : 0 : return NULL;
341 : : }
342 : 0 : EC_KEY_up_ref(pkey->pkey.ec);
343 : 0 : return pkey->pkey.ec;
344 : : }
345 : : #endif
346 : :
347 : :
348 : : #ifndef OPENSSL_NO_DH
349 : :
350 : 0 : int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
351 : : {
352 : 0 : int ret = EVP_PKEY_assign_DH(pkey, key);
353 [ # # ]: 0 : if(ret)
354 : 0 : DH_up_ref(key);
355 : 0 : return ret;
356 : : }
357 : :
358 : 0 : DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
359 : : {
360 [ # # ]: 0 : if(pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
361 : 0 : EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
362 : 0 : return NULL;
363 : : }
364 : 0 : DH_up_ref(pkey->pkey.dh);
365 : 0 : return pkey->pkey.dh;
366 : : }
367 : : #endif
368 : :
369 : 852 : int EVP_PKEY_type(int type)
370 : : {
371 : : int ret;
372 : : const EVP_PKEY_ASN1_METHOD *ameth;
373 : : ENGINE *e;
374 : 852 : ameth = EVP_PKEY_asn1_find(&e, type);
375 [ + - ]: 852 : if (ameth)
376 : 852 : ret = ameth->pkey_id;
377 : : else
378 : : ret = NID_undef;
379 : : #ifndef OPENSSL_NO_ENGINE
380 [ - + ]: 852 : if (e)
381 : 0 : ENGINE_finish(e);
382 : : #endif
383 : 852 : return ret;
384 : : }
385 : :
386 : 37 : int EVP_PKEY_id(const EVP_PKEY *pkey)
387 : : {
388 : 37 : return pkey->type;
389 : : }
390 : :
391 : 0 : int EVP_PKEY_base_id(const EVP_PKEY *pkey)
392 : : {
393 : 0 : return EVP_PKEY_type(pkey->type);
394 : : }
395 : :
396 : 265290 : void EVP_PKEY_free(EVP_PKEY *x)
397 : : {
398 : : int i;
399 : :
400 [ + + ]: 265290 : if (x == NULL) return;
401 : :
402 : 261444 : i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY);
403 : : #ifdef REF_PRINT
404 : : REF_PRINT("EVP_PKEY",x);
405 : : #endif
406 [ + + ]: 261444 : if (i > 0) return;
407 : : #ifdef REF_CHECK
408 : : if (i < 0)
409 : : {
410 : : fprintf(stderr,"EVP_PKEY_free, bad reference count\n");
411 : : abort();
412 : : }
413 : : #endif
414 : 21880 : EVP_PKEY_free_it(x);
415 [ - + ]: 21880 : if (x->attributes)
416 : 0 : sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
417 : 21880 : OPENSSL_free(x);
418 : : }
419 : :
420 : 21880 : static void EVP_PKEY_free_it(EVP_PKEY *x)
421 : : {
422 [ + - ][ + - ]: 21880 : if (x->ameth && x->ameth->pkey_free)
423 : : {
424 : 21880 : x->ameth->pkey_free(x);
425 : 21880 : x->pkey.ptr = NULL;
426 : : }
427 : : #ifndef OPENSSL_NO_ENGINE
428 [ - + ]: 21880 : if (x->engine)
429 : : {
430 : 0 : ENGINE_finish(x->engine);
431 : 0 : x->engine = NULL;
432 : : }
433 : : #endif
434 : 21880 : }
435 : :
436 : 0 : static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
437 : : const char *kstr)
438 : : {
439 : 0 : BIO_indent(out, indent, 128);
440 : 0 : BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
441 : : kstr, OBJ_nid2ln(pkey->type));
442 : 0 : return 1;
443 : : }
444 : :
445 : 40 : int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
446 : : int indent, ASN1_PCTX *pctx)
447 : : {
448 [ + - ][ + - ]: 40 : if (pkey->ameth && pkey->ameth->pub_print)
449 : 40 : return pkey->ameth->pub_print(out, pkey, indent, pctx);
450 : :
451 : 0 : return unsup_alg(out, pkey, indent, "Public Key");
452 : : }
453 : :
454 : 2 : int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
455 : : int indent, ASN1_PCTX *pctx)
456 : : {
457 [ + - ][ + - ]: 2 : if (pkey->ameth && pkey->ameth->priv_print)
458 : 2 : return pkey->ameth->priv_print(out, pkey, indent, pctx);
459 : :
460 : 0 : return unsup_alg(out, pkey, indent, "Private Key");
461 : : }
462 : :
463 : 0 : int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
464 : : int indent, ASN1_PCTX *pctx)
465 : : {
466 [ # # ][ # # ]: 0 : if (pkey->ameth && pkey->ameth->param_print)
467 : 0 : return pkey->ameth->param_print(out, pkey, indent, pctx);
468 : 0 : return unsup_alg(out, pkey, indent, "Parameters");
469 : : }
470 : :
471 : 90 : int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
472 : : {
473 [ + - ][ + - ]: 90 : if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
474 : : return -2;
475 : 90 : return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
476 : : 0, pnid);
477 : : }
478 : :
|