1 /*
2 * Copyright (C) 2003-2014 Free Software Foundation, Inc.
3 * Copyright (C) 2015-2016 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 #include "gnutls_int.h"
25 #include <libtasn1.h>
26 #include <datum.h>
27 #include <global.h>
28 #include "errors.h"
29 #include <str.h>
30 #include <x509.h>
31 #include <num.h>
32 #include <x509_b64.h>
33 #include <c-strcase.h>
34 #include "x509_int.h"
35 #include "extras/hex.h"
36 #include <common.h>
37
38 static int
39 data2hex(const void *data, size_t data_size,
40 gnutls_datum_t *out);
41
42 #define ENTRY(oid, ldap, asn, etype) {oid, sizeof(oid)-1, ldap, sizeof(ldap)-1, asn, etype}
43
44 /* when there is no name description */
45 #define ENTRY_ND(oid, asn, etype) {oid, sizeof(oid)-1, NULL, 0, asn, etype}
46
47 /* This list contains all the OIDs that may be
48 * contained in a rdnSequence and are printable.
49 */
50 static const struct oid_to_string _oid2str[] = {
51 /* PKIX
52 */
53 ENTRY("1.3.6.1.5.5.7.9.2", "placeOfBirth", "PKIX1.DirectoryString",
54 ASN1_ETYPE_INVALID),
55 ENTRY("1.3.6.1.5.5.7.9.3", "gender", NULL, ASN1_ETYPE_PRINTABLE_STRING),
56 ENTRY("1.3.6.1.5.5.7.9.4", "countryOfCitizenship", NULL,
57 ASN1_ETYPE_PRINTABLE_STRING),
58 ENTRY("1.3.6.1.5.5.7.9.5", "countryOfResidence", NULL,
59 ASN1_ETYPE_PRINTABLE_STRING),
60
61 ENTRY("2.5.4.6", "C", NULL, ASN1_ETYPE_PRINTABLE_STRING),
62 ENTRY("2.5.4.9", "street", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
63 ENTRY("2.5.4.12", "title", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
64 ENTRY("2.5.4.10", "O", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
65 ENTRY("2.5.4.11", "OU", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
66 ENTRY("2.5.4.3", "CN", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
67 ENTRY("2.5.4.7", "L", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
68 ENTRY("2.5.4.8", "ST", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
69 ENTRY("2.5.4.13", "description", "PKIX1.DirectoryString",
70 ASN1_ETYPE_INVALID),
71
72 ENTRY("2.5.4.5", "serialNumber", NULL, ASN1_ETYPE_PRINTABLE_STRING),
73 ENTRY("2.5.4.20", "telephoneNumber", NULL, ASN1_ETYPE_PRINTABLE_STRING),
74 ENTRY("2.5.4.4", "surName", "PKIX1.DirectoryString",
75 ASN1_ETYPE_INVALID),
76 ENTRY("2.5.4.43", "initials", "PKIX1.DirectoryString",
77 ASN1_ETYPE_INVALID),
78 ENTRY("2.5.4.44", "generationQualifier", "PKIX1.DirectoryString",
79 ASN1_ETYPE_INVALID),
80 ENTRY("2.5.4.42", "givenName", "PKIX1.DirectoryString",
81 ASN1_ETYPE_INVALID),
82 ENTRY("2.5.4.65", "pseudonym", "PKIX1.DirectoryString",
83 ASN1_ETYPE_INVALID),
84 ENTRY("2.5.4.46", "dnQualifier", NULL, ASN1_ETYPE_PRINTABLE_STRING),
85 ENTRY("2.5.4.17", "postalCode", "PKIX1.DirectoryString",
86 ASN1_ETYPE_INVALID),
87 ENTRY("2.5.4.41", "name", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
88 ENTRY("2.5.4.15", "businessCategory", "PKIX1.DirectoryString",
89 ASN1_ETYPE_INVALID),
90
91 ENTRY("0.9.2342.19200300.100.1.25", "DC", NULL, ASN1_ETYPE_IA5_STRING),
92 ENTRY("0.9.2342.19200300.100.1.1", "UID", "PKIX1.DirectoryString",
93 ASN1_ETYPE_INVALID),
94 ENTRY("1.2.840.113556.1.4.656", "userPrincipalName", "PKIX1.DirectoryString",
95 ASN1_ETYPE_INVALID),
96
97 /* Extended validation
98 */
99 ENTRY("1.3.6.1.4.1.311.60.2.1.1",
100 "jurisdictionOfIncorporationLocalityName",
101 "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
102 ENTRY("1.3.6.1.4.1.311.60.2.1.2",
103 "jurisdictionOfIncorporationStateOrProvinceName",
104 "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
105 ENTRY("1.3.6.1.4.1.311.60.2.1.3",
106 "jurisdictionOfIncorporationCountryName",
107 NULL, ASN1_ETYPE_PRINTABLE_STRING),
108
109 /* PKCS #9
110 */
111 ENTRY("1.2.840.113549.1.9.1", "EMAIL", NULL, ASN1_ETYPE_IA5_STRING),
112 ENTRY_ND("1.2.840.113549.1.9.7", "PKIX1.pkcs-9-challengePassword",
113 ASN1_ETYPE_INVALID),
114
115 /* friendly name */
116 ENTRY_ND("1.2.840.113549.1.9.20", NULL, ASN1_ETYPE_BMP_STRING),
117 /* local key id */
118 ENTRY_ND("1.2.840.113549.1.9.21", NULL, ASN1_ETYPE_OCTET_STRING),
119 ENTRY_ND("1.2.840.113549.1.9.4", NULL, ASN1_ETYPE_OCTET_STRING),
120
121 /* rfc3920 section 5.1.1 */
122 ENTRY("1.3.6.1.5.5.7.8.5", "XmppAddr", NULL, ASN1_ETYPE_UTF8_STRING),
123
124 /* Russian things: https://cdnimg.rg.ru/pril/66/91/91/23041_pril.pdf */
125 /* Main state registration number */
126 ENTRY("1.2.643.100.1", "OGRN", NULL, ASN1_ETYPE_NUMERIC_STRING),
127 /* Individual insurance account number */
128 ENTRY("1.2.643.100.3", "SNILS", NULL, ASN1_ETYPE_NUMERIC_STRING),
129 /* Main state registration number for individual enterpreneurs */
130 ENTRY("1.2.643.100.5", "OGRNIP", NULL, ASN1_ETYPE_NUMERIC_STRING),
131 /* VAT identification number */
132 ENTRY("1.2.643.3.131.1.1", "INN", NULL, ASN1_ETYPE_NUMERIC_STRING),
133
134 {NULL, 0, NULL, 0, NULL, 0}
135 };
136
_gnutls_oid_get_entry(const struct oid_to_string * ots,const char * oid)137 const struct oid_to_string *_gnutls_oid_get_entry(const struct oid_to_string *ots, const char *oid)
138 {
139 unsigned int i = 0;
140 unsigned len = strlen(oid);
141
142 do {
143 if (len == ots[i].oid_size &&
144 strcmp(ots[i].oid, oid) == 0)
145 return &ots[i];
146 i++;
147 }
148 while (ots[i].oid != NULL);
149
150 return NULL;
151 }
152
_gnutls_ldap_string_to_oid(const char * str,unsigned str_len)153 const char *_gnutls_ldap_string_to_oid(const char *str, unsigned str_len)
154 {
155 unsigned int i = 0;
156
157 do {
158 if ((_oid2str[i].name_desc != NULL) &&
159 (str_len == _oid2str[i].name_desc_size) &&
160 (c_strncasecmp(_oid2str[i].name_desc, str, str_len) ==
161 0))
162 return _oid2str[i].oid;
163 i++;
164 }
165 while (_oid2str[i].oid != NULL);
166
167 return NULL;
168 }
169
170 /* Escapes a string following the rules from RFC4514.
171 */
str_escape(const gnutls_datum_t * str,gnutls_datum_t * escaped)172 static int str_escape(const gnutls_datum_t * str, gnutls_datum_t * escaped)
173 {
174 unsigned int j, i;
175 uint8_t *buffer = NULL;
176 int ret;
177
178 if (str == NULL)
179 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
180
181 /* the string will be at most twice the original */
182 buffer = gnutls_malloc(str->size * 2 + 2);
183 if (buffer == NULL)
184 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
185
186 for (i = j = 0; i < str->size; i++) {
187 if (str->data[i] == 0) {
188 /* this is handled earlier */
189 ret = gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
190 goto cleanup;
191 }
192
193 if (str->data[i] == ',' || str->data[i] == '+'
194 || str->data[i] == '"' || str->data[i] == '\\'
195 || str->data[i] == '<' || str->data[i] == '>'
196 || str->data[i] == ';' || str->data[i] == 0)
197 buffer[j++] = '\\';
198 else if (i == 0 && str->data[i] == '#')
199 buffer[j++] = '\\';
200 else if (i == 0 && str->data[i] == ' ')
201 buffer[j++] = '\\';
202 else if (i == (str->size - 1) && str->data[i] == ' ')
203 buffer[j++] = '\\';
204
205 buffer[j++] = str->data[i];
206 }
207
208 /* null terminate the string */
209 buffer[j] = 0;
210 escaped->data = buffer;
211 escaped->size = j;
212
213 return 0;
214 cleanup:
215 gnutls_free(buffer);
216 return ret;
217 }
218
219 /**
220 * gnutls_x509_dn_oid_known:
221 * @oid: holds an Object Identifier in a null terminated string
222 *
223 * This function will inform about known DN OIDs. This is useful since
224 * functions like gnutls_x509_crt_set_dn_by_oid() use the information
225 * on known OIDs to properly encode their input. Object Identifiers
226 * that are not known are not encoded by these functions, and their
227 * input is stored directly into the ASN.1 structure. In that case of
228 * unknown OIDs, you have the responsibility of DER encoding your
229 * data.
230 *
231 * Returns: 1 on known OIDs and 0 otherwise.
232 **/
gnutls_x509_dn_oid_known(const char * oid)233 int gnutls_x509_dn_oid_known(const char *oid)
234 {
235 return _gnutls_oid_get_entry(_oid2str, oid) != NULL;
236 }
237
238 /**
239 * gnutls_x509_dn_oid_name:
240 * @oid: holds an Object Identifier in a null terminated string
241 * @flags: 0 or GNUTLS_X509_DN_OID_*
242 *
243 * This function will return the name of a known DN OID. If
244 * %GNUTLS_X509_DN_OID_RETURN_OID is specified this function
245 * will return the given OID if no descriptive name has been
246 * found.
247 *
248 * Returns: A null terminated string or NULL otherwise.
249 *
250 * Since: 3.0
251 **/
gnutls_x509_dn_oid_name(const char * oid,unsigned int flags)252 const char *gnutls_x509_dn_oid_name(const char *oid, unsigned int flags)
253 {
254 const struct oid_to_string *entry =_gnutls_oid_get_entry(_oid2str, oid);
255
256 if (entry && entry->name_desc)
257 return entry->name_desc;
258 if (flags & GNUTLS_X509_DN_OID_RETURN_OID)
259 return oid;
260 else
261 return NULL;
262 }
263
264 static int
make_printable_string(unsigned etype,const gnutls_datum_t * input,gnutls_datum_t * out)265 make_printable_string(unsigned etype, const gnutls_datum_t * input,
266 gnutls_datum_t * out)
267 {
268 int printable = 0;
269 int ret;
270
271 /* empty input strings result to a null string */
272 if (input->data == NULL || input->size == 0) {
273 out->data = gnutls_calloc(1, 1);
274 if (out->data == NULL)
275 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
276 out->size = 0;
277 return 0;
278 }
279
280 if (etype == ASN1_ETYPE_BMP_STRING) {
281 ret = _gnutls_ucs2_to_utf8(input->data, input->size, out, 1);
282 if (ret < 0) {
283 /* could not convert. Handle it as non-printable */
284 printable = 0;
285 } else
286 printable = 1;
287 } else if (etype == ASN1_ETYPE_TELETEX_STRING) {
288 /* HACK: if the teletex string contains only ascii
289 * characters then treat it as printable.
290 */
291 if (_gnutls_str_is_print((char*)input->data, input->size)) {
292 out->data = gnutls_malloc(input->size + 1);
293 if (out->data == NULL)
294 return
295 gnutls_assert_val
296 (GNUTLS_E_MEMORY_ERROR);
297
298 memcpy(out->data, input->data, input->size);
299 out->size = input->size;
300
301 out->data[out->size] = 0;
302
303 printable = 1;
304 }
305 } else if (etype != ASN1_ETYPE_UNIVERSAL_STRING) /* supported but not printable */
306 return GNUTLS_E_INVALID_REQUEST;
307
308 if (printable == 0) { /* need to allocate out */
309 ret = data2hex(input->data, input->size, out);
310 if (ret < 0) {
311 gnutls_assert();
312 return ret;
313 }
314 }
315
316 return 0;
317 }
318
319 static int
decode_complex_string(const struct oid_to_string * oentry,void * value,int value_size,gnutls_datum_t * out)320 decode_complex_string(const struct oid_to_string *oentry, void *value,
321 int value_size, gnutls_datum_t * out)
322 {
323 char str[MAX_STRING_LEN], tmpname[128];
324 int len = -1, result;
325 ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
326 char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
327 unsigned int etype;
328 gnutls_datum_t td = {NULL, 0};
329
330 if (oentry->asn_desc == NULL) {
331 gnutls_assert();
332 return GNUTLS_E_INTERNAL_ERROR;
333 }
334
335 if ((result =
336 asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc,
337 &tmpasn)) != ASN1_SUCCESS) {
338 gnutls_assert();
339 return _gnutls_asn2err(result);
340 }
341
342 if ((result =
343 _asn1_strict_der_decode(&tmpasn, value, value_size,
344 asn1_err)) != ASN1_SUCCESS) {
345 gnutls_assert();
346 _gnutls_debug_log("_asn1_strict_der_decode: %s\n", asn1_err);
347 asn1_delete_structure(&tmpasn);
348 return _gnutls_asn2err(result);
349 }
350
351 /* Read the type of choice.
352 */
353 len = sizeof(str) - 1;
354 if ((result = asn1_read_value(tmpasn, "", str, &len)) != ASN1_SUCCESS) { /* CHOICE */
355 gnutls_assert();
356 asn1_delete_structure(&tmpasn);
357 return _gnutls_asn2err(result);
358 }
359
360 str[len] = 0;
361
362 /* We set the etype on the strings that may need
363 * some conversion to UTF-8. The INVALID flag indicates
364 * no conversion needed */
365 if (strcmp(str, "teletexString") == 0)
366 etype = ASN1_ETYPE_TELETEX_STRING;
367 else if (strcmp(str, "bmpString") == 0)
368 etype = ASN1_ETYPE_BMP_STRING;
369 else if (strcmp(str, "universalString") == 0)
370 etype = ASN1_ETYPE_UNIVERSAL_STRING;
371 else
372 etype = ASN1_ETYPE_INVALID;
373
374 _gnutls_str_cpy(tmpname, sizeof(tmpname), str);
375
376 result = _gnutls_x509_read_value(tmpasn, tmpname, &td);
377 asn1_delete_structure(&tmpasn);
378 if (result < 0)
379 return gnutls_assert_val(result);
380
381 if (etype != ASN1_ETYPE_INVALID) {
382 result = make_printable_string(etype, &td, out);
383
384 _gnutls_free_datum(&td);
385
386 if (result < 0)
387 return gnutls_assert_val(result);
388 } else {
389 out->data = td.data;
390 out->size = td.size;
391 /* _gnutls_x509_read_value always null terminates */
392 }
393
394 assert(out->data != NULL);
395
396 /* Refuse to deal with strings containing NULs. */
397 if (strlen((void *) out->data) != (size_t) out->size) {
398 _gnutls_free_datum(out);
399 return gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
400 }
401
402 return 0;
403 }
404
405
406 /* This function will convert an attribute value, specified by the OID,
407 * to a string. The result will be a null terminated string.
408 *
409 * res may be null. This will just return the res_size, needed to
410 * hold the string.
411 */
412 int
_gnutls_x509_dn_to_string(const char * oid,void * value,int value_size,gnutls_datum_t * str)413 _gnutls_x509_dn_to_string(const char *oid, void *value,
414 int value_size, gnutls_datum_t * str)
415 {
416 const struct oid_to_string *oentry;
417 int ret;
418 gnutls_datum_t tmp = {NULL, 0};
419
420 if (value == NULL || value_size <= 0) {
421 gnutls_assert();
422 return GNUTLS_E_INVALID_REQUEST;
423 }
424
425 oentry = _gnutls_oid_get_entry(_oid2str, oid);
426 if (oentry == NULL) { /* unknown OID -> hex */
427 unknown_oid:
428 ret = data2hex(value, value_size, str);
429 if (ret < 0) {
430 gnutls_assert();
431 return ret;
432 }
433 return 0;
434 }
435
436 if (oentry->asn_desc != NULL) { /* complex */
437 ret =
438 decode_complex_string(oentry, value, value_size, &tmp);
439 if (ret < 0) {
440 /* we failed decoding -> handle it as unknown OID */
441 goto unknown_oid;
442 }
443 } else {
444 ret =
445 _gnutls_x509_decode_string(oentry->etype, value,
446 value_size, &tmp, 0);
447 if (ret < 0) {
448 /* we failed decoding -> handle it as unknown OID */
449 goto unknown_oid;
450 }
451 }
452
453 ret = str_escape(&tmp, str);
454 _gnutls_free_datum(&tmp);
455
456 if (ret < 0)
457 return gnutls_assert_val(ret);
458
459 return 0;
460 }
461
462 /* Converts a data string to an LDAP rfc2253 hex string
463 * something like '#01020304'
464 */
465 static int
data2hex(const void * data,size_t data_size,gnutls_datum_t * out)466 data2hex(const void *data, size_t data_size,
467 gnutls_datum_t *out)
468 {
469 gnutls_datum_t tmp, td;
470 int ret;
471 size_t size;
472
473 td.size = hex_str_size(data_size) + 1; /* +1 for '#' */
474 td.data = gnutls_malloc(td.size);
475 if (td.data == NULL)
476 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
477
478 tmp.data = (void*)data;
479 tmp.size = data_size;
480
481 td.data[0] = '#';
482 size = td.size-1; /* don't include '#' */
483 ret =
484 gnutls_hex_encode(&tmp,
485 (char*)&td.data[1], &size);
486 if (ret < 0) {
487 gnutls_assert();
488 gnutls_free(td.data);
489 return GNUTLS_E_SHORT_MEMORY_BUFFER;
490 }
491
492 td.size--; /* don't include null */
493
494 out->data = td.data;
495 out->size = td.size;
496
497 return 0;
498 }
499
_gnutls_x509_san_find_type(char * str_type)500 gnutls_x509_subject_alt_name_t _gnutls_x509_san_find_type(char *str_type)
501 {
502 if (strcmp(str_type, "dNSName") == 0)
503 return GNUTLS_SAN_DNSNAME;
504 if (strcmp(str_type, "rfc822Name") == 0)
505 return GNUTLS_SAN_RFC822NAME;
506 if (strcmp(str_type, "uniformResourceIdentifier") == 0)
507 return GNUTLS_SAN_URI;
508 if (strcmp(str_type, "iPAddress") == 0)
509 return GNUTLS_SAN_IPADDRESS;
510 if (strcmp(str_type, "otherName") == 0)
511 return GNUTLS_SAN_OTHERNAME;
512 if (strcmp(str_type, "directoryName") == 0)
513 return GNUTLS_SAN_DN;
514 if (strcmp(str_type, "registeredID") == 0)
515 return GNUTLS_SAN_REGISTERED_ID;
516
517 return (gnutls_x509_subject_alt_name_t) - 1;
518 }
519
520 /* A generic export function. Will export the given ASN.1 encoded data
521 * to PEM or DER raw data.
522 */
523 int
_gnutls_x509_export_int_named(ASN1_TYPE asn1_data,const char * name,gnutls_x509_crt_fmt_t format,const char * pem_header,unsigned char * output_data,size_t * output_data_size)524 _gnutls_x509_export_int_named(ASN1_TYPE asn1_data, const char *name,
525 gnutls_x509_crt_fmt_t format,
526 const char *pem_header,
527 unsigned char *output_data,
528 size_t * output_data_size)
529 {
530 int ret;
531 gnutls_datum_t out = {NULL,0};
532 size_t size;
533
534 ret = _gnutls_x509_export_int_named2(asn1_data, name,
535 format, pem_header, &out);
536 if (ret < 0)
537 return gnutls_assert_val(ret);
538
539 if (format == GNUTLS_X509_FMT_PEM)
540 size = out.size + 1;
541 else
542 size = out.size;
543
544 if (*output_data_size < size) {
545 *output_data_size = size;
546 ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
547 goto cleanup;
548 }
549
550 *output_data_size = (size_t) out.size;
551 if (output_data) {
552 memcpy(output_data, out.data, (size_t) out.size);
553 if (format == GNUTLS_X509_FMT_PEM)
554 output_data[out.size] = 0;
555 }
556
557 ret = 0;
558
559 cleanup:
560 gnutls_free(out.data);
561
562 return ret;
563 }
564
565 /* A generic export function. Will export the given ASN.1 encoded data
566 * to PEM or DER raw data.
567 */
568 int
_gnutls_x509_export_int_named2(ASN1_TYPE asn1_data,const char * name,gnutls_x509_crt_fmt_t format,const char * pem_header,gnutls_datum_t * out)569 _gnutls_x509_export_int_named2(ASN1_TYPE asn1_data, const char *name,
570 gnutls_x509_crt_fmt_t format,
571 const char *pem_header,
572 gnutls_datum_t * out)
573 {
574 int ret;
575
576 if (format == GNUTLS_X509_FMT_DER) {
577 ret = _gnutls_x509_der_encode(asn1_data, name, out, 0);
578 if (ret < 0)
579 return gnutls_assert_val(ret);
580 } else { /* PEM */
581 gnutls_datum_t tmp;
582
583 ret = _gnutls_x509_der_encode(asn1_data, name, &tmp, 0);
584 if (ret < 0)
585 return gnutls_assert_val(ret);
586
587 ret =
588 _gnutls_fbase64_encode(pem_header, tmp.data, tmp.size,
589 out);
590 _gnutls_free_datum(&tmp);
591
592 if (ret < 0)
593 return gnutls_assert_val(ret);
594 }
595
596 return 0;
597 }
598
599 /* Decodes an octet string. The etype specifies the string type.
600 * The returned string is always null terminated (but null is not
601 * included in size).
602 */
603 int
_gnutls_x509_decode_string(unsigned int etype,const uint8_t * der,size_t der_size,gnutls_datum_t * output,unsigned allow_ber)604 _gnutls_x509_decode_string(unsigned int etype,
605 const uint8_t * der, size_t der_size,
606 gnutls_datum_t * output, unsigned allow_ber)
607 {
608 int ret;
609 uint8_t *str;
610 unsigned int str_size, len;
611 gnutls_datum_t td;
612
613 output->data = NULL;
614 output->size = 0;
615
616 if (allow_ber)
617 ret =
618 asn1_decode_simple_ber(etype, der, der_size, &str, &str_size, NULL);
619 else
620 ret =
621 asn1_decode_simple_der(etype, der, der_size, (const uint8_t**)&str, &str_size);
622 if (ret != ASN1_SUCCESS) {
623 gnutls_assert();
624 ret = _gnutls_asn2err(ret);
625 return ret;
626 }
627
628 td.size = str_size;
629 td.data = gnutls_malloc(str_size + 1);
630 if (td.data == NULL)
631 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
632
633 memcpy(td.data, str, str_size);
634 td.data[str_size] = 0;
635
636 if (allow_ber)
637 free(str);
638
639 ret = make_printable_string(etype, &td, output);
640 if (ret == GNUTLS_E_INVALID_REQUEST) { /* unsupported etype */
641 output->data = td.data;
642 output->size = td.size;
643 ret = 0;
644 } else if (ret <= 0) {
645 _gnutls_free_datum(&td);
646 }
647
648 /* Refuse to deal with strings containing NULs. */
649 if (etype != ASN1_ETYPE_OCTET_STRING) {
650 if (output->data)
651 len = strlen((void *) output->data);
652 else
653 len = 0;
654
655 if (len != (size_t) output->size) {
656 _gnutls_free_datum(output);
657 ret = gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
658 }
659 }
660
661 return ret;
662 }
663
664
665 /* Reads a value from an ASN1 tree, and puts the output
666 * in an allocated variable in the given datum.
667 *
668 * Note that this function always allocates one plus
669 * the required data size (and places a null byte).
670 */
671 static int
x509_read_value(ASN1_TYPE c,const char * root,gnutls_datum_t * ret,unsigned allow_null)672 x509_read_value(ASN1_TYPE c, const char *root,
673 gnutls_datum_t * ret, unsigned allow_null)
674 {
675 int len = 0, result;
676 uint8_t *tmp = NULL;
677 unsigned int etype;
678
679 result = asn1_read_value_type(c, root, NULL, &len, &etype);
680 if (result == 0 && allow_null == 0 && len == 0) {
681 /* don't allow null strings */
682 return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
683 } else if (result == 0 && allow_null == 0 && etype == ASN1_ETYPE_OBJECT_ID && len == 1) {
684 return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
685 }
686
687 if (result != ASN1_MEM_ERROR) {
688 if (result != ASN1_SUCCESS || allow_null == 0 || len != 0) {
689 result = _gnutls_asn2err(result);
690 return result;
691 }
692 }
693
694 if (etype == ASN1_ETYPE_BIT_STRING) {
695 len = (len + 7)/8;
696 }
697
698 tmp = gnutls_malloc((size_t) len + 1);
699 if (tmp == NULL) {
700 gnutls_assert();
701 result = GNUTLS_E_MEMORY_ERROR;
702 goto cleanup;
703 }
704
705 if (len > 0) {
706 result = asn1_read_value(c, root, tmp, &len);
707 if (result != ASN1_SUCCESS) {
708 gnutls_assert();
709 result = _gnutls_asn2err(result);
710 goto cleanup;
711 }
712
713 if (etype == ASN1_ETYPE_BIT_STRING) {
714 ret->size = (len+7) / 8;
715 } else {
716 ret->size = (unsigned) len;
717 }
718 } else {
719 ret->size = 0;
720 }
721
722 tmp[ret->size] = 0;
723 ret->data = tmp;
724
725 return 0;
726
727 cleanup:
728 gnutls_free(tmp);
729 return result;
730 }
731
732 int
_gnutls_x509_read_value(ASN1_TYPE c,const char * root,gnutls_datum_t * ret)733 _gnutls_x509_read_value(ASN1_TYPE c, const char *root,
734 gnutls_datum_t * ret)
735 {
736 return x509_read_value(c, root, ret, 0);
737 }
738
739 int
_gnutls_x509_read_null_value(ASN1_TYPE c,const char * root,gnutls_datum_t * ret)740 _gnutls_x509_read_null_value(ASN1_TYPE c, const char *root,
741 gnutls_datum_t * ret)
742 {
743 return x509_read_value(c, root, ret, 1);
744 }
745
746 /* Reads a value from an ASN1 tree, then interprets it as the provided
747 * type of string and returns the output in an allocated variable.
748 *
749 * Note that this function always places a null character
750 * at the end of a readable string value (which is not accounted into size)
751 */
752 int
_gnutls_x509_read_string(ASN1_TYPE c,const char * root,gnutls_datum_t * ret,unsigned int etype,unsigned int allow_ber)753 _gnutls_x509_read_string(ASN1_TYPE c, const char *root,
754 gnutls_datum_t * ret, unsigned int etype, unsigned int allow_ber)
755 {
756 int len = 0, result;
757 size_t slen;
758 uint8_t *tmp = NULL;
759 unsigned rtype;
760
761 result = asn1_read_value_type(c, root, NULL, &len, &rtype);
762 if (result != ASN1_MEM_ERROR) {
763 gnutls_assert();
764 result = _gnutls_asn2err(result);
765 return result;
766 }
767
768 if (rtype == ASN1_ETYPE_BIT_STRING)
769 len /= 8;
770
771 tmp = gnutls_malloc((size_t) len + 1);
772 if (tmp == NULL) {
773 gnutls_assert();
774 result = GNUTLS_E_MEMORY_ERROR;
775 goto cleanup;
776 }
777
778 result = asn1_read_value(c, root, tmp, &len);
779 if (result != ASN1_SUCCESS) {
780 gnutls_assert();
781 result = _gnutls_asn2err(result);
782 goto cleanup;
783 }
784
785 if (rtype == ASN1_ETYPE_BIT_STRING)
786 len /= 8;
787
788 /* Extract the STRING.
789 */
790 slen = (size_t) len;
791
792 result = _gnutls_x509_decode_string(etype, tmp, slen, ret, allow_ber);
793 if (result < 0) {
794 gnutls_assert();
795 goto cleanup;
796 }
797 gnutls_free(tmp);
798
799 return 0;
800
801 cleanup:
802 gnutls_free(tmp);
803 return result;
804 }
805
806 /* The string type should be IA5String, UTF8String etc. Leave
807 * null for octet string */
_gnutls_x509_encode_string(unsigned int etype,const void * input_data,size_t input_size,gnutls_datum_t * output)808 int _gnutls_x509_encode_string(unsigned int etype,
809 const void *input_data, size_t input_size,
810 gnutls_datum_t * output)
811 {
812 uint8_t tl[ASN1_MAX_TL_SIZE];
813 unsigned int tl_size;
814 int ret;
815
816 tl_size = sizeof(tl);
817 ret =
818 asn1_encode_simple_der(etype, input_data, input_size, tl,
819 &tl_size);
820 if (ret != ASN1_SUCCESS) {
821 gnutls_assert();
822 ret = _gnutls_asn2err(ret);
823 return ret;
824 }
825
826 output->data = gnutls_malloc(tl_size + input_size);
827 if (output->data == NULL)
828 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
829
830 memcpy(output->data, tl, tl_size);
831 memcpy(output->data + tl_size, input_data, input_size);
832
833 output->size = tl_size + input_size;
834
835 return 0;
836 }
837
838 /* DER Encodes the src ASN1_TYPE and stores it to
839 * the given datum. If str is non zero then the data are encoded as
840 * an OCTET STRING.
841 */
842 int
_gnutls_x509_der_encode(ASN1_TYPE src,const char * src_name,gnutls_datum_t * res,int str)843 _gnutls_x509_der_encode(ASN1_TYPE src, const char *src_name,
844 gnutls_datum_t * res, int str)
845 {
846 int size, result;
847 int asize;
848 uint8_t *data = NULL;
849 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
850
851 size = 0;
852 result = asn1_der_coding(src, src_name, NULL, &size, NULL);
853 /* this check explicitly covers the case where size == 0 && result == 0 */
854 if (result != ASN1_MEM_ERROR) {
855 gnutls_assert();
856 return _gnutls_asn2err(result);
857 }
858
859 /* allocate data for the der
860 */
861
862 if (str)
863 size += 16; /* for later to include the octet tags */
864 asize = size;
865
866 data = gnutls_malloc((size_t) size);
867 if (data == NULL) {
868 gnutls_assert();
869 return GNUTLS_E_MEMORY_ERROR;
870 }
871
872 result = asn1_der_coding(src, src_name, data, &size, NULL);
873 if (result != ASN1_SUCCESS) {
874 gnutls_assert();
875 result = _gnutls_asn2err(result);
876 goto cleanup;
877 }
878
879 if (str) {
880 if ((result = asn1_create_element
881 (_gnutls_get_pkix(), "PKIX1.pkcs-7-Data",
882 &c2)) != ASN1_SUCCESS) {
883 gnutls_assert();
884 result = _gnutls_asn2err(result);
885 goto cleanup;
886 }
887
888 result = asn1_write_value(c2, "", data, size);
889 if (result != ASN1_SUCCESS) {
890 gnutls_assert();
891 result = _gnutls_asn2err(result);
892 goto cleanup;
893 }
894
895 result = asn1_der_coding(c2, "", data, &asize, NULL);
896 if (result != ASN1_SUCCESS) {
897 gnutls_assert();
898 result = _gnutls_asn2err(result);
899 goto cleanup;
900 }
901
902 size = asize;
903
904 asn1_delete_structure(&c2);
905 }
906
907 res->data = data;
908 res->size = (unsigned) size;
909 return 0;
910
911 cleanup:
912 gnutls_free(data);
913 asn1_delete_structure(&c2);
914 return result;
915
916 }
917
918 /* DER Encodes the src ASN1_TYPE and stores it to
919 * dest in dest_name. Useful to encode something and store it
920 * as OCTET. If str is non null then the data are encoded as
921 * an OCTET STRING.
922 */
923 int
_gnutls_x509_der_encode_and_copy(ASN1_TYPE src,const char * src_name,ASN1_TYPE dest,const char * dest_name,int str)924 _gnutls_x509_der_encode_and_copy(ASN1_TYPE src, const char *src_name,
925 ASN1_TYPE dest, const char *dest_name,
926 int str)
927 {
928 int result;
929 gnutls_datum_t encoded = {NULL, 0};
930
931 result = _gnutls_x509_der_encode(src, src_name, &encoded, str);
932
933 if (result < 0) {
934 gnutls_assert();
935 return result;
936 }
937
938 /* Write the data.
939 */
940 result =
941 asn1_write_value(dest, dest_name, encoded.data,
942 (int) encoded.size);
943
944 _gnutls_free_datum(&encoded);
945
946 if (result != ASN1_SUCCESS) {
947 gnutls_assert();
948 return _gnutls_asn2err(result);
949 }
950
951 return 0;
952 }
953
954 /* Writes the value of the datum in the given ASN1_TYPE.
955 */
956 int
_gnutls_x509_write_value(ASN1_TYPE c,const char * root,const gnutls_datum_t * data)957 _gnutls_x509_write_value(ASN1_TYPE c, const char *root,
958 const gnutls_datum_t * data)
959 {
960 int ret;
961
962 /* Write the data.
963 */
964 ret = asn1_write_value(c, root, data->data, data->size);
965 if (ret != ASN1_SUCCESS) {
966 gnutls_assert();
967 return _gnutls_asn2err(ret);
968 }
969
970 return 0;
971 }
972
973 /* Writes the value of the datum in the given ASN1_TYPE as a string.
974 */
975 int
_gnutls_x509_write_string(ASN1_TYPE c,const char * root,const gnutls_datum_t * data,unsigned int etype)976 _gnutls_x509_write_string(ASN1_TYPE c, const char *root,
977 const gnutls_datum_t * data, unsigned int etype)
978 {
979 int ret;
980 gnutls_datum_t val = { NULL, 0 };
981
982 ret =
983 _gnutls_x509_encode_string(etype, data->data, data->size,
984 &val);
985 if (ret < 0)
986 return gnutls_assert_val(ret);
987
988 /* Write the data.
989 */
990 ret = asn1_write_value(c, root, val.data, val.size);
991 if (ret != ASN1_SUCCESS) {
992 gnutls_assert();
993 ret = _gnutls_asn2err(ret);
994 goto cleanup;
995 }
996
997 ret = 0;
998
999 cleanup:
1000 _gnutls_free_datum(&val);
1001 return ret;
1002 }
1003
1004 void
_asnstr_append_name(char * name,size_t name_size,const char * part1,const char * part2)1005 _asnstr_append_name(char *name, size_t name_size, const char *part1,
1006 const char *part2)
1007 {
1008 if (part1[0] != 0) {
1009 _gnutls_str_cpy(name, name_size, part1);
1010 _gnutls_str_cat(name, name_size, part2);
1011 } else
1012 _gnutls_str_cpy(name, name_size,
1013 part2 + 1 /* remove initial dot */ );
1014 }
1015
1016
1017
1018 /* Encodes and copies the private key parameters into a
1019 * subjectPublicKeyInfo structure.
1020 *
1021 */
1022 int
_gnutls_x509_encode_and_copy_PKI_params(ASN1_TYPE dst,const char * dst_name,const gnutls_pk_params_st * params)1023 _gnutls_x509_encode_and_copy_PKI_params(ASN1_TYPE dst,
1024 const char *dst_name,
1025 const gnutls_pk_params_st * params)
1026 {
1027 const char *oid;
1028 gnutls_datum_t der = { NULL, 0 };
1029 int result;
1030 char name[128];
1031
1032 oid = gnutls_pk_get_oid(params->algo);
1033 if (oid == NULL) {
1034 gnutls_assert();
1035 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1036 }
1037
1038 /* write the OID
1039 */
1040 _asnstr_append_name(name, sizeof(name), dst_name,
1041 ".algorithm.algorithm");
1042
1043 result = asn1_write_value(dst, name, oid, 1);
1044 if (result != ASN1_SUCCESS) {
1045 gnutls_assert();
1046 return _gnutls_asn2err(result);
1047 }
1048
1049 result =
1050 _gnutls_x509_write_pubkey_params(params, &der);
1051 if (result < 0) {
1052 gnutls_assert();
1053 return result;
1054 }
1055
1056 _asnstr_append_name(name, sizeof(name), dst_name,
1057 ".algorithm.parameters");
1058
1059 result = asn1_write_value(dst, name, der.data, der.size);
1060 _gnutls_free_datum(&der);
1061
1062 if (result != ASN1_SUCCESS) {
1063 gnutls_assert();
1064 return _gnutls_asn2err(result);
1065 }
1066
1067 result = _gnutls_x509_write_pubkey(params, &der);
1068 if (result < 0) {
1069 gnutls_assert();
1070 return result;
1071 }
1072
1073 /* Write the DER parameters. (in bits)
1074 */
1075 _asnstr_append_name(name, sizeof(name), dst_name,
1076 ".subjectPublicKey");
1077 result = asn1_write_value(dst, name, der.data, der.size * 8);
1078 _gnutls_free_datum(&der);
1079
1080 if (result != ASN1_SUCCESS) {
1081 gnutls_assert();
1082 return _gnutls_asn2err(result);
1083 }
1084
1085 return 0;
1086 }
1087
1088 /* Encodes and public key parameters into a
1089 * subjectPublicKeyInfo structure and stores it in der.
1090 */
1091 int
_gnutls_x509_encode_PKI_params(gnutls_datum_t * der,const gnutls_pk_params_st * params)1092 _gnutls_x509_encode_PKI_params(gnutls_datum_t * der,
1093 const gnutls_pk_params_st * params)
1094 {
1095 int ret;
1096 ASN1_TYPE tmp;
1097
1098 ret = asn1_create_element(_gnutls_get_pkix(),
1099 "PKIX1.Certificate", &tmp);
1100 if (ret != ASN1_SUCCESS) {
1101 gnutls_assert();
1102 return _gnutls_asn2err(ret);
1103 }
1104
1105 ret = _gnutls_x509_encode_and_copy_PKI_params(tmp,
1106 "tbsCertificate.subjectPublicKeyInfo",
1107 params);
1108 if (ret != ASN1_SUCCESS) {
1109 gnutls_assert();
1110 ret = _gnutls_asn2err(ret);
1111 goto cleanup;
1112 }
1113
1114 ret =
1115 _gnutls_x509_der_encode(tmp,
1116 "tbsCertificate.subjectPublicKeyInfo",
1117 der, 0);
1118
1119 cleanup:
1120 asn1_delete_structure(&tmp);
1121
1122 return ret;
1123 }
1124
1125 /* Reads and returns the PK algorithm of the given certificate-like
1126 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1127 */
1128 int
_gnutls_x509_get_pk_algorithm(ASN1_TYPE src,const char * src_name,gnutls_ecc_curve_t * curve,unsigned int * bits)1129 _gnutls_x509_get_pk_algorithm(ASN1_TYPE src, const char *src_name,
1130 gnutls_ecc_curve_t *curve,
1131 unsigned int *bits)
1132 {
1133 int result;
1134 int algo;
1135 char oid[64];
1136 int len;
1137 gnutls_ecc_curve_t lcurve = GNUTLS_ECC_CURVE_INVALID;
1138 char name[128];
1139
1140 _asnstr_append_name(name, sizeof(name), src_name,
1141 ".algorithm.algorithm");
1142 len = sizeof(oid);
1143 result = asn1_read_value(src, name, oid, &len);
1144
1145 if (result != ASN1_SUCCESS) {
1146 gnutls_assert();
1147 return _gnutls_asn2err(result);
1148 }
1149
1150 algo = _gnutls_oid_to_pk_and_curve(oid, &lcurve);
1151 if (algo == GNUTLS_PK_UNKNOWN) {
1152 _gnutls_debug_log
1153 ("%s: unknown public key algorithm: %s\n", __func__,
1154 oid);
1155 }
1156
1157 if (curve)
1158 *curve = lcurve;
1159
1160 if (bits == NULL) {
1161 return algo;
1162 }
1163
1164 /* Now read the parameters' bits
1165 */
1166 if (lcurve != GNUTLS_ECC_CURVE_INVALID) { /* curve present */
1167 bits[0] = gnutls_ecc_curve_get_size(lcurve)*8;
1168 } else {
1169 gnutls_pk_params_st params;
1170 gnutls_pk_params_init(¶ms);
1171
1172 result = _gnutls_get_asn_mpis(src, src_name, ¶ms);
1173 if (result < 0)
1174 return gnutls_assert_val(result);
1175
1176 bits[0] = pubkey_to_bits(¶ms);
1177 gnutls_pk_params_release(¶ms);
1178 }
1179
1180 return algo;
1181 }
1182
1183 /* Reads the DER signed data from the certificate and allocates space and
1184 * returns them into signed_data.
1185 */
1186 int
_gnutls_x509_get_signed_data(ASN1_TYPE src,const gnutls_datum_t * der,const char * src_name,gnutls_datum_t * signed_data)1187 _gnutls_x509_get_signed_data(ASN1_TYPE src, const gnutls_datum_t *der,
1188 const char *src_name,
1189 gnutls_datum_t * signed_data)
1190 {
1191 int start, end, result;
1192
1193 if (der == NULL || der->size == 0) {
1194 return _gnutls_x509_der_encode(src, src_name, signed_data, 0);
1195 }
1196
1197 /* Get the signed data
1198 */
1199 result = asn1_der_decoding_startEnd(src, der->data, der->size,
1200 src_name, &start, &end);
1201 if (result != ASN1_SUCCESS) {
1202 result = _gnutls_asn2err(result);
1203 gnutls_assert();
1204 goto cleanup;
1205 }
1206
1207 result =
1208 _gnutls_set_datum(signed_data, &der->data[start],
1209 end - start + 1);
1210
1211 if (result < 0) {
1212 gnutls_assert();
1213 goto cleanup;
1214 }
1215
1216 result = 0;
1217
1218 cleanup:
1219 return result;
1220 }
1221
1222 /*-
1223 * gnutls_x509_get_signature_algorithm:
1224 * @src: should contain an ASN1_TYPE structure
1225 * @src_name: the description of the signature field
1226 *
1227 * This function will return a value of the #gnutls_sign_algorithm_t
1228 * enumeration that is the signature algorithm that has been used to
1229 * sign this certificate.
1230 *
1231 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
1232 * error.
1233 -*/
1234 int
_gnutls_x509_get_signature_algorithm(ASN1_TYPE src,const char * src_name)1235 _gnutls_x509_get_signature_algorithm(ASN1_TYPE src, const char *src_name)
1236 {
1237 int result;
1238 char name[128];
1239 gnutls_datum_t sa = {NULL, 0};
1240
1241 _gnutls_str_cpy(name, sizeof(name), src_name);
1242 _gnutls_str_cat(name, sizeof(name), ".algorithm");
1243
1244 /* Read the signature algorithm */
1245 result = _gnutls_x509_read_value(src, name, &sa);
1246
1247 if (result < 0) {
1248 gnutls_assert();
1249 return result;
1250 }
1251
1252 /* Read the signature parameters. Unless the algorithm is
1253 * RSA-PSS, parameters are not read. They will be read from
1254 * the issuer's certificate if needed.
1255 */
1256 if (sa.data && strcmp ((char *) sa.data, PK_PKIX1_RSA_PSS_OID) == 0) {
1257 gnutls_datum_t der = {NULL, 0};
1258 gnutls_x509_spki_st params;
1259
1260 _gnutls_str_cpy(name, sizeof(name), src_name);
1261 _gnutls_str_cat(name, sizeof(name), ".parameters");
1262
1263 result = _gnutls_x509_read_value(src, name, &der);
1264 if (result < 0) {
1265 _gnutls_free_datum(&sa);
1266 return gnutls_assert_val(result);
1267 }
1268
1269 result = _gnutls_x509_read_rsa_pss_params(der.data, der.size,
1270 ¶ms);
1271 _gnutls_free_datum(&der);
1272
1273 if (result == 0)
1274 result = gnutls_pk_to_sign(params.pk, params.rsa_pss_dig);
1275 } else if (sa.data) {
1276 result = gnutls_oid_to_sign((char *) sa.data);
1277 } else {
1278 result = GNUTLS_E_UNKNOWN_ALGORITHM;
1279 }
1280
1281 _gnutls_free_datum(&sa);
1282
1283 if (result == GNUTLS_SIGN_UNKNOWN)
1284 result = GNUTLS_E_UNKNOWN_ALGORITHM;
1285
1286 return result;
1287 }
1288
1289
1290 /* Reads the DER signature from the certificate and allocates space and
1291 * returns them into signed_data.
1292 */
1293 int
_gnutls_x509_get_signature(ASN1_TYPE src,const char * src_name,gnutls_datum_t * signature)1294 _gnutls_x509_get_signature(ASN1_TYPE src, const char *src_name,
1295 gnutls_datum_t * signature)
1296 {
1297 int result, len;
1298 int bits;
1299
1300 signature->data = NULL;
1301 signature->size = 0;
1302
1303 /* Read the signature
1304 */
1305 len = 0;
1306 result = asn1_read_value(src, src_name, NULL, &len);
1307
1308 if (result != ASN1_MEM_ERROR) {
1309 result = _gnutls_asn2err(result);
1310 gnutls_assert();
1311 goto cleanup;
1312 }
1313
1314 bits = len;
1315 if (bits % 8 != 0 || bits < 8) {
1316 gnutls_assert();
1317 result = GNUTLS_E_CERTIFICATE_ERROR;
1318 goto cleanup;
1319 }
1320
1321 len = bits / 8;
1322
1323 signature->data = gnutls_malloc(len);
1324 if (signature->data == NULL) {
1325 gnutls_assert();
1326 result = GNUTLS_E_MEMORY_ERROR;
1327 return result;
1328 }
1329
1330 /* read the bit string of the signature
1331 */
1332 bits = len;
1333 result =
1334 asn1_read_value(src, src_name, signature->data, &bits);
1335
1336 if (result != ASN1_SUCCESS) {
1337 result = _gnutls_asn2err(result);
1338 gnutls_assert();
1339 goto cleanup;
1340 }
1341
1342 signature->size = len;
1343
1344 return 0;
1345
1346 cleanup:
1347 gnutls_free(signature->data);
1348 return result;
1349 }
1350
1351 /* ASN.1 PrintableString rules */
is_printable(char p)1352 static int is_printable(char p)
1353 {
1354 if ((p >= 'a' && p <= 'z') || (p >= 'A' && p <= 'Z') ||
1355 (p >= '0' && p <= '9') || p == ' ' || p == '(' || p == ')' ||
1356 p == '+' || p == ',' || p == '-' || p == '.' || p == '/' ||
1357 p == ':' || p == '=' || p == '?')
1358 return 1;
1359
1360 return 0;
1361 }
1362
write_complex_string(ASN1_TYPE asn_struct,const char * where,const struct oid_to_string * oentry,const uint8_t * data,size_t data_size)1363 static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
1364 const struct oid_to_string *oentry,
1365 const uint8_t * data, size_t data_size)
1366 {
1367 char tmp[128];
1368 ASN1_TYPE c2;
1369 int result;
1370 const char *string_type;
1371 unsigned int i;
1372
1373 result =
1374 asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2);
1375 if (result != ASN1_SUCCESS) {
1376 gnutls_assert();
1377 return _gnutls_asn2err(result);
1378 }
1379
1380 tmp[0] = 0;
1381
1382 string_type = "printableString";
1383
1384 /* Check if the data is ASN.1 printable, and use
1385 * the UTF8 string type if not.
1386 */
1387 for (i = 0; i < data_size; i++) {
1388 if (!is_printable(data[i])) {
1389 string_type = "utf8String";
1390 break;
1391 }
1392 }
1393
1394 /* if the type is a CHOICE then write the
1395 * type we'll use.
1396 */
1397 result = asn1_write_value(c2, "", string_type, 1);
1398 if (result != ASN1_SUCCESS) {
1399 gnutls_assert();
1400 result = _gnutls_asn2err(result);
1401 goto error;
1402 }
1403
1404 _gnutls_str_cpy(tmp, sizeof(tmp), string_type);
1405
1406 result = asn1_write_value(c2, tmp, data, data_size);
1407 if (result != ASN1_SUCCESS) {
1408 gnutls_assert();
1409 result = _gnutls_asn2err(result);
1410 goto error;
1411 }
1412
1413 result =
1414 _gnutls_x509_der_encode_and_copy(c2, "", asn_struct, where, 0);
1415 if (result < 0) {
1416 gnutls_assert();
1417 goto error;
1418 }
1419
1420 result = 0;
1421
1422 error:
1423 asn1_delete_structure(&c2);
1424 return result;
1425 }
1426
1427
1428 /* This will encode and write the AttributeTypeAndValue field.
1429 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
1430 * In all cases only one value is written.
1431 */
1432 int
_gnutls_x509_encode_and_write_attribute(const char * given_oid,ASN1_TYPE asn1_struct,const char * where,const void * _data,int data_size,int multi)1433 _gnutls_x509_encode_and_write_attribute(const char *given_oid,
1434 ASN1_TYPE asn1_struct,
1435 const char *where,
1436 const void *_data,
1437 int data_size, int multi)
1438 {
1439 const uint8_t *data = _data;
1440 char tmp[128];
1441 int result;
1442 const struct oid_to_string *oentry;
1443
1444 oentry = _gnutls_oid_get_entry(_oid2str, given_oid);
1445 if (oentry == NULL) {
1446 gnutls_assert();
1447 _gnutls_debug_log("Cannot find OID: %s\n", given_oid);
1448 return GNUTLS_E_X509_UNSUPPORTED_OID;
1449 }
1450
1451 /* write the data (value)
1452 */
1453
1454 _gnutls_str_cpy(tmp, sizeof(tmp), where);
1455 _gnutls_str_cat(tmp, sizeof(tmp), ".value");
1456
1457 if (multi != 0) { /* if not writing an AttributeTypeAndValue, but an Attribute */
1458 _gnutls_str_cat(tmp, sizeof(tmp), "s"); /* values */
1459
1460 result = asn1_write_value(asn1_struct, tmp, "NEW", 1);
1461 if (result != ASN1_SUCCESS) {
1462 gnutls_assert();
1463 result = _gnutls_asn2err(result);
1464 goto error;
1465 }
1466
1467 _gnutls_str_cat(tmp, sizeof(tmp), ".?LAST");
1468 }
1469
1470 if (oentry->asn_desc != NULL) { /* write a complex string API */
1471 result =
1472 write_complex_string(asn1_struct, tmp, oentry, data,
1473 data_size);
1474 if (result < 0)
1475 return gnutls_assert_val(result);
1476 } else { /* write a simple string */
1477
1478 gnutls_datum_t td;
1479
1480 td.data = (void *) data;
1481 td.size = data_size;
1482 result =
1483 _gnutls_x509_write_string(asn1_struct, tmp, &td,
1484 oentry->etype);
1485 if (result < 0) {
1486 gnutls_assert();
1487 goto error;
1488 }
1489 }
1490
1491 /* write the type
1492 */
1493 _gnutls_str_cpy(tmp, sizeof(tmp), where);
1494 _gnutls_str_cat(tmp, sizeof(tmp), ".type");
1495
1496 result = asn1_write_value(asn1_struct, tmp, given_oid, 1);
1497 if (result != ASN1_SUCCESS) {
1498 gnutls_assert();
1499 result = _gnutls_asn2err(result);
1500 goto error;
1501 }
1502
1503 result = 0;
1504
1505 error:
1506 return result;
1507 }
1508
1509 /* copies a datum to a buffer. If it doesn't fit it returns
1510 * GNUTLS_E_SHORT_MEMORY_BUFFER. It always deinitializes the datum
1511 * after the copy.
1512 *
1513 * The buffer will always be null terminated.
1514 */
_gnutls_strdatum_to_buf(gnutls_datum_t * d,void * buf,size_t * buf_size)1515 int _gnutls_strdatum_to_buf(gnutls_datum_t * d, void *buf,
1516 size_t * buf_size)
1517 {
1518 int ret;
1519 uint8_t *_buf = buf;
1520
1521 if (buf == NULL || *buf_size < d->size + 1) {
1522 *buf_size = d->size + 1;
1523 ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
1524 goto cleanup;
1525 }
1526 memcpy(buf, d->data, d->size);
1527 _buf[d->size] = 0;
1528
1529 *buf_size = d->size;
1530 ret = 0;
1531
1532 cleanup:
1533 _gnutls_free_datum(d);
1534
1535 return ret;
1536 }
1537
1538 int
_gnutls_x509_get_raw_field2(ASN1_TYPE c2,const gnutls_datum_t * raw,const char * whom,gnutls_datum_t * dn)1539 _gnutls_x509_get_raw_field2(ASN1_TYPE c2, const gnutls_datum_t * raw,
1540 const char *whom, gnutls_datum_t * dn)
1541 {
1542 int result, len1;
1543 int start1, end1;
1544 result =
1545 asn1_der_decoding_startEnd(c2, raw->data, raw->size,
1546 whom, &start1, &end1);
1547
1548 if (result != ASN1_SUCCESS) {
1549 gnutls_assert();
1550 result = _gnutls_asn2err(result);
1551 goto cleanup;
1552 }
1553
1554 len1 = end1 - start1 + 1;
1555
1556 dn->data = &raw->data[start1];
1557 dn->size = len1;
1558 result = 0;
1559
1560 cleanup:
1561 return result;
1562 }
1563
_gnutls_copy_string(const gnutls_datum_t * str,uint8_t * out,size_t * out_size)1564 int _gnutls_copy_string(const gnutls_datum_t* str, uint8_t *out, size_t *out_size)
1565 {
1566 unsigned size_to_check;
1567
1568 size_to_check = str->size + 1;
1569
1570 if ((unsigned) size_to_check > *out_size) {
1571 gnutls_assert();
1572 (*out_size) = size_to_check;
1573 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1574 }
1575
1576 if (out != NULL && str->data != NULL) {
1577 memcpy(out, str->data, str->size);
1578 out[str->size] = 0;
1579 } else if (out != NULL) {
1580 out[0] = 0;
1581 }
1582 *out_size = str->size;
1583
1584 return 0;
1585 }
1586
_gnutls_copy_data(const gnutls_datum_t * str,uint8_t * out,size_t * out_size)1587 int _gnutls_copy_data(const gnutls_datum_t* str, uint8_t *out, size_t *out_size)
1588 {
1589 if ((unsigned) str->size > *out_size) {
1590 gnutls_assert();
1591 (*out_size) = str->size;
1592 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1593 }
1594
1595 if (out != NULL && str->data != NULL) {
1596 memcpy(out, str->data, str->size);
1597 }
1598 *out_size = str->size;
1599
1600 return 0;
1601 }
1602
1603 /* Converts an X.509 certificate to subjectPublicKeyInfo */
x509_crt_to_raw_pubkey(gnutls_x509_crt_t crt,gnutls_datum_t * rpubkey)1604 int x509_crt_to_raw_pubkey(gnutls_x509_crt_t crt,
1605 gnutls_datum_t * rpubkey)
1606 {
1607 gnutls_pubkey_t pubkey = NULL;
1608 int ret;
1609
1610 ret = gnutls_pubkey_init(&pubkey);
1611 if (ret < 0)
1612 return gnutls_assert_val(ret);
1613
1614 ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
1615 if (ret < 0) {
1616 gnutls_assert();
1617 goto cleanup;
1618 }
1619
1620 ret =
1621 gnutls_pubkey_export2(pubkey, GNUTLS_X509_FMT_DER, rpubkey);
1622 if (ret < 0) {
1623 gnutls_assert();
1624 goto cleanup;
1625 }
1626
1627 ret = 0;
1628
1629 cleanup:
1630 gnutls_pubkey_deinit(pubkey);
1631 return ret;
1632 }
1633
1634 /* Converts an X.509 certificate to subjectPublicKeyInfo */
_gnutls_x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,gnutls_datum_t * rpubkey)1635 int _gnutls_x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
1636 gnutls_datum_t * rpubkey)
1637 {
1638 gnutls_x509_crt_t crt = NULL;
1639 int ret;
1640
1641 ret = gnutls_x509_crt_init(&crt);
1642 if (ret < 0)
1643 return gnutls_assert_val(ret);
1644
1645 ret = gnutls_x509_crt_import(crt, cert, GNUTLS_X509_FMT_DER);
1646 if (ret < 0) {
1647 gnutls_assert();
1648 goto cleanup;
1649 }
1650
1651 ret = x509_crt_to_raw_pubkey(crt, rpubkey);
1652 cleanup:
1653 gnutls_x509_crt_deinit(crt);
1654
1655 return ret;
1656 }
1657
1658 unsigned
_gnutls_check_valid_key_id(const gnutls_datum_t * key_id,gnutls_x509_crt_t cert,time_t now,unsigned * has_ski)1659 _gnutls_check_valid_key_id(const gnutls_datum_t *key_id,
1660 gnutls_x509_crt_t cert, time_t now,
1661 unsigned *has_ski)
1662 {
1663 uint8_t id[MAX_KEY_ID_SIZE];
1664 size_t id_size;
1665 unsigned result = 0;
1666
1667 if (has_ski)
1668 *has_ski = 0;
1669
1670 if (now > gnutls_x509_crt_get_expiration_time(cert) ||
1671 now < gnutls_x509_crt_get_activation_time(cert)) {
1672 /* don't bother, certificate is not yet activated or expired */
1673 gnutls_assert();
1674 goto out;
1675 }
1676
1677 id_size = sizeof(id);
1678 if (gnutls_x509_crt_get_subject_key_id(cert, id, &id_size, NULL) < 0) {
1679 gnutls_assert();
1680 goto out;
1681 }
1682
1683 if (has_ski)
1684 *has_ski = 1;
1685
1686 if (id_size == key_id->size && !memcmp(id, key_id->data, id_size))
1687 result = 1;
1688
1689 out:
1690 return result;
1691 }
1692
1693 /* Takes a certificate list and orders it with subject, issuer order.
1694 *
1695 * *clist_size contains the size of the ordered list (which is always less or
1696 * equal to the original).
1697 * @func: the function to call to elements outside the sort.
1698 *
1699 * This function is intentionally kept simple to be easily verified
1700 * so that it can be used with untrusted chains. The introduction
1701 * of the func parameter added significant complexity in that aspect.
1702 * If more demanding use-cases need to be handled, consider splitting
1703 * that function.
1704 *
1705 * Returns the sorted list which may be the original clist.
1706 *
1707 */
_gnutls_sort_clist(gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH],gnutls_x509_crt_t * clist,unsigned int * clist_size,gnutls_cert_vfunc func)1708 gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t
1709 sorted[DEFAULT_MAX_VERIFY_DEPTH],
1710 gnutls_x509_crt_t *clist,
1711 unsigned int *clist_size,
1712 gnutls_cert_vfunc func)
1713 {
1714 int prev;
1715 unsigned int j, i;
1716 int issuer[DEFAULT_MAX_VERIFY_DEPTH]; /* contain the index of the issuers */
1717 bool insorted[DEFAULT_MAX_VERIFY_DEPTH]; /* non zero if clist[i] used in sorted list */
1718 unsigned orig_size = *clist_size;
1719
1720 /* Do not bother sorting if too many certificates are given.
1721 * Prevent any DoS attacks.
1722 */
1723 if (*clist_size > DEFAULT_MAX_VERIFY_DEPTH)
1724 return clist;
1725
1726 for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
1727 issuer[i] = -1;
1728 insorted[i] = 0;
1729 }
1730
1731 /* Find the issuer of each certificate and store it
1732 * in issuer array. O(n^2) so consider that before
1733 * increasing DEFAULT_MAX_VERIFY_DEPTH.
1734 */
1735 for (i = 0; i < *clist_size; i++) {
1736 for (j = 1; j < *clist_size; j++) {
1737 if (i == j)
1738 continue;
1739
1740 if (gnutls_x509_crt_check_issuer(clist[i],
1741 clist[j]) != 0) {
1742 issuer[i] = j;
1743 break;
1744 }
1745 }
1746 }
1747
1748 /* the first element is always included */
1749 sorted[0] = clist[0];
1750 insorted[0] = 1;
1751
1752 if (issuer[0] == -1) {
1753 *clist_size = 1;
1754 goto exit;
1755 }
1756
1757 prev = 0;
1758 for (i = 1; i < *clist_size; i++) {
1759 prev = issuer[prev];
1760 if (prev < 0) { /* no issuer */
1761 *clist_size = i;
1762 break;
1763 }
1764 sorted[i] = clist[prev];
1765 insorted[prev] = 1;
1766 }
1767
1768 exit:
1769 if (func) {
1770 /* call func() on all the elements that were
1771 * not used in the sorted list */
1772 for (i = 1; i < orig_size; i++) {
1773 if (insorted[i] == 0) {
1774 func(clist[i]);
1775 }
1776 }
1777 }
1778
1779 return sorted;
1780 }
1781
_gnutls_check_if_sorted(gnutls_x509_crt_t * crt,int nr)1782 int _gnutls_check_if_sorted(gnutls_x509_crt_t * crt, int nr)
1783 {
1784 int i, ret;
1785
1786 /* check if the X.509 list is ordered */
1787 if (nr > 1) {
1788 for (i = 0; i < nr; i++) {
1789 if (i > 0) {
1790 if (!_gnutls_x509_compare_raw_dn(&crt[i]->raw_dn,
1791 &crt[i-1]->raw_issuer_dn)) {
1792 ret =
1793 gnutls_assert_val
1794 (GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
1795 goto cleanup;
1796 }
1797 }
1798 }
1799 }
1800 ret = 0;
1801
1802 cleanup:
1803 return ret;
1804 }
1805
1806 /**
1807 * gnutls_gost_paramset_get_name:
1808 * @param: is a GOST 28147 param set
1809 *
1810 * Convert a #gnutls_gost_paramset_t value to a string.
1811 *
1812 * Returns: a string that contains the name of the specified GOST param set,
1813 * or %NULL.
1814 *
1815 * Since: 3.6.3
1816 **/
gnutls_gost_paramset_get_name(gnutls_gost_paramset_t param)1817 const char *gnutls_gost_paramset_get_name(gnutls_gost_paramset_t param)
1818 {
1819 switch(param) {
1820 case GNUTLS_GOST_PARAMSET_TC26_Z:
1821 return "TC26-Z";
1822 case GNUTLS_GOST_PARAMSET_CP_A:
1823 return "CryptoPro-A";
1824 case GNUTLS_GOST_PARAMSET_CP_B:
1825 return "CryptoPro-B";
1826 case GNUTLS_GOST_PARAMSET_CP_C:
1827 return "CryptoPro-C";
1828 case GNUTLS_GOST_PARAMSET_CP_D:
1829 return "CryptoPro-D";
1830 default:
1831 gnutls_assert();
1832 return "Unknown";
1833 }
1834 }
1835
1836 /**
1837 * gnutls_gost_paramset_get_oid:
1838 * @param: is a GOST 28147 param set
1839 *
1840 * Convert a #gnutls_gost_paramset_t value to its object identifier.
1841 *
1842 * Returns: a string that contains the object identifier of the specified GOST
1843 * param set, or %NULL.
1844 *
1845 * Since: 3.6.3
1846 **/
gnutls_gost_paramset_get_oid(gnutls_gost_paramset_t param)1847 const char *gnutls_gost_paramset_get_oid(gnutls_gost_paramset_t param)
1848 {
1849 switch(param) {
1850 case GNUTLS_GOST_PARAMSET_TC26_Z:
1851 return GOST28147_89_TC26Z_OID;
1852 case GNUTLS_GOST_PARAMSET_CP_A:
1853 return GOST28147_89_CPA_OID;
1854 case GNUTLS_GOST_PARAMSET_CP_B:
1855 return GOST28147_89_CPB_OID;
1856 case GNUTLS_GOST_PARAMSET_CP_C:
1857 return GOST28147_89_CPC_OID;
1858 case GNUTLS_GOST_PARAMSET_CP_D:
1859 return GOST28147_89_CPD_OID;
1860 default:
1861 gnutls_assert();
1862 return NULL;
1863 }
1864 }
1865
1866 /**
1867 * gnutls_oid_to_gost_paramset:
1868 * @oid: is an object identifier
1869 *
1870 * Converts a textual object identifier to a #gnutls_gost_paramset_t value.
1871 *
1872 * Returns: a #gnutls_gost_paramset_get_oid of the specified GOST 28147
1873 * param st, or %GNUTLS_GOST_PARAMSET_UNKNOWN on failure.
1874 *
1875 * Since: 3.6.3
1876 **/
gnutls_oid_to_gost_paramset(const char * oid)1877 gnutls_gost_paramset_t gnutls_oid_to_gost_paramset(const char *oid)
1878 {
1879 if (!strcmp(oid, GOST28147_89_TC26Z_OID))
1880 return GNUTLS_GOST_PARAMSET_TC26_Z;
1881 else if (!strcmp(oid, GOST28147_89_CPA_OID))
1882 return GNUTLS_GOST_PARAMSET_CP_A;
1883 else if (!strcmp(oid, GOST28147_89_CPB_OID))
1884 return GNUTLS_GOST_PARAMSET_CP_B;
1885 else if (!strcmp(oid, GOST28147_89_CPC_OID))
1886 return GNUTLS_GOST_PARAMSET_CP_C;
1887 else if (!strcmp(oid, GOST28147_89_CPD_OID))
1888 return GNUTLS_GOST_PARAMSET_CP_D;
1889 else
1890 return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN);
1891 }
1892
_gnutls_x509_get_version(ASN1_TYPE root,const char * name)1893 int _gnutls_x509_get_version(ASN1_TYPE root, const char *name)
1894 {
1895 uint8_t version[8];
1896 int len, result;
1897
1898 len = sizeof(version);
1899 result = asn1_read_value(root, name, version, &len);
1900 if (result != ASN1_SUCCESS) {
1901 if (result == ASN1_ELEMENT_NOT_FOUND)
1902 return 1; /* the DEFAULT version */
1903 gnutls_assert();
1904 return _gnutls_asn2err(result);
1905 }
1906
1907 if (len != 1 || version[0] >= 0x80)
1908 return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
1909
1910 return (int) version[0] + 1;
1911 }
1912