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