GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/evp/p_lib.c Lines: 125 183 68.3 %
Date: 2017-11-13 Branches: 59 120 49.2 %

Line Branch Exec Source
1
/* $OpenBSD: p_lib.c,v 1.17 2017/01/29 17:49:23 beck Exp $ */
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
61
#include <openssl/opensslconf.h>
62
63
#include <openssl/bn.h>
64
#include <openssl/err.h>
65
#include <openssl/evp.h>
66
#include <openssl/objects.h>
67
#include <openssl/x509.h>
68
69
#ifndef OPENSSL_NO_DH
70
#include <openssl/dh.h>
71
#endif
72
#ifndef OPENSSL_NO_DSA
73
#include <openssl/dsa.h>
74
#endif
75
#ifndef OPENSSL_NO_RSA
76
#include <openssl/rsa.h>
77
#endif
78
79
#ifndef OPENSSL_NO_ENGINE
80
#include <openssl/engine.h>
81
#endif
82
83
#include "asn1_locl.h"
84
85
static void EVP_PKEY_free_it(EVP_PKEY *x);
86
87
int
88
EVP_PKEY_bits(EVP_PKEY *pkey)
89
{
90

64
	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
91
16
		return pkey->ameth->pkey_bits(pkey);
92
	return 0;
93
16
}
94
95
int
96
EVP_PKEY_size(EVP_PKEY *pkey)
97
{
98

11928
	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
99
2982
		return pkey->ameth->pkey_size(pkey);
100
	return 0;
101
2982
}
102
103
int
104
EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
105
{
106
#ifndef OPENSSL_NO_DSA
107
4
	if (pkey->type == EVP_PKEY_DSA) {
108
		int ret = pkey->save_parameters;
109
110
		if (mode >= 0)
111
			pkey->save_parameters = mode;
112
		return (ret);
113
	}
114
#endif
115
#ifndef OPENSSL_NO_EC
116
2
	if (pkey->type == EVP_PKEY_EC) {
117
		int ret = pkey->save_parameters;
118
119
		if (mode >= 0)
120
			pkey->save_parameters = mode;
121
		return (ret);
122
	}
123
#endif
124
2
	return (0);
125
2
}
126
127
int
128
EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
129
{
130
612
	if (to->type != from->type) {
131
		EVPerror(EVP_R_DIFFERENT_KEY_TYPES);
132
		goto err;
133
	}
134
135
306
	if (EVP_PKEY_missing_parameters(from)) {
136
		EVPerror(EVP_R_MISSING_PARAMETERS);
137
		goto err;
138
	}
139

612
	if (from->ameth && from->ameth->param_copy)
140
8
		return from->ameth->param_copy(to, from);
141
142
err:
143
298
	return 0;
144
306
}
145
146
int
147
EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
148
{
149

4758
	if (pkey->ameth && pkey->ameth->param_missing)
150
8
		return pkey->ameth->param_missing(pkey);
151
1578
	return 0;
152
1586
}
153
154
int
155
EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
156
{
157
	if (a->type != b->type)
158
		return -1;
159
	if (a->ameth && a->ameth->param_cmp)
160
		return a->ameth->param_cmp(a, b);
161
	return -2;
162
}
163
164
int
165
EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
166
{
167
682
	if (a->type != b->type)
168
		return -1;
169
170
341
	if (a->ameth) {
171
		int ret;
172
		/* Compare parameters if the algorithm has them */
173
341
		if (a->ameth->param_cmp) {
174
			ret = a->ameth->param_cmp(a, b);
175
			if (ret <= 0)
176
				return ret;
177
		}
178
179
341
		if (a->ameth->pub_cmp)
180
341
			return a->ameth->pub_cmp(a, b);
181
	}
182
183
	return -2;
184
341
}
185
186
EVP_PKEY *
187
EVP_PKEY_new(void)
188
{
189
	EVP_PKEY *ret;
190
191
143724
	ret = malloc(sizeof(EVP_PKEY));
192
71862
	if (ret == NULL) {
193
		EVPerror(ERR_R_MALLOC_FAILURE);
194
		return (NULL);
195
	}
196
71862
	ret->type = EVP_PKEY_NONE;
197
71862
	ret->save_type = EVP_PKEY_NONE;
198
71862
	ret->references = 1;
199
71862
	ret->ameth = NULL;
200
71862
	ret->engine = NULL;
201
71862
	ret->pkey.ptr = NULL;
202
71862
	ret->attributes = NULL;
203
71862
	ret->save_parameters = 1;
204
71862
	return (ret);
205
71862
}
206
207
/* Setup a public key ASN1 method and ENGINE from a NID or a string.
208
 * If pkey is NULL just return 1 or 0 if the algorithm exists.
209
 */
210
211
static int
212
pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
213
{
214
	const EVP_PKEY_ASN1_METHOD *ameth;
215
148692
	ENGINE *e = NULL;
216
74346
	if (pkey) {
217
74346
		if (pkey->pkey.ptr)
218
			EVP_PKEY_free_it(pkey);
219
		/* If key type matches and a method exists then this
220
		 * lookup has succeeded once so just indicate success.
221
		 */
222

76830
		if ((type == pkey->save_type) && pkey->ameth)
223
2470
			return 1;
224
#ifndef OPENSSL_NO_ENGINE
225
		/* If we have an ENGINE release it */
226
71876
		if (pkey->engine) {
227
			ENGINE_finish(pkey->engine);
228
			pkey->engine = NULL;
229
		}
230
#endif
231
	}
232
71876
	if (str)
233
14
		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
234
	else
235
71862
		ameth = EVP_PKEY_asn1_find(&e, type);
236
#ifndef OPENSSL_NO_ENGINE
237
71876
	if (!pkey && e)
238
		ENGINE_finish(e);
239
#endif
240
71876
	if (!ameth) {
241
		EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
242
		return 0;
243
	}
244
71876
	if (pkey) {
245
71876
		pkey->ameth = ameth;
246
71876
		pkey->engine = e;
247
248
71876
		pkey->type = pkey->ameth->pkey_id;
249
71876
		pkey->save_type = type;
250
71876
	}
251
71876
	return 1;
252
74346
}
253
254
int
255
EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
256
{
257
148664
	return pkey_set_type(pkey, type, NULL, -1);
258
}
259
260
int
261
EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
262
{
263
28
	return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
264
}
265
266
int
267
EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
268
{
269
143724
	if (!EVP_PKEY_set_type(pkey, type))
270
		return 0;
271
71862
	pkey->pkey.ptr = key;
272
71862
	return (key != NULL);
273
71862
}
274
275
void *
276
EVP_PKEY_get0(EVP_PKEY *pkey)
277
{
278
48
	return pkey->pkey.ptr;
279
}
280
281
#ifndef OPENSSL_NO_RSA
282
int
283
EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
284
{
285
4
	int ret = EVP_PKEY_assign_RSA(pkey, key);
286
2
	if (ret)
287
2
		RSA_up_ref(key);
288
2
	return ret;
289
}
290
291
RSA *
292
EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
293
{
294
36
	if (pkey->type != EVP_PKEY_RSA) {
295
		EVPerror(EVP_R_EXPECTING_AN_RSA_KEY);
296
		return NULL;
297
	}
298
18
	RSA_up_ref(pkey->pkey.rsa);
299
18
	return pkey->pkey.rsa;
300
18
}
301
#endif
302
303
#ifndef OPENSSL_NO_DSA
304
int
305
EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
306
{
307
16
	int ret = EVP_PKEY_assign_DSA(pkey, key);
308
8
	if (ret)
309
8
		DSA_up_ref(key);
310
8
	return ret;
311
}
312
313
DSA *
314
EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
315
{
316
4
	if (pkey->type != EVP_PKEY_DSA) {
317
		EVPerror(EVP_R_EXPECTING_A_DSA_KEY);
318
		return NULL;
319
	}
320
2
	DSA_up_ref(pkey->pkey.dsa);
321
2
	return pkey->pkey.dsa;
322
2
}
323
#endif
324
325
#ifndef OPENSSL_NO_EC
326
327
int
328
EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
329
{
330
368
	int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
331
184
	if (ret)
332
184
		EC_KEY_up_ref(key);
333
184
	return ret;
334
}
335
336
EC_KEY *
337
EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
338
{
339
368
	if (pkey->type != EVP_PKEY_EC) {
340
		EVPerror(EVP_R_EXPECTING_A_EC_KEY);
341
		return NULL;
342
	}
343
184
	EC_KEY_up_ref(pkey->pkey.ec);
344
184
	return pkey->pkey.ec;
345
184
}
346
#endif
347
348
349
#ifndef OPENSSL_NO_DH
350
351
int
352
EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
353
{
354
	int ret = EVP_PKEY_assign_DH(pkey, key);
355
	if (ret)
356
		DH_up_ref(key);
357
	return ret;
358
}
359
360
DH *
361
EVP_PKEY_get1_DH(EVP_PKEY *pkey)
362
{
363
	if (pkey->type != EVP_PKEY_DH) {
364
		EVPerror(EVP_R_EXPECTING_A_DH_KEY);
365
		return NULL;
366
	}
367
	DH_up_ref(pkey->pkey.dh);
368
	return pkey->pkey.dh;
369
}
370
#endif
371
372
int
373
EVP_PKEY_type(int type)
374
{
375
	int ret;
376
	const EVP_PKEY_ASN1_METHOD *ameth;
377
2708
	ENGINE *e;
378
1354
	ameth = EVP_PKEY_asn1_find(&e, type);
379
1354
	if (ameth)
380
1354
		ret = ameth->pkey_id;
381
	else
382
		ret = NID_undef;
383
#ifndef OPENSSL_NO_ENGINE
384
1354
	if (e)
385
		ENGINE_finish(e);
386
#endif
387
1354
	return ret;
388
1354
}
389
390
int
391
EVP_PKEY_id(const EVP_PKEY *pkey)
392
{
393
8
	return pkey->type;
394
}
395
396
int
397
EVP_PKEY_base_id(const EVP_PKEY *pkey)
398
{
399
4
	return EVP_PKEY_type(pkey->type);
400
}
401
402
void
403
EVP_PKEY_free(EVP_PKEY *x)
404
{
405
	int i;
406
407
1518902
	if (x == NULL)
408
421436
		return;
409
410
338015
	i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
411
338015
	if (i > 0)
412
266159
		return;
413
414
71856
	EVP_PKEY_free_it(x);
415
71856
	if (x->attributes)
416
		sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
417
71856
	free(x);
418
831307
}
419
420
static void
421
EVP_PKEY_free_it(EVP_PKEY *x)
422
{
423

215568
	if (x->ameth && x->ameth->pkey_free) {
424
71856
		x->ameth->pkey_free(x);
425
71856
		x->pkey.ptr = NULL;
426
71856
	}
427
#ifndef OPENSSL_NO_ENGINE
428
71856
	if (x->engine) {
429
		ENGINE_finish(x->engine);
430
		x->engine = NULL;
431
	}
432
#endif
433
71856
}
434
435
static int
436
unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
437
{
438
	BIO_indent(out, indent, 128);
439
	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
440
	    kstr, OBJ_nid2ln(pkey->type));
441
	return 1;
442
}
443
444
int
445
EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
446
    ASN1_PCTX *pctx)
447
{
448

105
	if (pkey->ameth && pkey->ameth->pub_print)
449
35
		return pkey->ameth->pub_print(out, pkey, indent, pctx);
450
451
	return unsup_alg(out, pkey, indent, "Public Key");
452
35
}
453
454
int
455
EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
456
    ASN1_PCTX *pctx)
457
{
458

594
	if (pkey->ameth && pkey->ameth->priv_print)
459
198
		return pkey->ameth->priv_print(out, pkey, indent, pctx);
460
461
	return unsup_alg(out, pkey, indent, "Private Key");
462
198
}
463
464
int
465
EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
466
    ASN1_PCTX *pctx)
467
{
468

18
	if (pkey->ameth && pkey->ameth->param_print)
469
6
		return pkey->ameth->param_print(out, pkey, indent, pctx);
470
	return unsup_alg(out, pkey, indent, "Parameters");
471
6
}
472
473
int
474
EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
475
{
476

84
	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
477
		return -2;
478
28
	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
479
28
	    0, pnid);
480
28
}
481