GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/evp/p_lib.c Lines: 82 178 46.1 %
Date: 2016-12-06 Branches: 37 120 30.8 %

Line Branch Exec Source
1
/* $OpenBSD: p_lib.c,v 1.16 2014/07/12 22:26:01 miod 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
	if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
91
		return pkey->ameth->pkey_bits(pkey);
92
	return 0;
93
}
94
95
int
96
EVP_PKEY_size(EVP_PKEY *pkey)
97
11
{
98

11
	if (pkey && pkey->ameth && pkey->ameth->pkey_size)
99
11
		return pkey->ameth->pkey_size(pkey);
100
	return 0;
101
}
102
103
int
104
EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
105
{
106
#ifndef OPENSSL_NO_DSA
107
	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
	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
	return (0);
125
}
126
127
int
128
EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
129
{
130
	if (to->type != from->type) {
131
		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,
132
		    EVP_R_DIFFERENT_KEY_TYPES);
133
		goto err;
134
	}
135
136
	if (EVP_PKEY_missing_parameters(from)) {
137
		EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,
138
		    EVP_R_MISSING_PARAMETERS);
139
		goto err;
140
	}
141
	if (from->ameth && from->ameth->param_copy)
142
		return from->ameth->param_copy(to, from);
143
144
err:
145
	return 0;
146
}
147
148
int
149
EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
150
8
{
151

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

38
		if ((type == pkey->save_type) && pkey->ameth)
225
9
			return 1;
226
#ifndef OPENSSL_NO_ENGINE
227
		/* If we have an ENGINE release it */
228
29
		if (pkey->engine) {
229
			ENGINE_finish(pkey->engine);
230
			pkey->engine = NULL;
231
		}
232
#endif
233
	}
234
29
	if (str)
235
		ameth = EVP_PKEY_asn1_find_str(&e, str, len);
236
	else
237
29
		ameth = EVP_PKEY_asn1_find(&e, type);
238
#ifndef OPENSSL_NO_ENGINE
239

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

20
	if (x->ameth && x->ameth->pkey_free) {
426
20
		x->ameth->pkey_free(x);
427
20
		x->pkey.ptr = NULL;
428
	}
429
#ifndef OPENSSL_NO_ENGINE
430
20
	if (x->engine) {
431
		ENGINE_finish(x->engine);
432
		x->engine = NULL;
433
	}
434
#endif
435
20
}
436
437
static int
438
unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, const char *kstr)
439
{
440
	BIO_indent(out, indent, 128);
441
	BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
442
	    kstr, OBJ_nid2ln(pkey->type));
443
	return 1;
444
}
445
446
int
447
EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
448
    ASN1_PCTX *pctx)
449
{
450
	if (pkey->ameth && pkey->ameth->pub_print)
451
		return pkey->ameth->pub_print(out, pkey, indent, pctx);
452
453
	return unsup_alg(out, pkey, indent, "Public Key");
454
}
455
456
int
457
EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
458
    ASN1_PCTX *pctx)
459
2
{
460

2
	if (pkey->ameth && pkey->ameth->priv_print)
461
2
		return pkey->ameth->priv_print(out, pkey, indent, pctx);
462
463
	return unsup_alg(out, pkey, indent, "Private Key");
464
}
465
466
int
467
EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
468
    ASN1_PCTX *pctx)
469
{
470
	if (pkey->ameth && pkey->ameth->param_print)
471
		return pkey->ameth->param_print(out, pkey, indent, pctx);
472
	return unsup_alg(out, pkey, indent, "Parameters");
473
}
474
475
int
476
EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
477
2
{
478

2
	if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
479
		return -2;
480
2
	return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
481
	    0, pnid);
482
}
483