1 /*
2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3 * Copyright (C) 2013-2017 Red Hat
4 *
5 * Author: Nikos Mavrogiannopoulos
6 *
7 * This file is part of GnuTLS.
8 *
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>
21 *
22 */
23
24 #include "gnutls_int.h"
25 #include "errors.h"
26 #include <global.h>
27 #include <libtasn1.h>
28 #include <datum.h>
29 #include "common.h"
30 #include "x509_int.h"
31 #include <num.h>
32 #include <pk.h>
33 #include <mpi.h>
34 #include <ecc.h>
35
36 static int _gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st * params,
37 gnutls_datum_t * der);
38 static int _gnutls_x509_write_dsa_params(const gnutls_pk_params_st * params,
39 gnutls_datum_t * der);
40 static int _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st * params,
41 gnutls_datum_t * der);
42 static int _gnutls_x509_write_gost_params(const gnutls_pk_params_st * params,
43 gnutls_datum_t * der);
44 static int _gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st * params,
45 gnutls_datum_t * der);
46
47 /*
48 * some x509 certificate functions that relate to MPI parameter
49 * setting. This writes the BIT STRING subjectPublicKey.
50 * Needs 2 parameters (m,e).
51 *
52 * Allocates the space used to store the DER data.
53 */
54 static int
_gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st * params,gnutls_datum_t * der)55 _gnutls_x509_write_rsa_pubkey(const gnutls_pk_params_st * params,
56 gnutls_datum_t * der)
57 {
58 int result;
59 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
60
61 der->data = NULL;
62 der->size = 0;
63
64 if (params->params_nr < RSA_PUBLIC_PARAMS) {
65 gnutls_assert();
66 result = GNUTLS_E_INVALID_REQUEST;
67 goto cleanup;
68 }
69
70 if ((result = asn1_create_element
71 (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk))
72 != ASN1_SUCCESS) {
73 gnutls_assert();
74 return _gnutls_asn2err(result);
75 }
76
77 result =
78 _gnutls_x509_write_int(spk, "modulus", params->params[0], 1);
79 if (result < 0) {
80 gnutls_assert();
81 goto cleanup;
82 }
83
84 result =
85 _gnutls_x509_write_int(spk, "publicExponent",
86 params->params[1], 1);
87 if (result < 0) {
88 gnutls_assert();
89 goto cleanup;
90 }
91
92 result = _gnutls_x509_der_encode(spk, "", der, 0);
93 if (result < 0) {
94 gnutls_assert();
95 goto cleanup;
96 }
97
98 result = 0;
99
100 cleanup:
101 asn1_delete_structure(&spk);
102
103 return result;
104 }
105
106 /*
107 * some x509 certificate functions that relate to MPI parameter
108 * setting. This writes an ECPoint.
109 *
110 * Allocates the space used to store the DER data.
111 */
112 int
_gnutls_x509_write_ecc_pubkey(const gnutls_pk_params_st * params,gnutls_datum_t * der)113 _gnutls_x509_write_ecc_pubkey(const gnutls_pk_params_st * params,
114 gnutls_datum_t * der)
115 {
116 int result;
117
118 der->data = NULL;
119 der->size = 0;
120
121 if (params->params_nr < ECC_PUBLIC_PARAMS)
122 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
123
124 result =
125 _gnutls_ecc_ansi_x962_export(params->curve,
126 params->params[ECC_X],
127 params->params[ECC_Y], /*&out */
128 der);
129 if (result < 0)
130 return gnutls_assert_val(result);
131
132 return 0;
133 }
134
135 /*
136 * some x509 certificate functions that relate to MPI parameter
137 * setting. This writes a raw public key.
138 *
139 * Allocates the space used to store the data.
140 */
141 int
_gnutls_x509_write_eddsa_pubkey(const gnutls_pk_params_st * params,gnutls_datum_t * raw)142 _gnutls_x509_write_eddsa_pubkey(const gnutls_pk_params_st * params,
143 gnutls_datum_t * raw)
144 {
145 int ret;
146
147 raw->data = NULL;
148 raw->size = 0;
149
150 if (params->raw_pub.size == 0)
151 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
152
153 if (params->curve != GNUTLS_ECC_CURVE_ED25519 &&
154 params->curve != GNUTLS_ECC_CURVE_ED448)
155 return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
156
157 ret = _gnutls_set_datum(raw, params->raw_pub.data, params->raw_pub.size);
158 if (ret < 0)
159 return gnutls_assert_val(ret);
160
161 return 0;
162 }
163
164 int
_gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st * params,gnutls_datum_t * der)165 _gnutls_x509_write_gost_pubkey(const gnutls_pk_params_st * params,
166 gnutls_datum_t * der)
167 {
168 bigint_t x, y;
169 int numlen;
170 int byte_size, ret;
171 size_t size;
172 int pos;
173
174 der->data = NULL;
175 der->size = 0;
176
177 if (params->params_nr < GOST_PUBLIC_PARAMS)
178 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
179
180 x = params->params[GOST_X];
181 y = params->params[GOST_Y];
182 numlen = gnutls_ecc_curve_get_size(params->curve);
183
184 if (numlen == 0)
185 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
186
187 der->size = 1 + ASN1_MAX_LENGTH_SIZE + 2 * numlen;
188
189 der->data = gnutls_malloc(der->size);
190 if (der->data == NULL)
191 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
192
193 memset(der->data, 0, der->size);
194
195 der->data[0] = ASN1_TAG_OCTET_STRING;
196 asn1_length_der(2 * numlen, &der->data[1], &pos);
197 pos += 1;
198
199 /* pad and store x */
200 byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8;
201 if (numlen < byte_size) {
202 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
203 goto cleanup;
204 }
205
206 size = numlen;
207 ret = _gnutls_mpi_print_le(x, &der->data[pos], &size);
208 if (ret < 0) {
209 gnutls_assert();
210 goto cleanup;
211 }
212
213 /* pad and store y */
214 byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8;
215 if (numlen < byte_size) {
216 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
217 goto cleanup;
218 }
219
220 size = numlen;
221 ret = _gnutls_mpi_print_le(y, &der->data[pos + numlen], &size);
222 if (ret < 0) {
223 gnutls_assert();
224 goto cleanup;
225 }
226
227 der->size = pos + 2 * numlen;
228
229 return 0;
230
231 cleanup:
232 _gnutls_free_datum(der);
233 return ret;
234 }
235
236 int
_gnutls_x509_write_pubkey_params(const gnutls_pk_params_st * params,gnutls_datum_t * der)237 _gnutls_x509_write_pubkey_params(const gnutls_pk_params_st * params,
238 gnutls_datum_t * der)
239 {
240 switch (params->algo) {
241 case GNUTLS_PK_DSA:
242 return _gnutls_x509_write_dsa_params(params, der);
243 case GNUTLS_PK_RSA:
244 der->data = gnutls_malloc(ASN1_NULL_SIZE);
245 if (der->data == NULL)
246 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
247
248 memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE);
249 der->size = ASN1_NULL_SIZE;
250 return 0;
251 case GNUTLS_PK_RSA_PSS:
252 return _gnutls_x509_write_rsa_pss_params(¶ms->spki, der);
253 case GNUTLS_PK_ECDSA:
254 return _gnutls_x509_write_ecc_params(params->curve, der);
255 case GNUTLS_PK_EDDSA_ED25519:
256 case GNUTLS_PK_EDDSA_ED448:
257 der->data = NULL;
258 der->size = 0;
259
260 return 0;
261 case GNUTLS_PK_GOST_01:
262 case GNUTLS_PK_GOST_12_256:
263 case GNUTLS_PK_GOST_12_512:
264 return _gnutls_x509_write_gost_params(params, der);
265 default:
266 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
267 }
268 }
269
270 int
_gnutls_x509_write_pubkey(const gnutls_pk_params_st * params,gnutls_datum_t * der)271 _gnutls_x509_write_pubkey(const gnutls_pk_params_st * params,
272 gnutls_datum_t * der)
273 {
274 switch (params->algo) {
275 case GNUTLS_PK_DSA:
276 return _gnutls_x509_write_dsa_pubkey(params, der);
277 case GNUTLS_PK_RSA:
278 case GNUTLS_PK_RSA_PSS:
279 return _gnutls_x509_write_rsa_pubkey(params, der);
280 case GNUTLS_PK_ECDSA:
281 return _gnutls_x509_write_ecc_pubkey(params, der);
282 case GNUTLS_PK_EDDSA_ED25519:
283 case GNUTLS_PK_EDDSA_ED448:
284 return _gnutls_x509_write_eddsa_pubkey(params, der);
285 case GNUTLS_PK_GOST_01:
286 case GNUTLS_PK_GOST_12_256:
287 case GNUTLS_PK_GOST_12_512:
288 return _gnutls_x509_write_gost_pubkey(params, der);
289 default:
290 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
291 }
292 }
293
294 /*
295 * This function writes the parameters for DSS keys.
296 * Needs 3 parameters (p,q,g).
297 *
298 * Allocates the space used to store the DER data.
299 */
300 static int
_gnutls_x509_write_dsa_params(const gnutls_pk_params_st * params,gnutls_datum_t * der)301 _gnutls_x509_write_dsa_params(const gnutls_pk_params_st * params,
302 gnutls_datum_t * der)
303 {
304 int result;
305 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
306
307 der->data = NULL;
308 der->size = 0;
309
310 if (params->params_nr < DSA_PUBLIC_PARAMS - 1) {
311 gnutls_assert();
312 result = GNUTLS_E_INVALID_REQUEST;
313 goto cleanup;
314 }
315
316 if ((result = asn1_create_element
317 (_gnutls_get_gnutls_asn(), "GNUTLS.DSAParameters", &spk))
318 != ASN1_SUCCESS) {
319 gnutls_assert();
320 return _gnutls_asn2err(result);
321 }
322
323 result = _gnutls_x509_write_int(spk, "p", params->params[0], 1);
324 if (result < 0) {
325 gnutls_assert();
326 goto cleanup;
327 }
328
329 result = _gnutls_x509_write_int(spk, "q", params->params[1], 1);
330 if (result < 0) {
331 gnutls_assert();
332 goto cleanup;
333 }
334
335 result = _gnutls_x509_write_int(spk, "g", params->params[2], 1);
336 if (result < 0) {
337 gnutls_assert();
338 goto cleanup;
339 }
340
341 result = _gnutls_x509_der_encode(spk, "", der, 0);
342 if (result < 0) {
343 gnutls_assert();
344 goto cleanup;
345 }
346
347 result = 0;
348
349 cleanup:
350 asn1_delete_structure(&spk);
351 return result;
352 }
353
354 /*
355 * This function writes the parameters for ECC keys.
356 * That is the ECParameters struct.
357 *
358 * Allocates the space used to store the DER data.
359 */
360 int
_gnutls_x509_write_ecc_params(const gnutls_ecc_curve_t curve,gnutls_datum_t * der)361 _gnutls_x509_write_ecc_params(const gnutls_ecc_curve_t curve,
362 gnutls_datum_t * der)
363 {
364 int result;
365 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
366 const char *oid;
367
368 der->data = NULL;
369 der->size = 0;
370
371 oid = gnutls_ecc_curve_get_oid(curve);
372 if (oid == NULL)
373 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
374
375
376 if ((result = asn1_create_element
377 (_gnutls_get_gnutls_asn(), "GNUTLS.ECParameters", &spk))
378 != ASN1_SUCCESS) {
379 gnutls_assert();
380 return _gnutls_asn2err(result);
381 }
382
383 if ((result =
384 asn1_write_value(spk, "", "namedCurve", 1)) != ASN1_SUCCESS) {
385 gnutls_assert();
386 result = _gnutls_asn2err(result);
387 goto cleanup;
388 }
389
390 if ((result =
391 asn1_write_value(spk, "namedCurve", oid,
392 1)) != ASN1_SUCCESS) {
393 gnutls_assert();
394 result = _gnutls_asn2err(result);
395 goto cleanup;
396 }
397
398 result = _gnutls_x509_der_encode(spk, "", der, 0);
399 if (result < 0) {
400 gnutls_assert();
401 goto cleanup;
402 }
403
404 result = 0;
405
406 cleanup:
407 asn1_delete_structure(&spk);
408 return result;
409 }
410
411 int
_gnutls_x509_write_rsa_pss_params(const gnutls_x509_spki_st * params,gnutls_datum_t * der)412 _gnutls_x509_write_rsa_pss_params(const gnutls_x509_spki_st *params,
413 gnutls_datum_t *der)
414 {
415 int result;
416 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
417 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
418 const char *oid;
419 gnutls_datum_t tmp = { NULL, 0 };
420
421 der->data = NULL;
422 der->size = 0;
423
424 if (params->pk != GNUTLS_PK_RSA_PSS)
425 return 0;
426
427 /* refuse to write parameters we cannot read */
428 if (gnutls_pk_to_sign(GNUTLS_PK_RSA_PSS, params->rsa_pss_dig) == GNUTLS_SIGN_UNKNOWN)
429 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
430
431 if ((result = asn1_create_element
432 (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPSSParameters", &spk))
433 != ASN1_SUCCESS) {
434 gnutls_assert();
435 result = _gnutls_asn2err(result);
436 goto cleanup;
437 }
438
439 oid = gnutls_digest_get_oid(params->rsa_pss_dig);
440
441 if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid, 1))
442 != ASN1_SUCCESS) {
443 gnutls_assert();
444 result = _gnutls_asn2err(result);
445 goto cleanup;
446 }
447
448 if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL, 0))
449 != ASN1_SUCCESS) {
450 gnutls_assert();
451 result = _gnutls_asn2err(result);
452 goto cleanup;
453 }
454
455 if ((result =
456 asn1_write_value(spk, "maskGenAlgorithm.algorithm",
457 PKIX1_RSA_PSS_MGF1_OID, 1))
458 != ASN1_SUCCESS) {
459 gnutls_assert();
460 result = _gnutls_asn2err(result);
461 goto cleanup;
462 }
463
464 if ((result = asn1_create_element
465 (_gnutls_get_pkix(), "PKIX1.AlgorithmIdentifier", &c2))
466 != ASN1_SUCCESS) {
467 gnutls_assert();
468 result = _gnutls_asn2err(result);
469 goto cleanup;
470 }
471
472 if ((result = asn1_write_value(c2, "algorithm", oid, 1))
473 != ASN1_SUCCESS) {
474 gnutls_assert();
475 result = _gnutls_asn2err(result);
476 goto cleanup;
477 }
478
479 if ((result = asn1_write_value(c2, "parameters", NULL, 0))
480 != ASN1_SUCCESS) {
481 gnutls_assert();
482 result = _gnutls_asn2err(result);
483 goto cleanup;
484 }
485
486 result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
487 if (result < 0) {
488 gnutls_assert();
489 goto cleanup;
490 }
491
492 if ((result =
493 asn1_write_value(spk, "maskGenAlgorithm.parameters",
494 tmp.data, tmp.size))
495 != ASN1_SUCCESS) {
496 gnutls_assert();
497 result = _gnutls_asn2err(result);
498 goto cleanup;
499 }
500
501 result = _gnutls_x509_write_uint32(spk, "saltLength",
502 params->salt_size);
503 if (result < 0) {
504 gnutls_assert();
505 goto cleanup;
506 }
507
508 result = _gnutls_x509_write_uint32(spk, "trailerField", 1);
509 if (result < 0) {
510 gnutls_assert();
511 goto cleanup;
512 }
513
514 result = _gnutls_x509_der_encode(spk, "", der, 0);
515 if (result < 0) {
516 gnutls_assert();
517 goto cleanup;
518 }
519
520 result = 0;
521
522 cleanup:
523 _gnutls_free_datum(&tmp);
524 asn1_delete_structure(&c2);
525 asn1_delete_structure(&spk);
526 return result;
527 }
528
529 static int
_gnutls_x509_write_gost_params(const gnutls_pk_params_st * params,gnutls_datum_t * der)530 _gnutls_x509_write_gost_params(const gnutls_pk_params_st * params,
531 gnutls_datum_t * der)
532 {
533 int result;
534 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
535 const char *oid;
536
537 der->data = NULL;
538 der->size = 0;
539
540 oid = gnutls_ecc_curve_get_oid(params->curve);
541 if (oid == NULL)
542 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
543
544
545 if ((result = asn1_create_element
546 (_gnutls_get_gnutls_asn(),
547 params->algo == GNUTLS_PK_GOST_01 ?
548 "GNUTLS.GOSTParametersOld" :
549 "GNUTLS.GOSTParameters", &spk))
550 != ASN1_SUCCESS) {
551 gnutls_assert();
552 return _gnutls_asn2err(result);
553 }
554
555 if ((result =
556 asn1_write_value(spk, "publicKeyParamSet", oid,
557 1)) != ASN1_SUCCESS) {
558 gnutls_assert();
559 result = _gnutls_asn2err(result);
560 goto cleanup;
561 }
562
563 /* For compatibility per R 1323565.1.023—2018 provide digest OID only
564 * for GOST-2001 keys or GOST-2012 keys with CryptoPro curves. Do not
565 * set this optional parameter for TC26 curves */
566 if (params->algo == GNUTLS_PK_GOST_01)
567 oid = HASH_OID_GOST_R_3411_94_CRYPTOPRO_PARAMS;
568 else if (params->algo == GNUTLS_PK_GOST_12_256 &&
569 (params->curve == GNUTLS_ECC_CURVE_GOST256CPA ||
570 params->curve == GNUTLS_ECC_CURVE_GOST256CPB ||
571 params->curve == GNUTLS_ECC_CURVE_GOST256CPC ||
572 params->curve == GNUTLS_ECC_CURVE_GOST256CPXA ||
573 params->curve == GNUTLS_ECC_CURVE_GOST256CPXB))
574 oid = HASH_OID_STREEBOG_256;
575 else if (params->algo == GNUTLS_PK_GOST_12_512 &&
576 (params->curve == GNUTLS_ECC_CURVE_GOST512A ||
577 params->curve == GNUTLS_ECC_CURVE_GOST512B))
578 oid = HASH_OID_STREEBOG_512;
579 else
580 oid = NULL;
581
582 if ((result = asn1_write_value(spk, "digestParamSet", oid, oid ? 1 : 0)) != ASN1_SUCCESS) {
583 gnutls_assert();
584 result = _gnutls_asn2err(result);
585 goto cleanup;
586 }
587
588 oid = gnutls_gost_paramset_get_oid(params->gost_params);
589 if (oid == NULL) {
590 gnutls_assert();
591 result = GNUTLS_E_INVALID_REQUEST;
592 goto cleanup;
593 }
594
595 if (params->algo == GNUTLS_PK_GOST_01) {
596 if (params->gost_params == _gnutls_gost_paramset_default(params->algo))
597 oid = NULL;
598
599 if ((result =
600 asn1_write_value(spk, "encryptionParamSet", oid,
601 oid ? 1 : 0)) != ASN1_SUCCESS) {
602 gnutls_assert();
603 result = _gnutls_asn2err(result);
604 goto cleanup;
605 }
606 }
607
608 result = _gnutls_x509_der_encode(spk, "", der, 0);
609 if (result < 0) {
610 gnutls_assert();
611 goto cleanup;
612 }
613
614 result = 0;
615
616 cleanup:
617 asn1_delete_structure(&spk);
618 return result;
619 }
620
621 /*
622 * This function writes the public parameters for DSS keys.
623 * Needs 1 parameter (y).
624 *
625 * Allocates the space used to store the DER data.
626 */
627 static int
_gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st * params,gnutls_datum_t * der)628 _gnutls_x509_write_dsa_pubkey(const gnutls_pk_params_st * params,
629 gnutls_datum_t * der)
630 {
631 int result;
632 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
633
634 der->data = NULL;
635 der->size = 0;
636
637 if (params->params_nr < DSA_PUBLIC_PARAMS) {
638 gnutls_assert();
639 result = GNUTLS_E_INVALID_REQUEST;
640 goto cleanup;
641 }
642
643 if ((result = asn1_create_element
644 (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk))
645 != ASN1_SUCCESS) {
646 gnutls_assert();
647 return _gnutls_asn2err(result);
648 }
649
650 result = _gnutls_x509_write_int(spk, "", params->params[3], 1);
651 if (result < 0) {
652 gnutls_assert();
653 goto cleanup;
654 }
655
656 result = _gnutls_x509_der_encode(spk, "", der, 0);
657 if (result < 0) {
658 gnutls_assert();
659 goto cleanup;
660 }
661
662 result = 0;
663
664 cleanup:
665 asn1_delete_structure(&spk);
666 return result;
667 }
668
669 /* Encodes the RSA parameters into an ASN.1 RSA private key structure.
670 */
671 static int
_gnutls_asn1_encode_rsa(ASN1_TYPE * c2,gnutls_pk_params_st * params)672 _gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
673 {
674 int result, ret;
675 uint8_t null = '\0';
676 gnutls_pk_params_st pk_params;
677
678 /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
679 * i.e., regenerate some parameters in case they were broken */
680 gnutls_pk_params_init(&pk_params);
681
682 ret = _gnutls_pk_params_copy(&pk_params, params);
683 if (ret < 0) {
684 gnutls_assert();
685 return ret;
686 }
687
688 ret =
689 _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
690 if (ret < 0) {
691 gnutls_assert();
692 goto cleanup;
693 }
694
695 /* Ok. Now we have the data. Create the asn1 structures
696 */
697
698 /* first make sure that no previously allocated data are leaked */
699 if (*c2 != ASN1_TYPE_EMPTY) {
700 asn1_delete_structure(c2);
701 *c2 = ASN1_TYPE_EMPTY;
702 }
703
704 if ((result = asn1_create_element
705 (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2))
706 != ASN1_SUCCESS) {
707 gnutls_assert();
708 ret = _gnutls_asn2err(result);
709 goto cleanup;
710 }
711
712 /* Write PRIME
713 */
714 ret =
715 _gnutls_x509_write_int(*c2, "modulus",
716 params->params[RSA_MODULUS], 1);
717 if (ret < 0) {
718 gnutls_assert();
719 goto cleanup;
720 }
721
722 ret =
723 _gnutls_x509_write_int(*c2, "publicExponent",
724 params->params[RSA_PUB], 1);
725 if (ret < 0) {
726 gnutls_assert();
727 goto cleanup;
728 }
729
730 ret =
731 _gnutls_x509_write_key_int(*c2, "privateExponent",
732 params->params[RSA_PRIV], 1);
733 if (ret < 0) {
734 gnutls_assert();
735 goto cleanup;
736 }
737
738 ret =
739 _gnutls_x509_write_key_int(*c2, "prime1",
740 params->params[RSA_PRIME1], 1);
741 if (ret < 0) {
742 gnutls_assert();
743 goto cleanup;
744 }
745
746 ret =
747 _gnutls_x509_write_key_int(*c2, "prime2",
748 params->params[RSA_PRIME2], 1);
749 if (ret < 0) {
750 gnutls_assert();
751 goto cleanup;
752 }
753
754 ret =
755 _gnutls_x509_write_key_int(*c2, "coefficient",
756 params->params[RSA_COEF], 1);
757 if (ret < 0) {
758 gnutls_assert();
759 goto cleanup;
760 }
761
762 ret =
763 _gnutls_x509_write_key_int(*c2, "exponent1",
764 params->params[RSA_E1], 1);
765 if (ret < 0) {
766 gnutls_assert();
767 goto cleanup;
768 }
769
770 ret =
771 _gnutls_x509_write_key_int(*c2, "exponent2",
772 params->params[RSA_E2], 1);
773 if (ret < 0) {
774 gnutls_assert();
775 goto cleanup;
776 }
777
778 if ((result = asn1_write_value(*c2, "otherPrimeInfos",
779 NULL, 0)) != ASN1_SUCCESS) {
780 gnutls_assert();
781 ret = _gnutls_asn2err(result);
782 goto cleanup;
783 }
784
785 if ((result =
786 asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
787 gnutls_assert();
788 ret = _gnutls_asn2err(result);
789 goto cleanup;
790 }
791
792 ret = 0;
793
794 cleanup:
795 if (ret < 0)
796 asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
797
798 gnutls_pk_params_clear(&pk_params);
799 gnutls_pk_params_release(&pk_params);
800 return ret;
801 }
802
803 /* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
804 */
805 static int
_gnutls_asn1_encode_ecc(ASN1_TYPE * c2,gnutls_pk_params_st * params)806 _gnutls_asn1_encode_ecc(ASN1_TYPE * c2, gnutls_pk_params_st * params)
807 {
808 int ret;
809 uint8_t one = '\x01';
810 gnutls_datum_t pubkey = { NULL, 0 };
811 const char *oid;
812
813 oid = gnutls_ecc_curve_get_oid(params->curve);
814 if (oid == NULL)
815 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
816
817 /* first make sure that no previously allocated data are leaked */
818 if (*c2 != ASN1_TYPE_EMPTY) {
819 asn1_delete_structure(c2);
820 *c2 = ASN1_TYPE_EMPTY;
821 }
822
823 if ((ret = asn1_create_element
824 (_gnutls_get_gnutls_asn(), "GNUTLS.ECPrivateKey", c2))
825 != ASN1_SUCCESS) {
826 gnutls_assert();
827 ret = _gnutls_asn2err(ret);
828 goto cleanup;
829 }
830
831 if ((ret =
832 asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) {
833 gnutls_assert();
834 ret = _gnutls_asn2err(ret);
835 goto cleanup;
836 }
837
838 if (curve_is_eddsa(params->curve)) {
839 if (params->raw_pub.size == 0 || params->raw_priv.size == 0)
840 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
841 ret =
842 asn1_write_value(*c2, "privateKey", params->raw_priv.data, params->raw_priv.size);
843 if (ret != ASN1_SUCCESS) {
844 gnutls_assert();
845 ret = _gnutls_asn2err(ret);
846 goto cleanup;
847 }
848
849 ret =
850 asn1_write_value(*c2, "publicKey", params->raw_pub.data, params->raw_pub.size*8);
851 if (ret != ASN1_SUCCESS) {
852 gnutls_assert();
853 ret = _gnutls_asn2err(ret);
854 goto cleanup;
855 }
856 } else {
857 if (params->params_nr != ECC_PRIVATE_PARAMS)
858 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
859
860 ret =
861 _gnutls_ecc_ansi_x962_export(params->curve,
862 params->params[ECC_X],
863 params->params[ECC_Y], &pubkey);
864 if (ret < 0)
865 return gnutls_assert_val(ret);
866
867 ret =
868 _gnutls_x509_write_key_int(*c2, "privateKey",
869 params->params[ECC_K], 1);
870 if (ret < 0) {
871 gnutls_assert();
872 goto cleanup;
873 }
874
875 if ((ret =
876 asn1_write_value(*c2, "publicKey", pubkey.data,
877 pubkey.size * 8)) != ASN1_SUCCESS) {
878 gnutls_assert();
879 ret = _gnutls_asn2err(ret);
880 goto cleanup;
881 }
882 }
883
884 /* write our choice */
885 if ((ret =
886 asn1_write_value(*c2, "parameters", "namedCurve",
887 1)) != ASN1_SUCCESS) {
888 gnutls_assert();
889 ret = _gnutls_asn2err(ret);
890 goto cleanup;
891 }
892
893 if ((ret =
894 asn1_write_value(*c2, "parameters.namedCurve", oid,
895 1)) != ASN1_SUCCESS) {
896 gnutls_assert();
897 ret = _gnutls_asn2err(ret);
898 goto cleanup;
899 }
900
901 _gnutls_free_datum(&pubkey);
902 return 0;
903
904 cleanup:
905 asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
906 _gnutls_free_datum(&pubkey);
907
908 return ret;
909 }
910
911 static int
_gnutls_asn1_encode_gost(ASN1_TYPE * c2,gnutls_pk_params_st * params)912 _gnutls_asn1_encode_gost(ASN1_TYPE * c2, gnutls_pk_params_st * params)
913 {
914 int ret;
915 const char *oid;
916
917 oid = gnutls_pk_get_oid(params->algo);
918
919 if (params->params_nr != GOST_PRIVATE_PARAMS || oid == NULL)
920 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
921
922 /* first make sure that no previously allocated data are leaked */
923 if (*c2 != ASN1_TYPE_EMPTY) {
924 asn1_delete_structure(c2);
925 *c2 = ASN1_TYPE_EMPTY;
926 }
927
928 if ((ret = asn1_create_element
929 (_gnutls_get_gnutls_asn(), "GNUTLS.GOSTPrivateKey", c2))
930 != ASN1_SUCCESS) {
931 gnutls_assert();
932 ret = _gnutls_asn2err(ret);
933 goto cleanup;
934 }
935
936 ret =
937 _gnutls_x509_write_key_int_le(*c2, "", params->params[GOST_K]);
938 if (ret < 0) {
939 gnutls_assert();
940 goto cleanup;
941 }
942
943
944 return 0;
945
946 cleanup:
947 asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
948
949 return ret;
950 }
951
952 /* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
953 */
954 static int
_gnutls_asn1_encode_dsa(ASN1_TYPE * c2,gnutls_pk_params_st * params)955 _gnutls_asn1_encode_dsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
956 {
957 int result, ret;
958 const uint8_t null = '\0';
959
960 /* first make sure that no previously allocated data are leaked */
961 if (*c2 != ASN1_TYPE_EMPTY) {
962 asn1_delete_structure(c2);
963 *c2 = ASN1_TYPE_EMPTY;
964 }
965
966 if ((result = asn1_create_element
967 (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", c2))
968 != ASN1_SUCCESS) {
969 gnutls_assert();
970 return _gnutls_asn2err(result);
971 }
972
973 /* Write PRIME
974 */
975 ret =
976 _gnutls_x509_write_int(*c2, "p",
977 params->params[DSA_P], 1);
978 if (ret < 0) {
979 gnutls_assert();
980 goto cleanup;
981 }
982
983 ret =
984 _gnutls_x509_write_int(*c2, "q",
985 params->params[DSA_Q], 1);
986 if (ret < 0) {
987 gnutls_assert();
988 goto cleanup;
989 }
990
991 ret =
992 _gnutls_x509_write_int(*c2, "g",
993 params->params[DSA_G], 1);
994 if (ret < 0) {
995 gnutls_assert();
996 goto cleanup;
997 }
998
999 ret =
1000 _gnutls_x509_write_int(*c2, "Y",
1001 params->params[DSA_Y], 1);
1002 if (ret < 0) {
1003 gnutls_assert();
1004 goto cleanup;
1005 }
1006
1007 ret =
1008 _gnutls_x509_write_key_int(*c2, "priv",
1009 params->params[DSA_X], 1);
1010 if (ret < 0) {
1011 gnutls_assert();
1012 goto cleanup;
1013 }
1014
1015 if ((result =
1016 asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
1017 gnutls_assert();
1018 ret = _gnutls_asn2err(result);
1019 goto cleanup;
1020 }
1021
1022 return 0;
1023
1024 cleanup:
1025 asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
1026
1027 return ret;
1028 }
1029
_gnutls_asn1_encode_privkey(ASN1_TYPE * c2,gnutls_pk_params_st * params)1030 int _gnutls_asn1_encode_privkey(ASN1_TYPE * c2,
1031 gnutls_pk_params_st * params)
1032 {
1033 switch (params->algo) {
1034 case GNUTLS_PK_RSA:
1035 case GNUTLS_PK_RSA_PSS:
1036 return _gnutls_asn1_encode_rsa(c2, params);
1037 case GNUTLS_PK_DSA:
1038 return _gnutls_asn1_encode_dsa(c2, params);
1039 case GNUTLS_PK_ECDSA:
1040 case GNUTLS_PK_EDDSA_ED25519:
1041 case GNUTLS_PK_EDDSA_ED448:
1042 return _gnutls_asn1_encode_ecc(c2, params);
1043 case GNUTLS_PK_GOST_01:
1044 case GNUTLS_PK_GOST_12_256:
1045 case GNUTLS_PK_GOST_12_512:
1046 return _gnutls_asn1_encode_gost(c2, params);
1047 default:
1048 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1049 }
1050 }
1051