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
gnutls_encode_rs_value(gnutls_datum_t * sig_value,const gnutls_datum_t * r,const gnutls_datum_t * s)60 gnutls_encode_rs_value(gnutls_datum_t * sig_value,
61 const gnutls_datum_t * r,
62 const gnutls_datum_t * s)
63 {
64 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
_gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,const gnutls_datum_t * r,const gnutls_datum_t * s)71 _gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,
72 const gnutls_datum_t * r,
73 const gnutls_datum_t * s)
74 {
75 ASN1_TYPE sig;
76 int result, ret;
77 uint8_t *tmp = NULL;
78
79 if ((result =
80 asn1_create_element(_gnutls_get_gnutls_asn(),
81 "GNUTLS.DSASignatureValue",
82 &sig)) != ASN1_SUCCESS) {
83 gnutls_assert();
84 return _gnutls_asn2err(result);
85 }
86
87 if (s->data[0] >= 0x80 || r->data[0] >= 0x80) {
88 tmp = gnutls_malloc(MAX(r->size, s->size)+1);
89 if (tmp == NULL) {
90 ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
91 goto cleanup;
92 }
93 }
94
95 if (r->data[0] >= 0x80) {
96 tmp[0] = 0;
97 memcpy(&tmp[1], r->data, r->size);
98 result = asn1_write_value(sig, "r", tmp, 1+r->size);
99 } else {
100 result = asn1_write_value(sig, "r", r->data, r->size);
101 }
102
103 if (result != ASN1_SUCCESS) {
104 gnutls_assert();
105 ret = _gnutls_asn2err(result);
106 goto cleanup;
107 }
108
109
110 if (s->data[0] >= 0x80) {
111 tmp[0] = 0;
112 memcpy(&tmp[1], s->data, s->size);
113 result = asn1_write_value(sig, "s", tmp, 1+s->size);
114 } else {
115 result = asn1_write_value(sig, "s", s->data, s->size);
116 }
117
118 if (result != ASN1_SUCCESS) {
119 gnutls_assert();
120 ret = _gnutls_asn2err(result);
121 goto cleanup;
122 }
123
124 ret = _gnutls_x509_der_encode(sig, "", sig_value, 0);
125 if (ret < 0) {
126 gnutls_assert();
127 goto cleanup;
128 }
129
130 ret = 0;
131 cleanup:
132 gnutls_free(tmp);
133 asn1_delete_structure(&sig);
134 return ret;
135 }
136
137 int
_gnutls_encode_ber_rs(gnutls_datum_t * sig_value,bigint_t r,bigint_t s)138 _gnutls_encode_ber_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
139 {
140 ASN1_TYPE sig;
141 int result;
142
143 if ((result =
144 asn1_create_element(_gnutls_get_gnutls_asn(),
145 "GNUTLS.DSASignatureValue",
146 &sig)) != ASN1_SUCCESS) {
147 gnutls_assert();
148 return _gnutls_asn2err(result);
149 }
150
151 result = _gnutls_x509_write_int(sig, "r", r, 1);
152 if (result < 0) {
153 gnutls_assert();
154 asn1_delete_structure(&sig);
155 return result;
156 }
157
158 result = _gnutls_x509_write_int(sig, "s", s, 1);
159 if (result < 0) {
160 gnutls_assert();
161 asn1_delete_structure(&sig);
162 return result;
163 }
164
165 result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
166 asn1_delete_structure(&sig);
167
168 if (result < 0)
169 return gnutls_assert_val(result);
170
171 return 0;
172 }
173
174
175 /* decodes the Dss-Sig-Value structure
176 */
177 int
_gnutls_decode_ber_rs(const gnutls_datum_t * sig_value,bigint_t * r,bigint_t * s)178 _gnutls_decode_ber_rs(const gnutls_datum_t * sig_value, bigint_t * r,
179 bigint_t * s)
180 {
181 ASN1_TYPE sig;
182 int result;
183
184 if ((result =
185 asn1_create_element(_gnutls_get_gnutls_asn(),
186 "GNUTLS.DSASignatureValue",
187 &sig)) != ASN1_SUCCESS) {
188 gnutls_assert();
189 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 result =
195 asn1_der_decoding(&sig, sig_value->data, sig_value->size,
196 NULL);
197 if (result != ASN1_SUCCESS) {
198 gnutls_assert();
199 asn1_delete_structure(&sig);
200 return _gnutls_asn2err(result);
201 }
202
203 result = _gnutls_x509_read_int(sig, "r", r);
204 if (result < 0) {
205 gnutls_assert();
206 asn1_delete_structure(&sig);
207 return result;
208 }
209
210 result = _gnutls_x509_read_int(sig, "s", s);
211 if (result < 0) {
212 gnutls_assert();
213 _gnutls_mpi_release(r);
214 asn1_delete_structure(&sig);
215 return result;
216 }
217
218 asn1_delete_structure(&sig);
219
220 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 **/
gnutls_decode_rs_value(const gnutls_datum_t * sig_value,gnutls_datum_t * r,gnutls_datum_t * s)243 int gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
244 gnutls_datum_t *s)
245 {
246 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
_gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value,gnutls_datum_t * r,gnutls_datum_t * s)253 _gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
254 gnutls_datum_t *s)
255 {
256 ASN1_TYPE sig;
257 int result;
258
259 if ((result =
260 asn1_create_element(_gnutls_get_gnutls_asn(),
261 "GNUTLS.DSASignatureValue",
262 &sig)) != ASN1_SUCCESS) {
263 gnutls_assert();
264 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 result =
270 asn1_der_decoding(&sig, sig_value->data, sig_value->size,
271 NULL);
272 if (result != ASN1_SUCCESS) {
273 gnutls_assert();
274 asn1_delete_structure(&sig);
275 return _gnutls_asn2err(result);
276 }
277
278 result = _gnutls_x509_read_value(sig, "r", r);
279 if (result < 0) {
280 gnutls_assert();
281 asn1_delete_structure(&sig);
282 return result;
283 }
284
285 result = _gnutls_x509_read_value(sig, "s", s);
286 if (result < 0) {
287 gnutls_assert();
288 gnutls_free(r->data);
289 asn1_delete_structure(&sig);
290 return result;
291 }
292
293 asn1_delete_structure(&sig);
294
295 return 0;
296 }
297
298 int
_gnutls_encode_gost_rs(gnutls_datum_t * sig_value,bigint_t r,bigint_t s,size_t intsize)299 _gnutls_encode_gost_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s,
300 size_t intsize)
301 {
302 uint8_t *data;
303 int result;
304
305 data = gnutls_malloc(intsize * 2);
306 if (data == NULL) {
307 gnutls_assert();
308 return GNUTLS_E_MEMORY_ERROR;
309 }
310
311 if ((result = _gnutls_mpi_bprint_size(s, data, intsize)) < 0) {
312 gnutls_assert();
313 gnutls_free(data);
314 return result;
315 }
316
317 if ((result = _gnutls_mpi_bprint_size(r, data + intsize, intsize)) < 0) {
318 gnutls_assert();
319 gnutls_free(data);
320 return result;
321 }
322
323 sig_value->data = data;
324 sig_value->size = intsize * 2;
325
326 return 0;
327 }
328
329 int
_gnutls_decode_gost_rs(const gnutls_datum_t * sig_value,bigint_t * r,bigint_t * s)330 _gnutls_decode_gost_rs(const gnutls_datum_t * sig_value, bigint_t * r,
331 bigint_t * s)
332 {
333 int ret;
334 unsigned halfsize = sig_value->size >> 1;
335
336 if (sig_value->size % 2 != 0) {
337 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
338 }
339
340 ret = _gnutls_mpi_init_scan(s, sig_value->data, halfsize);
341 if (ret < 0)
342 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
343
344 ret = _gnutls_mpi_init_scan(r, sig_value->data + halfsize, halfsize);
345 if (ret < 0) {
346 _gnutls_mpi_release(s);
347 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 */
gnutls_encode_gost_rs_value(gnutls_datum_t * sig_value,const gnutls_datum_t * r,const gnutls_datum_t * s)370 int gnutls_encode_gost_rs_value(gnutls_datum_t * sig_value, const gnutls_datum_t * r, const gnutls_datum_t *s)
371 {
372 uint8_t *data;
373 size_t intsize = r->size;
374
375 if (s->size != intsize) {
376 gnutls_assert();
377 return GNUTLS_E_ILLEGAL_PARAMETER;
378 }
379
380 data = gnutls_malloc(intsize * 2);
381 if (data == NULL) {
382 gnutls_assert();
383 return GNUTLS_E_MEMORY_ERROR;
384 }
385
386 memcpy(data, s->data, intsize);
387 memcpy(data + intsize, r->data, intsize);
388
389 sig_value->data = data;
390 sig_value->size = intsize * 2;
391
392 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 */
gnutls_decode_gost_rs_value(const gnutls_datum_t * sig_value,gnutls_datum_t * r,gnutls_datum_t * s)413 int gnutls_decode_gost_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
414 {
415 int ret;
416 unsigned halfsize = sig_value->size >> 1;
417
418 if (sig_value->size % 2 != 0)
419 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
420
421 ret = _gnutls_set_datum(s, sig_value->data, halfsize);
422 if (ret != 0)
423 return gnutls_assert_val(ret);
424
425 ret = _gnutls_set_datum(r, sig_value->data + halfsize, halfsize);
426 if (ret != 0) {
427 _gnutls_free_datum(s);
428 return gnutls_assert_val(ret);
429 }
430
431 return 0;
432 }
433
_gnutls_gost_digest(gnutls_pk_algorithm_t pk)434 gnutls_digest_algorithm_t _gnutls_gost_digest(gnutls_pk_algorithm_t pk)
435 {
436 if (pk == GNUTLS_PK_GOST_01)
437 return GNUTLS_DIG_GOSTR_94;
438 else if (pk == GNUTLS_PK_GOST_12_256)
439 return GNUTLS_DIG_STREEBOG_256;
440 else if (pk == GNUTLS_PK_GOST_12_512)
441 return GNUTLS_DIG_STREEBOG_512;
442
443 gnutls_assert();
444
445 return GNUTLS_DIG_UNKNOWN;
446 }
447
_gnutls_digest_gost(gnutls_digest_algorithm_t digest)448 gnutls_pk_algorithm_t _gnutls_digest_gost(gnutls_digest_algorithm_t digest)
449 {
450 if (digest == GNUTLS_DIG_GOSTR_94)
451 return GNUTLS_PK_GOST_01;
452 else if (digest == GNUTLS_DIG_STREEBOG_256)
453 return GNUTLS_PK_GOST_12_256;
454 else if (digest == GNUTLS_DIG_STREEBOG_512)
455 return GNUTLS_PK_GOST_12_512;
456
457 gnutls_assert();
458
459 return GNUTLS_PK_UNKNOWN;
460 }
461
_gnutls_gost_paramset_default(gnutls_pk_algorithm_t pk)462 gnutls_gost_paramset_t _gnutls_gost_paramset_default(gnutls_pk_algorithm_t pk)
463 {
464 if (pk == GNUTLS_PK_GOST_01)
465 return GNUTLS_GOST_PARAMSET_CP_A;
466 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 return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN);
471 }
472
473 /* some generic pk functions */
474
_gnutls_pk_params_copy(gnutls_pk_params_st * dst,const gnutls_pk_params_st * src)475 int _gnutls_pk_params_copy(gnutls_pk_params_st * dst,
476 const gnutls_pk_params_st * src)
477 {
478 unsigned int i, j;
479 dst->params_nr = 0;
480
481 if (src == NULL || (src->params_nr == 0 && src->raw_pub.size == 0)) {
482 gnutls_assert();
483 return GNUTLS_E_INVALID_REQUEST;
484 }
485
486 dst->pkflags = src->pkflags;
487 dst->curve = src->curve;
488 dst->gost_params = src->gost_params;
489 dst->qbits = src->qbits;
490 dst->algo = src->algo;
491
492 for (i = 0; i < src->params_nr; i++) {
493 dst->params[i] = _gnutls_mpi_copy(src->params[i]);
494 if (dst->params[i] == NULL) {
495 goto fail;
496 }
497
498 dst->params_nr++;
499 }
500
501 if (_gnutls_set_datum(&dst->raw_priv, src->raw_priv.data, src->raw_priv.size) < 0) {
502 gnutls_assert();
503 goto fail;
504 }
505
506 if (_gnutls_set_datum(&dst->raw_pub, src->raw_pub.data, src->raw_pub.size) < 0) {
507 gnutls_assert();
508 goto fail;
509 }
510
511 if (src->seed_size) {
512 dst->seed_size = src->seed_size;
513 memcpy(dst->seed, src->seed, src->seed_size);
514 }
515 dst->palgo = src->palgo;
516
517 memcpy(&dst->spki, &src->spki, sizeof(gnutls_x509_spki_st));
518
519 return 0;
520
521 fail:
522 for (j = 0; j < i; j++)
523 _gnutls_mpi_release(&dst->params[j]);
524 return GNUTLS_E_MEMORY_ERROR;
525 }
526
gnutls_pk_params_init(gnutls_pk_params_st * p)527 void gnutls_pk_params_init(gnutls_pk_params_st * p)
528 {
529 memset(p, 0, sizeof(gnutls_pk_params_st));
530 }
531
gnutls_pk_params_release(gnutls_pk_params_st * p)532 void gnutls_pk_params_release(gnutls_pk_params_st * p)
533 {
534 unsigned int i;
535 for (i = 0; i < p->params_nr; i++) {
536 _gnutls_mpi_release(&p->params[i]);
537 }
538 gnutls_free(p->raw_priv.data);
539 gnutls_free(p->raw_pub.data);
540
541 p->params_nr = 0;
542 }
543
gnutls_pk_params_clear(gnutls_pk_params_st * p)544 void gnutls_pk_params_clear(gnutls_pk_params_st * p)
545 {
546 unsigned int i;
547 for (i = 0; i < p->params_nr; i++) {
548 if (p->params[i] != NULL)
549 _gnutls_mpi_clear(p->params[i]);
550 }
551 gnutls_memset(p->seed, 0, p->seed_size);
552 p->seed_size = 0;
553 if (p->raw_priv.data != NULL) {
554 gnutls_memset(p->raw_priv.data, 0, p->raw_priv.size);
555 p->raw_priv.size = 0;
556 }
557 }
558
559 int
_gnutls_find_rsa_pss_salt_size(unsigned bits,const mac_entry_st * me,unsigned salt_size)560 _gnutls_find_rsa_pss_salt_size(unsigned bits, const mac_entry_st *me,
561 unsigned salt_size)
562 {
563 unsigned digest_size;
564 int max_salt_size;
565 unsigned key_size;
566
567 digest_size = _gnutls_hash_get_algo_len(me);
568 key_size = (bits + 7) / 8;
569
570 if (key_size == 0) {
571 return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY);
572 } else {
573 max_salt_size = key_size - digest_size - 2;
574 if (max_salt_size < 0)
575 return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
576 }
577
578 if (salt_size < digest_size)
579 salt_size = digest_size;
580
581 if (salt_size > (unsigned)max_salt_size)
582 salt_size = max_salt_size;
583
584 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
encode_ber_digest_info(const mac_entry_st * e,const gnutls_datum_t * digest,gnutls_datum_t * output)591 encode_ber_digest_info(const mac_entry_st * e,
592 const gnutls_datum_t * digest,
593 gnutls_datum_t * output)
594 {
595 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
596 int result;
597 const char *algo;
598 uint8_t *tmp_output;
599 int tmp_output_size;
600
601 /* prevent asn1_write_value() treating input as string */
602 if (digest->size == 0)
603 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
604
605 algo = _gnutls_x509_mac_to_oid(e);
606 if (algo == NULL) {
607 gnutls_assert();
608 _gnutls_debug_log("Hash algorithm: %d has no OID\n",
609 e->id);
610 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
611 }
612
613 if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
614 "GNUTLS.DigestInfo",
615 &dinfo)) != ASN1_SUCCESS) {
616 gnutls_assert();
617 return _gnutls_asn2err(result);
618 }
619
620 result =
621 asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
622 if (result != ASN1_SUCCESS) {
623 gnutls_assert();
624 asn1_delete_structure(&dinfo);
625 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 result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
634 ASN1_NULL, ASN1_NULL_SIZE);
635 if (result != ASN1_SUCCESS) {
636 gnutls_assert();
637 asn1_delete_structure(&dinfo);
638 return _gnutls_asn2err(result);
639 }
640
641 result =
642 asn1_write_value(dinfo, "digest", digest->data, digest->size);
643 if (result != ASN1_SUCCESS) {
644 gnutls_assert();
645 asn1_delete_structure(&dinfo);
646 return _gnutls_asn2err(result);
647 }
648
649 tmp_output_size = 0;
650 result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
651 if (result != ASN1_MEM_ERROR) {
652 gnutls_assert();
653 asn1_delete_structure(&dinfo);
654 return _gnutls_asn2err(result);
655 }
656
657 tmp_output = gnutls_malloc(tmp_output_size);
658 if (tmp_output == NULL) {
659 gnutls_assert();
660 asn1_delete_structure(&dinfo);
661 return GNUTLS_E_MEMORY_ERROR;
662 }
663
664 result =
665 asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
666 if (result != ASN1_SUCCESS) {
667 gnutls_assert();
668 asn1_delete_structure(&dinfo);
669 return _gnutls_asn2err(result);
670 }
671
672 asn1_delete_structure(&dinfo);
673
674 output->size = tmp_output_size;
675 output->data = tmp_output;
676
677 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
gnutls_encode_ber_digest_info(gnutls_digest_algorithm_t hash,const gnutls_datum_t * digest,gnutls_datum_t * output)697 gnutls_encode_ber_digest_info(gnutls_digest_algorithm_t hash,
698 const gnutls_datum_t * digest,
699 gnutls_datum_t * output)
700 {
701 const mac_entry_st *e = hash_to_entry(hash);
702 if (unlikely(e == NULL))
703 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
704
705 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
gnutls_decode_ber_digest_info(const gnutls_datum_t * info,gnutls_digest_algorithm_t * hash,unsigned char * digest,unsigned int * digest_size)725 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 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
730 int result;
731 char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
732 int len;
733
734 if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
735 "GNUTLS.DigestInfo",
736 &dinfo)) != ASN1_SUCCESS) {
737 gnutls_assert();
738 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 result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
744 if (result != ASN1_SUCCESS) {
745 gnutls_assert();
746 asn1_delete_structure(&dinfo);
747 return _gnutls_asn2err(result);
748 }
749
750 len = sizeof(str) - 1;
751 result =
752 asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len);
753 if (result != ASN1_SUCCESS) {
754 gnutls_assert();
755 asn1_delete_structure(&dinfo);
756 return _gnutls_asn2err(result);
757 }
758
759 *hash = gnutls_oid_to_digest(str);
760
761 if (*hash == GNUTLS_DIG_UNKNOWN) {
762
763 _gnutls_debug_log("verify.c: HASH OID: %s\n", str);
764
765 gnutls_assert();
766 asn1_delete_structure(&dinfo);
767 return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
768 }
769
770 len = sizeof(str) - 1;
771 result =
772 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 if (!(result == ASN1_ELEMENT_NOT_FOUND ||
777 (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
778 memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
779 gnutls_assert();
780 asn1_delete_structure(&dinfo);
781 return GNUTLS_E_ASN1_GENERIC_ERROR;
782 }
783
784 len = *digest_size;
785 result = asn1_read_value(dinfo, "digest", digest, &len);
786
787 if (result != ASN1_SUCCESS) {
788 gnutls_assert();
789 *digest_size = len;
790 asn1_delete_structure(&dinfo);
791 return _gnutls_asn2err(result);
792 }
793
794 *digest_size = len;
795 asn1_delete_structure(&dinfo);
796
797 return 0;
798 }
799
800 int
_gnutls_params_get_rsa_raw(const gnutls_pk_params_st * params,gnutls_datum_t * m,gnutls_datum_t * e,gnutls_datum_t * d,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * u,gnutls_datum_t * e1,gnutls_datum_t * e2,unsigned int flags)801 _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 int ret;
810 mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
811
812 if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
813 dprint = _gnutls_mpi_dprint;
814
815 if (params == NULL) {
816 gnutls_assert();
817 return GNUTLS_E_INVALID_REQUEST;
818 }
819
820 if (!GNUTLS_PK_IS_RSA(params->algo)) {
821 gnutls_assert();
822 return GNUTLS_E_INVALID_REQUEST;
823 }
824
825 if (m) {
826 ret = dprint(params->params[0], m);
827 if (ret < 0) {
828 gnutls_assert();
829 goto error;
830 }
831 }
832
833 /* E */
834 if (e) {
835 ret = dprint(params->params[1], e);
836 if (ret < 0) {
837 gnutls_assert();
838 goto error;
839 }
840 }
841
842 /* D */
843 if (d && params->params[2]) {
844 ret = dprint(params->params[2], d);
845 if (ret < 0) {
846 gnutls_assert();
847 goto error;
848 }
849 } else if (d) {
850 d->data = NULL;
851 d->size = 0;
852 }
853
854 /* P */
855 if (p && params->params[3]) {
856 ret = dprint(params->params[3], p);
857 if (ret < 0) {
858 gnutls_assert();
859 goto error;
860 }
861 } else if (p) {
862 p->data = NULL;
863 p->size = 0;
864 }
865
866 /* Q */
867 if (q && params->params[4]) {
868 ret = dprint(params->params[4], q);
869 if (ret < 0) {
870 gnutls_assert();
871 goto error;
872 }
873 } else if (q) {
874 q->data = NULL;
875 q->size = 0;
876 }
877
878 /* U */
879 if (u && params->params[5]) {
880 ret = dprint(params->params[5], u);
881 if (ret < 0) {
882 gnutls_assert();
883 goto error;
884 }
885 } else if (u) {
886 u->data = NULL;
887 u->size = 0;
888 }
889
890 /* E1 */
891 if (e1 && params->params[6]) {
892 ret = dprint(params->params[6], e1);
893 if (ret < 0) {
894 gnutls_assert();
895 goto error;
896 }
897 } else if (e1) {
898 e1->data = NULL;
899 e1->size = 0;
900 }
901
902 /* E2 */
903 if (e2 && params->params[7]) {
904 ret = dprint(params->params[7], e2);
905 if (ret < 0) {
906 gnutls_assert();
907 goto error;
908 }
909 } else if (e2) {
910 e2->data = NULL;
911 e2->size = 0;
912 }
913
914 return 0;
915
916 error:
917 _gnutls_free_datum(m);
918 _gnutls_free_datum(d);
919 _gnutls_free_datum(e);
920 _gnutls_free_datum(e1);
921 _gnutls_free_datum(e2);
922 _gnutls_free_datum(p);
923 _gnutls_free_datum(q);
924
925 return ret;
926 }
927
928 int
_gnutls_params_get_dsa_raw(const gnutls_pk_params_st * params,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * g,gnutls_datum_t * y,gnutls_datum_t * x,unsigned int flags)929 _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 int ret;
935 mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
936
937 if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
938 dprint = _gnutls_mpi_dprint;
939
940 if (params == NULL) {
941 gnutls_assert();
942 return GNUTLS_E_INVALID_REQUEST;
943 }
944
945 if (params->algo != GNUTLS_PK_DSA) {
946 gnutls_assert();
947 return GNUTLS_E_INVALID_REQUEST;
948 }
949
950 /* P */
951 if (p) {
952 ret = dprint(params->params[0], p);
953 if (ret < 0) {
954 gnutls_assert();
955 return ret;
956 }
957 }
958
959 /* Q */
960 if (q) {
961 ret = dprint(params->params[1], q);
962 if (ret < 0) {
963 gnutls_assert();
964 _gnutls_free_datum(p);
965 return ret;
966 }
967 }
968
969
970 /* G */
971 if (g) {
972 ret = dprint(params->params[2], g);
973 if (ret < 0) {
974 gnutls_assert();
975 _gnutls_free_datum(p);
976 _gnutls_free_datum(q);
977 return ret;
978 }
979 }
980
981
982 /* Y */
983 if (y) {
984 ret = dprint(params->params[3], y);
985 if (ret < 0) {
986 gnutls_assert();
987 _gnutls_free_datum(p);
988 _gnutls_free_datum(g);
989 _gnutls_free_datum(q);
990 return ret;
991 }
992 }
993
994 /* X */
995 if (x) {
996 ret = dprint(params->params[4], x);
997 if (ret < 0) {
998 gnutls_assert();
999 _gnutls_free_datum(y);
1000 _gnutls_free_datum(p);
1001 _gnutls_free_datum(g);
1002 _gnutls_free_datum(q);
1003 return ret;
1004 }
1005 }
1006
1007 return 0;
1008 }
1009
_gnutls_params_get_ecc_raw(const gnutls_pk_params_st * params,gnutls_ecc_curve_t * curve,gnutls_datum_t * x,gnutls_datum_t * y,gnutls_datum_t * k,unsigned int flags)1010 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 int ret;
1018 mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1019 const gnutls_ecc_curve_entry_st *e;
1020
1021 if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1022 dprint = _gnutls_mpi_dprint;
1023
1024 if (params == NULL) {
1025 gnutls_assert();
1026 return GNUTLS_E_INVALID_REQUEST;
1027 }
1028
1029 if (curve)
1030 *curve = params->curve;
1031
1032 e = _gnutls_ecc_curve_get_params(params->curve);
1033
1034 if (_curve_is_eddsa(e)) {
1035 if (x) {
1036 ret = _gnutls_set_datum(x, params->raw_pub.data, params->raw_pub.size);
1037 if (ret < 0) {
1038 return gnutls_assert_val(ret);
1039 }
1040 }
1041
1042 if (y) {
1043 y->data = NULL;
1044 y->size = 0;
1045 }
1046
1047 if (k) {
1048 ret = _gnutls_set_datum(k, params->raw_priv.data, params->raw_priv.size);
1049 if (ret < 0) {
1050 _gnutls_free_datum(x);
1051 return gnutls_assert_val(ret);
1052 }
1053 }
1054
1055 return 0;
1056 }
1057
1058 if (unlikely(e == NULL || e->pk != GNUTLS_PK_ECDSA))
1059 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1060
1061 /* X */
1062 if (x) {
1063 ret = dprint(params->params[ECC_X], x);
1064 if (ret < 0) {
1065 gnutls_assert();
1066 return ret;
1067 }
1068 }
1069
1070 /* Y */
1071 if (y) {
1072 ret = dprint(params->params[ECC_Y], y);
1073 if (ret < 0) {
1074 gnutls_assert();
1075 _gnutls_free_datum(x);
1076 return ret;
1077 }
1078 }
1079
1080
1081 /* K */
1082 if (k) {
1083 ret = dprint(params->params[ECC_K], k);
1084 if (ret < 0) {
1085 gnutls_assert();
1086 _gnutls_free_datum(x);
1087 _gnutls_free_datum(y);
1088 return ret;
1089 }
1090 }
1091
1092 return 0;
1093
1094 }
1095
_gnutls_params_get_gost_raw(const gnutls_pk_params_st * params,gnutls_ecc_curve_t * curve,gnutls_digest_algorithm_t * digest,gnutls_gost_paramset_t * paramset,gnutls_datum_t * x,gnutls_datum_t * y,gnutls_datum_t * k,unsigned int flags)1096 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 int ret;
1106 mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1107
1108 if (params == NULL) {
1109 gnutls_assert();
1110 return GNUTLS_E_INVALID_REQUEST;
1111 }
1112
1113 if (curve)
1114 *curve = params->curve;
1115
1116 if (digest)
1117 *digest = _gnutls_gost_digest(params->algo);
1118
1119 if (paramset)
1120 *paramset = params->gost_params;
1121
1122 /* X */
1123 if (x) {
1124 ret = dprint(params->params[GOST_X], x);
1125 if (ret < 0) {
1126 gnutls_assert();
1127 return ret;
1128 }
1129 }
1130
1131 /* Y */
1132 if (y) {
1133 ret = dprint(params->params[GOST_Y], y);
1134 if (ret < 0) {
1135 gnutls_assert();
1136 _gnutls_free_datum(x);
1137 return ret;
1138 }
1139 }
1140
1141
1142 /* K */
1143 if (k) {
1144 ret = dprint(params->params[GOST_K], k);
1145 if (ret < 0) {
1146 gnutls_assert();
1147 _gnutls_free_datum(x);
1148 _gnutls_free_datum(y);
1149 return ret;
1150 }
1151 }
1152
1153 return 0;
1154
1155 }
1156
1157 int
pk_hash_data(gnutls_pk_algorithm_t pk,const mac_entry_st * hash,gnutls_pk_params_st * params,const gnutls_datum_t * data,gnutls_datum_t * digest)1158 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 int ret;
1163
1164 digest->size = _gnutls_hash_get_algo_len(hash);
1165 digest->data = gnutls_malloc(digest->size);
1166 if (digest->data == NULL) {
1167 gnutls_assert();
1168 return GNUTLS_E_MEMORY_ERROR;
1169 }
1170
1171 ret =
1172 _gnutls_hash_fast((gnutls_digest_algorithm_t)hash->id, data->data, data->size,
1173 digest->data);
1174 if (ret < 0) {
1175 gnutls_assert();
1176 goto cleanup;
1177 }
1178
1179 return 0;
1180
1181 cleanup:
1182 gnutls_free(digest->data);
1183 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
pk_prepare_hash(gnutls_pk_algorithm_t pk,const mac_entry_st * hash,gnutls_datum_t * digest)1193 pk_prepare_hash(gnutls_pk_algorithm_t pk,
1194 const mac_entry_st * hash, gnutls_datum_t * digest)
1195 {
1196 int ret;
1197 gnutls_datum_t old_digest = { digest->data, digest->size };
1198
1199 switch (pk) {
1200 case GNUTLS_PK_RSA:
1201 if (unlikely(hash == NULL))
1202 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1203 /* Encode the digest as a DigestInfo
1204 */
1205 if ((ret =
1206 encode_ber_digest_info(hash, &old_digest,
1207 digest)) != 0) {
1208 gnutls_assert();
1209 return ret;
1210 }
1211
1212 _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 default:
1224 gnutls_assert();
1225 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1226 }
1227
1228 return 0;
1229 }
1230