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