1 /*
2  * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3  * Copyright (C) 2012-2016 Nikos Mavrogiannopoulos
4  * Copyright (C) 2015-2017 Red Hat, Inc.
5  *
6  * Author: Nikos Mavrogiannopoulos
7  *
8  * This file is part of GnuTLS.
9  *
10  * The GnuTLS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1 of
13  * the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program.  If not, see <https://www.gnu.org/licenses/>
22  *
23  */
24 
25 #include "gnutls_int.h"
26 #include <datum.h>
27 #include <global.h>
28 #include "errors.h"
29 #include <tls-sig.h>
30 #include <common.h>
31 #include <x509.h>
32 #include <x509_b64.h>
33 #include <x509_int.h>
34 #include <pk.h>
35 #include <mpi.h>
36 #include <ecc.h>
37 #include <pin.h>
38 
39 /**
40  * gnutls_x509_privkey_init:
41  * @key: A pointer to the type to be initialized
42  *
43  * This function will initialize a private key type.
44  *
45  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
46  *   negative error value.
47  **/
gnutls_x509_privkey_init(gnutls_x509_privkey_t * key)48 int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key)
49 {
50 	FAIL_IF_LIB_ERROR;
51 
52 	*key = gnutls_calloc(1, sizeof(gnutls_x509_privkey_int));
53 
54 	if (*key) {
55 		(*key)->key = ASN1_TYPE_EMPTY;
56 		return 0;	/* success */
57 	}
58 
59 	return GNUTLS_E_MEMORY_ERROR;
60 }
61 
_gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key)62 void _gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key)
63 {
64 	gnutls_pk_params_clear(&key->params);
65 	gnutls_pk_params_release(&key->params);
66 	/* avoid re-use of fields which may have had some sensible value */
67 	memset(&key->params, 0, sizeof(key->params));
68 
69 	if (key->key)
70 		asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
71 	key->key = ASN1_TYPE_EMPTY;
72 }
73 
74 /**
75  * gnutls_x509_privkey_deinit:
76  * @key: The key to be deinitialized
77  *
78  * This function will deinitialize a private key structure.
79  **/
gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key)80 void gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key)
81 {
82 	if (!key)
83 		return;
84 
85 	_gnutls_x509_privkey_reinit(key);
86 	gnutls_free(key);
87 }
88 
89 /**
90  * gnutls_x509_privkey_cpy:
91  * @dst: The destination key, which should be initialized.
92  * @src: The source key
93  *
94  * This function will copy a private key from source to destination
95  * key. Destination has to be initialized.
96  *
97  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
98  *   negative error value.
99  **/
100 int
gnutls_x509_privkey_cpy(gnutls_x509_privkey_t dst,gnutls_x509_privkey_t src)101 gnutls_x509_privkey_cpy(gnutls_x509_privkey_t dst,
102 			gnutls_x509_privkey_t src)
103 {
104 	int ret;
105 
106 	if (!src || !dst)
107 		return GNUTLS_E_INVALID_REQUEST;
108 
109 	ret = _gnutls_pk_params_copy(&dst->params, &src->params);
110 	if (ret < 0) {
111 		return gnutls_assert_val(ret);
112 	}
113 
114 	ret =
115 	    _gnutls_asn1_encode_privkey(&dst->key,
116 					&dst->params);
117 	if (ret < 0) {
118 		gnutls_assert();
119 		gnutls_pk_params_release(&dst->params);
120 		return ret;
121 	}
122 
123 	return 0;
124 }
125 
126 /* Converts an RSA PKCS#1 key to
127  * an internal structure (gnutls_private_key)
128  */
129 ASN1_TYPE
_gnutls_privkey_decode_pkcs1_rsa_key(const gnutls_datum_t * raw_key,gnutls_x509_privkey_t pkey)130 _gnutls_privkey_decode_pkcs1_rsa_key(const gnutls_datum_t * raw_key,
131 				     gnutls_x509_privkey_t pkey)
132 {
133 	int result;
134 	ASN1_TYPE pkey_asn;
135 
136 	gnutls_pk_params_init(&pkey->params);
137 
138 	if ((result =
139 	     asn1_create_element(_gnutls_get_gnutls_asn(),
140 				 "GNUTLS.RSAPrivateKey",
141 				 &pkey_asn)) != ASN1_SUCCESS) {
142 		gnutls_assert();
143 		return NULL;
144 	}
145 
146 	result =
147 	    _asn1_strict_der_decode(&pkey_asn, raw_key->data, raw_key->size,
148 			      NULL);
149 	if (result != ASN1_SUCCESS) {
150 		gnutls_assert();
151 		goto error;
152 	}
153 
154 	if ((result = _gnutls_x509_read_int(pkey_asn, "modulus",
155 					    &pkey->params.params[0])) < 0)
156 	{
157 		gnutls_assert();
158 		goto error;
159 	}
160 	pkey->params.params_nr++;
161 
162 	if ((result =
163 	     _gnutls_x509_read_int(pkey_asn, "publicExponent",
164 				   &pkey->params.params[1])) < 0) {
165 		gnutls_assert();
166 		goto error;
167 	}
168 	pkey->params.params_nr++;
169 
170 	if ((result =
171 	     _gnutls_x509_read_key_int(pkey_asn, "privateExponent",
172 				   &pkey->params.params[2])) < 0) {
173 		gnutls_assert();
174 		goto error;
175 	}
176 	pkey->params.params_nr++;
177 
178 	if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime1",
179 					    &pkey->params.params[3])) < 0)
180 	{
181 		gnutls_assert();
182 		goto error;
183 	}
184 	pkey->params.params_nr++;
185 
186 	if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime2",
187 					    &pkey->params.params[4])) < 0)
188 	{
189 		gnutls_assert();
190 		goto error;
191 	}
192 	pkey->params.params_nr++;
193 
194 	if ((result = _gnutls_x509_read_key_int(pkey_asn, "coefficient",
195 					    &pkey->params.params[5])) < 0)
196 	{
197 		gnutls_assert();
198 		goto error;
199 	}
200 	pkey->params.params_nr++;
201 
202 	if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent1",
203 					    &pkey->params.params[6])) < 0)
204 	{
205 		gnutls_assert();
206 		goto error;
207 	}
208 	pkey->params.params_nr++;
209 
210 	if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent2",
211 					    &pkey->params.params[7])) < 0)
212 	{
213 		gnutls_assert();
214 		goto error;
215 	}
216 	pkey->params.params_nr++;
217 
218 	pkey->params.params_nr = RSA_PRIVATE_PARAMS;
219 	pkey->params.algo = GNUTLS_PK_RSA;
220 
221 	return pkey_asn;
222 
223       error:
224 	asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
225 	gnutls_pk_params_clear(&pkey->params);
226 	gnutls_pk_params_release(&pkey->params);
227 	return NULL;
228 }
229 
230 /* Converts an ECC key to
231  * an internal structure (gnutls_private_key)
232  */
233 int
_gnutls_privkey_decode_ecc_key(ASN1_TYPE * pkey_asn,const gnutls_datum_t * raw_key,gnutls_x509_privkey_t pkey,gnutls_ecc_curve_t curve)234 _gnutls_privkey_decode_ecc_key(ASN1_TYPE* pkey_asn, const gnutls_datum_t * raw_key,
235 			       gnutls_x509_privkey_t pkey, gnutls_ecc_curve_t curve)
236 {
237 	int ret;
238 	unsigned int version;
239 	char oid[MAX_OID_SIZE];
240 	int oid_size;
241 	gnutls_datum_t out;
242 
243 	if (curve_is_eddsa(curve)) {
244 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
245 	}
246 
247 	gnutls_pk_params_init(&pkey->params);
248 
249 	if ((ret =
250 	     asn1_create_element(_gnutls_get_gnutls_asn(),
251 				 "GNUTLS.ECPrivateKey",
252 				 pkey_asn)) != ASN1_SUCCESS) {
253 		gnutls_assert();
254 		return _gnutls_asn2err(ret);
255 	}
256 
257 	ret =
258 	    _asn1_strict_der_decode(pkey_asn, raw_key->data, raw_key->size,
259 			      NULL);
260 	if (ret != ASN1_SUCCESS) {
261 		gnutls_assert();
262 		ret = _gnutls_asn2err(ret);
263 		goto error;
264 	}
265 
266 	ret = _gnutls_x509_read_uint(*pkey_asn, "Version", &version);
267 	if (ret < 0) {
268 		gnutls_assert();
269 		goto error;
270 	}
271 
272 	if (version != 1) {
273 		_gnutls_debug_log
274 		    ("ECC private key version %u is not supported\n",
275 		     version);
276 		gnutls_assert();
277 		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
278 		goto error;
279 	}
280 
281 	/* read the curve */
282 	if (curve == GNUTLS_ECC_CURVE_INVALID) {
283 		oid_size = sizeof(oid);
284 		ret =
285 		    asn1_read_value(*pkey_asn, "parameters.namedCurve", oid,
286 			    &oid_size);
287 		if (ret != ASN1_SUCCESS) {
288 			gnutls_assert();
289 			ret = _gnutls_asn2err(ret);
290 			goto error;
291 		}
292 
293 		pkey->params.curve = gnutls_oid_to_ecc_curve(oid);
294 
295 		if (pkey->params.curve == GNUTLS_ECC_CURVE_INVALID) {
296 			_gnutls_debug_log("Curve %s is not supported\n", oid);
297 			gnutls_assert();
298 			ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
299 			goto error;
300 		}
301 	} else {
302 		pkey->params.curve = curve;
303 	}
304 
305 
306 	/* read the public key */
307 	ret = _gnutls_x509_read_value(*pkey_asn, "publicKey", &out);
308 	if (ret < 0) {
309 		gnutls_assert();
310 		goto error;
311 	}
312 
313 	ret =
314 	    _gnutls_ecc_ansi_x962_import(out.data, out.size,
315 					 &pkey->params.params[ECC_X],
316 					 &pkey->params.params[ECC_Y]);
317 
318 	_gnutls_free_datum(&out);
319 	if (ret < 0) {
320 		gnutls_assert();
321 		goto error;
322 	}
323 	pkey->params.params_nr += 2;
324 
325 	/* read the private key */
326 	ret =
327 	    _gnutls_x509_read_key_int(*pkey_asn, "privateKey",
328 				  &pkey->params.params[ECC_K]);
329 	if (ret < 0) {
330 		gnutls_assert();
331 		goto error;
332 	}
333 	pkey->params.params_nr++;
334 	pkey->params.algo = GNUTLS_PK_EC;
335 
336 	return 0;
337 
338       error:
339 	asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
340 	gnutls_pk_params_clear(&pkey->params);
341 	gnutls_pk_params_release(&pkey->params);
342 	return ret;
343 
344 }
345 
346 
347 static ASN1_TYPE
decode_dsa_key(const gnutls_datum_t * raw_key,gnutls_x509_privkey_t pkey)348 decode_dsa_key(const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
349 {
350 	int result;
351 	ASN1_TYPE dsa_asn;
352 	gnutls_datum_t seed = {NULL,0};
353 	char oid[MAX_OID_SIZE];
354 	int oid_size;
355 
356 	if ((result =
357 	     asn1_create_element(_gnutls_get_gnutls_asn(),
358 				 "GNUTLS.DSAPrivateKey",
359 				 &dsa_asn)) != ASN1_SUCCESS) {
360 		gnutls_assert();
361 		return NULL;
362 	}
363 
364 	gnutls_pk_params_init(&pkey->params);
365 
366 
367 	result =
368 	    _asn1_strict_der_decode(&dsa_asn, raw_key->data, raw_key->size,
369 			      NULL);
370 	if (result != ASN1_SUCCESS) {
371 		gnutls_assert();
372 		goto error;
373 	}
374 
375 	if ((result =
376 	     _gnutls_x509_read_int(dsa_asn, "p",
377 				   &pkey->params.params[0])) < 0) {
378 		gnutls_assert();
379 		goto error;
380 	}
381 	pkey->params.params_nr++;
382 
383 	if ((result =
384 	     _gnutls_x509_read_int(dsa_asn, "q",
385 				   &pkey->params.params[1])) < 0) {
386 		gnutls_assert();
387 		goto error;
388 	}
389 	pkey->params.params_nr++;
390 
391 	if ((result =
392 	     _gnutls_x509_read_int(dsa_asn, "g",
393 				   &pkey->params.params[2])) < 0) {
394 		gnutls_assert();
395 		goto error;
396 	}
397 	pkey->params.params_nr++;
398 
399 	if ((result =
400 	     _gnutls_x509_read_int(dsa_asn, "Y",
401 				   &pkey->params.params[3])) < 0) {
402 		gnutls_assert();
403 		goto error;
404 	}
405 	pkey->params.params_nr++;
406 
407 	if ((result = _gnutls_x509_read_key_int(dsa_asn, "priv",
408 					    &pkey->params.params[4])) < 0)
409 	{
410 		gnutls_assert();
411 		goto error;
412 	}
413 	pkey->params.params_nr++;
414 	pkey->params.algo = GNUTLS_PK_DSA;
415 
416 	oid_size = sizeof(oid);
417 	result = asn1_read_value(dsa_asn, "seed.algorithm", oid, &oid_size);
418 	if (result == ASN1_SUCCESS) {
419 		pkey->params.palgo = gnutls_oid_to_digest(oid);
420 
421 		result = _gnutls_x509_read_value(dsa_asn, "seed.seed", &seed);
422 		if (result == ASN1_SUCCESS) {
423 			if (seed.size <= sizeof(pkey->params.seed)) {
424 				memcpy(pkey->params.seed, seed.data, seed.size);
425 				pkey->params.seed_size = seed.size;
426 			}
427 			gnutls_free(seed.data);
428 		}
429 	}
430 
431 	return dsa_asn;
432 
433       error:
434 	asn1_delete_structure2(&dsa_asn, ASN1_DELETE_FLAG_ZEROIZE);
435 	gnutls_pk_params_clear(&pkey->params);
436 	gnutls_pk_params_release(&pkey->params);
437 	return NULL;
438 
439 }
440 
441 
442 #define PEM_KEY_DSA "DSA PRIVATE KEY"
443 #define PEM_KEY_RSA "RSA PRIVATE KEY"
444 #define PEM_KEY_ECC "EC PRIVATE KEY"
445 #define PEM_KEY_PKCS8 "PRIVATE KEY"
446 
447 #define MAX_PEM_HEADER_SIZE 25
448 
449 #define IF_CHECK_FOR(pemstr, _algo, cptr, bptr, size, key) \
450 		if (left > sizeof(pemstr) && memcmp(cptr, pemstr, sizeof(pemstr)-1) == 0) { \
451 			result = _gnutls_fbase64_decode(pemstr, bptr, size, &_data); \
452 			if (result >= 0) \
453 				key->params.algo = _algo; \
454 		}
455 
456 /**
457  * gnutls_x509_privkey_import:
458  * @key: The data to store the parsed key
459  * @data: The DER or PEM encoded certificate.
460  * @format: One of DER or PEM
461  *
462  * This function will convert the given DER or PEM encoded key to the
463  * native #gnutls_x509_privkey_t format. The output will be stored in
464  * @key .
465  *
466  * If the key is PEM encoded it should have a header that contains "PRIVATE
467  * KEY". Note that this function falls back to PKCS #8 decoding without
468  * password, if the default format fails to import.
469  *
470  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
471  *   negative error value.
472  **/
473 int
gnutls_x509_privkey_import(gnutls_x509_privkey_t key,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format)474 gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
475 			   const gnutls_datum_t * data,
476 			   gnutls_x509_crt_fmt_t format)
477 {
478 	int result = 0, need_free = 0;
479 	gnutls_datum_t _data;
480 
481 	if (key == NULL) {
482 		gnutls_assert();
483 		return GNUTLS_E_INVALID_REQUEST;
484 	}
485 
486 	_data.data = data->data;
487 	_data.size = data->size;
488 
489 	key->params.algo = GNUTLS_PK_UNKNOWN;
490 
491 	/* If the Certificate is in PEM format then decode it
492 	 */
493 	if (format == GNUTLS_X509_FMT_PEM) {
494 		unsigned left;
495 		char *ptr;
496 		uint8_t *begin_ptr;
497 
498 		ptr = memmem(data->data, data->size, "PRIVATE KEY-----", sizeof("PRIVATE KEY-----")-1);
499 
500 		result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
501 
502 		if (ptr != NULL) {
503 			left = data->size - ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
504 
505 			if (data->size - left > MAX_PEM_HEADER_SIZE) {
506 				ptr -= MAX_PEM_HEADER_SIZE;
507 				left += MAX_PEM_HEADER_SIZE;
508 			} else {
509 				ptr = (char*)data->data;
510 				left = data->size;
511 			}
512 
513 			ptr = memmem(ptr, left, "-----BEGIN ", sizeof("-----BEGIN ")-1);
514 			if (ptr != NULL) {
515 				begin_ptr = (uint8_t*)ptr;
516 				left = data->size - ((ptrdiff_t)begin_ptr - (ptrdiff_t)data->data);
517 
518 				ptr += sizeof("-----BEGIN ")-1;
519 
520 				IF_CHECK_FOR(PEM_KEY_RSA, GNUTLS_PK_RSA, ptr, begin_ptr, left, key)
521 				else IF_CHECK_FOR(PEM_KEY_ECC, GNUTLS_PK_EC, ptr, begin_ptr, left, key)
522 				else IF_CHECK_FOR(PEM_KEY_DSA, GNUTLS_PK_DSA, ptr, begin_ptr, left, key)
523 
524 				if (key->params.algo == GNUTLS_PK_UNKNOWN && left >= sizeof(PEM_KEY_PKCS8)) {
525 					if (memcmp(ptr, PEM_KEY_PKCS8, sizeof(PEM_KEY_PKCS8)-1) == 0) {
526 						result =
527 							_gnutls_fbase64_decode(PEM_KEY_PKCS8,
528 								begin_ptr, left, &_data);
529 						if (result >= 0) {
530 							/* signal for PKCS #8 keys */
531 							key->params.algo = -1;
532 						}
533 					}
534 				}
535 			}
536 
537 		}
538 
539 		if (result < 0) {
540 			gnutls_assert();
541 			return result;
542 		}
543 
544 		need_free = 1;
545 	}
546 
547 	if (key->expanded) {
548 		_gnutls_x509_privkey_reinit(key);
549 	}
550 	key->expanded = 1;
551 
552 	if (key->params.algo == (gnutls_pk_algorithm_t)-1) {
553 		result =
554 		    gnutls_x509_privkey_import_pkcs8(key, data, format,
555 						     NULL,
556 						     GNUTLS_PKCS_PLAIN);
557 		if (result < 0) {
558 			gnutls_assert();
559 			key->key = NULL;
560 			goto cleanup;
561 		} else {
562 			/* some keys under PKCS#8 don't set key->key */
563 			goto finish;
564 		}
565 	} else if (key->params.algo == GNUTLS_PK_RSA) {
566 		key->key =
567 		    _gnutls_privkey_decode_pkcs1_rsa_key(&_data, key);
568 		if (key->key == NULL)
569 			gnutls_assert();
570 	} else if (key->params.algo == GNUTLS_PK_DSA) {
571 		key->key = decode_dsa_key(&_data, key);
572 		if (key->key == NULL)
573 			gnutls_assert();
574 	} else if (key->params.algo == GNUTLS_PK_EC) {
575 		result = _gnutls_privkey_decode_ecc_key(&key->key, &_data, key, 0);
576 		if (result < 0) {
577 			gnutls_assert();
578 			key->key = NULL;
579 		}
580 	} else {
581 		/* Try decoding each of the keys, and accept the one that
582 		 * succeeds.
583 		 */
584 		key->params.algo = GNUTLS_PK_RSA;
585 		key->key =
586 		    _gnutls_privkey_decode_pkcs1_rsa_key(&_data, key);
587 
588 		if (key->key == NULL) {
589 			key->params.algo = GNUTLS_PK_DSA;
590 			key->key = decode_dsa_key(&_data, key);
591 			if (key->key == NULL) {
592 				key->params.algo = GNUTLS_PK_EC;
593 				result =
594 				    _gnutls_privkey_decode_ecc_key(&key->key, &_data, key, 0);
595 				if (result < 0) {
596 					result =
597 					    gnutls_x509_privkey_import_pkcs8(key, data, format,
598 									     NULL,
599 									     GNUTLS_PKCS_PLAIN);
600 					if (result >= 0) {
601 						/* there are keys (ed25519) which leave key->key NULL */
602 						goto finish;
603 					}
604 
605 					/* result < 0 */
606 					gnutls_assert();
607 					key->key = NULL;
608 
609 					if (result == GNUTLS_E_PK_INVALID_PRIVKEY)
610 						goto cleanup;
611 				}
612 			}
613 		}
614 	}
615 
616 	if (key->key == NULL) {
617 		gnutls_assert();
618 		result = GNUTLS_E_ASN1_DER_ERROR;
619 		goto cleanup;
620 	}
621 
622  finish:
623 	result =
624 	    _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
625 	if (result < 0) {
626 		gnutls_assert();
627 	}
628 
629  cleanup:
630 	if (need_free)
631 		_gnutls_free_datum(&_data);
632 
633 	/* The key has now been decoded.
634 	 */
635 
636 	return result;
637 }
638 
import_pkcs12_privkey(gnutls_x509_privkey_t key,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,const char * password,unsigned int flags)639 static int import_pkcs12_privkey(gnutls_x509_privkey_t key,
640 				 const gnutls_datum_t * data,
641 				 gnutls_x509_crt_fmt_t format,
642 				 const char *password, unsigned int flags)
643 {
644 	int ret;
645 	gnutls_pkcs12_t p12;
646 	gnutls_x509_privkey_t newkey;
647 
648 	ret = gnutls_pkcs12_init(&p12);
649 	if (ret < 0)
650 		return gnutls_assert_val(ret);
651 
652 	ret = gnutls_pkcs12_import(p12, data, format, flags);
653 	if (ret < 0) {
654 		gnutls_assert();
655 		goto fail;
656 	}
657 
658 	ret =
659 	    gnutls_pkcs12_simple_parse(p12, password, &newkey, NULL, NULL,
660 				       NULL, NULL, NULL, 0);
661 	if (ret < 0) {
662 		gnutls_assert();
663 		goto fail;
664 	}
665 
666 	ret = gnutls_x509_privkey_cpy(key, newkey);
667 	gnutls_x509_privkey_deinit(newkey);
668 	if (ret < 0) {
669 		gnutls_assert();
670 		goto fail;
671 	}
672 
673 	ret = 0;
674       fail:
675 
676 	gnutls_pkcs12_deinit(p12);
677 
678 	return ret;
679 }
680 
681 /**
682  * gnutls_x509_privkey_import2:
683  * @key: The data to store the parsed key
684  * @data: The DER or PEM encoded key.
685  * @format: One of DER or PEM
686  * @password: A password (optional)
687  * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
688  *
689  * This function will import the given DER or PEM encoded key, to
690  * the native #gnutls_x509_privkey_t format, irrespective of the
691  * input format. The input format is auto-detected.
692  *
693  * The supported formats are basic unencrypted key, PKCS8, PKCS12,
694  * and the openssl format.
695  *
696  * If the provided key is encrypted but no password was given, then
697  * %GNUTLS_E_DECRYPTION_FAILED is returned. Since GnuTLS 3.4.0 this
698  * function will utilize the PIN callbacks if any.
699  *
700  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
701  *   negative error value.
702  **/
703 int
gnutls_x509_privkey_import2(gnutls_x509_privkey_t key,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,const char * password,unsigned int flags)704 gnutls_x509_privkey_import2(gnutls_x509_privkey_t key,
705 			    const gnutls_datum_t * data,
706 			    gnutls_x509_crt_fmt_t format,
707 			    const char *password, unsigned int flags)
708 {
709 	int ret = 0;
710 	int saved_ret = GNUTLS_E_PARSING_ERROR;
711 	char pin[GNUTLS_PKCS11_MAX_PIN_LEN];
712 	unsigned head_enc = 1;
713 
714 	if (format == GNUTLS_X509_FMT_PEM) {
715 		size_t left;
716 		char *ptr;
717 
718 		ptr = memmem(data->data, data->size, "PRIVATE KEY-----", sizeof("PRIVATE KEY-----")-1);
719 
720 		if (ptr != NULL) {
721 			left = data->size - ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
722 
723 			if (data->size - left > 15) {
724 				ptr -= 15;
725 				left += 15;
726 			} else {
727 				ptr = (char*)data->data;
728 				left = data->size;
729 			}
730 
731 			ptr = memmem(ptr, left, "-----BEGIN ", sizeof("-----BEGIN ")-1);
732 			if (ptr != NULL) {
733 				ptr += sizeof("-----BEGIN ")-1;
734 				left = data->size - ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
735 			}
736 
737 			if (ptr != NULL && left > sizeof(PEM_KEY_RSA)) {
738 				if (memcmp(ptr, PEM_KEY_RSA, sizeof(PEM_KEY_RSA)-1) == 0 ||
739 				    memcmp(ptr, PEM_KEY_ECC, sizeof(PEM_KEY_ECC)-1) == 0 ||
740 				    memcmp(ptr, PEM_KEY_DSA, sizeof(PEM_KEY_DSA)-1) == 0) {
741 					head_enc = 0;
742 				}
743 			}
744 		}
745 	}
746 
747 	if (head_enc == 0 || (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD))) {
748 		ret = gnutls_x509_privkey_import(key, data, format);
749 		if (ret >= 0)
750 			return ret;
751 
752 		if (ret < 0) {
753 			gnutls_assert();
754 			saved_ret = ret;
755 			/* fall through to PKCS #8 decoding */
756 		}
757 	}
758 
759 	if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD))
760 	    || ret < 0) {
761 
762 		ret =
763 		    gnutls_x509_privkey_import_pkcs8(key, data, format,
764 						     password, flags);
765 
766 		if (ret == GNUTLS_E_DECRYPTION_FAILED &&
767 		    password == NULL && (!(flags & GNUTLS_PKCS_PLAIN))) {
768 		    /* use the callback if any */
769 			ret = _gnutls_retrieve_pin(&key->pin, "key:", "", 0, pin, sizeof(pin));
770 			if (ret == 0) {
771 				password = pin;
772 			}
773 
774 			ret =
775 			    gnutls_x509_privkey_import_pkcs8(key, data, format,
776 						     password, flags);
777 		}
778 
779 		if (saved_ret == GNUTLS_E_PARSING_ERROR)
780 			saved_ret = ret;
781 
782 		if (ret < 0) {
783 			if (ret == GNUTLS_E_DECRYPTION_FAILED)
784 				goto cleanup;
785 			ret =
786 			    import_pkcs12_privkey(key, data, format,
787 						  password, flags);
788 			if (ret < 0 && format == GNUTLS_X509_FMT_PEM) {
789 				if (ret == GNUTLS_E_DECRYPTION_FAILED)
790 					goto cleanup;
791 
792 				ret =
793 				    gnutls_x509_privkey_import_openssl(key,
794 								       data,
795 								       password);
796 				if (ret < 0) {
797 					gnutls_assert();
798 					goto cleanup;
799 				}
800 			} else {
801 				gnutls_assert();
802 				goto cleanup;
803 			}
804 		}
805 	}
806 
807 	ret = 0;
808 
809       cleanup:
810 	if (ret == GNUTLS_E_PARSING_ERROR)
811 		ret = saved_ret;
812 
813 	return ret;
814 }
815 
816 
817 /**
818  * gnutls_x509_privkey_import_rsa_raw:
819  * @key: The data to store the parsed key
820  * @m: holds the modulus
821  * @e: holds the public exponent
822  * @d: holds the private exponent
823  * @p: holds the first prime (p)
824  * @q: holds the second prime (q)
825  * @u: holds the coefficient
826  *
827  * This function will convert the given RSA raw parameters to the
828  * native #gnutls_x509_privkey_t format.  The output will be stored in
829  * @key.
830  *
831  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
832  *   negative error value.
833  **/
834 int
gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,const gnutls_datum_t * m,const gnutls_datum_t * e,const gnutls_datum_t * d,const gnutls_datum_t * p,const gnutls_datum_t * q,const gnutls_datum_t * u)835 gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
836 				   const gnutls_datum_t * m,
837 				   const gnutls_datum_t * e,
838 				   const gnutls_datum_t * d,
839 				   const gnutls_datum_t * p,
840 				   const gnutls_datum_t * q,
841 				   const gnutls_datum_t * u)
842 {
843 	return gnutls_x509_privkey_import_rsa_raw2(key, m, e, d, p, q, u,
844 						   NULL, NULL);
845 }
846 
847 /**
848  * gnutls_x509_privkey_import_rsa_raw2:
849  * @key: The data to store the parsed key
850  * @m: holds the modulus
851  * @e: holds the public exponent
852  * @d: holds the private exponent
853  * @p: holds the first prime (p)
854  * @q: holds the second prime (q)
855  * @u: holds the coefficient (optional)
856  * @e1: holds e1 = d mod (p-1) (optional)
857  * @e2: holds e2 = d mod (q-1) (optional)
858  *
859  * This function will convert the given RSA raw parameters to the
860  * native #gnutls_x509_privkey_t format.  The output will be stored in
861  * @key.
862  *
863  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
864  *   negative error value.
865  **/
866 int
gnutls_x509_privkey_import_rsa_raw2(gnutls_x509_privkey_t key,const gnutls_datum_t * m,const gnutls_datum_t * e,const gnutls_datum_t * d,const gnutls_datum_t * p,const gnutls_datum_t * q,const gnutls_datum_t * u,const gnutls_datum_t * e1,const gnutls_datum_t * e2)867 gnutls_x509_privkey_import_rsa_raw2(gnutls_x509_privkey_t key,
868 				    const gnutls_datum_t * m,
869 				    const gnutls_datum_t * e,
870 				    const gnutls_datum_t * d,
871 				    const gnutls_datum_t * p,
872 				    const gnutls_datum_t * q,
873 				    const gnutls_datum_t * u,
874 				    const gnutls_datum_t * e1,
875 				    const gnutls_datum_t * e2)
876 {
877 	int ret;
878 	size_t siz = 0;
879 
880 	if (key == NULL) {
881 		gnutls_assert();
882 		return GNUTLS_E_INVALID_REQUEST;
883 	}
884 
885 	gnutls_pk_params_init(&key->params);
886 
887 	siz = m->size;
888 	if (_gnutls_mpi_init_scan_nz(&key->params.params[0], m->data, siz)) {
889 		gnutls_assert();
890 		ret = GNUTLS_E_MPI_SCAN_FAILED;
891 		goto cleanup;
892 	}
893 	key->params.params_nr++;
894 
895 	siz = e->size;
896 	if (_gnutls_mpi_init_scan_nz(&key->params.params[1], e->data, siz)) {
897 		gnutls_assert();
898 		ret = GNUTLS_E_MPI_SCAN_FAILED;
899 		goto cleanup;
900 	}
901 	key->params.params_nr++;
902 
903 	siz = d->size;
904 	if (_gnutls_mpi_init_scan_nz(&key->params.params[2], d->data, siz)) {
905 		gnutls_assert();
906 		ret = GNUTLS_E_MPI_SCAN_FAILED;
907 		goto cleanup;
908 	}
909 	key->params.params_nr++;
910 
911 	siz = p->size;
912 	if (_gnutls_mpi_init_scan_nz(&key->params.params[3], p->data, siz)) {
913 		gnutls_assert();
914 		ret = GNUTLS_E_MPI_SCAN_FAILED;
915 		goto cleanup;
916 	}
917 	key->params.params_nr++;
918 
919 	siz = q->size;
920 	if (_gnutls_mpi_init_scan_nz(&key->params.params[4], q->data, siz)) {
921 		gnutls_assert();
922 		ret = GNUTLS_E_MPI_SCAN_FAILED;
923 		goto cleanup;
924 	}
925 	key->params.params_nr++;
926 
927 	if (u) {
928 		siz = u->size;
929 		if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_COEF], u->data, siz)) {
930 			gnutls_assert();
931 			ret = GNUTLS_E_MPI_SCAN_FAILED;
932 			goto cleanup;
933 		}
934 		key->params.params_nr++;
935 	}
936 
937 	if (e1 && e2) {
938 		siz = e1->size;
939 		if (_gnutls_mpi_init_scan_nz
940 		    (&key->params.params[RSA_E1], e1->data, siz)) {
941 			gnutls_assert();
942 			ret = GNUTLS_E_MPI_SCAN_FAILED;
943 			goto cleanup;
944 		}
945 		key->params.params_nr++;
946 
947 		siz = e2->size;
948 		if (_gnutls_mpi_init_scan_nz
949 		    (&key->params.params[RSA_E2], e2->data, siz)) {
950 			gnutls_assert();
951 			ret = GNUTLS_E_MPI_SCAN_FAILED;
952 			goto cleanup;
953 		}
954 		key->params.params_nr++;
955 	}
956 
957 	key->params.algo = GNUTLS_PK_RSA;
958 
959 	ret = _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
960 	if (ret < 0) {
961 		gnutls_assert();
962 		goto cleanup;
963 	}
964 
965 	key->params.params_nr = RSA_PRIVATE_PARAMS;
966 	key->params.algo = GNUTLS_PK_RSA;
967 
968 	ret =
969 	    _gnutls_asn1_encode_privkey(&key->key,
970 					&key->params);
971 	if (ret < 0) {
972 		gnutls_assert();
973 		goto cleanup;
974 	}
975 
976 	return 0;
977 
978       cleanup:
979 	gnutls_pk_params_clear(&key->params);
980 	gnutls_pk_params_release(&key->params);
981 	return ret;
982 
983 }
984 
985 /**
986  * gnutls_x509_privkey_import_dsa_raw:
987  * @key: The data to store the parsed key
988  * @p: holds the p
989  * @q: holds the q
990  * @g: holds the g
991  * @y: holds the y
992  * @x: holds the x
993  *
994  * This function will convert the given DSA raw parameters to the
995  * native #gnutls_x509_privkey_t format.  The output will be stored
996  * in @key.
997  *
998  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
999  *   negative error value.
1000  **/
1001 int
gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,const gnutls_datum_t * p,const gnutls_datum_t * q,const gnutls_datum_t * g,const gnutls_datum_t * y,const gnutls_datum_t * x)1002 gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
1003 				   const gnutls_datum_t * p,
1004 				   const gnutls_datum_t * q,
1005 				   const gnutls_datum_t * g,
1006 				   const gnutls_datum_t * y,
1007 				   const gnutls_datum_t * x)
1008 {
1009 	int ret;
1010 	size_t siz = 0;
1011 
1012 	if (key == NULL) {
1013 		gnutls_assert();
1014 		return GNUTLS_E_INVALID_REQUEST;
1015 	}
1016 
1017 	gnutls_pk_params_init(&key->params);
1018 
1019 	siz = p->size;
1020 	if (_gnutls_mpi_init_scan_nz(&key->params.params[0], p->data, siz)) {
1021 		gnutls_assert();
1022 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1023 		goto cleanup;
1024 	}
1025 
1026 	siz = q->size;
1027 	if (_gnutls_mpi_init_scan_nz(&key->params.params[1], q->data, siz)) {
1028 		gnutls_assert();
1029 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1030 		goto cleanup;
1031 	}
1032 
1033 	siz = g->size;
1034 	if (_gnutls_mpi_init_scan_nz(&key->params.params[2], g->data, siz)) {
1035 		gnutls_assert();
1036 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1037 		goto cleanup;
1038 	}
1039 
1040 	siz = y->size;
1041 	if (_gnutls_mpi_init_scan_nz(&key->params.params[3], y->data, siz)) {
1042 		gnutls_assert();
1043 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1044 		goto cleanup;
1045 	}
1046 
1047 	siz = x->size;
1048 	if (_gnutls_mpi_init_scan_nz(&key->params.params[4], x->data, siz)) {
1049 		gnutls_assert();
1050 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1051 		goto cleanup;
1052 	}
1053 
1054 	ret =
1055 	    _gnutls_pk_fixup(GNUTLS_PK_DSA, GNUTLS_IMPORT, &key->params);
1056 	if (ret < 0) {
1057 		gnutls_assert();
1058 		goto cleanup;
1059 	}
1060 
1061 	key->params.algo = GNUTLS_PK_DSA;
1062 	key->params.params_nr = DSA_PRIVATE_PARAMS;
1063 
1064 	ret =
1065 	    _gnutls_asn1_encode_privkey(&key->key,
1066 					&key->params);
1067 	if (ret < 0) {
1068 		gnutls_assert();
1069 		goto cleanup;
1070 	}
1071 
1072 	return 0;
1073 
1074       cleanup:
1075 	gnutls_pk_params_clear(&key->params);
1076 	gnutls_pk_params_release(&key->params);
1077 	return ret;
1078 
1079 }
1080 
1081 /**
1082  * gnutls_x509_privkey_import_ecc_raw:
1083  * @key: The data to store the parsed key
1084  * @curve: holds the curve
1085  * @x: holds the x-coordinate
1086  * @y: holds the y-coordinate
1087  * @k: holds the k
1088  *
1089  * This function will convert the given elliptic curve parameters to the
1090  * native #gnutls_x509_privkey_t format.  The output will be stored
1091  * in @key. For EdDSA keys, the @x and @k values must be in the
1092  * native to curve format.
1093  *
1094  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1095  *   negative error value.
1096  *
1097  * Since: 3.0
1098  **/
1099 int
gnutls_x509_privkey_import_ecc_raw(gnutls_x509_privkey_t key,gnutls_ecc_curve_t curve,const gnutls_datum_t * x,const gnutls_datum_t * y,const gnutls_datum_t * k)1100 gnutls_x509_privkey_import_ecc_raw(gnutls_x509_privkey_t key,
1101 				   gnutls_ecc_curve_t curve,
1102 				   const gnutls_datum_t * x,
1103 				   const gnutls_datum_t * y,
1104 				   const gnutls_datum_t * k)
1105 {
1106 	int ret;
1107 
1108 	if (key == NULL) {
1109 		gnutls_assert();
1110 		return GNUTLS_E_INVALID_REQUEST;
1111 	}
1112 
1113 	gnutls_pk_params_init(&key->params);
1114 
1115 	key->params.curve = curve;
1116 
1117 	if (curve_is_eddsa(curve)) {
1118 		unsigned size;
1119 		switch (curve) {
1120 		case GNUTLS_ECC_CURVE_ED25519:
1121 			key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1122 			break;
1123 		case GNUTLS_ECC_CURVE_ED448:
1124 			key->params.algo = GNUTLS_PK_EDDSA_ED448;
1125 			break;
1126 		default:
1127 			ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1128 			goto cleanup;
1129 		}
1130 
1131 		size = gnutls_ecc_curve_get_size(curve);
1132 		if (x->size != size || k->size != size) {
1133 			ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1134 			goto cleanup;
1135 		}
1136 
1137 		ret = _gnutls_set_datum(&key->params.raw_pub, x->data, x->size);
1138 		if (ret < 0) {
1139 			gnutls_assert();
1140 			goto cleanup;
1141 		}
1142 
1143 		ret = _gnutls_set_datum(&key->params.raw_priv, k->data, k->size);
1144 		if (ret < 0) {
1145 			gnutls_assert();
1146 			goto cleanup;
1147 		}
1148 
1149 		return 0;
1150 	}
1151 
1152 	if (_gnutls_mpi_init_scan_nz
1153 	    (&key->params.params[ECC_X], x->data, x->size)) {
1154 		gnutls_assert();
1155 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1156 		goto cleanup;
1157 	}
1158 	key->params.params_nr++;
1159 
1160 	if (_gnutls_mpi_init_scan_nz
1161 	    (&key->params.params[ECC_Y], y->data, y->size)) {
1162 		gnutls_assert();
1163 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1164 		goto cleanup;
1165 	}
1166 	key->params.params_nr++;
1167 
1168 	if (_gnutls_mpi_init_scan_nz
1169 	    (&key->params.params[ECC_K], k->data, k->size)) {
1170 		gnutls_assert();
1171 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1172 		goto cleanup;
1173 	}
1174 	key->params.params_nr++;
1175 
1176 	key->params.algo = GNUTLS_PK_EC;
1177 
1178 	ret =
1179 	    _gnutls_pk_fixup(GNUTLS_PK_EC, GNUTLS_IMPORT, &key->params);
1180 	if (ret < 0) {
1181 		gnutls_assert();
1182 		goto cleanup;
1183 	}
1184 
1185 	ret =
1186 	    _gnutls_asn1_encode_privkey(&key->key,
1187 					&key->params);
1188 	if (ret < 0) {
1189 		gnutls_assert();
1190 		goto cleanup;
1191 	}
1192 
1193 	return 0;
1194 
1195       cleanup:
1196 	gnutls_pk_params_clear(&key->params);
1197 	gnutls_pk_params_release(&key->params);
1198 	return ret;
1199 
1200 }
1201 
1202 /**
1203  * gnutls_x509_privkey_import_gost_raw:
1204  * @key: The data to store the parsed key
1205  * @curve: holds the curve
1206  * @digest: will hold the digest
1207  * @paramset: will hold the GOST parameter set ID
1208  * @x: holds the x-coordinate
1209  * @y: holds the y-coordinate
1210  * @k: holds the k (private key)
1211  *
1212  * This function will convert the given GOST private key's parameters to the
1213  * native #gnutls_x509_privkey_t format.  The output will be stored
1214  * in @key.  @digest should be one of GNUTLS_DIG_GOSR_94,
1215  * GNUTLS_DIG_STREEBOG_256 or GNUTLS_DIG_STREEBOG_512.  If @paramset is set to
1216  * GNUTLS_GOST_PARAMSET_UNKNOWN default one will be selected depending on
1217  * @digest.
1218  *
1219  * Note: parameters should be stored with least significant byte first. On
1220  * version 3.6.3 big-endian format was used incorrectly.
1221  *
1222  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1223  *   negative error value.
1224  *
1225  * Since: 3.6.3
1226  **/
1227 int
gnutls_x509_privkey_import_gost_raw(gnutls_x509_privkey_t key,gnutls_ecc_curve_t curve,gnutls_digest_algorithm_t digest,gnutls_gost_paramset_t paramset,const gnutls_datum_t * x,const gnutls_datum_t * y,const gnutls_datum_t * k)1228 gnutls_x509_privkey_import_gost_raw(gnutls_x509_privkey_t key,
1229 				    gnutls_ecc_curve_t curve,
1230 				    gnutls_digest_algorithm_t digest,
1231 				    gnutls_gost_paramset_t paramset,
1232 				    const gnutls_datum_t * x,
1233 				    const gnutls_datum_t * y,
1234 				    const gnutls_datum_t * k)
1235 {
1236 	int ret;
1237 
1238 	if (key == NULL) {
1239 		gnutls_assert();
1240 		return GNUTLS_E_INVALID_REQUEST;
1241 	}
1242 
1243 	key->params.curve = curve;
1244 	key->params.algo = _gnutls_digest_gost(digest);
1245 
1246 	if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1247 		paramset = _gnutls_gost_paramset_default(key->params.algo);
1248 
1249 	key->params.gost_params = paramset;
1250 
1251 	if (_gnutls_mpi_init_scan_le
1252 	    (&key->params.params[GOST_X], x->data, x->size)) {
1253 		gnutls_assert();
1254 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1255 		goto cleanup;
1256 	}
1257 	key->params.params_nr++;
1258 
1259 	if (_gnutls_mpi_init_scan_le
1260 	    (&key->params.params[GOST_Y], y->data, y->size)) {
1261 		gnutls_assert();
1262 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1263 		goto cleanup;
1264 	}
1265 	key->params.params_nr++;
1266 
1267 	if (_gnutls_mpi_init_scan_le
1268 	    (&key->params.params[GOST_K], k->data, k->size)) {
1269 		gnutls_assert();
1270 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1271 		goto cleanup;
1272 	}
1273 	key->params.params_nr++;
1274 
1275 	ret =
1276 	    _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
1277 	if (ret < 0) {
1278 		gnutls_assert();
1279 		goto cleanup;
1280 	}
1281 
1282 	return 0;
1283 
1284       cleanup:
1285 	gnutls_pk_params_clear(&key->params);
1286 	gnutls_pk_params_release(&key->params);
1287 	return ret;
1288 
1289 }
1290 
1291 
1292 /**
1293  * gnutls_x509_privkey_get_pk_algorithm:
1294  * @key: should contain a #gnutls_x509_privkey_t type
1295  *
1296  * This function will return the public key algorithm of a private
1297  * key.
1298  *
1299  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1300  *   success, or a negative error code on error.
1301  **/
gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key)1302 int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key)
1303 {
1304 	if (key == NULL) {
1305 		gnutls_assert();
1306 		return GNUTLS_E_INVALID_REQUEST;
1307 	}
1308 
1309 	return key->params.algo;
1310 }
1311 
1312 /**
1313  * gnutls_x509_privkey_get_pk_algorithm2:
1314  * @key: should contain a #gnutls_x509_privkey_t type
1315  * @bits: The number of bits in the public key algorithm
1316  *
1317  * This function will return the public key algorithm of a private
1318  * key.
1319  *
1320  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1321  *   success, or a negative error code on error.
1322  **/
1323 int
gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t key,unsigned int * bits)1324 gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t key,
1325 				      unsigned int *bits)
1326 {
1327 	int ret;
1328 
1329 	if (key == NULL) {
1330 		gnutls_assert();
1331 		return GNUTLS_E_INVALID_REQUEST;
1332 	}
1333 
1334 	if (bits) {
1335 		ret = pubkey_to_bits(&key->params);
1336 		if (ret < 0)
1337 			ret = 0;
1338 		*bits = ret;
1339 	}
1340 
1341 	return key->params.algo;
1342 }
1343 
1344 void
_gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,gnutls_x509_spki_st * params)1345 _gnutls_x509_privkey_get_spki_params(gnutls_x509_privkey_t key,
1346 				     gnutls_x509_spki_st *params)
1347 {
1348 	memcpy(params, &key->params.spki, sizeof(gnutls_x509_spki_st));
1349 }
1350 
1351 /**
1352  * gnutls_x509_privkey_get_spki:
1353  * @key: should contain a #gnutls_x509_privkey_t type
1354  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1355  * @flags: must be zero
1356  *
1357  * This function will return the public key information of a private
1358  * key. The provided @spki must be initialized.
1359  *
1360  * Returns: Zero on success, or a negative error code on error.
1361  **/
1362 int
gnutls_x509_privkey_get_spki(gnutls_x509_privkey_t key,gnutls_x509_spki_t spki,unsigned int flags)1363 gnutls_x509_privkey_get_spki(gnutls_x509_privkey_t key, gnutls_x509_spki_t spki, unsigned int flags)
1364 {
1365 	if (key == NULL) {
1366 		gnutls_assert();
1367 		return GNUTLS_E_INVALID_REQUEST;
1368 	}
1369 
1370 	if (key->params.spki.pk == GNUTLS_PK_UNKNOWN)
1371 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1372 
1373 	_gnutls_x509_privkey_get_spki_params(key, spki);
1374 
1375 	return 0;
1376 }
1377 
1378 /**
1379  * gnutls_x509_privkey_set_spki:
1380  * @key: should contain a #gnutls_x509_privkey_t type
1381  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1382  * @flags: must be zero
1383  *
1384  * This function will return the public key information of a private
1385  * key. The provided @spki must be initialized.
1386  *
1387  * Returns: Zero on success, or a negative error code on error.
1388  **/
1389 int
gnutls_x509_privkey_set_spki(gnutls_x509_privkey_t key,const gnutls_x509_spki_t spki,unsigned int flags)1390 gnutls_x509_privkey_set_spki(gnutls_x509_privkey_t key, const gnutls_x509_spki_t spki, unsigned int flags)
1391 {
1392 	gnutls_pk_params_st tparams;
1393 	int ret;
1394 
1395 	if (key == NULL) {
1396 		gnutls_assert();
1397 		return GNUTLS_E_INVALID_REQUEST;
1398 	}
1399 
1400 	if (!_gnutls_pk_are_compat(key->params.algo, spki->pk))
1401                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1402 
1403 	memcpy(&tparams, &key->params, sizeof(gnutls_pk_params_st));
1404 	memcpy(&tparams.spki, spki, sizeof (gnutls_x509_spki_st));
1405 	ret = _gnutls_x509_check_pubkey_params(&tparams);
1406 	if (ret < 0)
1407 		return gnutls_assert_val(ret);
1408 
1409 	memcpy(&key->params.spki, spki, sizeof (gnutls_x509_spki_st));
1410 
1411 	key->params.algo = spki->pk;
1412 
1413 	return 0;
1414 }
1415 
set_msg(gnutls_x509_privkey_t key)1416 static const char *set_msg(gnutls_x509_privkey_t key)
1417 {
1418 	if (GNUTLS_PK_IS_RSA(key->params.algo)) {
1419 		return PEM_KEY_RSA;
1420 	} else if (key->params.algo == GNUTLS_PK_DSA) {
1421 		return PEM_KEY_DSA;
1422 	} else if (key->params.algo == GNUTLS_PK_EC)
1423 		return PEM_KEY_ECC;
1424 	else
1425 		return "UNKNOWN";
1426 }
1427 
1428 /**
1429  * gnutls_x509_privkey_export:
1430  * @key: Holds the key
1431  * @format: the format of output params. One of PEM or DER.
1432  * @output_data: will contain a private key PEM or DER encoded
1433  * @output_data_size: holds the size of output_data (and will be
1434  *   replaced by the actual size of parameters)
1435  *
1436  * This function will export the private key to a PKCS#1 structure for
1437  * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1438  * will be exported in PKCS#8 form.
1439  *
1440  * If the structure is PEM encoded, it will have a header
1441  * of "BEGIN RSA PRIVATE KEY".
1442  *
1443  * It is recommended to use gnutls_x509_privkey_export_pkcs8() instead
1444  * of this function, when a consistent output format is required.
1445  *
1446  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1447  *   negative error value.
1448  **/
1449 int
gnutls_x509_privkey_export(gnutls_x509_privkey_t key,gnutls_x509_crt_fmt_t format,void * output_data,size_t * output_data_size)1450 gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
1451 			   gnutls_x509_crt_fmt_t format, void *output_data,
1452 			   size_t * output_data_size)
1453 {
1454 	gnutls_datum_t out;
1455 	int ret;
1456 
1457 	ret = gnutls_x509_privkey_export2(key, format, &out);
1458 	if (ret < 0)
1459 		return gnutls_assert_val(ret);
1460 
1461 	if (format == GNUTLS_X509_FMT_PEM)
1462 		ret = _gnutls_copy_string(&out, output_data, output_data_size);
1463 	else
1464 		ret = _gnutls_copy_data(&out, output_data, output_data_size);
1465 	gnutls_free(out.data);
1466 
1467 	return ret;
1468 }
1469 
1470 /**
1471  * gnutls_x509_privkey_export2:
1472  * @key: Holds the key
1473  * @format: the format of output params. One of PEM or DER.
1474  * @out: will contain a private key PEM or DER encoded
1475  *
1476  * This function will export the private key to a PKCS#1 structure for
1477  * RSA or RSA-PSS keys, and integer sequence for DSA keys. Other keys types
1478  * will be exported in PKCS#8 form.
1479  *
1480  * The output buffer is allocated using gnutls_malloc().
1481  *
1482  * It is recommended to use gnutls_x509_privkey_export2_pkcs8() instead
1483  * of this function, when a consistent output format is required.
1484  *
1485  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1486  *   negative error value.
1487  *
1488  * Since 3.1.3
1489  **/
1490 int
gnutls_x509_privkey_export2(gnutls_x509_privkey_t key,gnutls_x509_crt_fmt_t format,gnutls_datum_t * out)1491 gnutls_x509_privkey_export2(gnutls_x509_privkey_t key,
1492 			    gnutls_x509_crt_fmt_t format,
1493 			    gnutls_datum_t * out)
1494 {
1495 	const char *msg;
1496 	int ret;
1497 
1498 	if (key == NULL) {
1499 		gnutls_assert();
1500 		return GNUTLS_E_INVALID_REQUEST;
1501 	}
1502 
1503 	if (key->key == NULL) { /* can only export in PKCS#8 form */
1504 		return gnutls_x509_privkey_export2_pkcs8(key, format, NULL, 0, out);
1505 	}
1506 
1507 	msg = set_msg(key);
1508 
1509 	if (key->flags & GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT) {
1510 		ret = gnutls_x509_privkey_fix(key);
1511 		if (ret < 0)
1512 			return gnutls_assert_val(ret);
1513 	}
1514 
1515 	return _gnutls_x509_export_int2(key->key, format, msg, out);
1516 }
1517 
1518 /**
1519  * gnutls_x509_privkey_sec_param:
1520  * @key: a key
1521  *
1522  * This function will return the security parameter appropriate with
1523  * this private key.
1524  *
1525  * Returns: On success, a valid security parameter is returned otherwise
1526  * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
1527  *
1528  * Since: 2.12.0
1529  **/
gnutls_x509_privkey_sec_param(gnutls_x509_privkey_t key)1530 gnutls_sec_param_t gnutls_x509_privkey_sec_param(gnutls_x509_privkey_t key)
1531 {
1532 	int bits;
1533 
1534 	bits = pubkey_to_bits(&key->params);
1535 	if (bits <= 0)
1536 		return GNUTLS_SEC_PARAM_UNKNOWN;
1537 
1538 	return gnutls_pk_bits_to_sec_param(key->params.algo, bits);
1539 }
1540 
1541 /**
1542  * gnutls_x509_privkey_export_ecc_raw:
1543  * @key: a key
1544  * @curve: will hold the curve
1545  * @x: will hold the x-coordinate
1546  * @y: will hold the y-coordinate
1547  * @k: will hold the private key
1548  *
1549  * This function will export the ECC private key's parameters found
1550  * in the given structure. The new parameters will be allocated using
1551  * gnutls_malloc() and will be stored in the appropriate datum.
1552  *
1553  * In EdDSA curves the @y parameter will be %NULL and the other parameters
1554  * will be in the native format for the curve.
1555  *
1556  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1557  *   negative error value.
1558  *
1559  * Since: 3.0
1560  **/
gnutls_x509_privkey_export_ecc_raw(gnutls_x509_privkey_t key,gnutls_ecc_curve_t * curve,gnutls_datum_t * x,gnutls_datum_t * y,gnutls_datum_t * k)1561 int gnutls_x509_privkey_export_ecc_raw(gnutls_x509_privkey_t key,
1562 				       gnutls_ecc_curve_t *curve,
1563 				       gnutls_datum_t *x,
1564 				       gnutls_datum_t *y,
1565 				       gnutls_datum_t *k)
1566 {
1567 	if (key == NULL) {
1568 		gnutls_assert();
1569 		return GNUTLS_E_INVALID_REQUEST;
1570 	}
1571 
1572 	return _gnutls_params_get_ecc_raw(&key->params, curve, x, y, k, 0);
1573 }
1574 
1575 /**
1576  * gnutls_x509_privkey_export_gost_raw:
1577  * @key: a key
1578  * @curve: will hold the curve
1579  * @digest: will hold the digest
1580  * @paramset: will hold the GOST parameter set ID
1581  * @x: will hold the x-coordinate
1582  * @y: will hold the y-coordinate
1583  * @k: will hold the private key
1584  *
1585  * This function will export the GOST private key's parameters found
1586  * in the given structure. The new parameters will be allocated using
1587  * gnutls_malloc() and will be stored in the appropriate datum.
1588  *
1589  * Note: parameters will be stored with least significant byte first. On
1590  * version 3.6.3 this was incorrectly returned in big-endian format.
1591  *
1592  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1593  *   negative error value.
1594  *
1595  * Since: 3.6.3
1596  **/
gnutls_x509_privkey_export_gost_raw(gnutls_x509_privkey_t key,gnutls_ecc_curve_t * curve,gnutls_digest_algorithm_t * digest,gnutls_gost_paramset_t * paramset,gnutls_datum_t * x,gnutls_datum_t * y,gnutls_datum_t * k)1597 int gnutls_x509_privkey_export_gost_raw(gnutls_x509_privkey_t key,
1598 					gnutls_ecc_curve_t * curve,
1599 					gnutls_digest_algorithm_t * digest,
1600 					gnutls_gost_paramset_t * paramset,
1601 					gnutls_datum_t * x,
1602 					gnutls_datum_t * y,
1603 					gnutls_datum_t * k)
1604 {
1605 	if (key == NULL) {
1606 		gnutls_assert();
1607 		return GNUTLS_E_INVALID_REQUEST;
1608 	}
1609 
1610 	return _gnutls_params_get_gost_raw(&key->params, curve, digest, paramset,
1611 					   x, y, k, 0);
1612 }
1613 
1614 /**
1615  * gnutls_x509_privkey_export_rsa_raw:
1616  * @key: a key
1617  * @m: will hold the modulus
1618  * @e: will hold the public exponent
1619  * @d: will hold the private exponent
1620  * @p: will hold the first prime (p)
1621  * @q: will hold the second prime (q)
1622  * @u: will hold the coefficient
1623  *
1624  * This function will export the RSA private key's parameters found
1625  * in the given structure. The new parameters will be allocated using
1626  * gnutls_malloc() and will be stored in the appropriate datum.
1627  *
1628  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1629  *   negative error value.
1630  **/
1631 int
gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,gnutls_datum_t * m,gnutls_datum_t * e,gnutls_datum_t * d,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * u)1632 gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
1633 				   gnutls_datum_t * m, gnutls_datum_t * e,
1634 				   gnutls_datum_t * d, gnutls_datum_t * p,
1635 				   gnutls_datum_t * q, gnutls_datum_t * u)
1636 {
1637 	return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, NULL, NULL, 0);
1638 }
1639 
1640 /**
1641  * gnutls_x509_privkey_export_rsa_raw2:
1642  * @key: a key
1643  * @m: will hold the modulus
1644  * @e: will hold the public exponent
1645  * @d: will hold the private exponent
1646  * @p: will hold the first prime (p)
1647  * @q: will hold the second prime (q)
1648  * @u: will hold the coefficient
1649  * @e1: will hold e1 = d mod (p-1)
1650  * @e2: will hold e2 = d mod (q-1)
1651  *
1652  * This function will export the RSA private key's parameters found
1653  * in the given structure. The new parameters will be allocated using
1654  * gnutls_malloc() and will be stored in the appropriate datum.
1655  *
1656  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1657  *   negative error value.
1658  *
1659  * Since: 2.12.0
1660  **/
1661 int
gnutls_x509_privkey_export_rsa_raw2(gnutls_x509_privkey_t key,gnutls_datum_t * m,gnutls_datum_t * e,gnutls_datum_t * d,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * u,gnutls_datum_t * e1,gnutls_datum_t * e2)1662 gnutls_x509_privkey_export_rsa_raw2(gnutls_x509_privkey_t key,
1663 				    gnutls_datum_t * m, gnutls_datum_t * e,
1664 				    gnutls_datum_t * d, gnutls_datum_t * p,
1665 				    gnutls_datum_t * q, gnutls_datum_t * u,
1666 				    gnutls_datum_t * e1,
1667 				    gnutls_datum_t * e2)
1668 {
1669 	return _gnutls_params_get_rsa_raw(&key->params, m, e, d, p, q, u, e1, e2, 0);
1670 }
1671 
1672 /**
1673  * gnutls_x509_privkey_export_dsa_raw:
1674  * @key: a key
1675  * @p: will hold the p
1676  * @q: will hold the q
1677  * @g: will hold the g
1678  * @y: will hold the y
1679  * @x: will hold the x
1680  *
1681  * This function will export the DSA private key's parameters found
1682  * in the given structure. The new parameters will be allocated using
1683  * gnutls_malloc() and will be stored in the appropriate datum.
1684  *
1685  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1686  *   negative error value.
1687  **/
1688 int
gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * g,gnutls_datum_t * y,gnutls_datum_t * x)1689 gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,
1690 				   gnutls_datum_t * p, gnutls_datum_t * q,
1691 				   gnutls_datum_t * g, gnutls_datum_t * y,
1692 				   gnutls_datum_t * x)
1693 {
1694 	return _gnutls_params_get_dsa_raw(&key->params, p, q, g, y, x, 0);
1695 }
1696 
1697 /**
1698  * gnutls_x509_privkey_generate:
1699  * @key: an initialized key
1700  * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1701  * @bits: the size of the parameters to generate
1702  * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1703  *
1704  * This function will generate a random private key. Note that this
1705  * function must be called on an initialized private key.
1706  *
1707  * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1708  * instructs the key generation process to use algorithms like Shawe-Taylor
1709  * (from FIPS PUB186-4) which generate provable parameters out of a seed
1710  * for RSA and DSA keys. See gnutls_x509_privkey_generate2() for more
1711  * information.
1712  *
1713  * Note that when generating an elliptic curve key, the curve
1714  * can be substituted in the place of the bits parameter using the
1715  * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
1716  * %gnutls_ecc_curve_t.
1717  *
1718  * For DSA keys, if the subgroup size needs to be specified check
1719  * the GNUTLS_SUBGROUP_TO_BITS() macro.
1720  *
1721  * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
1722  *
1723  * See also gnutls_privkey_generate(), gnutls_x509_privkey_generate2().
1724  *
1725  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1726  *   negative error value.
1727  **/
1728 int
gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,gnutls_pk_algorithm_t algo,unsigned int bits,unsigned int flags)1729 gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
1730 			     gnutls_pk_algorithm_t algo, unsigned int bits,
1731 			     unsigned int flags)
1732 {
1733 	return gnutls_x509_privkey_generate2(key, algo, bits, flags, NULL, 0);
1734 }
1735 
1736 /**
1737  * gnutls_x509_privkey_generate2:
1738  * @key: a key
1739  * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1740  * @bits: the size of the modulus
1741  * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1742  * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
1743  * @data_size: The number of @data available.
1744  *
1745  * This function will generate a random private key. Note that this
1746  * function must be called on an initialized private key.
1747  *
1748  * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1749  * instructs the key generation process to use algorithms like Shawe-Taylor
1750  * (from FIPS PUB186-4) which generate provable parameters out of a seed
1751  * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
1752  * seed, while on RSA the two primes. To specify an explicit seed
1753  * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
1754  * type.
1755  *
1756  * Note that when generating an elliptic curve key, the curve
1757  * can be substituted in the place of the bits parameter using the
1758  * GNUTLS_CURVE_TO_BITS() macro.
1759  *
1760  * To export the generated keys in memory or in files it is recommended to use the
1761  * PKCS#8 form as it can handle all key types, and can store additional parameters
1762  * such as the seed, in case of provable RSA or DSA keys.
1763  * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
1764  * and then with gnutls_x509_privkey_export2_pkcs8().
1765  *
1766  * If key generation is part of your application, avoid setting the number
1767  * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
1768  * That way the generated keys will adapt to the security levels
1769  * of the underlying GnuTLS library.
1770  *
1771  * See also gnutls_privkey_generate2().
1772  *
1773  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1774  *   negative error value.
1775  **/
1776 int
gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,gnutls_pk_algorithm_t algo,unsigned int bits,unsigned int flags,const gnutls_keygen_data_st * data,unsigned data_size)1777 gnutls_x509_privkey_generate2(gnutls_x509_privkey_t key,
1778 			      gnutls_pk_algorithm_t algo, unsigned int bits,
1779 			      unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size)
1780 {
1781 	int ret;
1782 	unsigned i;
1783 	gnutls_x509_spki_t tpki = NULL;
1784 
1785 	if (key == NULL) {
1786 		gnutls_assert();
1787 		return GNUTLS_E_INVALID_REQUEST;
1788 	}
1789 
1790 	gnutls_pk_params_init(&key->params);
1791 
1792 	for (i=0;i<data_size;i++) {
1793 		if (data[i].type == GNUTLS_KEYGEN_SEED && data[i].size < sizeof(key->params.seed)) {
1794 			key->params.seed_size = data[i].size;
1795 			memcpy(key->params.seed, data[i].data, data[i].size);
1796 		} else if (data[i].type == GNUTLS_KEYGEN_DIGEST) {
1797 			key->params.palgo = data[i].size;
1798 		} else if (data[i].type == GNUTLS_KEYGEN_SPKI) {
1799 			tpki = (void*)data[i].data;
1800 		}
1801 	}
1802 
1803 	if (IS_EC(algo)) {
1804 		if (GNUTLS_BITS_ARE_CURVE(bits))
1805 			bits = GNUTLS_BITS_TO_CURVE(bits);
1806 		else
1807 			bits = _gnutls_ecc_bits_to_curve(algo, bits);
1808 
1809 		if (gnutls_ecc_curve_get_pk(bits) != algo) {
1810 			_gnutls_debug_log("curve is incompatible with public key algorithm\n");
1811 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1812 		}
1813 	}
1814 
1815 	if (IS_GOSTEC(algo)) {
1816 		int size;
1817 
1818 		if (GNUTLS_BITS_ARE_CURVE(bits))
1819 			bits = GNUTLS_BITS_TO_CURVE(bits);
1820 		else
1821 			bits = _gnutls_ecc_bits_to_curve(algo, bits);
1822 
1823 		size = gnutls_ecc_curve_get_size(bits);
1824 
1825 		if ((algo == GNUTLS_PK_GOST_01 && size != 32) ||
1826 		    (algo == GNUTLS_PK_GOST_12_256 && size != 32) ||
1827 		    (algo == GNUTLS_PK_GOST_12_512 && size != 64)) {
1828 			_gnutls_debug_log("curve is incompatible with public key algorithm\n");
1829 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1830 		}
1831 
1832 		key->params.gost_params = _gnutls_gost_paramset_default(algo);
1833 	}
1834 
1835 	if (flags & GNUTLS_PRIVKEY_FLAG_PROVABLE) {
1836 		key->params.pkflags |= GNUTLS_PK_FLAG_PROVABLE;
1837 	}
1838 
1839 	key->params.algo = algo;
1840 
1841 	ret = _gnutls_pk_generate_params(algo, bits, &key->params);
1842 	if (ret < 0) {
1843 		gnutls_assert();
1844 		return ret;
1845 	}
1846 
1847 	if (algo == GNUTLS_PK_RSA_PSS && (flags & GNUTLS_PRIVKEY_FLAG_CA) &&
1848 	    !key->params.spki.pk) {
1849 		const mac_entry_st *me;
1850 		key->params.spki.pk = GNUTLS_PK_RSA_PSS;
1851 
1852 		key->params.spki.rsa_pss_dig = _gnutls_pk_bits_to_sha_hash(bits);
1853 
1854 		me = hash_to_entry(key->params.spki.rsa_pss_dig);
1855 		if (unlikely(me == NULL)) {
1856 			gnutls_assert();
1857 			ret = GNUTLS_E_INVALID_REQUEST;
1858 			goto cleanup;
1859 		}
1860 
1861 		ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
1862 		if (ret < 0) {
1863 			gnutls_assert();
1864 			goto cleanup;
1865 		}
1866 
1867 		key->params.spki.salt_size = ret;
1868 	}
1869 
1870 	ret = _gnutls_pk_generate_keys(algo, bits, &key->params, 0);
1871 	if (ret < 0) {
1872 		gnutls_assert();
1873 		goto cleanup;
1874 	}
1875 
1876 	ret = _gnutls_pk_verify_priv_params(algo, &key->params);
1877 	if (ret < 0) {
1878 		gnutls_assert();
1879 		goto cleanup;
1880 	}
1881 
1882 	if (tpki) {
1883 		ret = gnutls_x509_privkey_set_spki(key, tpki, 0);
1884 		if (ret < 0) {
1885 			gnutls_assert();
1886 			goto cleanup;
1887 		}
1888 	}
1889 
1890 	ret = _gnutls_asn1_encode_privkey(&key->key, &key->params);
1891 	if (ret < 0) {
1892 		gnutls_assert();
1893 		goto cleanup;
1894 	}
1895 
1896 	return 0;
1897 
1898       cleanup:
1899 	key->params.algo = GNUTLS_PK_UNKNOWN;
1900 	gnutls_pk_params_clear(&key->params);
1901 	gnutls_pk_params_release(&key->params);
1902 
1903 	return ret;
1904 }
1905 
1906 /**
1907  * gnutls_x509_privkey_get_seed:
1908  * @key: should contain a #gnutls_x509_privkey_t type
1909  * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
1910  * @seed: where seed will be copied to
1911  * @seed_size: originally holds the size of @seed, will be updated with actual size
1912  *
1913  * This function will return the seed that was used to generate the
1914  * given private key. That function will succeed only if the key was generated
1915  * as a provable key.
1916  *
1917  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1918  *   negative error value.
1919  *
1920  * Since: 3.5.0
1921  **/
gnutls_x509_privkey_get_seed(gnutls_x509_privkey_t key,gnutls_digest_algorithm_t * digest,void * seed,size_t * seed_size)1922 int gnutls_x509_privkey_get_seed(gnutls_x509_privkey_t key, gnutls_digest_algorithm_t *digest, void *seed, size_t *seed_size)
1923 {
1924 	if (key->params.seed_size == 0)
1925 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1926 
1927 	if (seed_size == NULL || seed == NULL) {
1928 		if (key->params.seed_size)
1929 			return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
1930 		else
1931 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1932 	}
1933 
1934 	if (*seed_size < key->params.seed_size) {
1935 		*seed_size = key->params.seed_size;
1936 		return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
1937 	}
1938 
1939 	if (digest)
1940 		*digest = key->params.palgo;
1941 
1942 	memcpy(seed, key->params.seed, key->params.seed_size);
1943 	*seed_size = key->params.seed_size;
1944 	return 0;
1945 }
1946 
1947 static
cmp_rsa_key(gnutls_x509_privkey_t key1,gnutls_x509_privkey_t key2)1948 int cmp_rsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
1949 {
1950 	gnutls_datum_t m1 = {NULL, 0}, e1 = {NULL, 0}, d1 = {NULL, 0}, p1 = {NULL, 0}, q1 = {NULL, 0};
1951 	gnutls_datum_t m2 = {NULL, 0}, e2 = {NULL, 0}, d2 = {NULL, 0}, p2 = {NULL, 0}, q2 = {NULL, 0};
1952 	int ret;
1953 
1954 	ret = gnutls_x509_privkey_export_rsa_raw(key1, &m1, &e1, &d1, &p1, &q1, NULL);
1955 	if (ret < 0) {
1956 		gnutls_assert();
1957 		return ret;
1958 	}
1959 
1960 	ret = gnutls_x509_privkey_export_rsa_raw(key2, &m2, &e2, &d2, &p2, &q2, NULL);
1961 	if (ret < 0) {
1962 		gnutls_assert();
1963 		goto cleanup;
1964 	}
1965 
1966 	if (m1.size != m2.size || memcmp(m1.data, m2.data, m1.size) != 0) {
1967 		gnutls_assert();
1968 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
1969 		goto cleanup;
1970 	}
1971 
1972 	if (d1.size != d2.size || memcmp(d1.data, d2.data, d1.size) != 0) {
1973 		gnutls_assert();
1974 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
1975 		goto cleanup;
1976 	}
1977 
1978 	if (e1.size != e2.size || memcmp(e1.data, e2.data, e1.size) != 0) {
1979 		gnutls_assert();
1980 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
1981 		goto cleanup;
1982 	}
1983 
1984 	if (p1.size != p2.size || memcmp(p1.data, p2.data, p1.size) != 0) {
1985 		gnutls_assert();
1986 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
1987 		goto cleanup;
1988 	}
1989 
1990 	if (q1.size != q2.size || memcmp(q1.data, q2.data, q1.size) != 0) {
1991 		gnutls_assert();
1992 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
1993 		goto cleanup;
1994 	}
1995 
1996 	ret = 0;
1997  cleanup:
1998 	gnutls_free(m1.data);
1999 	gnutls_free(e1.data);
2000 	gnutls_free(d1.data);
2001 	gnutls_free(p1.data);
2002 	gnutls_free(q1.data);
2003 	gnutls_free(m2.data);
2004 	gnutls_free(e2.data);
2005 	gnutls_free(d2.data);
2006 	gnutls_free(p2.data);
2007 	gnutls_free(q2.data);
2008 	return ret;
2009 }
2010 
2011 static
cmp_dsa_key(gnutls_x509_privkey_t key1,gnutls_x509_privkey_t key2)2012 int cmp_dsa_key(gnutls_x509_privkey_t key1, gnutls_x509_privkey_t key2)
2013 {
2014 	gnutls_datum_t p1 = {NULL, 0}, q1 = {NULL, 0}, g1 = {NULL, 0};
2015 	gnutls_datum_t p2 = {NULL, 0}, q2 = {NULL, 0}, g2 = {NULL, 0};
2016 	int ret;
2017 
2018 	ret = gnutls_x509_privkey_export_dsa_raw(key1, &p1, &q1, &g1, NULL, NULL);
2019 	if (ret < 0) {
2020 		gnutls_assert();
2021 		return ret;
2022 	}
2023 
2024 	ret = gnutls_x509_privkey_export_dsa_raw(key2, &p2, &q2, &g2, NULL, NULL);
2025 	if (ret < 0) {
2026 		gnutls_assert();
2027 		goto cleanup;
2028 	}
2029 
2030 	if (g1.size != g2.size || memcmp(g1.data, g2.data, g1.size) != 0) {
2031 		gnutls_assert();
2032 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2033 		goto cleanup;
2034 	}
2035 
2036 	if (p1.size != p2.size || memcmp(p1.data, p2.data, p1.size) != 0) {
2037 		gnutls_assert();
2038 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2039 		goto cleanup;
2040 	}
2041 
2042 	if (q1.size != q2.size || memcmp(q1.data, q2.data, q1.size) != 0) {
2043 		gnutls_assert();
2044 		ret = GNUTLS_E_PRIVKEY_VERIFICATION_ERROR;
2045 		goto cleanup;
2046 	}
2047 
2048 	ret = 0;
2049  cleanup:
2050 	gnutls_free(g1.data);
2051 	gnutls_free(p1.data);
2052 	gnutls_free(q1.data);
2053 	gnutls_free(g2.data);
2054 	gnutls_free(p2.data);
2055 	gnutls_free(q2.data);
2056 	return ret;
2057 }
2058 
2059 /**
2060  * gnutls_x509_privkey_verify_seed:
2061  * @key: should contain a #gnutls_x509_privkey_t type
2062  * @digest: it contains the digest algorithm used for key generation (if applicable)
2063  * @seed: the seed of the key to be checked with
2064  * @seed_size: holds the size of @seed
2065  *
2066  * This function will verify that the given private key was generated from
2067  * the provided seed. If @seed is %NULL then the seed stored in the @key's structure
2068  * will be used for verification.
2069  *
2070  * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
2071  * is returned, and zero or positive code on success.
2072  *
2073  * Since: 3.5.0
2074  **/
gnutls_x509_privkey_verify_seed(gnutls_x509_privkey_t key,gnutls_digest_algorithm_t digest,const void * seed,size_t seed_size)2075 int gnutls_x509_privkey_verify_seed(gnutls_x509_privkey_t key, gnutls_digest_algorithm_t digest, const void *seed, size_t seed_size)
2076 {
2077 	int ret;
2078 	gnutls_x509_privkey_t okey;
2079 	unsigned bits;
2080 	gnutls_keygen_data_st data;
2081 
2082 	if (key == NULL) {
2083 		gnutls_assert();
2084 		return GNUTLS_E_INVALID_REQUEST;
2085 	}
2086 
2087 	if (key->params.algo != GNUTLS_PK_RSA && key->params.algo != GNUTLS_PK_DSA)
2088 		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
2089 
2090 	ret = gnutls_x509_privkey_get_pk_algorithm2(key, &bits);
2091 	if (ret < 0)
2092 		return gnutls_assert_val(ret);
2093 
2094 	ret = gnutls_x509_privkey_init(&okey);
2095 	if (ret < 0)
2096 		return gnutls_assert_val(ret);
2097 
2098 	if (seed == NULL) {
2099 		seed = key->params.seed;
2100 		seed_size = key->params.seed_size;
2101 	}
2102 
2103 	if (seed == NULL || seed_size == 0)
2104 		return gnutls_assert_val(GNUTLS_E_PK_NO_VALIDATION_PARAMS);
2105 
2106 	data.type = GNUTLS_KEYGEN_SEED;
2107 	data.data = (void*)seed;
2108 	data.size = seed_size;
2109 
2110 	ret = gnutls_x509_privkey_generate2(okey, key->params.algo, bits,
2111 					    GNUTLS_PRIVKEY_FLAG_PROVABLE, &data, 1);
2112 	if (ret < 0) {
2113 		gnutls_assert();
2114 		goto cleanup;
2115 	}
2116 
2117 	if (key->params.algo == GNUTLS_PK_RSA)
2118 		ret = cmp_rsa_key(key, okey);
2119 	else
2120 		ret = cmp_dsa_key(key, okey);
2121 
2122       cleanup:
2123 	gnutls_x509_privkey_deinit(okey);
2124 
2125 	return ret;
2126 }
2127 
2128 /**
2129  * gnutls_x509_privkey_verify_params:
2130  * @key: a key
2131  *
2132  * This function will verify the private key parameters.
2133  *
2134  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2135  *   negative error value.
2136  **/
gnutls_x509_privkey_verify_params(gnutls_x509_privkey_t key)2137 int gnutls_x509_privkey_verify_params(gnutls_x509_privkey_t key)
2138 {
2139 	int ret;
2140 
2141 	ret = _gnutls_pk_verify_priv_params(key->params.algo, &key->params);
2142 	if (ret < 0) {
2143 		gnutls_assert();
2144 		return ret;
2145 	}
2146 
2147 	return 0;
2148 }
2149 
2150 /**
2151  * gnutls_x509_privkey_get_key_id:
2152  * @key: a key
2153  * @flags: should be one of the flags from %gnutls_keyid_flags_t
2154  * @output_data: will contain the key ID
2155  * @output_data_size: holds the size of output_data (and will be
2156  *   replaced by the actual size of parameters)
2157  *
2158  * This function will return a unique ID that depends on the public key
2159  * parameters. This ID can be used in checking whether a certificate
2160  * corresponds to the given key.
2161  *
2162  * If the buffer provided is not long enough to hold the output, then
2163  * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2164  * be returned.  The output will normally be a SHA-1 hash output,
2165  * which is 20 bytes.
2166  *
2167  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2168  *   negative error value.
2169  **/
2170 int
gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,unsigned int flags,unsigned char * output_data,size_t * output_data_size)2171 gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,
2172 			       unsigned int flags,
2173 			       unsigned char *output_data,
2174 			       size_t * output_data_size)
2175 {
2176 	int ret;
2177 
2178 	if (key == NULL) {
2179 		gnutls_assert();
2180 		return GNUTLS_E_INVALID_REQUEST;
2181 	}
2182 
2183 	ret =
2184 	    _gnutls_get_key_id(&key->params,
2185 			       output_data, output_data_size, flags);
2186 	if (ret < 0) {
2187 		gnutls_assert();
2188 	}
2189 
2190 	return ret;
2191 }
2192 
2193 
2194 /**
2195  * gnutls_x509_privkey_sign_hash:
2196  * @key: a key
2197  * @hash: holds the data to be signed
2198  * @signature: will contain newly allocated signature
2199  *
2200  * This function will sign the given hash using the private key. Do not
2201  * use this function directly unless you know what it is. Typical signing
2202  * requires the data to be hashed and stored in special formats
2203  * (e.g. BER Digest-Info for RSA).
2204  *
2205  * This API is provided only for backwards compatibility, and thus
2206  * restricted to RSA, DSA and ECDSA key types. For other key types please
2207  * use gnutls_privkey_sign_hash() and gnutls_privkey_sign_data().
2208  *
2209  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2210  *   negative error value.
2211  *
2212  * Deprecated in: 2.12.0
2213  */
2214 int
gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,const gnutls_datum_t * hash,gnutls_datum_t * signature)2215 gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,
2216 			      const gnutls_datum_t * hash,
2217 			      gnutls_datum_t * signature)
2218 {
2219 	int result;
2220 
2221 	if (key == NULL) {
2222 		gnutls_assert();
2223 		return GNUTLS_E_INVALID_REQUEST;
2224 	}
2225 
2226 	if (key->params.algo != GNUTLS_PK_RSA && key->params.algo != GNUTLS_PK_ECDSA &&
2227 	    key->params.algo != GNUTLS_PK_DSA) {
2228 		/* too primitive API - use only with legacy types */
2229 		gnutls_assert();
2230 		return GNUTLS_E_INVALID_REQUEST;
2231 	}
2232 
2233 	result =
2234 	    _gnutls_pk_sign(key->params.algo, signature, hash,
2235 			    &key->params, &key->params.spki);
2236 
2237 	if (result < 0) {
2238 		gnutls_assert();
2239 		return result;
2240 	}
2241 
2242 	return 0;
2243 }
2244 
2245 /**
2246  * gnutls_x509_privkey_sign_data:
2247  * @key: a key
2248  * @digest: should be a digest algorithm
2249  * @flags: should be 0 for now
2250  * @data: holds the data to be signed
2251  * @signature: will contain the signature
2252  * @signature_size: holds the size of signature (and will be replaced
2253  *   by the new size)
2254  *
2255  * This function will sign the given data using a signature algorithm
2256  * supported by the private key. Signature algorithms are always used
2257  * together with a hash functions.  Different hash functions may be
2258  * used for the RSA algorithm, but only SHA-1 for the DSA keys.
2259  *
2260  * If the buffer provided is not long enough to hold the output, then
2261  * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
2262  * be returned.
2263  *
2264  * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
2265  * the hash algorithm.
2266  *
2267  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2268  *   negative error value.
2269  */
2270 int
gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,gnutls_digest_algorithm_t digest,unsigned int flags,const gnutls_datum_t * data,void * signature,size_t * signature_size)2271 gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,
2272 			      gnutls_digest_algorithm_t digest,
2273 			      unsigned int flags,
2274 			      const gnutls_datum_t * data,
2275 			      void *signature, size_t * signature_size)
2276 {
2277 	gnutls_privkey_t privkey;
2278 	gnutls_datum_t sig = {NULL, 0};
2279 	int ret;
2280 
2281 	ret = gnutls_privkey_init(&privkey);
2282 	if (ret < 0)
2283 		return gnutls_assert_val(ret);
2284 
2285 	ret = gnutls_privkey_import_x509(privkey, key, 0);
2286 	if (ret < 0) {
2287 		gnutls_assert();
2288 		goto cleanup;
2289 	}
2290 
2291 	ret = gnutls_privkey_sign_data(privkey, digest, flags, data, &sig);
2292 	if (ret < 0) {
2293 		gnutls_assert();
2294 		goto cleanup;
2295 	}
2296 
2297 	if (*signature_size < sig.size) {
2298 		*signature_size = sig.size;
2299 		ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
2300 		goto cleanup;
2301 	}
2302 
2303 	*signature_size = sig.size;
2304 	memcpy(signature, sig.data, sig.size);
2305 
2306 cleanup:
2307 	_gnutls_free_datum(&sig);
2308 	gnutls_privkey_deinit(privkey);
2309 	return ret;
2310 }
2311 
2312 /**
2313  * gnutls_x509_privkey_fix:
2314  * @key: a key
2315  *
2316  * This function will recalculate the secondary parameters in a key.
2317  * In RSA keys, this can be the coefficient and exponent1,2.
2318  *
2319  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2320  *   negative error value.
2321  **/
gnutls_x509_privkey_fix(gnutls_x509_privkey_t key)2322 int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key)
2323 {
2324 	int ret;
2325 
2326 	if (key == NULL) {
2327 		gnutls_assert();
2328 		return GNUTLS_E_INVALID_REQUEST;
2329 	}
2330 
2331 	if (key->key) {
2332 		asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
2333 
2334 		ret =
2335 		    _gnutls_asn1_encode_privkey(&key->key,
2336 						&key->params);
2337 		if (ret < 0) {
2338 			gnutls_assert();
2339 			return ret;
2340 		}
2341 	}
2342 
2343 	return 0;
2344 }
2345 
2346 /**
2347  * gnutls_x509_privkey_set_pin_function:
2348  * @privkey: The certificate structure
2349  * @fn: the callback
2350  * @userdata: data associated with the callback
2351  *
2352  * This function will set a callback function to be used when
2353  * it is required to access a protected object. This function overrides
2354  * the global function set using gnutls_pkcs11_set_pin_function().
2355  *
2356  * Note that this callback is used when decrypting a key.
2357  *
2358  * Since: 3.4.0
2359  *
2360  **/
gnutls_x509_privkey_set_pin_function(gnutls_x509_privkey_t privkey,gnutls_pin_callback_t fn,void * userdata)2361 void gnutls_x509_privkey_set_pin_function(gnutls_x509_privkey_t privkey,
2362 				      gnutls_pin_callback_t fn,
2363 				      void *userdata)
2364 {
2365 	privkey->pin.cb = fn;
2366 	privkey->pin.data = userdata;
2367 }
2368 
2369 /**
2370  * gnutls_x509_privkey_set_flags:
2371  * @key: A key of type #gnutls_x509_privkey_t
2372  * @flags: flags from the %gnutls_privkey_flags
2373  *
2374  * This function will set flags for the specified private key, after
2375  * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
2376  * to allow exporting a "provable" private key in backwards compatible way.
2377  *
2378  * Since: 3.5.0
2379  *
2380  **/
gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key,unsigned int flags)2381 void gnutls_x509_privkey_set_flags(gnutls_x509_privkey_t key,
2382 				   unsigned int flags)
2383 {
2384 	key->flags |= flags;
2385 }
2386 
2387