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(&params->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