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(&params);
1171 
1172 		result = _gnutls_get_asn_mpis(src, src_name, &params);
1173 		if (result < 0)
1174 			return gnutls_assert_val(result);
1175 
1176 		bits[0] = pubkey_to_bits(&params);
1177 		gnutls_pk_params_release(&params);
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 							  &params);
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