Fix CVE-2017-6891 in minitasn1 code
[platform/upstream/gnutls.git] / lib / gnutls_pk.c
1 /*
2  * Copyright (C) 2001-2014 Free Software Foundation, Inc.
3  *
4  * Author: Nikos Mavrogiannopoulos
5  *
6  * This file is part of GnuTLS.
7  *
8  * The GnuTLS is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>
20  *
21  */
22
23 /* This file contains the functions needed for RSA/DSA public key
24  * encryption and signatures. 
25  */
26
27 #include <gnutls_int.h>
28 #include <gnutls_mpi.h>
29 #include <gnutls_pk.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_datum.h>
32 #include <gnutls_global.h>
33 #include <gnutls_num.h>
34 #include "debug.h"
35 #include <x509/x509_int.h>
36 #include <x509/common.h>
37 #include <random.h>
38
39 /* encodes the Dss-Sig-Value structure
40  */
41 int
42 _gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,
43                           const gnutls_datum_t * r,
44                           const gnutls_datum_t * s)
45 {
46         ASN1_TYPE sig;
47         int result, ret;
48         uint8_t *tmp = NULL;
49
50         if ((result =
51              asn1_create_element(_gnutls_get_gnutls_asn(),
52                                  "GNUTLS.DSASignatureValue",
53                                  &sig)) != ASN1_SUCCESS) {
54                 gnutls_assert();
55                 return _gnutls_asn2err(result);
56         }
57
58         if (r->data[0] >= 0x80) {
59                 tmp = gnutls_malloc(r->size+1);
60                 if (tmp == NULL) {
61                         ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
62                         goto cleanup;
63                 }
64                 memcpy(&tmp[1], r->data, r->size);
65                 tmp[0] = 0;
66                 result = asn1_write_value(sig, "r", tmp, 1+r->size);
67
68                 gnutls_free(tmp);
69                 tmp = NULL;
70         } else {
71                 result = asn1_write_value(sig, "r", r->data, r->size);
72         }
73         if (result != ASN1_SUCCESS) {
74                 gnutls_assert();
75                 ret = _gnutls_asn2err(result);
76                 goto cleanup;
77         }
78
79         if (s->data[0] >= 0x80) {
80                 tmp = gnutls_malloc(s->size+1);
81                 if (tmp == NULL) {
82                         ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
83                         goto cleanup;
84                 }
85                 memcpy(&tmp[1], s->data, s->size);
86                 tmp[0] = 0;
87                 result = asn1_write_value(sig, "s", tmp, 1+s->size);
88
89                 gnutls_free(tmp);
90                 tmp = NULL;
91         } else {
92                 result = asn1_write_value(sig, "s", s->data, s->size);
93         }
94
95         if (result != ASN1_SUCCESS) {
96                 gnutls_assert();
97                 ret = _gnutls_asn2err(result);
98                 goto cleanup;
99         }
100
101         ret = _gnutls_x509_der_encode(sig, "", sig_value, 0);
102         if (ret < 0) {
103                 gnutls_assert();
104                 goto cleanup;
105         }
106
107         ret = 0;
108  cleanup:
109         asn1_delete_structure(&sig);
110         return ret;
111 }
112
113 int
114 _gnutls_encode_ber_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
115 {
116         ASN1_TYPE sig;
117         int result;
118
119         if ((result =
120              asn1_create_element(_gnutls_get_gnutls_asn(),
121                                  "GNUTLS.DSASignatureValue",
122                                  &sig)) != ASN1_SUCCESS) {
123                 gnutls_assert();
124                 return _gnutls_asn2err(result);
125         }
126
127         result = _gnutls_x509_write_int(sig, "r", r, 1);
128         if (result < 0) {
129                 gnutls_assert();
130                 asn1_delete_structure(&sig);
131                 return result;
132         }
133
134         result = _gnutls_x509_write_int(sig, "s", s, 1);
135         if (result < 0) {
136                 gnutls_assert();
137                 asn1_delete_structure(&sig);
138                 return result;
139         }
140
141         result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
142         asn1_delete_structure(&sig);
143
144         if (result < 0)
145                 return gnutls_assert_val(result);
146
147         return 0;
148 }
149
150
151 /* decodes the Dss-Sig-Value structure
152  */
153 int
154 _gnutls_decode_ber_rs(const gnutls_datum_t * sig_value, bigint_t * r,
155                       bigint_t * s)
156 {
157         ASN1_TYPE sig;
158         int result;
159
160         if ((result =
161              asn1_create_element(_gnutls_get_gnutls_asn(),
162                                  "GNUTLS.DSASignatureValue",
163                                  &sig)) != ASN1_SUCCESS) {
164                 gnutls_assert();
165                 return _gnutls_asn2err(result);
166         }
167
168         result =
169             asn1_der_decoding(&sig, sig_value->data, sig_value->size,
170                               NULL);
171         if (result != ASN1_SUCCESS) {
172                 gnutls_assert();
173                 asn1_delete_structure(&sig);
174                 return _gnutls_asn2err(result);
175         }
176
177         result = _gnutls_x509_read_int(sig, "r", r);
178         if (result < 0) {
179                 gnutls_assert();
180                 asn1_delete_structure(&sig);
181                 return result;
182         }
183
184         result = _gnutls_x509_read_int(sig, "s", s);
185         if (result < 0) {
186                 gnutls_assert();
187                 _gnutls_mpi_release(s);
188                 asn1_delete_structure(&sig);
189                 return result;
190         }
191
192         asn1_delete_structure(&sig);
193
194         return 0;
195 }
196
197 /* some generic pk functions */
198
199 int _gnutls_pk_params_copy(gnutls_pk_params_st * dst,
200                            const gnutls_pk_params_st * src)
201 {
202         unsigned int i, j;
203         dst->params_nr = 0;
204
205         if (src == NULL || src->params_nr == 0) {
206                 gnutls_assert();
207                 return GNUTLS_E_INVALID_REQUEST;
208         }
209
210         dst->flags = src->flags;
211         dst->algo = src->algo;
212
213         for (i = 0; i < src->params_nr; i++) {
214                 dst->params[i] = _gnutls_mpi_copy(src->params[i]);
215                 if (dst->params[i] == NULL) {
216                         goto fail;
217                 }
218
219                 dst->params_nr++;
220         }
221
222         return 0;
223
224 fail:
225         for (j = 0; j < i; j++)
226                 _gnutls_mpi_release(&dst->params[j]);
227         return GNUTLS_E_MEMORY_ERROR;
228 }
229
230 void gnutls_pk_params_init(gnutls_pk_params_st * p)
231 {
232         memset(p, 0, sizeof(gnutls_pk_params_st));
233 }
234
235 void gnutls_pk_params_release(gnutls_pk_params_st * p)
236 {
237         unsigned int i;
238         for (i = 0; i < p->params_nr; i++) {
239                 _gnutls_mpi_release(&p->params[i]);
240         }
241         p->params_nr = 0;
242 }
243
244 void gnutls_pk_params_clear(gnutls_pk_params_st * p)
245 {
246         unsigned int i;
247         for (i = 0; i < p->params_nr; i++) {
248                 if (p->params[i] != NULL)
249                         _gnutls_mpi_clear(p->params[i]);
250         }
251 }
252
253 int
254 _gnutls_pk_get_hash_algorithm(gnutls_pk_algorithm_t pk,
255                               gnutls_pk_params_st * params,
256                               gnutls_digest_algorithm_t * dig,
257                               unsigned int *mand)
258 {
259         if (mand) {
260                 if (pk == GNUTLS_PK_DSA)
261                         *mand = 1;
262                 else
263                         *mand = 0;
264         }
265
266         return _gnutls_x509_verify_algorithm(dig, NULL, pk, params);
267
268 }
269
270 /* Writes the digest information and the digest in a DER encoded
271  * structure. The digest info is allocated and stored into the info structure.
272  */
273 int
274 encode_ber_digest_info(const mac_entry_st * e,
275                        const gnutls_datum_t * digest,
276                        gnutls_datum_t * output)
277 {
278         ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
279         int result;
280         const char *algo;
281         uint8_t *tmp_output;
282         int tmp_output_size;
283
284         algo = _gnutls_x509_mac_to_oid(e);
285         if (algo == NULL) {
286                 gnutls_assert();
287                 _gnutls_debug_log("Hash algorithm: %d has no OID\n",
288                                   e->id);
289                 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
290         }
291
292         if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
293                                           "GNUTLS.DigestInfo",
294                                           &dinfo)) != ASN1_SUCCESS) {
295                 gnutls_assert();
296                 return _gnutls_asn2err(result);
297         }
298
299         result =
300             asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
301         if (result != ASN1_SUCCESS) {
302                 gnutls_assert();
303                 asn1_delete_structure(&dinfo);
304                 return _gnutls_asn2err(result);
305         }
306
307         /* Write an ASN.1 NULL in the parameters field.  This matches RFC
308            3279 and RFC 4055, although is arguable incorrect from a historic
309            perspective (see those documents for more information).
310            Regardless of what is correct, this appears to be what most
311            implementations do.  */
312         result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
313                                   ASN1_NULL, ASN1_NULL_SIZE);
314         if (result != ASN1_SUCCESS) {
315                 gnutls_assert();
316                 asn1_delete_structure(&dinfo);
317                 return _gnutls_asn2err(result);
318         }
319
320         result =
321             asn1_write_value(dinfo, "digest", digest->data, digest->size);
322         if (result != ASN1_SUCCESS) {
323                 gnutls_assert();
324                 asn1_delete_structure(&dinfo);
325                 return _gnutls_asn2err(result);
326         }
327
328         tmp_output_size = 0;
329         result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
330         if (result != ASN1_MEM_ERROR) {
331                 gnutls_assert();
332                 asn1_delete_structure(&dinfo);
333                 return _gnutls_asn2err(result);
334         }
335
336         tmp_output = gnutls_malloc(tmp_output_size);
337         if (tmp_output == NULL) {
338                 gnutls_assert();
339                 asn1_delete_structure(&dinfo);
340                 return GNUTLS_E_MEMORY_ERROR;
341         }
342
343         result =
344             asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
345         if (result != ASN1_SUCCESS) {
346                 gnutls_assert();
347                 asn1_delete_structure(&dinfo);
348                 return _gnutls_asn2err(result);
349         }
350
351         asn1_delete_structure(&dinfo);
352
353         output->size = tmp_output_size;
354         output->data = tmp_output;
355
356         return 0;
357 }
358
359 /* Reads the digest information.
360  * we use DER here, although we should use BER. It works fine
361  * anyway.
362  */
363 int
364 decode_ber_digest_info(const gnutls_datum_t * info,
365                        gnutls_digest_algorithm_t * hash,
366                        uint8_t * digest, unsigned int *digest_size)
367 {
368         ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
369         int result;
370         char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
371         int len;
372
373         if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
374                                           "GNUTLS.DigestInfo",
375                                           &dinfo)) != ASN1_SUCCESS) {
376                 gnutls_assert();
377                 return _gnutls_asn2err(result);
378         }
379
380         result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
381         if (result != ASN1_SUCCESS) {
382                 gnutls_assert();
383                 asn1_delete_structure(&dinfo);
384                 return _gnutls_asn2err(result);
385         }
386
387         len = sizeof(str) - 1;
388         result =
389             asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len);
390         if (result != ASN1_SUCCESS) {
391                 gnutls_assert();
392                 asn1_delete_structure(&dinfo);
393                 return _gnutls_asn2err(result);
394         }
395
396         *hash = _gnutls_x509_oid_to_digest(str);
397
398         if (*hash == GNUTLS_DIG_UNKNOWN) {
399
400                 _gnutls_debug_log("verify.c: HASH OID: %s\n", str);
401
402                 gnutls_assert();
403                 asn1_delete_structure(&dinfo);
404                 return GNUTLS_E_UNKNOWN_ALGORITHM;
405         }
406
407         len = sizeof(str) - 1;
408         result =
409             asn1_read_value(dinfo, "digestAlgorithm.parameters", str,
410                             &len);
411         /* To avoid permitting garbage in the parameters field, either the
412            parameters field is not present, or it contains 0x05 0x00. */
413         if (!(result == ASN1_ELEMENT_NOT_FOUND ||
414               (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
415                memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
416                 gnutls_assert();
417                 asn1_delete_structure(&dinfo);
418                 return GNUTLS_E_ASN1_GENERIC_ERROR;
419         }
420
421         len = *digest_size;
422         result = asn1_read_value(dinfo, "digest", digest, &len);
423
424         if (result != ASN1_SUCCESS) {
425                 gnutls_assert();
426                 *digest_size = len;
427                 asn1_delete_structure(&dinfo);
428                 return _gnutls_asn2err(result);
429         }
430
431         *digest_size = len;
432         asn1_delete_structure(&dinfo);
433
434         return 0;
435 }
436
437 int
438 _gnutls_params_get_rsa_raw(const gnutls_pk_params_st* params,
439                                     gnutls_datum_t * m, gnutls_datum_t * e,
440                                     gnutls_datum_t * d, gnutls_datum_t * p,
441                                     gnutls_datum_t * q, gnutls_datum_t * u,
442                                     gnutls_datum_t * e1,
443                                     gnutls_datum_t * e2)
444 {
445         int ret;
446
447         if (params == NULL) {
448                 gnutls_assert();
449                 return GNUTLS_E_INVALID_REQUEST;
450         }
451
452         if (params->algo != GNUTLS_PK_RSA) {
453                 gnutls_assert();
454                 return GNUTLS_E_INVALID_REQUEST;
455         }
456
457         if (m) {
458                 ret = _gnutls_mpi_dprint_lz(params->params[0], m);
459                 if (ret < 0) {
460                         gnutls_assert();
461                         goto error;
462                 }
463         }
464
465         /* E */
466         if (e) {
467                 ret = _gnutls_mpi_dprint_lz(params->params[1], e);
468                 if (ret < 0) {
469                         gnutls_assert();
470                         goto error;
471                 }
472         }
473
474         /* D */
475         if (d && params->params[2]) {
476                 ret = _gnutls_mpi_dprint_lz(params->params[2], d);
477                 if (ret < 0) {
478                         gnutls_assert();
479                         goto error;
480                 }
481         } else if (d) {
482                 d->data = NULL;
483                 d->size = 0;
484         }
485
486         /* P */
487         if (p && params->params[3]) {
488                 ret = _gnutls_mpi_dprint_lz(params->params[3], p);
489                 if (ret < 0) {
490                         gnutls_assert();
491                         goto error;
492                 }
493         } else if (p) {
494                 p->data = NULL;
495                 p->size = 0;
496         }
497
498         /* Q */
499         if (q && params->params[4]) {
500                 ret = _gnutls_mpi_dprint_lz(params->params[4], q);
501                 if (ret < 0) {
502                         gnutls_assert();
503                         goto error;
504                 }
505         } else if (q) {
506                 q->data = NULL;
507                 q->size = 0;
508         }
509
510         /* U */
511         if (u && params->params[5]) {
512                 ret = _gnutls_mpi_dprint_lz(params->params[5], u);
513                 if (ret < 0) {
514                         gnutls_assert();
515                         goto error;
516                 }
517         } else if (u) {
518                 u->data = NULL;
519                 u->size = 0;
520         }
521
522         /* E1 */
523         if (e1 && params->params[6]) {
524                 ret = _gnutls_mpi_dprint_lz(params->params[6], e1);
525                 if (ret < 0) {
526                         gnutls_assert();
527                         goto error;
528                 }
529         } else if (e1) {
530                 e1->data = NULL;
531                 e1->size = 0;
532         }
533
534         /* E2 */
535         if (e2 && params->params[7]) {
536                 ret = _gnutls_mpi_dprint_lz(params->params[7], e2);
537                 if (ret < 0) {
538                         gnutls_assert();
539                         goto error;
540                 }
541         } else if (e2) {
542                 e2->data = NULL;
543                 e2->size = 0;
544         }
545
546         return 0;
547
548       error:
549         _gnutls_free_datum(m);
550         _gnutls_free_datum(d);
551         _gnutls_free_datum(e);
552         _gnutls_free_datum(e1);
553         _gnutls_free_datum(e2);
554         _gnutls_free_datum(p);
555         _gnutls_free_datum(q);
556
557         return ret;
558 }
559
560 int
561 _gnutls_params_get_dsa_raw(const gnutls_pk_params_st* params,
562                              gnutls_datum_t * p, gnutls_datum_t * q,
563                              gnutls_datum_t * g, gnutls_datum_t * y,
564                              gnutls_datum_t * x)
565 {
566         int ret;
567
568         if (params == NULL) {
569                 gnutls_assert();
570                 return GNUTLS_E_INVALID_REQUEST;
571         }
572
573         if (params->algo != GNUTLS_PK_DSA) {
574                 gnutls_assert();
575                 return GNUTLS_E_INVALID_REQUEST;
576         }
577
578         /* P */
579         if (p) {
580                 ret = _gnutls_mpi_dprint_lz(params->params[0], p);
581                 if (ret < 0) {
582                         gnutls_assert();
583                         return ret;
584                 }
585         }
586
587         /* Q */
588         if (q) {
589                 ret = _gnutls_mpi_dprint_lz(params->params[1], q);
590                 if (ret < 0) {
591                         gnutls_assert();
592                         _gnutls_free_datum(p);
593                         return ret;
594                 }
595         }
596
597
598         /* G */
599         if (g) {
600                 ret = _gnutls_mpi_dprint_lz(params->params[2], g);
601                 if (ret < 0) {
602                         gnutls_assert();
603                         _gnutls_free_datum(p);
604                         _gnutls_free_datum(q);
605                         return ret;
606                 }
607         }
608
609
610         /* Y */
611         if (y) {
612                 ret = _gnutls_mpi_dprint_lz(params->params[3], y);
613                 if (ret < 0) {
614                         gnutls_assert();
615                         _gnutls_free_datum(p);
616                         _gnutls_free_datum(g);
617                         _gnutls_free_datum(q);
618                         return ret;
619                 }
620         }
621
622         /* X */
623         if (x) {
624                 ret = _gnutls_mpi_dprint_lz(params->params[4], x);
625                 if (ret < 0) {
626                         gnutls_assert();
627                         _gnutls_free_datum(y);
628                         _gnutls_free_datum(p);
629                         _gnutls_free_datum(g);
630                         _gnutls_free_datum(q);
631                         return ret;
632                 }
633         }
634
635         return 0;
636 }
637
638 int _gnutls_params_get_ecc_raw(const gnutls_pk_params_st* params,
639                                        gnutls_ecc_curve_t * curve,
640                                        gnutls_datum_t * x,
641                                        gnutls_datum_t * y,
642                                        gnutls_datum_t * k)
643 {
644         int ret;
645
646         if (params == NULL) {
647                 gnutls_assert();
648                 return GNUTLS_E_INVALID_REQUEST;
649         }
650
651         if (curve)
652                 *curve = params->flags;
653
654         /* X */
655         if (x) {
656                 ret = _gnutls_mpi_dprint_lz(params->params[ECC_X], x);
657                 if (ret < 0) {
658                         gnutls_assert();
659                         return ret;
660                 }
661         }
662
663         /* Y */
664         if (y) {
665                 ret = _gnutls_mpi_dprint_lz(params->params[ECC_Y], y);
666                 if (ret < 0) {
667                         gnutls_assert();
668                         _gnutls_free_datum(x);
669                         return ret;
670                 }
671         }
672
673
674         /* K */
675         if (k) {
676                 ret = _gnutls_mpi_dprint_lz(params->params[ECC_K], k);
677                 if (ret < 0) {
678                         gnutls_assert();
679                         _gnutls_free_datum(x);
680                         _gnutls_free_datum(y);
681                         return ret;
682                 }
683         }
684
685         return 0;
686
687 }