Line data Source code
1 : /*
2 : * Copyright (C) 2001-2014 Free Software Foundation, Inc.
3 : * Copyright (C) 2017 Red Hat, Inc.
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 : /* This file contains the functions needed for RSA/DSA public key
25 : * encryption and signatures.
26 : */
27 :
28 : #include "gnutls_int.h"
29 : #include <mpi.h>
30 : #include <pk.h>
31 : #include "errors.h"
32 : #include <datum.h>
33 : #include <global.h>
34 : #include <num.h>
35 : #include "debug.h"
36 : #include <x509/x509_int.h>
37 : #include <x509/common.h>
38 : #include <random.h>
39 : #include <gnutls/crypto.h>
40 :
41 : /**
42 : * gnutls_encode_rs_value:
43 : * @sig_value: will hold a Dss-Sig-Value DER encoded structure
44 : * @r: must contain the r value
45 : * @s: must contain the s value
46 : *
47 : * This function will encode the provided r and s values,
48 : * into a Dss-Sig-Value structure, used for DSA and ECDSA
49 : * signatures.
50 : *
51 : * The output value should be deallocated using gnutls_free().
52 : *
53 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
54 : * an error code is returned.
55 : *
56 : * Since: 3.6.0
57 : *
58 : **/
59 : int
60 9 : gnutls_encode_rs_value(gnutls_datum_t * sig_value,
61 : const gnutls_datum_t * r,
62 : const gnutls_datum_t * s)
63 : {
64 9 : return _gnutls_encode_ber_rs_raw(sig_value, r, s);
65 : }
66 :
67 : /* same as gnutls_encode_rs_value(), but kept since it used
68 : * to be exported for FIPS140 CAVS testing.
69 : */
70 : int
71 114 : _gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,
72 : const gnutls_datum_t * r,
73 : const gnutls_datum_t * s)
74 : {
75 114 : ASN1_TYPE sig;
76 114 : int result, ret;
77 114 : uint8_t *tmp = NULL;
78 :
79 228 : if ((result =
80 114 : asn1_create_element(_gnutls_get_gnutls_asn(),
81 : "GNUTLS.DSASignatureValue",
82 : &sig)) != ASN1_SUCCESS) {
83 0 : gnutls_assert();
84 0 : return _gnutls_asn2err(result);
85 : }
86 :
87 114 : if (s->data[0] >= 0x80 || r->data[0] >= 0x80) {
88 85 : tmp = gnutls_malloc(MAX(r->size, s->size)+1);
89 85 : if (tmp == NULL) {
90 0 : ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
91 0 : goto cleanup;
92 : }
93 : }
94 :
95 114 : if (r->data[0] >= 0x80) {
96 60 : tmp[0] = 0;
97 60 : memcpy(&tmp[1], r->data, r->size);
98 60 : result = asn1_write_value(sig, "r", tmp, 1+r->size);
99 : } else {
100 54 : result = asn1_write_value(sig, "r", r->data, r->size);
101 : }
102 :
103 114 : if (result != ASN1_SUCCESS) {
104 0 : gnutls_assert();
105 0 : ret = _gnutls_asn2err(result);
106 0 : goto cleanup;
107 : }
108 :
109 :
110 114 : if (s->data[0] >= 0x80) {
111 57 : tmp[0] = 0;
112 57 : memcpy(&tmp[1], s->data, s->size);
113 57 : result = asn1_write_value(sig, "s", tmp, 1+s->size);
114 : } else {
115 57 : result = asn1_write_value(sig, "s", s->data, s->size);
116 : }
117 :
118 114 : if (result != ASN1_SUCCESS) {
119 0 : gnutls_assert();
120 0 : ret = _gnutls_asn2err(result);
121 0 : goto cleanup;
122 : }
123 :
124 114 : ret = _gnutls_x509_der_encode(sig, "", sig_value, 0);
125 114 : if (ret < 0) {
126 0 : gnutls_assert();
127 0 : goto cleanup;
128 : }
129 :
130 : ret = 0;
131 114 : cleanup:
132 114 : gnutls_free(tmp);
133 114 : asn1_delete_structure(&sig);
134 114 : return ret;
135 : }
136 :
137 : int
138 3548 : _gnutls_encode_ber_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
139 : {
140 3548 : ASN1_TYPE sig;
141 3548 : int result;
142 :
143 7096 : if ((result =
144 3548 : asn1_create_element(_gnutls_get_gnutls_asn(),
145 : "GNUTLS.DSASignatureValue",
146 : &sig)) != ASN1_SUCCESS) {
147 0 : gnutls_assert();
148 0 : return _gnutls_asn2err(result);
149 : }
150 :
151 3548 : result = _gnutls_x509_write_int(sig, "r", r, 1);
152 3548 : if (result < 0) {
153 0 : gnutls_assert();
154 0 : asn1_delete_structure(&sig);
155 0 : return result;
156 : }
157 :
158 3548 : result = _gnutls_x509_write_int(sig, "s", s, 1);
159 3548 : if (result < 0) {
160 0 : gnutls_assert();
161 0 : asn1_delete_structure(&sig);
162 0 : return result;
163 : }
164 :
165 3548 : result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
166 3548 : asn1_delete_structure(&sig);
167 :
168 3548 : if (result < 0)
169 0 : return gnutls_assert_val(result);
170 :
171 : return 0;
172 : }
173 :
174 :
175 : /* decodes the Dss-Sig-Value structure
176 : */
177 : int
178 4979 : _gnutls_decode_ber_rs(const gnutls_datum_t * sig_value, bigint_t * r,
179 : bigint_t * s)
180 : {
181 4979 : ASN1_TYPE sig;
182 4979 : int result;
183 :
184 9958 : if ((result =
185 4979 : asn1_create_element(_gnutls_get_gnutls_asn(),
186 : "GNUTLS.DSASignatureValue",
187 : &sig)) != ASN1_SUCCESS) {
188 0 : gnutls_assert();
189 0 : return _gnutls_asn2err(result);
190 : }
191 :
192 : /* rfc3279 doesn't specify whether Dss-Sig-Value is encoded
193 : * as DER or BER. As such we do not restrict to the DER subset. */
194 4979 : result =
195 4979 : asn1_der_decoding(&sig, sig_value->data, sig_value->size,
196 : NULL);
197 4979 : if (result != ASN1_SUCCESS) {
198 1 : gnutls_assert();
199 1 : asn1_delete_structure(&sig);
200 1 : return _gnutls_asn2err(result);
201 : }
202 :
203 4978 : result = _gnutls_x509_read_int(sig, "r", r);
204 4978 : if (result < 0) {
205 1 : gnutls_assert();
206 1 : asn1_delete_structure(&sig);
207 1 : return result;
208 : }
209 :
210 4977 : result = _gnutls_x509_read_int(sig, "s", s);
211 4977 : if (result < 0) {
212 1 : gnutls_assert();
213 1 : _gnutls_mpi_release(r);
214 1 : asn1_delete_structure(&sig);
215 1 : return result;
216 : }
217 :
218 4976 : asn1_delete_structure(&sig);
219 :
220 4976 : return 0;
221 : }
222 :
223 : /**
224 : * gnutls_decode_rs_value:
225 : * @sig_value: holds a Dss-Sig-Value DER or BER encoded structure
226 : * @r: will contain the r value
227 : * @s: will contain the s value
228 : *
229 : * This function will decode the provided @sig_value,
230 : * into @r and @s elements. The Dss-Sig-Value is used for DSA and ECDSA
231 : * signatures.
232 : *
233 : * The output values may be padded with a zero byte to prevent them
234 : * from being interpreted as negative values. The value
235 : * should be deallocated using gnutls_free().
236 : *
237 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
238 : * an error code is returned.
239 : *
240 : * Since: 3.6.0
241 : *
242 : **/
243 9 : int gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
244 : gnutls_datum_t *s)
245 : {
246 9 : return _gnutls_decode_ber_rs_raw(sig_value, r, s);
247 : }
248 :
249 : /* same as gnutls_decode_rs_value(), but kept since it used
250 : * to be exported for FIPS140 CAVS testing.
251 : */
252 : int
253 109 : _gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
254 : gnutls_datum_t *s)
255 : {
256 109 : ASN1_TYPE sig;
257 109 : int result;
258 :
259 218 : if ((result =
260 109 : asn1_create_element(_gnutls_get_gnutls_asn(),
261 : "GNUTLS.DSASignatureValue",
262 : &sig)) != ASN1_SUCCESS) {
263 0 : gnutls_assert();
264 0 : return _gnutls_asn2err(result);
265 : }
266 :
267 : /* rfc3279 doesn't specify whether Dss-Sig-Value is encoded
268 : * as DER or BER. As such we do not restrict to the DER subset. */
269 109 : result =
270 109 : asn1_der_decoding(&sig, sig_value->data, sig_value->size,
271 : NULL);
272 109 : if (result != ASN1_SUCCESS) {
273 0 : gnutls_assert();
274 0 : asn1_delete_structure(&sig);
275 0 : return _gnutls_asn2err(result);
276 : }
277 :
278 109 : result = _gnutls_x509_read_value(sig, "r", r);
279 109 : if (result < 0) {
280 0 : gnutls_assert();
281 0 : asn1_delete_structure(&sig);
282 0 : return result;
283 : }
284 :
285 109 : result = _gnutls_x509_read_value(sig, "s", s);
286 109 : if (result < 0) {
287 0 : gnutls_assert();
288 0 : gnutls_free(r->data);
289 0 : asn1_delete_structure(&sig);
290 0 : return result;
291 : }
292 :
293 109 : asn1_delete_structure(&sig);
294 :
295 109 : return 0;
296 : }
297 :
298 : int
299 549 : _gnutls_encode_gost_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s,
300 : size_t intsize)
301 : {
302 549 : uint8_t *data;
303 549 : int result;
304 :
305 549 : data = gnutls_malloc(intsize * 2);
306 549 : if (data == NULL) {
307 0 : gnutls_assert();
308 0 : return GNUTLS_E_MEMORY_ERROR;
309 : }
310 :
311 549 : if ((result = _gnutls_mpi_bprint_size(s, data, intsize)) < 0) {
312 0 : gnutls_assert();
313 0 : gnutls_free(data);
314 0 : return result;
315 : }
316 :
317 549 : if ((result = _gnutls_mpi_bprint_size(r, data + intsize, intsize)) < 0) {
318 0 : gnutls_assert();
319 0 : gnutls_free(data);
320 0 : return result;
321 : }
322 :
323 549 : sig_value->data = data;
324 549 : sig_value->size = intsize * 2;
325 :
326 549 : return 0;
327 : }
328 :
329 : int
330 1066 : _gnutls_decode_gost_rs(const gnutls_datum_t * sig_value, bigint_t * r,
331 : bigint_t * s)
332 : {
333 1066 : int ret;
334 1066 : unsigned halfsize = sig_value->size >> 1;
335 :
336 1066 : if (sig_value->size % 2 != 0) {
337 0 : return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
338 : }
339 :
340 1066 : ret = _gnutls_mpi_init_scan(s, sig_value->data, halfsize);
341 1066 : if (ret < 0)
342 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
343 :
344 1066 : ret = _gnutls_mpi_init_scan(r, sig_value->data + halfsize, halfsize);
345 1066 : if (ret < 0) {
346 0 : _gnutls_mpi_release(s);
347 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
348 : }
349 :
350 : return 0;
351 : }
352 :
353 : /**
354 : * gnutls_encode_gost_rs_value:
355 : * @sig_value: will hold a GOST signature according to RFC 4491 section 2.2.2
356 : * @r: must contain the r value
357 : * @s: must contain the s value
358 : *
359 : * This function will encode the provided r and s values, into binary
360 : * representation according to RFC 4491 section 2.2.2, used for GOST R
361 : * 34.10-2001 (and thus also for GOST R 34.10-2012) signatures.
362 : *
363 : * The output value should be deallocated using gnutls_free().
364 : *
365 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
366 : * an error code is returned.
367 : *
368 : * Since: 3.6.0
369 : */
370 0 : int gnutls_encode_gost_rs_value(gnutls_datum_t * sig_value, const gnutls_datum_t * r, const gnutls_datum_t *s)
371 : {
372 0 : uint8_t *data;
373 0 : size_t intsize = r->size;
374 :
375 0 : if (s->size != intsize) {
376 0 : gnutls_assert();
377 0 : return GNUTLS_E_ILLEGAL_PARAMETER;
378 : }
379 :
380 0 : data = gnutls_malloc(intsize * 2);
381 0 : if (data == NULL) {
382 0 : gnutls_assert();
383 0 : return GNUTLS_E_MEMORY_ERROR;
384 : }
385 :
386 0 : memcpy(data, s->data, intsize);
387 0 : memcpy(data + intsize, r->data, intsize);
388 :
389 0 : sig_value->data = data;
390 0 : sig_value->size = intsize * 2;
391 :
392 0 : return 0;
393 : }
394 :
395 : /**
396 : * gnutls_decode_gost_rs_value:
397 : * @sig_value: will holds a GOST signature according to RFC 4491 section 2.2.2
398 : * @r: will contain the r value
399 : * @s: will contain the s value
400 : *
401 : * This function will decode the provided @sig_value, into @r and @s elements.
402 : * See RFC 4491 section 2.2.2 for the format of signature value.
403 : *
404 : * The output values may be padded with a zero byte to prevent them
405 : * from being interpreted as negative values. The value
406 : * should be deallocated using gnutls_free().
407 : *
408 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
409 : * an error code is returned.
410 : *
411 : * Since: 3.6.0
412 : */
413 0 : int gnutls_decode_gost_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
414 : {
415 0 : int ret;
416 0 : unsigned halfsize = sig_value->size >> 1;
417 :
418 0 : if (sig_value->size % 2 != 0)
419 0 : return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
420 :
421 0 : ret = _gnutls_set_datum(s, sig_value->data, halfsize);
422 0 : if (ret != 0)
423 0 : return gnutls_assert_val(ret);
424 :
425 0 : ret = _gnutls_set_datum(r, sig_value->data + halfsize, halfsize);
426 0 : if (ret != 0) {
427 0 : _gnutls_free_datum(s);
428 0 : return gnutls_assert_val(ret);
429 : }
430 :
431 : return 0;
432 : }
433 :
434 3256 : gnutls_digest_algorithm_t _gnutls_gost_digest(gnutls_pk_algorithm_t pk)
435 : {
436 3256 : if (pk == GNUTLS_PK_GOST_01)
437 : return GNUTLS_DIG_GOSTR_94;
438 1996 : else if (pk == GNUTLS_PK_GOST_12_256)
439 : return GNUTLS_DIG_STREEBOG_256;
440 718 : else if (pk == GNUTLS_PK_GOST_12_512)
441 : return GNUTLS_DIG_STREEBOG_512;
442 :
443 0 : gnutls_assert();
444 :
445 : return GNUTLS_DIG_UNKNOWN;
446 : }
447 :
448 2 : gnutls_pk_algorithm_t _gnutls_digest_gost(gnutls_digest_algorithm_t digest)
449 : {
450 2 : if (digest == GNUTLS_DIG_GOSTR_94)
451 : return GNUTLS_PK_GOST_01;
452 0 : else if (digest == GNUTLS_DIG_STREEBOG_256)
453 : return GNUTLS_PK_GOST_12_256;
454 0 : else if (digest == GNUTLS_DIG_STREEBOG_512)
455 : return GNUTLS_PK_GOST_12_512;
456 :
457 0 : gnutls_assert();
458 :
459 : return GNUTLS_PK_UNKNOWN;
460 : }
461 :
462 1152 : gnutls_gost_paramset_t _gnutls_gost_paramset_default(gnutls_pk_algorithm_t pk)
463 : {
464 1152 : if (pk == GNUTLS_PK_GOST_01)
465 : return GNUTLS_GOST_PARAMSET_CP_A;
466 681 : else if (pk == GNUTLS_PK_GOST_12_256 ||
467 : pk == GNUTLS_PK_GOST_12_512)
468 : return GNUTLS_GOST_PARAMSET_TC26_Z;
469 : else
470 0 : return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN);
471 : }
472 :
473 : /* some generic pk functions */
474 :
475 2064 : int _gnutls_pk_params_copy(gnutls_pk_params_st * dst,
476 : const gnutls_pk_params_st * src)
477 : {
478 2064 : unsigned int i, j;
479 2064 : dst->params_nr = 0;
480 :
481 2064 : if (src == NULL || (src->params_nr == 0 && src->raw_pub.size == 0)) {
482 0 : gnutls_assert();
483 0 : return GNUTLS_E_INVALID_REQUEST;
484 : }
485 :
486 2064 : dst->pkflags = src->pkflags;
487 2064 : dst->curve = src->curve;
488 2064 : dst->gost_params = src->gost_params;
489 2064 : dst->qbits = src->qbits;
490 2064 : dst->algo = src->algo;
491 :
492 11898 : for (i = 0; i < src->params_nr; i++) {
493 9834 : dst->params[i] = _gnutls_mpi_copy(src->params[i]);
494 9834 : if (dst->params[i] == NULL) {
495 0 : goto fail;
496 : }
497 :
498 9834 : dst->params_nr++;
499 : }
500 :
501 2064 : if (_gnutls_set_datum(&dst->raw_priv, src->raw_priv.data, src->raw_priv.size) < 0) {
502 0 : gnutls_assert();
503 0 : goto fail;
504 : }
505 :
506 2064 : if (_gnutls_set_datum(&dst->raw_pub, src->raw_pub.data, src->raw_pub.size) < 0) {
507 0 : gnutls_assert();
508 0 : goto fail;
509 : }
510 :
511 2064 : if (src->seed_size) {
512 8 : dst->seed_size = src->seed_size;
513 8 : memcpy(dst->seed, src->seed, src->seed_size);
514 : }
515 2064 : dst->palgo = src->palgo;
516 :
517 2064 : memcpy(&dst->spki, &src->spki, sizeof(gnutls_x509_spki_st));
518 :
519 2064 : return 0;
520 :
521 : fail:
522 0 : for (j = 0; j < i; j++)
523 0 : _gnutls_mpi_release(&dst->params[j]);
524 : return GNUTLS_E_MEMORY_ERROR;
525 : }
526 :
527 116810 : void gnutls_pk_params_init(gnutls_pk_params_st * p)
528 : {
529 116810 : memset(p, 0, sizeof(gnutls_pk_params_st));
530 116810 : }
531 :
532 279360 : void gnutls_pk_params_release(gnutls_pk_params_st * p)
533 : {
534 279360 : unsigned int i;
535 457903 : for (i = 0; i < p->params_nr; i++) {
536 355428 : _gnutls_mpi_release(&p->params[i]);
537 : }
538 279360 : gnutls_free(p->raw_priv.data);
539 279360 : gnutls_free(p->raw_pub.data);
540 :
541 279360 : p->params_nr = 0;
542 279360 : }
543 :
544 40407 : void gnutls_pk_params_clear(gnutls_pk_params_st * p)
545 : {
546 40407 : unsigned int i;
547 104807 : for (i = 0; i < p->params_nr; i++) {
548 64400 : if (p->params[i] != NULL)
549 62883 : _gnutls_mpi_clear(p->params[i]);
550 : }
551 40407 : gnutls_memset(p->seed, 0, p->seed_size);
552 40407 : p->seed_size = 0;
553 40407 : if (p->raw_priv.data != NULL) {
554 4102 : gnutls_memset(p->raw_priv.data, 0, p->raw_priv.size);
555 4102 : p->raw_priv.size = 0;
556 : }
557 40407 : }
558 :
559 : int
560 5455 : _gnutls_find_rsa_pss_salt_size(unsigned bits, const mac_entry_st *me,
561 : unsigned salt_size)
562 : {
563 5455 : unsigned digest_size;
564 5455 : int max_salt_size;
565 5455 : unsigned key_size;
566 :
567 5455 : digest_size = _gnutls_hash_get_algo_len(me);
568 5455 : key_size = (bits + 7) / 8;
569 :
570 5455 : if (key_size == 0) {
571 1 : return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY);
572 : } else {
573 5454 : max_salt_size = key_size - digest_size - 2;
574 5454 : if (max_salt_size < 0)
575 0 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
576 : }
577 :
578 5454 : if (salt_size < digest_size)
579 5415 : salt_size = digest_size;
580 :
581 5454 : if (salt_size > (unsigned)max_salt_size)
582 3 : salt_size = max_salt_size;
583 :
584 5454 : return salt_size;
585 : }
586 :
587 : /* Writes the digest information and the digest in a DER encoded
588 : * structure. The digest info is allocated and stored into the info structure.
589 : */
590 : int
591 13299 : encode_ber_digest_info(const mac_entry_st * e,
592 : const gnutls_datum_t * digest,
593 : gnutls_datum_t * output)
594 : {
595 13299 : ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
596 13299 : int result;
597 13299 : const char *algo;
598 13299 : uint8_t *tmp_output;
599 13299 : int tmp_output_size;
600 :
601 : /* prevent asn1_write_value() treating input as string */
602 13299 : if (digest->size == 0)
603 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
604 :
605 13299 : algo = _gnutls_x509_mac_to_oid(e);
606 13299 : if (algo == NULL) {
607 0 : gnutls_assert();
608 0 : _gnutls_debug_log("Hash algorithm: %d has no OID\n",
609 : e->id);
610 0 : return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
611 : }
612 :
613 13299 : if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
614 : "GNUTLS.DigestInfo",
615 : &dinfo)) != ASN1_SUCCESS) {
616 0 : gnutls_assert();
617 0 : return _gnutls_asn2err(result);
618 : }
619 :
620 13299 : result =
621 13299 : asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
622 13299 : if (result != ASN1_SUCCESS) {
623 0 : gnutls_assert();
624 0 : asn1_delete_structure(&dinfo);
625 0 : return _gnutls_asn2err(result);
626 : }
627 :
628 : /* Write an ASN.1 NULL in the parameters field. This matches RFC
629 : 3279 and RFC 4055, although is arguable incorrect from a historic
630 : perspective (see those documents for more information).
631 : Regardless of what is correct, this appears to be what most
632 : implementations do. */
633 13299 : result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
634 : ASN1_NULL, ASN1_NULL_SIZE);
635 13299 : if (result != ASN1_SUCCESS) {
636 0 : gnutls_assert();
637 0 : asn1_delete_structure(&dinfo);
638 0 : return _gnutls_asn2err(result);
639 : }
640 :
641 13299 : result =
642 13299 : asn1_write_value(dinfo, "digest", digest->data, digest->size);
643 13299 : if (result != ASN1_SUCCESS) {
644 0 : gnutls_assert();
645 0 : asn1_delete_structure(&dinfo);
646 0 : return _gnutls_asn2err(result);
647 : }
648 :
649 13299 : tmp_output_size = 0;
650 13299 : result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
651 13299 : if (result != ASN1_MEM_ERROR) {
652 0 : gnutls_assert();
653 0 : asn1_delete_structure(&dinfo);
654 0 : return _gnutls_asn2err(result);
655 : }
656 :
657 13299 : tmp_output = gnutls_malloc(tmp_output_size);
658 13299 : if (tmp_output == NULL) {
659 0 : gnutls_assert();
660 0 : asn1_delete_structure(&dinfo);
661 0 : return GNUTLS_E_MEMORY_ERROR;
662 : }
663 :
664 13299 : result =
665 13299 : asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
666 13299 : if (result != ASN1_SUCCESS) {
667 0 : gnutls_assert();
668 0 : asn1_delete_structure(&dinfo);
669 0 : return _gnutls_asn2err(result);
670 : }
671 :
672 13299 : asn1_delete_structure(&dinfo);
673 :
674 13299 : output->size = tmp_output_size;
675 13299 : output->data = tmp_output;
676 :
677 13299 : return 0;
678 : }
679 :
680 : /**
681 : * gnutls_encode_ber_digest_info:
682 : * @info: an RSA BER encoded DigestInfo structure
683 : * @hash: the hash algorithm that was used to get the digest
684 : * @digest: must contain the digest data
685 : * @output: will contain the allocated DigestInfo BER encoded data
686 : *
687 : * This function will encode the provided digest data, and its
688 : * algorithm into an RSA PKCS#1 1.5 DigestInfo structure.
689 : *
690 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
691 : * an error code is returned.
692 : *
693 : * Since: 3.5.0
694 : *
695 : **/
696 : int
697 2 : gnutls_encode_ber_digest_info(gnutls_digest_algorithm_t hash,
698 : const gnutls_datum_t * digest,
699 : gnutls_datum_t * output)
700 : {
701 2 : const mac_entry_st *e = hash_to_entry(hash);
702 2 : if (unlikely(e == NULL))
703 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
704 :
705 2 : return encode_ber_digest_info(e , digest, output);
706 : }
707 :
708 : /**
709 : * gnutls_decode_ber_digest_info:
710 : * @info: an RSA BER encoded DigestInfo structure
711 : * @hash: will contain the hash algorithm of the structure
712 : * @digest: will contain the hash output of the structure
713 : * @digest_size: will contain the hash size of the structure; initially must hold the maximum size of @digest
714 : *
715 : * This function will parse an RSA PKCS#1 1.5 DigestInfo structure
716 : * and report the hash algorithm used as well as the digest data.
717 : *
718 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
719 : * an error code is returned.
720 : *
721 : * Since: 3.5.0
722 : *
723 : **/
724 : int
725 7 : gnutls_decode_ber_digest_info(const gnutls_datum_t * info,
726 : gnutls_digest_algorithm_t * hash,
727 : unsigned char * digest, unsigned int *digest_size)
728 : {
729 7 : ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
730 7 : int result;
731 7 : char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
732 7 : int len;
733 :
734 7 : if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
735 : "GNUTLS.DigestInfo",
736 : &dinfo)) != ASN1_SUCCESS) {
737 0 : gnutls_assert();
738 0 : return _gnutls_asn2err(result);
739 : }
740 :
741 : /* rfc2313 required BER encoding of that field, thus
742 : * we don't restrict libtasn1 to DER subset */
743 7 : result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
744 7 : if (result != ASN1_SUCCESS) {
745 2 : gnutls_assert();
746 2 : asn1_delete_structure(&dinfo);
747 2 : return _gnutls_asn2err(result);
748 : }
749 :
750 5 : len = sizeof(str) - 1;
751 5 : result =
752 5 : asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len);
753 5 : if (result != ASN1_SUCCESS) {
754 0 : gnutls_assert();
755 0 : asn1_delete_structure(&dinfo);
756 0 : return _gnutls_asn2err(result);
757 : }
758 :
759 5 : *hash = gnutls_oid_to_digest(str);
760 :
761 5 : if (*hash == GNUTLS_DIG_UNKNOWN) {
762 :
763 1 : _gnutls_debug_log("verify.c: HASH OID: %s\n", str);
764 :
765 1 : gnutls_assert();
766 1 : asn1_delete_structure(&dinfo);
767 1 : return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
768 : }
769 :
770 4 : len = sizeof(str) - 1;
771 4 : result =
772 4 : asn1_read_value(dinfo, "digestAlgorithm.parameters", str,
773 : &len);
774 : /* To avoid permitting garbage in the parameters field, either the
775 : parameters field is not present, or it contains 0x05 0x00. */
776 4 : if (!(result == ASN1_ELEMENT_NOT_FOUND ||
777 4 : (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
778 4 : memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
779 0 : gnutls_assert();
780 0 : asn1_delete_structure(&dinfo);
781 0 : return GNUTLS_E_ASN1_GENERIC_ERROR;
782 : }
783 :
784 4 : len = *digest_size;
785 4 : result = asn1_read_value(dinfo, "digest", digest, &len);
786 :
787 4 : if (result != ASN1_SUCCESS) {
788 0 : gnutls_assert();
789 0 : *digest_size = len;
790 0 : asn1_delete_structure(&dinfo);
791 0 : return _gnutls_asn2err(result);
792 : }
793 :
794 4 : *digest_size = len;
795 4 : asn1_delete_structure(&dinfo);
796 :
797 4 : return 0;
798 : }
799 :
800 : int
801 65 : _gnutls_params_get_rsa_raw(const gnutls_pk_params_st* params,
802 : gnutls_datum_t * m, gnutls_datum_t * e,
803 : gnutls_datum_t * d, gnutls_datum_t * p,
804 : gnutls_datum_t * q, gnutls_datum_t * u,
805 : gnutls_datum_t * e1,
806 : gnutls_datum_t * e2,
807 : unsigned int flags)
808 : {
809 65 : int ret;
810 65 : mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
811 :
812 65 : if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
813 23 : dprint = _gnutls_mpi_dprint;
814 :
815 65 : if (params == NULL) {
816 0 : gnutls_assert();
817 0 : return GNUTLS_E_INVALID_REQUEST;
818 : }
819 :
820 65 : if (!GNUTLS_PK_IS_RSA(params->algo)) {
821 0 : gnutls_assert();
822 0 : return GNUTLS_E_INVALID_REQUEST;
823 : }
824 :
825 65 : if (m) {
826 65 : ret = dprint(params->params[0], m);
827 65 : if (ret < 0) {
828 0 : gnutls_assert();
829 0 : goto error;
830 : }
831 : }
832 :
833 : /* E */
834 65 : if (e) {
835 65 : ret = dprint(params->params[1], e);
836 65 : if (ret < 0) {
837 0 : gnutls_assert();
838 0 : goto error;
839 : }
840 : }
841 :
842 : /* D */
843 65 : if (d && params->params[2]) {
844 65 : ret = dprint(params->params[2], d);
845 65 : if (ret < 0) {
846 0 : gnutls_assert();
847 0 : goto error;
848 : }
849 0 : } else if (d) {
850 0 : d->data = NULL;
851 0 : d->size = 0;
852 : }
853 :
854 : /* P */
855 65 : if (p && params->params[3]) {
856 65 : ret = dprint(params->params[3], p);
857 65 : if (ret < 0) {
858 0 : gnutls_assert();
859 0 : goto error;
860 : }
861 0 : } else if (p) {
862 0 : p->data = NULL;
863 0 : p->size = 0;
864 : }
865 :
866 : /* Q */
867 65 : if (q && params->params[4]) {
868 65 : ret = dprint(params->params[4], q);
869 65 : if (ret < 0) {
870 0 : gnutls_assert();
871 0 : goto error;
872 : }
873 0 : } else if (q) {
874 0 : q->data = NULL;
875 0 : q->size = 0;
876 : }
877 :
878 : /* U */
879 65 : if (u && params->params[5]) {
880 55 : ret = dprint(params->params[5], u);
881 55 : if (ret < 0) {
882 0 : gnutls_assert();
883 0 : goto error;
884 : }
885 10 : } else if (u) {
886 0 : u->data = NULL;
887 0 : u->size = 0;
888 : }
889 :
890 : /* E1 */
891 65 : if (e1 && params->params[6]) {
892 55 : ret = dprint(params->params[6], e1);
893 55 : if (ret < 0) {
894 0 : gnutls_assert();
895 0 : goto error;
896 : }
897 10 : } else if (e1) {
898 0 : e1->data = NULL;
899 0 : e1->size = 0;
900 : }
901 :
902 : /* E2 */
903 65 : if (e2 && params->params[7]) {
904 55 : ret = dprint(params->params[7], e2);
905 55 : if (ret < 0) {
906 0 : gnutls_assert();
907 0 : goto error;
908 : }
909 10 : } else if (e2) {
910 0 : e2->data = NULL;
911 0 : e2->size = 0;
912 : }
913 :
914 : return 0;
915 :
916 0 : error:
917 0 : _gnutls_free_datum(m);
918 0 : _gnutls_free_datum(d);
919 0 : _gnutls_free_datum(e);
920 0 : _gnutls_free_datum(e1);
921 0 : _gnutls_free_datum(e2);
922 0 : _gnutls_free_datum(p);
923 0 : _gnutls_free_datum(q);
924 :
925 : return ret;
926 : }
927 :
928 : int
929 30 : _gnutls_params_get_dsa_raw(const gnutls_pk_params_st* params,
930 : gnutls_datum_t * p, gnutls_datum_t * q,
931 : gnutls_datum_t * g, gnutls_datum_t * y,
932 : gnutls_datum_t * x, unsigned int flags)
933 : {
934 30 : int ret;
935 30 : mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
936 :
937 30 : if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
938 2 : dprint = _gnutls_mpi_dprint;
939 :
940 30 : if (params == NULL) {
941 0 : gnutls_assert();
942 0 : return GNUTLS_E_INVALID_REQUEST;
943 : }
944 :
945 30 : if (params->algo != GNUTLS_PK_DSA) {
946 0 : gnutls_assert();
947 0 : return GNUTLS_E_INVALID_REQUEST;
948 : }
949 :
950 : /* P */
951 30 : if (p) {
952 30 : ret = dprint(params->params[0], p);
953 30 : if (ret < 0) {
954 0 : gnutls_assert();
955 0 : return ret;
956 : }
957 : }
958 :
959 : /* Q */
960 30 : if (q) {
961 30 : ret = dprint(params->params[1], q);
962 30 : if (ret < 0) {
963 0 : gnutls_assert();
964 0 : _gnutls_free_datum(p);
965 0 : return ret;
966 : }
967 : }
968 :
969 :
970 : /* G */
971 30 : if (g) {
972 30 : ret = dprint(params->params[2], g);
973 30 : if (ret < 0) {
974 0 : gnutls_assert();
975 0 : _gnutls_free_datum(p);
976 0 : _gnutls_free_datum(q);
977 0 : return ret;
978 : }
979 : }
980 :
981 :
982 : /* Y */
983 30 : if (y) {
984 10 : ret = dprint(params->params[3], y);
985 10 : if (ret < 0) {
986 0 : gnutls_assert();
987 0 : _gnutls_free_datum(p);
988 0 : _gnutls_free_datum(g);
989 0 : _gnutls_free_datum(q);
990 0 : return ret;
991 : }
992 : }
993 :
994 : /* X */
995 30 : if (x) {
996 10 : ret = dprint(params->params[4], x);
997 10 : if (ret < 0) {
998 0 : gnutls_assert();
999 0 : _gnutls_free_datum(y);
1000 0 : _gnutls_free_datum(p);
1001 0 : _gnutls_free_datum(g);
1002 0 : _gnutls_free_datum(q);
1003 0 : return ret;
1004 : }
1005 : }
1006 :
1007 : return 0;
1008 : }
1009 :
1010 23 : int _gnutls_params_get_ecc_raw(const gnutls_pk_params_st* params,
1011 : gnutls_ecc_curve_t * curve,
1012 : gnutls_datum_t * x,
1013 : gnutls_datum_t * y,
1014 : gnutls_datum_t * k,
1015 : unsigned int flags)
1016 : {
1017 23 : int ret;
1018 23 : mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1019 23 : const gnutls_ecc_curve_entry_st *e;
1020 :
1021 23 : if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1022 1 : dprint = _gnutls_mpi_dprint;
1023 :
1024 23 : if (params == NULL) {
1025 0 : gnutls_assert();
1026 0 : return GNUTLS_E_INVALID_REQUEST;
1027 : }
1028 :
1029 23 : if (curve)
1030 23 : *curve = params->curve;
1031 :
1032 23 : e = _gnutls_ecc_curve_get_params(params->curve);
1033 :
1034 23 : if (_curve_is_eddsa(e)) {
1035 6 : if (x) {
1036 6 : ret = _gnutls_set_datum(x, params->raw_pub.data, params->raw_pub.size);
1037 6 : if (ret < 0) {
1038 0 : return gnutls_assert_val(ret);
1039 : }
1040 : }
1041 :
1042 6 : if (y) {
1043 4 : y->data = NULL;
1044 4 : y->size = 0;
1045 : }
1046 :
1047 6 : if (k) {
1048 6 : ret = _gnutls_set_datum(k, params->raw_priv.data, params->raw_priv.size);
1049 6 : if (ret < 0) {
1050 0 : _gnutls_free_datum(x);
1051 0 : return gnutls_assert_val(ret);
1052 : }
1053 : }
1054 :
1055 6 : return 0;
1056 : }
1057 :
1058 17 : if (unlikely(e == NULL || e->pk != GNUTLS_PK_ECDSA))
1059 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1060 :
1061 : /* X */
1062 17 : if (x) {
1063 17 : ret = dprint(params->params[ECC_X], x);
1064 17 : if (ret < 0) {
1065 0 : gnutls_assert();
1066 0 : return ret;
1067 : }
1068 : }
1069 :
1070 : /* Y */
1071 17 : if (y) {
1072 17 : ret = dprint(params->params[ECC_Y], y);
1073 17 : if (ret < 0) {
1074 0 : gnutls_assert();
1075 0 : _gnutls_free_datum(x);
1076 0 : return ret;
1077 : }
1078 : }
1079 :
1080 :
1081 : /* K */
1082 17 : if (k) {
1083 17 : ret = dprint(params->params[ECC_K], k);
1084 17 : if (ret < 0) {
1085 0 : gnutls_assert();
1086 0 : _gnutls_free_datum(x);
1087 0 : _gnutls_free_datum(y);
1088 0 : return ret;
1089 : }
1090 : }
1091 :
1092 : return 0;
1093 :
1094 : }
1095 :
1096 13 : int _gnutls_params_get_gost_raw(const gnutls_pk_params_st* params,
1097 : gnutls_ecc_curve_t * curve,
1098 : gnutls_digest_algorithm_t * digest,
1099 : gnutls_gost_paramset_t * paramset,
1100 : gnutls_datum_t * x,
1101 : gnutls_datum_t * y,
1102 : gnutls_datum_t * k,
1103 : unsigned int flags)
1104 : {
1105 13 : int ret;
1106 13 : mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1107 :
1108 13 : if (params == NULL) {
1109 0 : gnutls_assert();
1110 0 : return GNUTLS_E_INVALID_REQUEST;
1111 : }
1112 :
1113 13 : if (curve)
1114 13 : *curve = params->curve;
1115 :
1116 13 : if (digest)
1117 13 : *digest = _gnutls_gost_digest(params->algo);
1118 :
1119 13 : if (paramset)
1120 13 : *paramset = params->gost_params;
1121 :
1122 : /* X */
1123 13 : if (x) {
1124 13 : ret = dprint(params->params[GOST_X], x);
1125 13 : if (ret < 0) {
1126 0 : gnutls_assert();
1127 0 : return ret;
1128 : }
1129 : }
1130 :
1131 : /* Y */
1132 13 : if (y) {
1133 13 : ret = dprint(params->params[GOST_Y], y);
1134 13 : if (ret < 0) {
1135 0 : gnutls_assert();
1136 0 : _gnutls_free_datum(x);
1137 0 : return ret;
1138 : }
1139 : }
1140 :
1141 :
1142 : /* K */
1143 13 : if (k) {
1144 13 : ret = dprint(params->params[GOST_K], k);
1145 13 : if (ret < 0) {
1146 0 : gnutls_assert();
1147 0 : _gnutls_free_datum(x);
1148 0 : _gnutls_free_datum(y);
1149 0 : return ret;
1150 : }
1151 : }
1152 :
1153 : return 0;
1154 :
1155 : }
1156 :
1157 : int
1158 13564 : pk_hash_data(gnutls_pk_algorithm_t pk, const mac_entry_st * hash,
1159 : gnutls_pk_params_st * params,
1160 : const gnutls_datum_t * data, gnutls_datum_t * digest)
1161 : {
1162 13564 : int ret;
1163 :
1164 13564 : digest->size = _gnutls_hash_get_algo_len(hash);
1165 13564 : digest->data = gnutls_malloc(digest->size);
1166 13564 : if (digest->data == NULL) {
1167 0 : gnutls_assert();
1168 0 : return GNUTLS_E_MEMORY_ERROR;
1169 : }
1170 :
1171 13564 : ret =
1172 13564 : _gnutls_hash_fast((gnutls_digest_algorithm_t)hash->id, data->data, data->size,
1173 : digest->data);
1174 13564 : if (ret < 0) {
1175 0 : gnutls_assert();
1176 0 : goto cleanup;
1177 : }
1178 :
1179 : return 0;
1180 :
1181 0 : cleanup:
1182 0 : gnutls_free(digest->data);
1183 0 : return ret;
1184 : }
1185 :
1186 :
1187 : /*
1188 : * This function will do RSA PKCS #1 1.5 encoding
1189 : * on the given digest. The given digest must be allocated
1190 : * and will be freed if replacement is required.
1191 : */
1192 : int
1193 14928 : pk_prepare_hash(gnutls_pk_algorithm_t pk,
1194 : const mac_entry_st * hash, gnutls_datum_t * digest)
1195 : {
1196 14928 : int ret;
1197 14928 : gnutls_datum_t old_digest = { digest->data, digest->size };
1198 :
1199 14928 : switch (pk) {
1200 6445 : case GNUTLS_PK_RSA:
1201 6445 : if (unlikely(hash == NULL))
1202 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1203 : /* Encode the digest as a DigestInfo
1204 : */
1205 12890 : if ((ret =
1206 6445 : encode_ber_digest_info(hash, &old_digest,
1207 : digest)) != 0) {
1208 0 : gnutls_assert();
1209 0 : return ret;
1210 : }
1211 :
1212 6445 : _gnutls_free_datum(&old_digest);
1213 : break;
1214 : case GNUTLS_PK_RSA_PSS:
1215 : case GNUTLS_PK_DSA:
1216 : case GNUTLS_PK_ECDSA:
1217 : case GNUTLS_PK_EDDSA_ED25519:
1218 : case GNUTLS_PK_EDDSA_ED448:
1219 : case GNUTLS_PK_GOST_01:
1220 : case GNUTLS_PK_GOST_12_256:
1221 : case GNUTLS_PK_GOST_12_512:
1222 : break;
1223 0 : default:
1224 0 : gnutls_assert();
1225 : return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1226 : }
1227 :
1228 : return 0;
1229 : }
|