1 /*
2  * Copyright (C) 2014-2016 Free Software Foundation, Inc.
3  * Copyright (C) 2016 Red Hat, Inc.
4  *
5  * This file is part of GnuTLS.
6  *
7  * The GnuTLS is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>
19  *
20  */
21 
22 /* This file contains functions to handle X.509 certificate extensions (the x509-ext API)
23  */
24 
25 #include "gnutls_int.h"
26 #include <datum.h>
27 #include "errors.h"
28 #include <common.h>
29 #include <x509.h>
30 #include <x509_b64.h>
31 #include "x509_ext_int.h"
32 #include "virt-san.h"
33 #include <gnutls/x509-ext.h>
34 
35 #define MAX_ENTRIES 64
36 struct gnutls_subject_alt_names_st {
37 	struct name_st *names;
38 	unsigned int size;
39 };
40 
41 /**
42  * gnutls_subject_alt_names_init:
43  * @sans: The alternative names
44  *
45  * This function will initialize an alternative names structure.
46  *
47  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
48  *
49  * Since: 3.3.0
50  **/
gnutls_subject_alt_names_init(gnutls_subject_alt_names_t * sans)51 int gnutls_subject_alt_names_init(gnutls_subject_alt_names_t * sans)
52 {
53 	*sans = gnutls_calloc(1, sizeof(struct gnutls_subject_alt_names_st));
54 	if (*sans == NULL) {
55 		gnutls_assert();
56 		return GNUTLS_E_MEMORY_ERROR;
57 	}
58 
59 	return 0;
60 }
61 
subject_alt_names_deinit(gnutls_subject_alt_names_t sans)62 static void subject_alt_names_deinit(gnutls_subject_alt_names_t sans)
63 {
64 	unsigned int i;
65 
66 	for (i = 0; i < sans->size; i++) {
67 		gnutls_free(sans->names[i].san.data);
68 		gnutls_free(sans->names[i].othername_oid.data);
69 	}
70 	gnutls_free(sans->names);
71 }
72 
73 /**
74  * gnutls_subject_alt_names_deinit:
75  * @sans: The alternative names
76  *
77  * This function will deinitialize an alternative names structure.
78  *
79  * Since: 3.3.0
80  **/
gnutls_subject_alt_names_deinit(gnutls_subject_alt_names_t sans)81 void gnutls_subject_alt_names_deinit(gnutls_subject_alt_names_t sans)
82 {
83 	subject_alt_names_deinit(sans);
84 	gnutls_free(sans);
85 }
86 
87 /**
88  * gnutls_subject_alt_names_get:
89  * @sans: The alternative names
90  * @seq: The index of the name to get
91  * @san_type: Will hold the type of the name (of %gnutls_subject_alt_names_t)
92  * @san: The alternative name data (should be treated as constant)
93  * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME (should be treated as constant)
94  *
95  * This function will return a specific alternative name as stored in
96  * the @sans type. The returned values should be treated as constant
97  * and valid for the lifetime of @sans.
98  *
99  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
100  * if the index is out of bounds, otherwise a negative error value.
101  *
102  * Since: 3.3.0
103  **/
gnutls_subject_alt_names_get(gnutls_subject_alt_names_t sans,unsigned int seq,unsigned int * san_type,gnutls_datum_t * san,gnutls_datum_t * othername_oid)104 int gnutls_subject_alt_names_get(gnutls_subject_alt_names_t sans,
105 				 unsigned int seq, unsigned int *san_type,
106 				 gnutls_datum_t * san,
107 				 gnutls_datum_t * othername_oid)
108 {
109 	if (seq >= sans->size)
110 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
111 
112 	if (san) {
113 		memcpy(san, &sans->names[seq].san, sizeof(gnutls_datum_t));
114 	}
115 
116 	if (san_type)
117 		*san_type = sans->names[seq].type;
118 
119 	if (othername_oid != NULL && sans->names[seq].type == GNUTLS_SAN_OTHERNAME) {
120 		othername_oid->data = sans->names[seq].othername_oid.data;
121 		othername_oid->size = sans->names[seq].othername_oid.size;
122 	}
123 
124 	return 0;
125 }
126 
127 /* This is the same as gnutls_subject_alt_names_set() but will not
128  * copy the strings. It expects all the provided input to be already
129  * allocated by gnutls. */
130 static
subject_alt_names_set(struct name_st ** names,unsigned int * size,unsigned int san_type,gnutls_datum_t * san,char * othername_oid,unsigned raw)131 int subject_alt_names_set(struct name_st **names,
132 			  unsigned int *size,
133 			  unsigned int san_type,
134 			  gnutls_datum_t * san, char *othername_oid,
135 			  unsigned raw)
136 {
137 	void *tmp;
138 	int ret;
139 
140 	tmp = gnutls_realloc(*names, (*size + 1) * sizeof((*names)[0]));
141 	if (tmp == NULL) {
142 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
143 	}
144 	*names = tmp;
145 
146 	ret = _gnutls_alt_name_assign_virt_type(&(*names)[*size], san_type, san, othername_oid, raw);
147 	if (ret < 0)
148 		return gnutls_assert_val(ret);
149 
150 	(*size)++;
151 	return 0;
152 }
153 
154 /**
155  * gnutls_subject_alt_names_set:
156  * @sans: The alternative names
157  * @san_type: The type of the name (of %gnutls_subject_alt_names_t)
158  * @san: The alternative name data
159  * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
160  *
161  * This function will store the specified alternative name in
162  * the @sans.
163  *
164  * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
165  * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
166  *
167  * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
168  *
169  * Since: 3.3.0
170  **/
gnutls_subject_alt_names_set(gnutls_subject_alt_names_t sans,unsigned int san_type,const gnutls_datum_t * san,const char * othername_oid)171 int gnutls_subject_alt_names_set(gnutls_subject_alt_names_t sans,
172 				 unsigned int san_type,
173 				 const gnutls_datum_t * san,
174 				 const char *othername_oid)
175 {
176 	int ret;
177 	gnutls_datum_t copy;
178 	char *ooc;
179 
180 	ret = _gnutls_set_strdatum(&copy, san->data, san->size);
181 	if (ret < 0)
182 		return gnutls_assert_val(ret);
183 
184 	if (othername_oid != NULL)
185 		ooc = gnutls_strdup(othername_oid);
186 	else
187 		ooc = NULL;
188 	ret = subject_alt_names_set(&sans->names, &sans->size,
189 				    san_type, &copy, ooc, 0);
190 	if (ret < 0) {
191 		gnutls_free(copy.data);
192 		return gnutls_assert_val(ret);
193 	}
194 
195 	return 0;
196 }
197 
198 /**
199  * gnutls_x509_ext_import_subject_alt_names:
200  * @ext: The DER-encoded extension data
201  * @sans: The alternative names
202  * @flags: should be zero
203  *
204  * This function will export the alternative names in the provided DER-encoded
205  * SubjectAltName PKIX extension, to a %gnutls_subject_alt_names_t type. @sans
206  * must be initialized.
207  *
208  * This function will succeed even if there no subject alternative names
209  * in the structure.
210  *
211  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
212  *
213  * Since: 3.3.0
214  **/
gnutls_x509_ext_import_subject_alt_names(const gnutls_datum_t * ext,gnutls_subject_alt_names_t sans,unsigned int flags)215 int gnutls_x509_ext_import_subject_alt_names(const gnutls_datum_t * ext,
216 					  gnutls_subject_alt_names_t sans,
217 					  unsigned int flags)
218 {
219 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
220 	int result, ret;
221 	unsigned int i;
222 	gnutls_datum_t san, othername_oid;
223 	unsigned type;
224 
225 	result =
226 	    asn1_create_element(_gnutls_get_pkix(), "PKIX1.GeneralNames", &c2);
227 	if (result != ASN1_SUCCESS) {
228 		gnutls_assert();
229 		return _gnutls_asn2err(result);
230 	}
231 
232 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
233 	if (result != ASN1_SUCCESS) {
234 		gnutls_assert();
235 		ret = _gnutls_asn2err(result);
236 		goto cleanup;
237 	}
238 
239 	for (i=0;;i++) {
240 		san.data = NULL;
241 		san.size = 0;
242 		othername_oid.data = NULL;
243 
244 		ret = _gnutls_parse_general_name2(c2, "", i, &san, &type, 0);
245 		if (ret < 0)
246 			break;
247 
248 		if (type == GNUTLS_SAN_OTHERNAME) {
249 			ret =
250 			    _gnutls_parse_general_name2(c2, "", i,
251 							&othername_oid,
252 							NULL, 1);
253 			if (ret < 0)
254 				break;
255 
256 		} else if (san.size == 0 || san.data == NULL) {
257 			ret = gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
258 			break;
259 		}
260 
261 		ret = subject_alt_names_set(&sans->names, &sans->size,
262 					    type, &san,
263 					    (char *)othername_oid.data, 1);
264 		if (ret < 0)
265 			break;
266 	}
267 
268 	sans->size = i;
269 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
270 		gnutls_free(san.data);
271 		gnutls_free(othername_oid.data);
272 		gnutls_assert();
273 		goto cleanup;
274 	}
275 
276 	ret = 0;
277  cleanup:
278 	asn1_delete_structure(&c2);
279 	return ret;
280 }
281 
282 /**
283  * gnutls_x509_ext_export_subject_alt_names:
284  * @sans: The alternative names
285  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
286  *
287  * This function will convert the provided alternative names structure to a
288  * DER-encoded SubjectAltName PKIX extension. The output data in @ext will be allocated using
289  * gnutls_malloc().
290  *
291  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
292  *
293  * Since: 3.3.0
294  **/
gnutls_x509_ext_export_subject_alt_names(gnutls_subject_alt_names_t sans,gnutls_datum_t * ext)295 int gnutls_x509_ext_export_subject_alt_names(gnutls_subject_alt_names_t sans,
296 					  gnutls_datum_t * ext)
297 {
298 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
299 	int result, ret;
300 	unsigned i;
301 
302 	result =
303 	    asn1_create_element(_gnutls_get_pkix(), "PKIX1.GeneralNames", &c2);
304 	if (result != ASN1_SUCCESS) {
305 		gnutls_assert();
306 		return _gnutls_asn2err(result);
307 	}
308 
309 	for (i = 0; i < sans->size; i++) {
310 		if (sans->names[i].type == GNUTLS_SAN_OTHERNAME) {
311 			ret = _gnutls_write_new_othername(c2, "", (char*)sans->names[i].othername_oid.data,
312 					      sans->names[i].san.data, sans->names[i].san.size);
313 		} else {
314 			ret =
315 			    _gnutls_write_new_general_name(c2, "", sans->names[i].type,
316 							   sans->names[i].san.data,
317 							   sans->names[i].san.size);
318 		}
319 
320 		if (ret < 0) {
321 			gnutls_assert();
322 			goto cleanup;
323 		}
324 	}
325 
326 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
327 	if (ret < 0) {
328 		gnutls_assert();
329 		goto cleanup;
330 	}
331 
332 	ret = 0;
333 
334  cleanup:
335 	asn1_delete_structure(&c2);
336 	return ret;
337 }
338 
339 /**
340  * gnutls_x509_ext_import_name_constraints:
341  * @ext: a DER encoded extension
342  * @nc: The nameconstraints
343  * @flags: zero or %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND
344  *
345  * This function will return an intermediate type containing
346  * the name constraints of the provided NameConstraints extension. That
347  * can be used in combination with gnutls_x509_name_constraints_check()
348  * to verify whether a server's name is in accordance with the constraints.
349  *
350  * When the @flags is set to %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, then if
351  * the @nc type is empty this function will behave identically as if the flag was not set.
352  * Otherwise if there are elements in the @nc structure then the
353  * constraints will be merged with the existing constraints following
354  * RFC5280 p6.1.4 (excluded constraints will be appended, permitted
355  * will be intersected).
356  *
357  * Note that @nc must be initialized prior to calling this function.
358  *
359  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
360  * if the extension is not present, otherwise a negative error value.
361  *
362  * Since: 3.3.0
363  **/
gnutls_x509_ext_import_name_constraints(const gnutls_datum_t * ext,gnutls_x509_name_constraints_t nc,unsigned int flags)364 int gnutls_x509_ext_import_name_constraints(const gnutls_datum_t * ext,
365 					 gnutls_x509_name_constraints_t nc,
366 					 unsigned int flags)
367 {
368 	int result, ret;
369 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
370 	gnutls_x509_name_constraints_t nc2 = NULL;
371 
372 	result = asn1_create_element
373 	    (_gnutls_get_pkix(), "PKIX1.NameConstraints", &c2);
374 	if (result != ASN1_SUCCESS) {
375 		gnutls_assert();
376 		return _gnutls_asn2err(result);
377 	}
378 
379 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
380 	if (result != ASN1_SUCCESS) {
381 		gnutls_assert();
382 		ret = _gnutls_asn2err(result);
383 		goto cleanup;
384 	}
385 
386 	if (flags & GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND &&
387 	    (nc->permitted != NULL || nc->excluded != NULL)) {
388 		ret = gnutls_x509_name_constraints_init (&nc2);
389 		if (ret < 0) {
390 			gnutls_assert();
391 			goto cleanup;
392 		}
393 
394 		ret =
395 		    _gnutls_extract_name_constraints(c2, "permittedSubtrees",
396 						     &nc2->permitted);
397 		if (ret < 0) {
398 			gnutls_assert();
399 			goto cleanup;
400 		}
401 
402 		ret =
403 		    _gnutls_extract_name_constraints(c2, "excludedSubtrees",
404 						     &nc2->excluded);
405 		if (ret < 0) {
406 			gnutls_assert();
407 			goto cleanup;
408 		}
409 
410 		ret = _gnutls_x509_name_constraints_merge(nc, nc2);
411 		if (ret < 0) {
412 			gnutls_assert();
413 			goto cleanup;
414 		}
415 	} else {
416 		_gnutls_name_constraints_node_free(nc->permitted);
417 		_gnutls_name_constraints_node_free(nc->excluded);
418 
419 		ret =
420 		    _gnutls_extract_name_constraints(c2, "permittedSubtrees",
421 						     &nc->permitted);
422 		if (ret < 0) {
423 			gnutls_assert();
424 			goto cleanup;
425 		}
426 
427 		ret =
428 		    _gnutls_extract_name_constraints(c2, "excludedSubtrees",
429 						     &nc->excluded);
430 		if (ret < 0) {
431 			gnutls_assert();
432 			goto cleanup;
433 		}
434 	}
435 
436 	ret = 0;
437 
438  cleanup:
439 	asn1_delete_structure(&c2);
440 	if (nc2)
441 		gnutls_x509_name_constraints_deinit (nc2);
442 
443 	return ret;
444 }
445 
446 /**
447  * gnutls_x509_ext_export_name_constraints:
448  * @nc: The nameconstraints
449  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
450  *
451  * This function will convert the provided name constraints type to a
452  * DER-encoded PKIX NameConstraints (2.5.29.30) extension. The output data in
453  * @ext will be allocated using gnutls_malloc().
454  *
455  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
456  *
457  * Since: 3.3.0
458  **/
gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc,gnutls_datum_t * ext)459 int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc,
460 					 gnutls_datum_t * ext)
461 {
462 	int ret, result;
463 	uint8_t null = 0;
464 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
465 	struct name_constraints_node_st *tmp;
466 
467 	if (nc->permitted == NULL && nc->excluded == NULL)
468 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
469 
470 	result = asn1_create_element
471 	    (_gnutls_get_pkix(), "PKIX1.NameConstraints", &c2);
472 	if (result != ASN1_SUCCESS) {
473 		gnutls_assert();
474 		return _gnutls_asn2err(result);
475 	}
476 
477 	if (nc->permitted == NULL) {
478 		(void)asn1_write_value(c2, "permittedSubtrees", NULL, 0);
479 	} else {
480 		tmp = nc->permitted;
481 		do {
482 			result =
483 			    asn1_write_value(c2, "permittedSubtrees", "NEW", 1);
484 			if (result != ASN1_SUCCESS) {
485 				gnutls_assert();
486 				ret = _gnutls_asn2err(result);
487 				goto cleanup;
488 			}
489 
490 			result =
491 			    asn1_write_value(c2,
492 					     "permittedSubtrees.?LAST.maximum",
493 					     NULL, 0);
494 			if (result != ASN1_SUCCESS) {
495 				gnutls_assert();
496 				ret = _gnutls_asn2err(result);
497 				goto cleanup;
498 			}
499 
500 			result =
501 			    asn1_write_value(c2,
502 					     "permittedSubtrees.?LAST.minimum",
503 					     &null, 1);
504 			if (result != ASN1_SUCCESS) {
505 				gnutls_assert();
506 				ret = _gnutls_asn2err(result);
507 				goto cleanup;
508 			}
509 
510 			ret =
511 			    _gnutls_write_general_name(c2,
512 						       "permittedSubtrees.?LAST.base",
513 						       tmp->type,
514 						       tmp->name.data,
515 						       tmp->name.size);
516 			if (ret < 0) {
517 				gnutls_assert();
518 				goto cleanup;
519 			}
520 			tmp = tmp->next;
521 		} while (tmp != NULL);
522 	}
523 
524 	if (nc->excluded == NULL) {
525 		(void)asn1_write_value(c2, "excludedSubtrees", NULL, 0);
526 	} else {
527 		tmp = nc->excluded;
528 		do {
529 			result =
530 			    asn1_write_value(c2, "excludedSubtrees", "NEW", 1);
531 			if (result != ASN1_SUCCESS) {
532 				gnutls_assert();
533 				ret = _gnutls_asn2err(result);
534 				goto cleanup;
535 			}
536 
537 			result =
538 			    asn1_write_value(c2,
539 					     "excludedSubtrees.?LAST.maximum",
540 					     NULL, 0);
541 			if (result != ASN1_SUCCESS) {
542 				gnutls_assert();
543 				ret = _gnutls_asn2err(result);
544 				goto cleanup;
545 			}
546 
547 			result =
548 			    asn1_write_value(c2,
549 					     "excludedSubtrees.?LAST.minimum",
550 					     &null, 1);
551 			if (result != ASN1_SUCCESS) {
552 				gnutls_assert();
553 				ret = _gnutls_asn2err(result);
554 				goto cleanup;
555 			}
556 
557 			ret =
558 			    _gnutls_write_general_name(c2,
559 						       "excludedSubtrees.?LAST.base",
560 						       tmp->type,
561 						       tmp->name.data,
562 						       tmp->name.size);
563 			if (ret < 0) {
564 				gnutls_assert();
565 				goto cleanup;
566 			}
567 			tmp = tmp->next;
568 		} while (tmp != NULL);
569 
570 	}
571 
572 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
573 	if (ret < 0) {
574 		gnutls_assert();
575 		goto cleanup;
576 	}
577 
578 	ret = 0;
579 
580  cleanup:
581 	asn1_delete_structure(&c2);
582 	return ret;
583 }
584 
585 /**
586  * gnutls_x509_ext_import_subject_key_id:
587  * @ext: a DER encoded extension
588  * @id: will contain the subject key ID
589  *
590  * This function will return the subject key ID stored in the provided
591  * SubjectKeyIdentifier extension. The ID will be allocated using
592  * gnutls_malloc().
593  *
594  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
595  * if the extension is not present, otherwise a negative error value.
596  *
597  * Since: 3.3.0
598  **/
gnutls_x509_ext_import_subject_key_id(const gnutls_datum_t * ext,gnutls_datum_t * id)599 int gnutls_x509_ext_import_subject_key_id(const gnutls_datum_t * ext,
600 				       gnutls_datum_t * id)
601 {
602 	int result, ret;
603 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
604 
605 	if (ext->size == 0 || ext->data == NULL) {
606 		gnutls_assert();
607 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
608 	}
609 
610 	result = asn1_create_element
611 	    (_gnutls_get_pkix(), "PKIX1.SubjectKeyIdentifier", &c2);
612 	if (result != ASN1_SUCCESS) {
613 		gnutls_assert();
614 		return _gnutls_asn2err(result);
615 	}
616 
617 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
618 	if (result != ASN1_SUCCESS) {
619 		gnutls_assert();
620 		ret = _gnutls_asn2err(result);
621 		goto cleanup;
622 	}
623 
624 	ret = _gnutls_x509_read_value(c2, "", id);
625 	if (ret < 0) {
626 		gnutls_assert();
627 		goto cleanup;
628 	}
629 
630 	ret = 0;
631  cleanup:
632 	asn1_delete_structure(&c2);
633 
634 	return ret;
635 
636 }
637 
638 /**
639  * gnutls_x509_ext_export_subject_key_id:
640  * @id: The key identifier
641  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
642  *
643  * This function will convert the provided key identifier to a
644  * DER-encoded PKIX SubjectKeyIdentifier extension.
645  * The output data in @ext will be allocated using
646  * gnutls_malloc().
647  *
648  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
649  *
650  * Since: 3.3.0
651  **/
gnutls_x509_ext_export_subject_key_id(const gnutls_datum_t * id,gnutls_datum_t * ext)652 int gnutls_x509_ext_export_subject_key_id(const gnutls_datum_t * id,
653 				       gnutls_datum_t * ext)
654 {
655 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
656 	int ret, result;
657 
658 	result =
659 	    asn1_create_element(_gnutls_get_pkix(),
660 				"PKIX1.SubjectKeyIdentifier", &c2);
661 	if (result != ASN1_SUCCESS) {
662 		gnutls_assert();
663 		return _gnutls_asn2err(result);
664 	}
665 
666 	result = asn1_write_value(c2, "", id->data, id->size);
667 	if (result != ASN1_SUCCESS) {
668 		gnutls_assert();
669 		ret = _gnutls_asn2err(result);
670 		goto cleanup;
671 	}
672 
673 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
674 	if (ret < 0) {
675 		gnutls_assert();
676 		goto cleanup;
677 	}
678 
679 	ret = 0;
680  cleanup:
681 	asn1_delete_structure(&c2);
682 	return ret;
683 }
684 
685 struct gnutls_x509_aki_st {
686 	gnutls_datum_t id;
687 	struct gnutls_subject_alt_names_st cert_issuer;
688 	gnutls_datum_t serial;
689 };
690 
691 /**
692  * gnutls_x509_aki_init:
693  * @aki: The authority key ID type
694  *
695  * This function will initialize an authority key ID.
696  *
697  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
698  *
699  * Since: 3.3.0
700  **/
gnutls_x509_aki_init(gnutls_x509_aki_t * aki)701 int gnutls_x509_aki_init(gnutls_x509_aki_t * aki)
702 {
703 	*aki = gnutls_calloc(1, sizeof(struct gnutls_x509_aki_st));
704 	if (*aki == NULL)
705 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
706 
707 	return 0;
708 }
709 
710 /**
711  * gnutls_x509_aki_deinit:
712  * @aki: The authority key identifier type
713  *
714  * This function will deinitialize an authority key identifier.
715  *
716  * Since: 3.3.0
717  **/
gnutls_x509_aki_deinit(gnutls_x509_aki_t aki)718 void gnutls_x509_aki_deinit(gnutls_x509_aki_t aki)
719 {
720 	gnutls_free(aki->serial.data);
721 	gnutls_free(aki->id.data);
722 	subject_alt_names_deinit(&aki->cert_issuer);
723 	gnutls_free(aki);
724 }
725 
726 /**
727  * gnutls_x509_aki_get_id:
728  * @aki: The authority key ID
729  * @id: Will hold the identifier
730  *
731  * This function will return the key identifier as stored in
732  * the @aki type. The identifier should be treated as constant.
733  *
734  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
735  * if the index is out of bounds, otherwise a negative error value.
736  *
737  * Since: 3.3.0
738  **/
gnutls_x509_aki_get_id(gnutls_x509_aki_t aki,gnutls_datum_t * id)739 int gnutls_x509_aki_get_id(gnutls_x509_aki_t aki, gnutls_datum_t * id)
740 {
741 	if (aki->id.size == 0)
742 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
743 
744 	memcpy(id, &aki->id, sizeof(gnutls_datum_t));
745 	return 0;
746 }
747 
748 /**
749  * gnutls_x509_aki_set_id:
750  * @aki: The authority key ID
751  * @id: the key identifier
752  *
753  * This function will set the keyIdentifier to be stored in the @aki
754  * type.
755  *
756  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
757  *
758  * Since: 3.3.0
759  **/
gnutls_x509_aki_set_id(gnutls_x509_aki_t aki,const gnutls_datum_t * id)760 int gnutls_x509_aki_set_id(gnutls_x509_aki_t aki, const gnutls_datum_t * id)
761 {
762 	return _gnutls_set_datum(&aki->id, id->data, id->size);
763 }
764 
765 /**
766  * gnutls_x509_aki_set_cert_issuer:
767  * @aki: The authority key ID
768  * @san_type: the type of the name (of %gnutls_subject_alt_names_t), may be null
769  * @san: The alternative name data
770  * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
771  * @serial: The authorityCertSerialNumber number (may be null)
772  *
773  * This function will set the authorityCertIssuer name and the authorityCertSerialNumber
774  * to be stored in the @aki type. When storing multiple names, the serial
775  * should be set on the first call, and subsequent calls should use a %NULL serial.
776  *
777  * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
778  * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
779  *
780  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
781  *
782  * Since: 3.3.0
783  **/
gnutls_x509_aki_set_cert_issuer(gnutls_x509_aki_t aki,unsigned int san_type,const gnutls_datum_t * san,const char * othername_oid,const gnutls_datum_t * serial)784 int gnutls_x509_aki_set_cert_issuer(gnutls_x509_aki_t aki,
785 				    unsigned int san_type,
786 				    const gnutls_datum_t *san,
787 				    const char *othername_oid,
788 				    const gnutls_datum_t *serial)
789 {
790 	int ret;
791 	gnutls_datum_t t_san, t_othername_oid = { NULL, 0 };
792 
793 	ret = _gnutls_set_datum(&aki->serial, serial->data, serial->size);
794 	if (ret < 0)
795 		return gnutls_assert_val(ret);
796 
797 	aki->cert_issuer.names[aki->cert_issuer.size].type = san_type;
798 
799 	ret = _gnutls_set_strdatum(&t_san, san->data, san->size);
800 	if (ret < 0)
801 		return gnutls_assert_val(ret);
802 
803 	if (othername_oid) {
804 		t_othername_oid.data = (uint8_t *) gnutls_strdup(othername_oid);
805 		if (t_othername_oid.data == NULL) {
806 			gnutls_free(t_san.data);
807 			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
808 		}
809 		t_othername_oid.size = strlen(othername_oid);
810 	}
811 
812 	ret =
813 	    subject_alt_names_set(&aki->cert_issuer.names,
814 				  &aki->cert_issuer.size, san_type, &t_san,
815 				  (char *)t_othername_oid.data, 0);
816 	if (ret < 0) {
817 		gnutls_assert();
818 		return ret;
819 	}
820 
821 	return 0;
822 }
823 
824 /**
825  * gnutls_x509_aki_get_cert_issuer:
826  * @aki: The authority key ID
827  * @seq: The index of the name to get
828  * @san_type: Will hold the type of the name (of %gnutls_subject_alt_names_t)
829  * @san: The alternative name data
830  * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
831  * @serial: The authorityCertSerialNumber number
832  *
833  * This function will return a specific authorityCertIssuer name as stored in
834  * the @aki type, as well as the authorityCertSerialNumber. All the returned
835  * values should be treated as constant, and may be set to %NULL when are not required.
836  *
837  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
838  * if the index is out of bounds, otherwise a negative error value.
839  *
840  * Since: 3.3.0
841  **/
gnutls_x509_aki_get_cert_issuer(gnutls_x509_aki_t aki,unsigned int seq,unsigned int * san_type,gnutls_datum_t * san,gnutls_datum_t * othername_oid,gnutls_datum_t * serial)842 int gnutls_x509_aki_get_cert_issuer(gnutls_x509_aki_t aki, unsigned int seq,
843 				    unsigned int *san_type,
844 				    gnutls_datum_t *san,
845 				    gnutls_datum_t *othername_oid,
846 				    gnutls_datum_t *serial)
847 {
848 	if (seq >= aki->cert_issuer.size)
849 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
850 
851 	if (aki->serial.size == 0)
852 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
853 
854 	if (serial)
855 		memcpy(serial, &aki->serial, sizeof(gnutls_datum_t));
856 
857 	if (san) {
858 		memcpy(san, &aki->cert_issuer.names[seq].san,
859 		       sizeof(gnutls_datum_t));
860 	}
861 
862 	if (othername_oid != NULL
863 	    && aki->cert_issuer.names[seq].type == GNUTLS_SAN_OTHERNAME) {
864 		othername_oid->data =
865 		    aki->cert_issuer.names[seq].othername_oid.data;
866 		othername_oid->size =
867 		    aki->cert_issuer.names[seq].othername_oid.size;
868 	}
869 
870 	if (san_type)
871 		*san_type = aki->cert_issuer.names[seq].type;
872 
873 	return 0;
874 
875 }
876 
877 /**
878  * gnutls_x509_ext_import_authority_key_id:
879  * @ext: a DER encoded extension
880  * @aki: An initialized authority key identifier type
881  * @flags: should be zero
882  *
883  * This function will return the subject key ID stored in the provided
884  * AuthorityKeyIdentifier extension.
885  *
886  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
887  * if the extension is not present, otherwise a negative error value.
888  *
889  * Since: 3.3.0
890  **/
gnutls_x509_ext_import_authority_key_id(const gnutls_datum_t * ext,gnutls_x509_aki_t aki,unsigned int flags)891 int gnutls_x509_ext_import_authority_key_id(const gnutls_datum_t * ext,
892 					 gnutls_x509_aki_t aki,
893 					 unsigned int flags)
894 {
895 	int ret;
896 	unsigned i;
897 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
898 	gnutls_datum_t san, othername_oid;
899 	unsigned type;
900 
901 	ret = asn1_create_element
902 	    (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", &c2);
903 	if (ret != ASN1_SUCCESS) {
904 		gnutls_assert();
905 		return _gnutls_asn2err(ret);
906 	}
907 
908 	ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
909 	if (ret != ASN1_SUCCESS) {
910 		gnutls_assert();
911 		ret = _gnutls_asn2err(ret);
912 		goto cleanup;
913 	}
914 
915 	/* Read authorityCertIssuer */
916 	for (i=0;;i++) {
917 		san.data = NULL;
918 		san.size = 0;
919 		othername_oid.data = NULL;
920 
921 		ret = _gnutls_parse_general_name2(c2, "authorityCertIssuer", i,
922 						  &san, &type, 0);
923 		if (ret < 0)
924 			break;
925 
926 		if (type == GNUTLS_SAN_OTHERNAME) {
927 			ret =
928 			    _gnutls_parse_general_name2(c2,
929 							"authorityCertIssuer",
930 							i,
931 							&othername_oid,
932 							NULL, 1);
933 			if (ret < 0)
934 				break;
935 		}
936 
937 		ret = subject_alt_names_set(&aki->cert_issuer.names,
938 					    &aki->cert_issuer.size,
939 					    type, &san,
940 					    (char *)othername_oid.data, 1);
941 		if (ret < 0)
942 			break;
943 	}
944 
945 	aki->cert_issuer.size = i;
946 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
947 	    && ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
948 		gnutls_assert();
949 		gnutls_free(san.data);
950 		gnutls_free(othername_oid.data);
951 		goto cleanup;
952 	}
953 
954 	/* Read the serial number */
955 	ret =
956 	    _gnutls_x509_read_value(c2, "authorityCertSerialNumber",
957 				    &aki->serial);
958 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
959 	    && ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
960 		gnutls_assert();
961 		goto cleanup;
962 	}
963 
964 	/* Read the key identifier */
965 	ret = _gnutls_x509_read_value(c2, "keyIdentifier", &aki->id);
966 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
967 	    && ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
968 		gnutls_assert();
969 		goto cleanup;
970 	}
971 
972 	ret = 0;
973 
974  cleanup:
975 	asn1_delete_structure(&c2);
976 
977 	return ret;
978 }
979 
980 /**
981  * gnutls_x509_ext_export_authority_key_id:
982  * @aki: An initialized authority key identifier
983  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
984  *
985  * This function will convert the provided key identifier to a
986  * DER-encoded PKIX AuthorityKeyIdentifier extension.
987  * The output data in @ext will be allocated using
988  * gnutls_malloc().
989  *
990  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
991  *
992  * Since: 3.3.0
993  **/
gnutls_x509_ext_export_authority_key_id(gnutls_x509_aki_t aki,gnutls_datum_t * ext)994 int gnutls_x509_ext_export_authority_key_id(gnutls_x509_aki_t aki,
995 					 gnutls_datum_t * ext)
996 {
997 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
998 	unsigned i;
999 	int result, ret;
1000 
1001 	result =
1002 	    asn1_create_element(_gnutls_get_pkix(),
1003 				"PKIX1.AuthorityKeyIdentifier", &c2);
1004 	if (result != ASN1_SUCCESS) {
1005 		gnutls_assert();
1006 		return _gnutls_asn2err(result);
1007 	}
1008 
1009 	if (aki->id.data != NULL) {
1010 		result =
1011 		    asn1_write_value(c2, "keyIdentifier", aki->id.data,
1012 				     aki->id.size);
1013 		if (result != ASN1_SUCCESS) {
1014 			gnutls_assert();
1015 			ret = _gnutls_asn2err(result);
1016 			goto cleanup;
1017 		}
1018 	} else {
1019 		(void)asn1_write_value(c2, "keyIdentifier", NULL, 0);
1020 	}
1021 
1022 	if (aki->serial.data != NULL) {
1023 		result =
1024 		    asn1_write_value(c2, "authorityCertSerialNumber",
1025 				     aki->serial.data, aki->serial.size);
1026 		if (result != ASN1_SUCCESS) {
1027 			gnutls_assert();
1028 			ret = _gnutls_asn2err(result);
1029 			goto cleanup;
1030 		}
1031 	} else {
1032 		(void)asn1_write_value(c2, "authorityCertSerialNumber", NULL, 0);
1033 	}
1034 
1035 	if (aki->cert_issuer.size == 0) {
1036 		(void)asn1_write_value(c2, "authorityCertIssuer", NULL, 0);
1037 	} else {
1038 		for (i = 0; i < aki->cert_issuer.size; i++) {
1039 			ret =
1040 			    _gnutls_write_new_general_name(c2,
1041 							   "authorityCertIssuer",
1042 							   aki->cert_issuer.
1043 							   names[i].type,
1044 							   aki->
1045 							   cert_issuer.names[i].
1046 							   san.data,
1047 							   aki->cert_issuer.
1048 							   names[i].san.size);
1049 			if (ret < 0) {
1050 				gnutls_assert();
1051 				goto cleanup;
1052 			}
1053 		}
1054 	}
1055 
1056 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
1057 	if (ret < 0) {
1058 		gnutls_assert();
1059 		goto cleanup;
1060 	}
1061 
1062 	ret = 0;
1063  cleanup:
1064 	asn1_delete_structure(&c2);
1065 	return ret;
1066 
1067 }
1068 
1069 /**
1070  * gnutls_x509_ext_import_key_usage:
1071  * @ext: the DER encoded extension data
1072  * @key_usage: where the key usage bits will be stored
1073  *
1074  * This function will return certificate's key usage, by reading the DER
1075  * data of the keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1076  * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1077  * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1078  * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1079  * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1080  * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1081  *
1082  * Returns: the certificate key usage, or a negative error code in case of
1083  *   parsing error.  If the certificate does not contain the keyUsage
1084  *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1085  *   returned.
1086  *
1087  * Since: 3.3.0
1088  **/
gnutls_x509_ext_import_key_usage(const gnutls_datum_t * ext,unsigned int * key_usage)1089 int gnutls_x509_ext_import_key_usage(const gnutls_datum_t * ext,
1090 				  unsigned int *key_usage)
1091 {
1092 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1093 	int len, result;
1094 	uint8_t str[2];
1095 
1096 	str[0] = str[1] = 0;
1097 	*key_usage = 0;
1098 
1099 	if ((result = asn1_create_element
1100 	     (_gnutls_get_pkix(), "PKIX1.KeyUsage", &c2)) != ASN1_SUCCESS) {
1101 		gnutls_assert();
1102 		return _gnutls_asn2err(result);
1103 	}
1104 
1105 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1106 	if (result != ASN1_SUCCESS) {
1107 		gnutls_assert();
1108 		asn1_delete_structure(&c2);
1109 		return _gnutls_asn2err(result);
1110 	}
1111 
1112 	len = sizeof(str);
1113 	result = asn1_read_value(c2, "", str, &len);
1114 	if (result != ASN1_SUCCESS) {
1115 		gnutls_assert();
1116 		asn1_delete_structure(&c2);
1117 		return 0;
1118 	}
1119 
1120 	*key_usage = str[0] | (str[1] << 8);
1121 
1122 	asn1_delete_structure(&c2);
1123 
1124 	return 0;
1125 }
1126 
1127 /**
1128  * gnutls_x509_ext_export_key_usage:
1129  * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1130  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1131  *
1132  * This function will convert the keyUsage bit string to a DER
1133  * encoded PKIX extension. The @ext data will be allocated using
1134  * gnutls_malloc().
1135  *
1136  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1137  *   negative error value.
1138  *
1139  * Since: 3.3.0
1140  **/
gnutls_x509_ext_export_key_usage(unsigned int usage,gnutls_datum_t * ext)1141 int gnutls_x509_ext_export_key_usage(unsigned int usage, gnutls_datum_t * ext)
1142 {
1143 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1144 	int result;
1145 	uint8_t str[2];
1146 
1147 	result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.KeyUsage", &c2);
1148 	if (result != ASN1_SUCCESS) {
1149 		gnutls_assert();
1150 		return _gnutls_asn2err(result);
1151 	}
1152 
1153 	str[0] = usage & 0xff;
1154 	str[1] = usage >> 8;
1155 
1156 	/* Since KeyUsage is a BIT STRING, the input to asn1_write_value
1157 	 * is the number of bits to be read. */
1158 	result = asn1_write_value(c2, "", str, 9);
1159 	if (result != ASN1_SUCCESS) {
1160 		gnutls_assert();
1161 		asn1_delete_structure(&c2);
1162 		return _gnutls_asn2err(result);
1163 	}
1164 
1165 	result = _gnutls_x509_der_encode(c2, "", ext, 0);
1166 
1167 	asn1_delete_structure(&c2);
1168 
1169 	if (result < 0) {
1170 		gnutls_assert();
1171 		return result;
1172 	}
1173 
1174 	return 0;
1175 }
1176 
1177 /**
1178  * gnutls_x509_ext_import_inhibit_anypolicy:
1179  * @ext: the DER encoded extension data
1180  * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable.
1181  *
1182  * This function will return certificate's value of SkipCerts,
1183  * by reading the DER data of the Inhibit anyPolicy X.509 extension (2.5.29.54).
1184  *
1185  * The @skipcerts value is the number of additional certificates that
1186  * may appear in the path before the anyPolicy (%GNUTLS_X509_OID_POLICY_ANY)
1187  * is no longer acceptable.
1188  *
1189  * Returns: zero, or a negative error code in case of
1190  *   parsing error.  If the certificate does not contain the Inhibit anyPolicy
1191  *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1192  *   returned.
1193  *
1194  * Since: 3.6.0
1195  **/
gnutls_x509_ext_import_inhibit_anypolicy(const gnutls_datum_t * ext,unsigned int * skipcerts)1196 int gnutls_x509_ext_import_inhibit_anypolicy(const gnutls_datum_t * ext,
1197 				  unsigned int *skipcerts)
1198 {
1199 	int ret;
1200 
1201 	ret = _gnutls_x509_read_der_uint(ext->data, ext->size, skipcerts);
1202 	if (ret < 0) {
1203 		gnutls_assert();
1204 	}
1205 
1206 	return ret;
1207 }
1208 
1209 /**
1210  * gnutls_x509_ext_export_inhibit_anypolicy:
1211  * @skipcerts: number of certificates after which anypolicy is no longer acceptable.
1212  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1213  *
1214  * This function will convert the @skipcerts value to a DER
1215  * encoded Inhibit AnyPolicy PKIX extension. The @ext data will be allocated using
1216  * gnutls_malloc().
1217  *
1218  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1219  *   negative error value.
1220  *
1221  * Since: 3.6.0
1222  **/
gnutls_x509_ext_export_inhibit_anypolicy(unsigned int skipcerts,gnutls_datum_t * ext)1223 int gnutls_x509_ext_export_inhibit_anypolicy(unsigned int skipcerts, gnutls_datum_t * ext)
1224 {
1225 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1226 	int result, ret;
1227 
1228 	result = asn1_create_element(_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &c2);
1229 	if (result != ASN1_SUCCESS) {
1230 		gnutls_assert();
1231 		return _gnutls_asn2err(result);
1232 	}
1233 
1234 	ret = _gnutls_x509_write_uint32(c2, "", skipcerts);
1235 	if (ret < 0) {
1236 		gnutls_assert();
1237 		goto cleanup;
1238 	}
1239 
1240 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
1241 	if (ret < 0) {
1242 		gnutls_assert();
1243 		goto cleanup;
1244 	}
1245 
1246 	ret = 0;
1247 
1248  cleanup:
1249 	asn1_delete_structure(&c2);
1250 
1251 	return ret;
1252 }
1253 
1254 /**
1255  * gnutls_x509_ext_import_private_key_usage_period:
1256  * @ext: the DER encoded extension data
1257  * @activation: Will hold the activation time
1258  * @expiration: Will hold the expiration time
1259  *
1260  * This function will return the expiration and activation
1261  * times of the private key as written in the
1262  * PKIX extension 2.5.29.16.
1263  *
1264  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1265  *   negative error value.
1266  *
1267  * Since: 3.3.0
1268  **/
gnutls_x509_ext_import_private_key_usage_period(const gnutls_datum_t * ext,time_t * activation,time_t * expiration)1269 int gnutls_x509_ext_import_private_key_usage_period(const gnutls_datum_t * ext,
1270 						 time_t * activation,
1271 						 time_t * expiration)
1272 {
1273 	int result, ret;
1274 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1275 
1276 	result = asn1_create_element
1277 	    (_gnutls_get_pkix(), "PKIX1.PrivateKeyUsagePeriod", &c2);
1278 	if (result != ASN1_SUCCESS) {
1279 		gnutls_assert();
1280 		ret = _gnutls_asn2err(result);
1281 		goto cleanup;
1282 	}
1283 
1284 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1285 	if (result != ASN1_SUCCESS) {
1286 		gnutls_assert();
1287 		ret = _gnutls_asn2err(result);
1288 		goto cleanup;
1289 	}
1290 
1291 	if (activation)
1292 		*activation = _gnutls_x509_get_time(c2, "notBefore", 1);
1293 
1294 	if (expiration)
1295 		*expiration = _gnutls_x509_get_time(c2, "notAfter", 1);
1296 
1297 	ret = 0;
1298 
1299  cleanup:
1300 	asn1_delete_structure(&c2);
1301 
1302 	return ret;
1303 }
1304 
1305 /**
1306  * gnutls_x509_ext_export_private_key_usage_period:
1307  * @activation: The activation time
1308  * @expiration: The expiration time
1309  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1310  *
1311  * This function will convert the periods provided to a private key
1312  * usage DER encoded extension (2.5.29.16).
1313  (
1314  * The @ext data will be allocated using
1315  * gnutls_malloc().
1316  *
1317  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1318  *   negative error value.
1319  *
1320  * Since: 3.3.0
1321  **/
gnutls_x509_ext_export_private_key_usage_period(time_t activation,time_t expiration,gnutls_datum_t * ext)1322 int gnutls_x509_ext_export_private_key_usage_period(time_t activation,
1323 						 time_t expiration,
1324 						 gnutls_datum_t * ext)
1325 {
1326 	int result;
1327 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1328 
1329 	result =
1330 	    asn1_create_element(_gnutls_get_pkix(),
1331 				"PKIX1.PrivateKeyUsagePeriod", &c2);
1332 	if (result != ASN1_SUCCESS) {
1333 		gnutls_assert();
1334 		return _gnutls_asn2err(result);
1335 	}
1336 
1337 	result = _gnutls_x509_set_time(c2, "notBefore", activation, 1);
1338 	if (result < 0) {
1339 		gnutls_assert();
1340 		goto cleanup;
1341 	}
1342 
1343 	result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1);
1344 	if (result < 0) {
1345 		gnutls_assert();
1346 		goto cleanup;
1347 	}
1348 
1349 	result = _gnutls_x509_der_encode(c2, "", ext, 0);
1350 	if (result < 0) {
1351 		gnutls_assert();
1352 		goto cleanup;
1353 	}
1354 
1355  cleanup:
1356 	asn1_delete_structure(&c2);
1357 
1358 	return result;
1359 
1360 }
1361 
1362 /**
1363  * gnutls_x509_ext_import_basic_constraints:
1364  * @ext: the DER encoded extension data
1365  * @ca: will be non zero if the CA status is true
1366  * @pathlen: the path length constraint; will be set to -1 for no limit
1367  *
1368  * This function will return the CA status and path length constraint
1369  * as written in the PKIX extension 2.5.29.19.
1370  *
1371  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1372  *   negative error value.
1373  *
1374  * Since: 3.3.0
1375  **/
gnutls_x509_ext_import_basic_constraints(const gnutls_datum_t * ext,unsigned int * ca,int * pathlen)1376 int gnutls_x509_ext_import_basic_constraints(const gnutls_datum_t * ext,
1377 					  unsigned int *ca, int *pathlen)
1378 {
1379 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1380 	char str[128]="";
1381 	int len, result;
1382 
1383 	if ((result = asn1_create_element
1384 	     (_gnutls_get_pkix(), "PKIX1.BasicConstraints",
1385 	      &c2)) != ASN1_SUCCESS) {
1386 		gnutls_assert();
1387 		return _gnutls_asn2err(result);
1388 	}
1389 
1390 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1391 	if (result != ASN1_SUCCESS) {
1392 		gnutls_assert();
1393 		result = _gnutls_asn2err(result);
1394 		goto cleanup;
1395 	}
1396 
1397 	if (pathlen) {
1398 		result = _gnutls_x509_read_uint(c2, "pathLenConstraint",
1399 						(unsigned int *)
1400 						pathlen);
1401 		if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1402 			*pathlen = -1;
1403 		else if (result != GNUTLS_E_SUCCESS) {
1404 			gnutls_assert();
1405 			result = _gnutls_asn2err(result);
1406 			goto cleanup;
1407 		}
1408 	}
1409 
1410 	/* the default value of cA is false.
1411 	 */
1412 	len = sizeof(str) - 1;
1413 	result = asn1_read_value(c2, "cA", str, &len);
1414 	if (result == ASN1_SUCCESS && strcmp(str, "TRUE") == 0)
1415 		*ca = 1;
1416 	else
1417 		*ca = 0;
1418 
1419 	result = 0;
1420  cleanup:
1421 	asn1_delete_structure(&c2);
1422 
1423 	return result;
1424 
1425 }
1426 
1427 /**
1428  * gnutls_x509_ext_export_basic_constraints:
1429  * @ca: non-zero for a CA
1430  * @pathlen: The path length constraint (set to -1 for no constraint)
1431  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1432  *
1433  * This function will convert the parameters provided to a basic constraints
1434  * DER encoded extension (2.5.29.19).
1435  (
1436  * The @ext data will be allocated using
1437  * gnutls_malloc().
1438  *
1439  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1440  *   negative error value.
1441  *
1442  * Since: 3.3.0
1443  **/
gnutls_x509_ext_export_basic_constraints(unsigned int ca,int pathlen,gnutls_datum_t * ext)1444 int gnutls_x509_ext_export_basic_constraints(unsigned int ca, int pathlen,
1445 					  gnutls_datum_t * ext)
1446 {
1447 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1448 	const char *str;
1449 	int result;
1450 
1451 	if (ca == 0)
1452 		str = "FALSE";
1453 	else
1454 		str = "TRUE";
1455 
1456 	result =
1457 	    asn1_create_element(_gnutls_get_pkix(),
1458 				"PKIX1.BasicConstraints", &c2);
1459 	if (result != ASN1_SUCCESS) {
1460 		gnutls_assert();
1461 		result = _gnutls_asn2err(result);
1462 		goto cleanup;
1463 	}
1464 
1465 	result = asn1_write_value(c2, "cA", str, 1);
1466 	if (result != ASN1_SUCCESS) {
1467 		gnutls_assert();
1468 		result = _gnutls_asn2err(result);
1469 		goto cleanup;
1470 	}
1471 
1472 	if (pathlen < 0) {
1473 		result = asn1_write_value(c2, "pathLenConstraint", NULL, 0);
1474 		if (result < 0)
1475 			result = _gnutls_asn2err(result);
1476 	} else
1477 		result =
1478 		    _gnutls_x509_write_uint32(c2, "pathLenConstraint", pathlen);
1479 	if (result < 0) {
1480 		gnutls_assert();
1481 		goto cleanup;
1482 	}
1483 
1484 	result = _gnutls_x509_der_encode(c2, "", ext, 0);
1485 	if (result < 0) {
1486 		gnutls_assert();
1487 		goto cleanup;
1488 	}
1489 
1490 	result = 0;
1491 
1492  cleanup:
1493 	asn1_delete_structure(&c2);
1494 	return result;
1495 
1496 }
1497 
1498 /**
1499  * gnutls_x509_ext_import_proxy:
1500  * @ext: the DER encoded extension data
1501  * @pathlen: pointer to output integer indicating path length (may be
1502  *   NULL), non-negative error codes indicate a present pCPathLenConstraint
1503  *   field and the actual value, -1 indicate that the field is absent.
1504  * @policyLanguage: output variable with OID of policy language
1505  * @policy: output variable with policy data
1506  * @sizeof_policy: output variable with size of policy data
1507  *
1508  * This function will return the information from a proxy certificate
1509  * extension. It reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1510  * The @policyLanguage and @policy values must be deinitialized using gnutls_free() after use.
1511  *
1512  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1513  *   negative error value.
1514  *
1515  * Since: 3.3.0
1516  **/
gnutls_x509_ext_import_proxy(const gnutls_datum_t * ext,int * pathlen,char ** policyLanguage,char ** policy,size_t * sizeof_policy)1517 int gnutls_x509_ext_import_proxy(const gnutls_datum_t *ext, int *pathlen,
1518 			         char **policyLanguage, char **policy,
1519 			         size_t *sizeof_policy)
1520 {
1521 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1522 	int result;
1523 	gnutls_datum_t value1 = { NULL, 0 };
1524 	gnutls_datum_t value2 = { NULL, 0 };
1525 
1526 	if ((result = asn1_create_element
1527 	     (_gnutls_get_pkix(), "PKIX1.ProxyCertInfo",
1528 	      &c2)) != ASN1_SUCCESS) {
1529 		gnutls_assert();
1530 		return _gnutls_asn2err(result);
1531 	}
1532 
1533 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1534 	if (result != ASN1_SUCCESS) {
1535 		gnutls_assert();
1536 		result = _gnutls_asn2err(result);
1537 		goto cleanup;
1538 	}
1539 
1540 	if (pathlen) {
1541 		result = _gnutls_x509_read_uint(c2, "pCPathLenConstraint",
1542 						(unsigned int *)
1543 						pathlen);
1544 		if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1545 			*pathlen = -1;
1546 		else if (result != GNUTLS_E_SUCCESS) {
1547 			gnutls_assert();
1548 			result = _gnutls_asn2err(result);
1549 			goto cleanup;
1550 		}
1551 	}
1552 
1553 	result = _gnutls_x509_read_value(c2, "proxyPolicy.policyLanguage",
1554 					 &value1);
1555 	if (result < 0) {
1556 		gnutls_assert();
1557 		goto cleanup;
1558 	}
1559 
1560 	result = _gnutls_x509_read_value(c2, "proxyPolicy.policy", &value2);
1561 	if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
1562 		if (policy)
1563 			*policy = NULL;
1564 		if (sizeof_policy)
1565 			*sizeof_policy = 0;
1566 	} else if (result < 0) {
1567 		gnutls_assert();
1568 		goto cleanup;
1569 	} else {
1570 		if (policy) {
1571 			*policy = (char *)value2.data;
1572 			value2.data = NULL;
1573 		}
1574 		if (sizeof_policy)
1575 			*sizeof_policy = value2.size;
1576 	}
1577 
1578 	if (policyLanguage) {
1579 		*policyLanguage = (char *)value1.data;
1580 		value1.data = NULL;
1581 	}
1582 
1583 	result = 0;
1584  cleanup:
1585 	gnutls_free(value1.data);
1586 	gnutls_free(value2.data);
1587 	asn1_delete_structure(&c2);
1588 
1589 	return result;
1590 }
1591 
1592 /**
1593  * gnutls_x509_ext_export_proxy:
1594  * @pathLenConstraint: A negative value will remove the path length constraint,
1595  *   while non-negative values will be set as the length of the pathLenConstraints field.
1596  * @policyLanguage: OID describing the language of @policy.
1597  * @policy: uint8_t byte array with policy language, can be %NULL
1598  * @sizeof_policy: size of @policy.
1599  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1600  *
1601  * This function will convert the parameters provided to a proxyCertInfo extension.
1602  *
1603  * The @ext data will be allocated using gnutls_malloc().
1604  *
1605  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1606  *   negative error value.
1607  *
1608  * Since: 3.3.0
1609  **/
gnutls_x509_ext_export_proxy(int pathLenConstraint,const char * policyLanguage,const char * policy,size_t sizeof_policy,gnutls_datum_t * ext)1610 int gnutls_x509_ext_export_proxy(int pathLenConstraint, const char *policyLanguage,
1611 			      const char *policy, size_t sizeof_policy,
1612 			      gnutls_datum_t * ext)
1613 {
1614 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1615 	int result;
1616 
1617 	result = asn1_create_element(_gnutls_get_pkix(),
1618 				     "PKIX1.ProxyCertInfo", &c2);
1619 	if (result != ASN1_SUCCESS) {
1620 		gnutls_assert();
1621 		return _gnutls_asn2err(result);
1622 	}
1623 
1624 	if (pathLenConstraint < 0) {
1625 		result = asn1_write_value(c2, "pCPathLenConstraint", NULL, 0);
1626 		if (result != ASN1_SUCCESS) {
1627 			gnutls_assert();
1628 			result = _gnutls_asn2err(result);
1629 			goto cleanup;
1630 		}
1631 	} else {
1632 		result =
1633 		    _gnutls_x509_write_uint32(c2, "pCPathLenConstraint",
1634 					      pathLenConstraint);
1635 
1636 		if (result < 0) {
1637 			gnutls_assert();
1638 			goto cleanup;
1639 		}
1640 	}
1641 
1642 	result = asn1_write_value(c2, "proxyPolicy.policyLanguage",
1643 				  policyLanguage, 1);
1644 	if (result < 0) {
1645 		gnutls_assert();
1646 		result = _gnutls_asn2err(result);
1647 		goto cleanup;
1648 	}
1649 
1650 	result = asn1_write_value(c2, "proxyPolicy.policy",
1651 				  policy, sizeof_policy);
1652 	if (result < 0) {
1653 		gnutls_assert();
1654 		result = _gnutls_asn2err(result);
1655 		goto cleanup;
1656 	}
1657 
1658 	result = _gnutls_x509_der_encode(c2, "", ext, 0);
1659 	if (result < 0) {
1660 		gnutls_assert();
1661 		goto cleanup;
1662 	}
1663 
1664 	result = 0;
1665  cleanup:
1666 	asn1_delete_structure(&c2);
1667 	return result;
1668 
1669 }
1670 
decode_user_notice(const void * data,size_t size,gnutls_datum_t * txt)1671 static int decode_user_notice(const void *data, size_t size,
1672 			      gnutls_datum_t * txt)
1673 {
1674 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1675 	int ret, len;
1676 	char choice_type[64];
1677 	char name[128];
1678 	gnutls_datum_t td = {NULL,0}, utd;
1679 
1680 	ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.UserNotice", &c2);
1681 	if (ret != ASN1_SUCCESS) {
1682 		gnutls_assert();
1683 		ret = GNUTLS_E_PARSING_ERROR;
1684 		goto cleanup;
1685 	}
1686 
1687 	ret = _asn1_strict_der_decode(&c2, data, size, NULL);
1688 	if (ret != ASN1_SUCCESS) {
1689 		gnutls_assert();
1690 		ret = GNUTLS_E_PARSING_ERROR;
1691 		goto cleanup;
1692 	}
1693 
1694 	len = sizeof(choice_type);
1695 	ret = asn1_read_value(c2, "explicitText", choice_type, &len);
1696 	if (ret != ASN1_SUCCESS) {
1697 		gnutls_assert();
1698 		ret = GNUTLS_E_PARSING_ERROR;
1699 		goto cleanup;
1700 	}
1701 
1702 	if (strcmp(choice_type, "utf8String") != 0
1703 	    && strcmp(choice_type, "ia5String") != 0
1704 	    && strcmp(choice_type, "bmpString") != 0
1705 	    && strcmp(choice_type, "visibleString") != 0) {
1706 		gnutls_assert();
1707 		ret = GNUTLS_E_PARSING_ERROR;
1708 		goto cleanup;
1709 	}
1710 
1711 	snprintf(name, sizeof(name), "explicitText.%s", choice_type);
1712 
1713 	ret = _gnutls_x509_read_value(c2, name, &td);
1714 	if (ret < 0) {
1715 		gnutls_assert();
1716 		goto cleanup;
1717 	}
1718 
1719 	if (strcmp(choice_type, "bmpString") == 0) {	/* convert to UTF-8 */
1720 		ret = _gnutls_ucs2_to_utf8(td.data, td.size, &utd, 1);
1721 		_gnutls_free_datum(&td);
1722 		if (ret < 0) {
1723 			gnutls_assert();
1724 			goto cleanup;
1725 		}
1726 
1727 		td.data = utd.data;
1728 		td.size = utd.size;
1729 	} else {
1730 		/* _gnutls_x509_read_value allows that */
1731 		td.data[td.size] = 0;
1732 	}
1733 
1734 	txt->data = (void *)td.data;
1735 	txt->size = td.size;
1736 	ret = 0;
1737 
1738  cleanup:
1739 	asn1_delete_structure(&c2);
1740 	return ret;
1741 
1742 }
1743 
1744 struct gnutls_x509_policies_st {
1745 	struct gnutls_x509_policy_st policy[MAX_ENTRIES];
1746 	unsigned int size;
1747 };
1748 
1749 /**
1750  * gnutls_x509_policies_init:
1751  * @policies: The authority key ID
1752  *
1753  * This function will initialize an authority key ID type.
1754  *
1755  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1756  *
1757  * Since: 3.3.0
1758  **/
gnutls_x509_policies_init(gnutls_x509_policies_t * policies)1759 int gnutls_x509_policies_init(gnutls_x509_policies_t * policies)
1760 {
1761 	*policies = gnutls_calloc(1, sizeof(struct gnutls_x509_policies_st));
1762 	if (*policies == NULL)
1763 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1764 
1765 	return 0;
1766 }
1767 
1768 /**
1769  * gnutls_x509_policies_deinit:
1770  * @policies: The authority key identifier
1771  *
1772  * This function will deinitialize an authority key identifier type.
1773  *
1774  * Since: 3.3.0
1775  **/
gnutls_x509_policies_deinit(gnutls_x509_policies_t policies)1776 void gnutls_x509_policies_deinit(gnutls_x509_policies_t policies)
1777 {
1778 	unsigned i;
1779 
1780 	for (i = 0; i < policies->size; i++) {
1781 		gnutls_x509_policy_release(&policies->policy[i]);
1782 	}
1783 	gnutls_free(policies);
1784 }
1785 
1786 /**
1787  * gnutls_x509_policies_get:
1788  * @policies: The policies
1789  * @seq: The index of the name to get
1790  * @policy: Will hold the policy
1791  *
1792  * This function will return a specific policy as stored in
1793  * the @policies type. The returned values should be treated as constant
1794  * and valid for the lifetime of @policies.
1795  *
1796  * The any policy OID is available as the %GNUTLS_X509_OID_POLICY_ANY macro.
1797  *
1798  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1799  * if the index is out of bounds, otherwise a negative error value.
1800  *
1801  * Since: 3.3.0
1802  **/
gnutls_x509_policies_get(gnutls_x509_policies_t policies,unsigned int seq,struct gnutls_x509_policy_st * policy)1803 int gnutls_x509_policies_get(gnutls_x509_policies_t policies,
1804 			     unsigned int seq,
1805 			     struct gnutls_x509_policy_st *policy)
1806 {
1807 	if (seq >= policies->size)
1808 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1809 
1810 	if (policy) {
1811 		memcpy(policy, &policies->policy[seq],
1812 		       sizeof(struct gnutls_x509_policy_st));
1813 	}
1814 
1815 	return 0;
1816 }
1817 
_gnutls_x509_policies_erase(gnutls_x509_policies_t policies,unsigned int seq)1818 void _gnutls_x509_policies_erase(gnutls_x509_policies_t policies,
1819 				 unsigned int seq)
1820 {
1821 	if (seq >= policies->size)
1822 		return;
1823 
1824 	memset(&policies->policy[seq], 0, sizeof(struct gnutls_x509_policy_st));
1825 }
1826 
1827 /**
1828  * gnutls_x509_policies_set:
1829  * @policies: An initialized policies
1830  * @seq: The index of the name to get
1831  * @policy: Contains the policy to set
1832  *
1833  * This function will store the specified policy in
1834  * the provided @policies.
1835  *
1836  * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
1837  *
1838  * Since: 3.3.0
1839  **/
gnutls_x509_policies_set(gnutls_x509_policies_t policies,const struct gnutls_x509_policy_st * policy)1840 int gnutls_x509_policies_set(gnutls_x509_policies_t policies,
1841 			     const struct gnutls_x509_policy_st *policy)
1842 {
1843 	unsigned i;
1844 
1845 	if (policies->size + 1 > MAX_ENTRIES)
1846 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1847 
1848 	policies->policy[policies->size].oid = gnutls_strdup(policy->oid);
1849 	if (policies->policy[policies->size].oid == NULL)
1850 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1851 
1852 	for (i = 0; i < policy->qualifiers; i++) {
1853 		policies->policy[policies->size].qualifier[i].type =
1854 		    policy->qualifier[i].type;
1855 		policies->policy[policies->size].qualifier[i].size =
1856 		    policy->qualifier[i].size;
1857 		policies->policy[policies->size].qualifier[i].data =
1858 		    gnutls_malloc(policy->qualifier[i].size + 1);
1859 		if (policies->policy[policies->size].qualifier[i].data == NULL)
1860 			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1861 		memcpy(policies->policy[policies->size].qualifier[i].data,
1862 		       policy->qualifier[i].data, policy->qualifier[i].size);
1863 		policies->policy[policies->size].qualifier[i].data[policy->
1864 								   qualifier[i].
1865 								   size] = 0;
1866 	}
1867 
1868 	policies->policy[policies->size].qualifiers = policy->qualifiers;
1869 	policies->size++;
1870 
1871 	return 0;
1872 }
1873 
1874 /**
1875  * gnutls_x509_ext_import_policies:
1876  * @ext: the DER encoded extension data
1877  * @policies: A pointer to an initialized policies.
1878  * @flags: should be zero
1879  *
1880  * This function will extract the certificate policy extension (2.5.29.32)
1881  * and store it the provided policies.
1882  *
1883  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1884  *
1885  * Since: 3.3.0
1886  **/
gnutls_x509_ext_import_policies(const gnutls_datum_t * ext,gnutls_x509_policies_t policies,unsigned int flags)1887 int gnutls_x509_ext_import_policies(const gnutls_datum_t * ext,
1888 				 gnutls_x509_policies_t policies,
1889 				 unsigned int flags)
1890 {
1891 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1892 	char tmpstr[128];
1893 	char tmpoid[MAX_OID_SIZE];
1894 	gnutls_datum_t tmpd = { NULL, 0 };
1895 	int ret, len;
1896 	unsigned i, j, current = 0;
1897 
1898 	ret = asn1_create_element
1899 	    (_gnutls_get_pkix(), "PKIX1.certificatePolicies", &c2);
1900 	if (ret != ASN1_SUCCESS) {
1901 		gnutls_assert();
1902 		ret = _gnutls_asn2err(ret);
1903 		goto cleanup;
1904 	}
1905 
1906 	ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1907 	if (ret != ASN1_SUCCESS) {
1908 		gnutls_assert();
1909 		ret = _gnutls_asn2err(ret);
1910 		goto cleanup;
1911 	}
1912 
1913 	for (j = 0;; j++) {
1914 		if (j >= MAX_ENTRIES)
1915 			break;
1916 
1917 		memset(&policies->policy[j], 0,
1918 		       sizeof(struct gnutls_x509_policy_st));
1919 
1920 		/* create a string like "?1"
1921 		 */
1922 		snprintf(tmpstr, sizeof(tmpstr), "?%u.policyIdentifier", j + 1);
1923 		current = j+1;
1924 
1925 		ret = _gnutls_x509_read_value(c2, tmpstr, &tmpd);
1926 		if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1927 			break;
1928 
1929 		if (ret < 0) {
1930 			gnutls_assert();
1931 			goto full_cleanup;
1932 		}
1933 
1934 		policies->policy[j].oid = (void *)tmpd.data;
1935 		tmpd.data = NULL;
1936 
1937 		for (i = 0; i < GNUTLS_MAX_QUALIFIERS; i++) {
1938 			gnutls_datum_t td;
1939 
1940 			snprintf(tmpstr, sizeof(tmpstr),
1941 				 "?%u.policyQualifiers.?%u.policyQualifierId",
1942 				 j + 1, i + 1);
1943 
1944 			len = sizeof(tmpoid);
1945 			ret = asn1_read_value(c2, tmpstr, tmpoid, &len);
1946 
1947 			if (ret == ASN1_ELEMENT_NOT_FOUND)
1948 				break;	/* finished */
1949 
1950 			if (ret != ASN1_SUCCESS) {
1951 				gnutls_assert();
1952 				ret = _gnutls_asn2err(ret);
1953 				goto full_cleanup;
1954 			}
1955 
1956 			if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.1") == 0) {
1957 				snprintf(tmpstr, sizeof(tmpstr),
1958 					 "?%u.policyQualifiers.?%u.qualifier",
1959 					 j + 1, i + 1);
1960 
1961 				ret =
1962 				    _gnutls_x509_read_string(c2, tmpstr, &td,
1963 							     ASN1_ETYPE_IA5_STRING, 0);
1964 				if (ret < 0) {
1965 					gnutls_assert();
1966 					goto full_cleanup;
1967 				}
1968 
1969 				policies->policy[j].qualifier[i].data =
1970 				    (void *)td.data;
1971 				policies->policy[j].qualifier[i].size = td.size;
1972 				td.data = NULL;
1973 				policies->policy[j].qualifier[i].type =
1974 				    GNUTLS_X509_QUALIFIER_URI;
1975 			} else if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.2") == 0) {
1976 				gnutls_datum_t txt = {NULL, 0};
1977 
1978 				snprintf(tmpstr, sizeof(tmpstr),
1979 					 "?%u.policyQualifiers.?%u.qualifier",
1980 					 j + 1, i + 1);
1981 
1982 				ret = _gnutls_x509_read_value(c2, tmpstr, &td);
1983 				if (ret < 0) {
1984 					gnutls_assert();
1985 					goto full_cleanup;
1986 				}
1987 
1988 				ret =
1989 				    decode_user_notice(td.data, td.size, &txt);
1990 				gnutls_free(td.data);
1991 
1992 				if (ret < 0) {
1993 					gnutls_assert();
1994 					goto full_cleanup;
1995 				}
1996 
1997 				policies->policy[j].qualifier[i].data =
1998 				    (void *)txt.data;
1999 				policies->policy[j].qualifier[i].size =
2000 				    txt.size;
2001 				policies->policy[j].qualifier[i].type =
2002 				    GNUTLS_X509_QUALIFIER_NOTICE;
2003 			} else
2004 				policies->policy[j].qualifier[i].type =
2005 				    GNUTLS_X509_QUALIFIER_UNKNOWN;
2006 
2007 			policies->policy[j].qualifiers++;
2008 		}
2009 
2010 	}
2011 
2012 	policies->size = j;
2013 
2014 	ret = 0;
2015 	goto cleanup;
2016 
2017  full_cleanup:
2018 	for (j = 0; j < current; j++)
2019 		gnutls_x509_policy_release(&policies->policy[j]);
2020 
2021  cleanup:
2022 	_gnutls_free_datum(&tmpd);
2023 	asn1_delete_structure(&c2);
2024 	return ret;
2025 
2026 }
2027 
encode_user_notice(const gnutls_datum_t * txt,gnutls_datum_t * der_data)2028 static int encode_user_notice(const gnutls_datum_t * txt,
2029 			      gnutls_datum_t * der_data)
2030 {
2031 	int result;
2032 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2033 
2034 	if ((result =
2035 	     asn1_create_element(_gnutls_get_pkix(),
2036 				 "PKIX1.UserNotice", &c2)) != ASN1_SUCCESS) {
2037 		gnutls_assert();
2038 		result = _gnutls_asn2err(result);
2039 		goto error;
2040 	}
2041 
2042 	/* delete noticeRef */
2043 	result = asn1_write_value(c2, "noticeRef", NULL, 0);
2044 	if (result != ASN1_SUCCESS) {
2045 		gnutls_assert();
2046 		result = _gnutls_asn2err(result);
2047 		goto error;
2048 	}
2049 
2050 	result = asn1_write_value(c2, "explicitText", "utf8String", 1);
2051 	if (result != ASN1_SUCCESS) {
2052 		gnutls_assert();
2053 		result = _gnutls_asn2err(result);
2054 		goto error;
2055 	}
2056 
2057 	result =
2058 	    asn1_write_value(c2, "explicitText.utf8String", txt->data,
2059 			     txt->size);
2060 	if (result != ASN1_SUCCESS) {
2061 		gnutls_assert();
2062 		result = _gnutls_asn2err(result);
2063 		goto error;
2064 	}
2065 
2066 	result = _gnutls_x509_der_encode(c2, "", der_data, 0);
2067 	if (result < 0) {
2068 		gnutls_assert();
2069 		goto error;
2070 	}
2071 
2072 	result = 0;
2073 
2074  error:
2075 	asn1_delete_structure(&c2);
2076 	return result;
2077 
2078 }
2079 
2080 /**
2081  * gnutls_x509_ext_export_policies:
2082  * @policies: A pointer to an initialized policies.
2083  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2084  *
2085  * This function will convert the provided policies, to a certificate policy
2086  * DER encoded extension (2.5.29.32).
2087  *
2088  * The @ext data will be allocated using gnutls_malloc().
2089  *
2090  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2091  *
2092  * Since: 3.3.0
2093  **/
gnutls_x509_ext_export_policies(gnutls_x509_policies_t policies,gnutls_datum_t * ext)2094 int gnutls_x509_ext_export_policies(gnutls_x509_policies_t policies,
2095 				 gnutls_datum_t * ext)
2096 {
2097 	int result;
2098 	unsigned i, j;
2099 	gnutls_datum_t der_data = {NULL, 0}, tmpd;
2100 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2101 	const char *oid;
2102 
2103 	result =
2104 	    asn1_create_element(_gnutls_get_pkix(),
2105 				"PKIX1.certificatePolicies", &c2);
2106 	if (result != ASN1_SUCCESS) {
2107 		gnutls_assert();
2108 		result = _gnutls_asn2err(result);
2109 		goto cleanup;
2110 	}
2111 
2112 	for (j = 0; j < policies->size; j++) {
2113 		/* 1. write a new policy */
2114 		result = asn1_write_value(c2, "", "NEW", 1);
2115 		if (result != ASN1_SUCCESS) {
2116 			gnutls_assert();
2117 			result = _gnutls_asn2err(result);
2118 			goto cleanup;
2119 		}
2120 
2121 		/* 2. Add the OID.
2122 		 */
2123 		result =
2124 		    asn1_write_value(c2, "?LAST.policyIdentifier",
2125 				     policies->policy[j].oid, 1);
2126 		if (result != ASN1_SUCCESS) {
2127 			gnutls_assert();
2128 			result = _gnutls_asn2err(result);
2129 			goto cleanup;
2130 		}
2131 
2132 		for (i = 0;
2133 		     i < MIN(policies->policy[j].qualifiers,
2134 			     GNUTLS_MAX_QUALIFIERS); i++) {
2135 			result =
2136 			    asn1_write_value(c2, "?LAST.policyQualifiers",
2137 					     "NEW", 1);
2138 			if (result != ASN1_SUCCESS) {
2139 				gnutls_assert();
2140 				result = _gnutls_asn2err(result);
2141 				goto cleanup;
2142 			}
2143 
2144 			if (policies->policy[j].qualifier[i].type ==
2145 			    GNUTLS_X509_QUALIFIER_URI)
2146 				oid = "1.3.6.1.5.5.7.2.1";
2147 			else if (policies->policy[j].qualifier[i].type ==
2148 				 GNUTLS_X509_QUALIFIER_NOTICE)
2149 				oid = "1.3.6.1.5.5.7.2.2";
2150 			else {
2151 				result =
2152 				    gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2153 				goto cleanup;
2154 			}
2155 
2156 			result =
2157 			    asn1_write_value(c2,
2158 					     "?LAST.policyQualifiers.?LAST.policyQualifierId",
2159 					     oid, 1);
2160 			if (result != ASN1_SUCCESS) {
2161 				gnutls_assert();
2162 				result = _gnutls_asn2err(result);
2163 				goto cleanup;
2164 			}
2165 
2166 			if (policies->policy[j].qualifier[i].type ==
2167 			    GNUTLS_X509_QUALIFIER_URI) {
2168 				tmpd.data =
2169 				    (void *)policies->policy[j].qualifier[i].
2170 				    data;
2171 				tmpd.size =
2172 				    policies->policy[j].qualifier[i].size;
2173 				result =
2174 				    _gnutls_x509_write_string(c2,
2175 							      "?LAST.policyQualifiers.?LAST.qualifier",
2176 							      &tmpd,
2177 							      ASN1_ETYPE_IA5_STRING);
2178 				if (result < 0) {
2179 					gnutls_assert();
2180 					goto cleanup;
2181 				}
2182 			} else if (policies->policy[j].qualifier[i].type ==
2183 				   GNUTLS_X509_QUALIFIER_NOTICE) {
2184 				tmpd.data =
2185 				    (void *)policies->policy[j].qualifier[i].
2186 				    data;
2187 				tmpd.size =
2188 				    policies->policy[j].qualifier[i].size;
2189 
2190 				if (tmpd.size > 200) {
2191 					gnutls_assert();
2192 					result = GNUTLS_E_INVALID_REQUEST;
2193 					goto cleanup;
2194 				}
2195 
2196 				result = encode_user_notice(&tmpd, &der_data);
2197 				if (result < 0) {
2198 					gnutls_assert();
2199 					goto cleanup;
2200 				}
2201 
2202 				result =
2203 				    _gnutls_x509_write_value(c2,
2204 							     "?LAST.policyQualifiers.?LAST.qualifier",
2205 							     &der_data);
2206 				_gnutls_free_datum(&der_data);
2207 				if (result < 0) {
2208 					gnutls_assert();
2209 					goto cleanup;
2210 				}
2211 			}
2212 		}
2213 	}
2214 
2215 	result = _gnutls_x509_der_encode(c2, "", ext, 0);
2216 	if (result < 0) {
2217 		gnutls_assert();
2218 		goto cleanup;
2219 	}
2220 
2221  cleanup:
2222 	asn1_delete_structure(&c2);
2223 
2224 	return result;
2225 }
2226 
2227 struct crl_dist_point_st {
2228 	unsigned int type;
2229 	gnutls_datum_t san;
2230 	unsigned int reasons;
2231 };
2232 
2233 struct gnutls_x509_crl_dist_points_st {
2234 	struct crl_dist_point_st *points;
2235 	unsigned int size;
2236 };
2237 
2238 /**
2239  * gnutls_x509_crl_dist_points_init:
2240  * @cdp: The CRL distribution points
2241  *
2242  * This function will initialize a CRL distribution points type.
2243  *
2244  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2245  *
2246  * Since: 3.3.0
2247  **/
gnutls_x509_crl_dist_points_init(gnutls_x509_crl_dist_points_t * cdp)2248 int gnutls_x509_crl_dist_points_init(gnutls_x509_crl_dist_points_t * cdp)
2249 {
2250 	*cdp = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_dist_points_st));
2251 	if (*cdp == NULL)
2252 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2253 
2254 	return 0;
2255 }
2256 
2257 /**
2258  * gnutls_x509_crl_dist_points_deinit:
2259  * @cdp: The CRL distribution points
2260  *
2261  * This function will deinitialize a CRL distribution points type.
2262  *
2263  * Since: 3.3.0
2264  **/
gnutls_x509_crl_dist_points_deinit(gnutls_x509_crl_dist_points_t cdp)2265 void gnutls_x509_crl_dist_points_deinit(gnutls_x509_crl_dist_points_t cdp)
2266 {
2267 	unsigned i;
2268 
2269 	for (i = 0; i < cdp->size; i++) {
2270 		gnutls_free(cdp->points[i].san.data);
2271 	}
2272 	gnutls_free(cdp->points);
2273 	gnutls_free(cdp);
2274 }
2275 
2276 /**
2277  * gnutls_x509_crl_dist_points_get:
2278  * @cdp: The CRL distribution points
2279  * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2280  * @type: The name type of the corresponding name (gnutls_x509_subject_alt_name_t)
2281  * @san: The distribution point names (to be treated as constant)
2282  * @reasons: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2283  *
2284  * This function retrieves the individual CRL distribution points (2.5.29.31),
2285  * contained in provided type.
2286  *
2287  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2288  * if the index is out of bounds, otherwise a negative error value.
2289  **/
2290 
gnutls_x509_crl_dist_points_get(gnutls_x509_crl_dist_points_t cdp,unsigned int seq,unsigned int * type,gnutls_datum_t * san,unsigned int * reasons)2291 int gnutls_x509_crl_dist_points_get(gnutls_x509_crl_dist_points_t cdp,
2292 				    unsigned int seq, unsigned int *type,
2293 				    gnutls_datum_t * san, unsigned int *reasons)
2294 {
2295 	if (seq >= cdp->size)
2296 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2297 
2298 	if (reasons)
2299 		*reasons = cdp->points[seq].reasons;
2300 
2301 	if (type)
2302 		*type = cdp->points[seq].type;
2303 
2304 	if (san) {
2305 		san->data = cdp->points[seq].san.data;
2306 		san->size = cdp->points[seq].san.size;
2307 	}
2308 
2309 	return 0;
2310 }
2311 
2312 static
crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,gnutls_x509_subject_alt_name_t type,const gnutls_datum_t * san,unsigned int reasons)2313 int crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
2314 			gnutls_x509_subject_alt_name_t type,
2315 			const gnutls_datum_t * san, unsigned int reasons)
2316 {
2317 	void *tmp;
2318 
2319 	/* new dist point */
2320 	tmp =
2321 	    gnutls_realloc(cdp->points,
2322 			   (cdp->size + 1) * sizeof(cdp->points[0]));
2323 	if (tmp == NULL) {
2324 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2325 	}
2326 	cdp->points = tmp;
2327 
2328 	cdp->points[cdp->size].type = type;
2329 	cdp->points[cdp->size].san.data = san->data;
2330 	cdp->points[cdp->size].san.size = san->size;
2331 	cdp->points[cdp->size].reasons = reasons;
2332 
2333 	cdp->size++;
2334 	return 0;
2335 
2336 }
2337 
2338 /**
2339  * gnutls_x509_crl_dist_points_set:
2340  * @cdp: The CRL distribution points
2341  * @type: The type of the name (of %gnutls_subject_alt_names_t)
2342  * @san: The point name data
2343  * @reasons: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2344  *
2345  * This function will store the specified CRL distribution point value
2346  * the @cdp type.
2347  *
2348  * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2349  *
2350  * Since: 3.3.0
2351  **/
gnutls_x509_crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,gnutls_x509_subject_alt_name_t type,const gnutls_datum_t * san,unsigned int reasons)2352 int gnutls_x509_crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
2353 				    gnutls_x509_subject_alt_name_t type,
2354 				    const gnutls_datum_t * san,
2355 				    unsigned int reasons)
2356 {
2357 	int ret;
2358 	gnutls_datum_t t_san;
2359 
2360 	ret = _gnutls_set_datum(&t_san, san->data, san->size);
2361 	if (ret < 0)
2362 		return gnutls_assert_val(ret);
2363 
2364 	ret = crl_dist_points_set(cdp, type, &t_san, reasons);
2365 	if (ret < 0) {
2366 		gnutls_free(t_san.data);
2367 		return gnutls_assert_val(ret);
2368 	}
2369 
2370 	return 0;
2371 }
2372 
2373 /**
2374  * gnutls_x509_ext_import_crl_dist_points:
2375  * @ext: the DER encoded extension data
2376  * @cdp: A pointer to an initialized CRL distribution points.
2377  * @flags: should be zero
2378  *
2379  * This function will extract the CRL distribution points extension (2.5.29.31)
2380  * and store it into the provided type.
2381  *
2382  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2383  *
2384  * Since: 3.3.0
2385  **/
gnutls_x509_ext_import_crl_dist_points(const gnutls_datum_t * ext,gnutls_x509_crl_dist_points_t cdp,unsigned int flags)2386 int gnutls_x509_ext_import_crl_dist_points(const gnutls_datum_t * ext,
2387 					gnutls_x509_crl_dist_points_t cdp,
2388 					unsigned int flags)
2389 {
2390 	int result;
2391 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2392 	char name[MAX_NAME_SIZE];
2393 	int len, ret;
2394 	uint8_t reasons[2];
2395 	unsigned i, type, rflags, j;
2396 	gnutls_datum_t san = {NULL, 0};
2397 
2398 	result = asn1_create_element
2399 	    (_gnutls_get_pkix(), "PKIX1.CRLDistributionPoints", &c2);
2400 	if (result != ASN1_SUCCESS) {
2401 		gnutls_assert();
2402 		return _gnutls_asn2err(result);
2403 	}
2404 
2405 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
2406 
2407 	if (result != ASN1_SUCCESS) {
2408 		gnutls_assert();
2409 		ret = _gnutls_asn2err(result);
2410 		goto cleanup;
2411 	}
2412 
2413 	/* Return the different names from the first CRLDistr. point.
2414 	 * The whole thing is a mess.
2415 	 */
2416 
2417 	i = 0;
2418 	do {
2419 		snprintf(name, sizeof(name), "?%u.reasons", (unsigned)i + 1);
2420 
2421 		len = sizeof(reasons);
2422 		result = asn1_read_value(c2, name, reasons, &len);
2423 
2424 		if (result != ASN1_VALUE_NOT_FOUND &&
2425 		    result != ASN1_ELEMENT_NOT_FOUND &&
2426 		    result != ASN1_SUCCESS) {
2427 			gnutls_assert();
2428 			ret = _gnutls_asn2err(result);
2429 			break;
2430 		}
2431 
2432 		if (result == ASN1_VALUE_NOT_FOUND
2433 		    || result == ASN1_ELEMENT_NOT_FOUND)
2434 			rflags = 0;
2435 		else
2436 			rflags = reasons[0] | (reasons[1] << 8);
2437 
2438 		snprintf(name, sizeof(name),
2439 			 "?%u.distributionPoint.fullName", (unsigned)i + 1);
2440 
2441 		for (j=0;;j++) {
2442 			san.data = NULL;
2443 			san.size = 0;
2444 
2445 			ret =
2446 			    _gnutls_parse_general_name2(c2, name, j, &san,
2447 							&type, 0);
2448 			if (j > 0
2449 			    && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2450 				ret = 0;
2451 				break;
2452 			}
2453 			if (ret < 0)
2454 				break;
2455 
2456 			ret = crl_dist_points_set(cdp, type, &san, rflags);
2457 			if (ret < 0)
2458 				break;
2459 			san.data = NULL; /* it is now in cdp */
2460 		}
2461 
2462 		i++;
2463 	} while (ret >= 0);
2464 
2465 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2466 		gnutls_assert();
2467 		gnutls_free(san.data);
2468 		goto cleanup;
2469 	}
2470 
2471 	ret = 0;
2472  cleanup:
2473 	asn1_delete_structure(&c2);
2474 	return ret;
2475 }
2476 
2477 /**
2478  * gnutls_x509_ext_export_crl_dist_points:
2479  * @cdp: A pointer to an initialized CRL distribution points.
2480  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2481  *
2482  * This function will convert the provided policies, to a certificate policy
2483  * DER encoded extension (2.5.29.31).
2484  *
2485  * The @ext data will be allocated using gnutls_malloc().
2486  *
2487  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2488  *
2489  * Since: 3.3.0
2490  **/
gnutls_x509_ext_export_crl_dist_points(gnutls_x509_crl_dist_points_t cdp,gnutls_datum_t * ext)2491 int gnutls_x509_ext_export_crl_dist_points(gnutls_x509_crl_dist_points_t cdp,
2492 					gnutls_datum_t * ext)
2493 {
2494 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2495 	int result;
2496 	uint8_t reasons[2];
2497 	unsigned i;
2498 
2499 	result =
2500 	    asn1_create_element(_gnutls_get_pkix(),
2501 				"PKIX1.CRLDistributionPoints", &c2);
2502 	if (result != ASN1_SUCCESS) {
2503 		gnutls_assert();
2504 		result = _gnutls_asn2err(result);
2505 		goto cleanup;
2506 	}
2507 
2508 	for (i = 0; i < cdp->size; i++) {
2509 
2510 		if (i == 0
2511 		    || cdp->points[i].reasons != cdp->points[i - 1].reasons) {
2512 			result = asn1_write_value(c2, "", "NEW", 1);
2513 			if (result != ASN1_SUCCESS) {
2514 				gnutls_assert();
2515 				result = _gnutls_asn2err(result);
2516 				goto cleanup;
2517 			}
2518 
2519 			if (cdp->points[i].reasons) {
2520 				reasons[0] = cdp->points[i].reasons & 0xff;
2521 				reasons[1] = cdp->points[i].reasons >> 8;
2522 
2523 				result =
2524 				    asn1_write_value(c2, "?LAST.reasons",
2525 						     reasons, 2);
2526 			} else {
2527 				result =
2528 				    asn1_write_value(c2, "?LAST.reasons", NULL,
2529 						     0);
2530 			}
2531 
2532 			if (result != ASN1_SUCCESS) {
2533 				gnutls_assert();
2534 				result = _gnutls_asn2err(result);
2535 				goto cleanup;
2536 			}
2537 
2538 			result =
2539 			    asn1_write_value(c2, "?LAST.cRLIssuer", NULL, 0);
2540 			if (result != ASN1_SUCCESS) {
2541 				gnutls_assert();
2542 				result = _gnutls_asn2err(result);
2543 				goto cleanup;
2544 			}
2545 			/* When used as type CHOICE.
2546 			 */
2547 			result =
2548 			    asn1_write_value(c2, "?LAST.distributionPoint",
2549 					     "fullName", 1);
2550 			if (result != ASN1_SUCCESS) {
2551 				gnutls_assert();
2552 				result = _gnutls_asn2err(result);
2553 				goto cleanup;
2554 			}
2555 		}
2556 
2557 		result =
2558 		    _gnutls_write_new_general_name(c2,
2559 						   "?LAST.distributionPoint.fullName",
2560 						   cdp->points[i].type,
2561 						   cdp->points[i].san.data,
2562 						   cdp->points[i].san.size);
2563 		if (result < 0) {
2564 			gnutls_assert();
2565 			goto cleanup;
2566 		}
2567 	}
2568 
2569 	result = _gnutls_x509_der_encode(c2, "", ext, 0);
2570 	if (result < 0) {
2571 		gnutls_assert();
2572 		goto cleanup;
2573 	}
2574 
2575 	result = 0;
2576 
2577  cleanup:
2578 	asn1_delete_structure(&c2);
2579 
2580 	return result;
2581 
2582 }
2583 
2584 struct gnutls_x509_aia_st {
2585 	struct {
2586 		gnutls_datum_t oid;
2587 		unsigned int san_type;
2588 		gnutls_datum_t san;
2589 	} *aia;
2590 	unsigned int size;
2591 };
2592 
2593 /**
2594  * gnutls_x509_aia_init:
2595  * @aia: The authority info access
2596  *
2597  * This function will initialize an authority info access type.
2598  *
2599  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2600  *
2601  * Since: 3.3.0
2602  **/
gnutls_x509_aia_init(gnutls_x509_aia_t * aia)2603 int gnutls_x509_aia_init(gnutls_x509_aia_t * aia)
2604 {
2605 	*aia = gnutls_calloc(1, sizeof(struct gnutls_x509_aia_st));
2606 	if (*aia == NULL)
2607 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2608 
2609 	return 0;
2610 }
2611 
2612 /**
2613  * gnutls_x509_aia_deinit:
2614  * @aia: The authority info access
2615  *
2616  * This function will deinitialize an authority info access type.
2617  *
2618  * Since: 3.3.0
2619  **/
gnutls_x509_aia_deinit(gnutls_x509_aia_t aia)2620 void gnutls_x509_aia_deinit(gnutls_x509_aia_t aia)
2621 {
2622 	unsigned i;
2623 
2624 	for (i = 0; i < aia->size; i++) {
2625 		gnutls_free(aia->aia[i].san.data);
2626 		gnutls_free(aia->aia[i].oid.data);
2627 	}
2628 	gnutls_free(aia->aia);
2629 	gnutls_free(aia);
2630 }
2631 
2632 /**
2633  * gnutls_x509_aia_get:
2634  * @aia: The authority info access
2635  * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
2636  * @oid: the type of available data; to be treated as constant.
2637  * @san_type: Will hold the type of the name of %gnutls_subject_alt_names_t (may be null).
2638  * @san: the access location name; to be treated as constant (may be null).
2639  *
2640  * This function reads from the Authority Information Access type.
2641  *
2642  * The @seq input parameter is used to indicate which member of the
2643  * sequence the caller is interested in.  The first member is 0, the
2644  * second member 1 and so on.  When the @seq value is out of bounds,
2645  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2646  *
2647  * Typically @oid is %GNUTLS_OID_AD_CAISSUERS or %GNUTLS_OID_AD_OCSP.
2648  *
2649  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2650  *
2651  * Since: 3.3.0
2652  **/
gnutls_x509_aia_get(gnutls_x509_aia_t aia,unsigned int seq,gnutls_datum_t * oid,unsigned * san_type,gnutls_datum_t * san)2653 int gnutls_x509_aia_get(gnutls_x509_aia_t aia, unsigned int seq,
2654 			gnutls_datum_t *oid,
2655 			unsigned *san_type,
2656 			gnutls_datum_t *san)
2657 {
2658 	if (seq >= aia->size)
2659 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2660 
2661 	if (san_type)
2662 		*san_type = aia->aia[seq].san_type;
2663 	if (san) {
2664 		san->data = aia->aia[seq].san.data;
2665 		san->size = aia->aia[seq].san.size;
2666 	}
2667 
2668 	if (oid) {
2669 		oid->data = aia->aia[seq].oid.data;
2670 		oid->size = aia->aia[seq].oid.size;
2671 	}
2672 
2673 	return 0;
2674 }
2675 
_gnutls_alt_name_process(gnutls_datum_t * out,unsigned type,const gnutls_datum_t * san,unsigned raw)2676 int _gnutls_alt_name_process(gnutls_datum_t *out, unsigned type, const gnutls_datum_t *san, unsigned raw)
2677 {
2678 	int ret;
2679 	if (type == GNUTLS_SAN_DNSNAME && !raw) {
2680 		ret = gnutls_idna_map((char*)san->data, san->size, out, 0);
2681 		if (ret < 0) {
2682 			return gnutls_assert_val(ret);
2683 		}
2684 	} else if (type == GNUTLS_SAN_RFC822NAME && !raw) {
2685 		ret = _gnutls_idna_email_map((char*)san->data, san->size, out);
2686 		if (ret < 0) {
2687 			return gnutls_assert_val(ret);
2688 		}
2689 	} else if (type == GNUTLS_SAN_URI && !raw) {
2690 		if (!_gnutls_str_is_print((char*)san->data, san->size)) {
2691 			_gnutls_debug_log("non-ASCII URIs are not supported\n");
2692 			return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
2693 		} else {
2694 			ret = _gnutls_set_strdatum(out, san->data, san->size);
2695 			if (ret < 0)
2696 				return gnutls_assert_val(ret);
2697 		}
2698 	} else {
2699 		ret = _gnutls_set_strdatum(out, san->data, san->size);
2700 		if (ret < 0)
2701 			return gnutls_assert_val(ret);
2702 	}
2703 
2704 	return 0;
2705 }
2706 
2707 /**
2708  * gnutls_x509_aia_set:
2709  * @aia: The authority info access
2710  * @oid: the type of data.
2711  * @san_type: The type of the name (of %gnutls_subject_alt_names_t)
2712  * @san: The alternative name data
2713  * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
2714  *
2715  * This function will store the specified alternative name in
2716  * the @aia type.
2717  *
2718  * Typically the value for @oid should be %GNUTLS_OID_AD_OCSP, or
2719  * %GNUTLS_OID_AD_CAISSUERS.
2720  *
2721  * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, and %GNUTLS_SAN_DNSNAME,
2722  * are converted to ACE format when necessary.
2723  *
2724  * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2725  *
2726  * Since: 3.3.0
2727  **/
gnutls_x509_aia_set(gnutls_x509_aia_t aia,const char * oid,unsigned san_type,const gnutls_datum_t * san)2728 int gnutls_x509_aia_set(gnutls_x509_aia_t aia,
2729 			const char *oid,
2730 			unsigned san_type,
2731 			const gnutls_datum_t * san)
2732 {
2733 	int ret;
2734 	void *tmp;
2735 	unsigned indx;
2736 
2737 	tmp = gnutls_realloc(aia->aia, (aia->size + 1) * sizeof(aia->aia[0]));
2738 	if (tmp == NULL) {
2739 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2740 	}
2741 	aia->aia = tmp;
2742 	indx = aia->size;
2743 
2744 	aia->aia[indx].san_type = san_type;
2745 	if (oid) {
2746 		aia->aia[indx].oid.data = (void*)gnutls_strdup(oid);
2747 		aia->aia[indx].oid.size = strlen(oid);
2748 	} else {
2749 		aia->aia[indx].oid.data = NULL;
2750 		aia->aia[indx].oid.size = 0;
2751 	}
2752 
2753 	ret = _gnutls_alt_name_process(&aia->aia[indx].san, san_type, san, 0);
2754 	if (ret < 0)
2755 		return gnutls_assert_val(ret);
2756 
2757 	aia->size++;
2758 
2759 	return 0;
2760 }
2761 
2762 
parse_aia(ASN1_TYPE c2,gnutls_x509_aia_t aia)2763 static int parse_aia(ASN1_TYPE c2, gnutls_x509_aia_t aia)
2764 {
2765 	int len;
2766 	char nptr[MAX_NAME_SIZE];
2767 	int ret, result;
2768 	char tmpoid[MAX_OID_SIZE];
2769 	void * tmp;
2770 	unsigned i, indx;
2771 
2772 	for (i = 1;; i++) {
2773 		snprintf(nptr, sizeof(nptr), "?%u.accessMethod", i);
2774 
2775 		len = sizeof(tmpoid);
2776 		result = asn1_read_value(c2, nptr, tmpoid, &len);
2777 		if (result == ASN1_VALUE_NOT_FOUND
2778 		    || result == ASN1_ELEMENT_NOT_FOUND) {
2779 			ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2780 			break;
2781 		}
2782 
2783 		if (result != ASN1_SUCCESS) {
2784 			gnutls_assert();
2785 			return _gnutls_asn2err(result);
2786 		}
2787 
2788 		indx = aia->size;
2789 		tmp = gnutls_realloc(aia->aia, (aia->size + 1) * sizeof(aia->aia[0]));
2790 		if (tmp == NULL) {
2791 			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2792 		}
2793 		aia->aia = tmp;
2794 
2795 		snprintf(nptr, sizeof(nptr), "?%u.accessLocation", i);
2796 
2797 
2798 		ret = _gnutls_parse_general_name2(c2, nptr, -1, &aia->aia[indx].san,
2799 			&aia->aia[indx].san_type, 0);
2800 		if (ret < 0)
2801 			break;
2802 
2803 		/* we do the strdup after parsing to avoid a memory leak */
2804 		aia->aia[indx].oid.data = (void*)gnutls_strdup(tmpoid);
2805 		aia->aia[indx].oid.size = strlen(tmpoid);
2806 
2807 		aia->size++;
2808 
2809 		if (aia->aia[indx].oid.data == NULL) {
2810 			gnutls_assert();
2811 			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2812 		}
2813 	}
2814 
2815 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2816 		return ret;
2817 	}
2818 
2819 	return 0;
2820 }
2821 
2822 /**
2823  * gnutls_x509_ext_import_aia:
2824  * @ext: The DER-encoded extension data
2825  * @aia: The authority info access
2826  * @flags: should be zero
2827  *
2828  * This function extracts the Authority Information Access (AIA)
2829  * extension from the provided DER-encoded data; see RFC 5280 section 4.2.2.1
2830  * for more information on the extension.  The
2831  * AIA extension holds a sequence of AccessDescription (AD) data.
2832  *
2833  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2834  *
2835  * Since: 3.3.0
2836  **/
gnutls_x509_ext_import_aia(const gnutls_datum_t * ext,gnutls_x509_aia_t aia,unsigned int flags)2837 int gnutls_x509_ext_import_aia(const gnutls_datum_t * ext,
2838 					      gnutls_x509_aia_t aia,
2839 					      unsigned int flags)
2840 {
2841 	int ret;
2842 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2843 
2844 	if (ext->size == 0 || ext->data == NULL) {
2845 		gnutls_assert();
2846 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2847 	}
2848 
2849 	ret = asn1_create_element(_gnutls_get_pkix(),
2850 				  "PKIX1.AuthorityInfoAccessSyntax", &c2);
2851 	if (ret != ASN1_SUCCESS) {
2852 		gnutls_assert();
2853 		return _gnutls_asn2err(ret);
2854 	}
2855 
2856 	ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
2857 	if (ret != ASN1_SUCCESS) {
2858 		gnutls_assert();
2859 		ret = _gnutls_asn2err(ret);
2860 		goto cleanup;
2861 	}
2862 
2863 	ret = parse_aia(c2, aia);
2864 	if (ret < 0) {
2865 		gnutls_assert();
2866 	}
2867 
2868  cleanup:
2869 	asn1_delete_structure(&c2);
2870 
2871 	return ret;
2872 
2873 }
2874 
2875 /**
2876  * gnutls_x509_ext_export_aia:
2877  * @aia: The authority info access
2878  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2879  *
2880  * This function will DER encode the Authority Information Access (AIA)
2881  * extension; see RFC 5280 section 4.2.2.1 for more information on the
2882  * extension.
2883  *
2884  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2885  *   negative error value.
2886  *
2887  * Since: 3.3.0
2888  **/
gnutls_x509_ext_export_aia(gnutls_x509_aia_t aia,gnutls_datum_t * ext)2889 int gnutls_x509_ext_export_aia(gnutls_x509_aia_t aia,
2890 					      gnutls_datum_t * ext)
2891 {
2892 	int ret, result;
2893 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2894 	unsigned int i;
2895 
2896 	ret = asn1_create_element(_gnutls_get_pkix(),
2897 				  "PKIX1.AuthorityInfoAccessSyntax", &c2);
2898 	if (ret != ASN1_SUCCESS) {
2899 		gnutls_assert();
2900 		return _gnutls_asn2err(ret);
2901 	}
2902 
2903 	/* 1. create a new element.
2904 	 */
2905 	for (i=0;i<aia->size;i++) {
2906 		result = asn1_write_value(c2, "", "NEW", 1);
2907 		if (result != ASN1_SUCCESS) {
2908 			gnutls_assert();
2909 			ret = _gnutls_asn2err(result);
2910 			goto cleanup;
2911 		}
2912 
2913 		/* 2. Add the OID.
2914 		 */
2915 		result = asn1_write_value(c2, "?LAST.accessMethod", aia->aia[i].oid.data, 1);
2916 		if (result != ASN1_SUCCESS) {
2917 			gnutls_assert();
2918 			ret = _gnutls_asn2err(result);
2919 			goto cleanup;
2920 		}
2921 
2922 		ret =
2923 		    _gnutls_write_general_name(c2,
2924 						   "?LAST.accessLocation",
2925 						   aia->aia[i].san_type,
2926 						   aia->aia[i].san.data,
2927 						   aia->aia[i].san.size);
2928 		if (ret < 0) {
2929 			gnutls_assert();
2930 			goto cleanup;
2931 		}
2932 	}
2933 
2934 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
2935 	if (ret < 0) {
2936 		gnutls_assert();
2937 		goto cleanup;
2938 	}
2939 
2940  cleanup:
2941 	asn1_delete_structure(&c2);
2942 
2943 	return ret;
2944 }
2945 
2946 
2947 struct gnutls_x509_key_purposes_st {
2948 	gnutls_datum_t oid[MAX_ENTRIES];
2949 	unsigned int size;
2950 };
2951 
2952 /**
2953  * gnutls_subject_alt_names_init:
2954  * @p: The key purposes
2955  *
2956  * This function will initialize an alternative names type.
2957  *
2958  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2959  *
2960  * Since: 3.3.0
2961  **/
gnutls_x509_key_purpose_init(gnutls_x509_key_purposes_t * p)2962 int gnutls_x509_key_purpose_init(gnutls_x509_key_purposes_t * p)
2963 {
2964 	*p = gnutls_calloc(1, sizeof(struct gnutls_x509_key_purposes_st));
2965 	if (*p == NULL) {
2966 		gnutls_assert();
2967 		return GNUTLS_E_MEMORY_ERROR;
2968 	}
2969 
2970 	return 0;
2971 }
2972 
key_purposes_deinit(gnutls_x509_key_purposes_t p)2973 static void key_purposes_deinit(gnutls_x509_key_purposes_t p)
2974 {
2975 	unsigned int i;
2976 
2977 	for (i = 0; i < p->size; i++) {
2978 		gnutls_free(p->oid[i].data);
2979 	}
2980 }
2981 
2982 /**
2983  * gnutls_x509_key_purpose_deinit:
2984  * @p: The key purposes
2985  *
2986  * This function will deinitialize a key purposes type.
2987  *
2988  * Since: 3.3.0
2989  **/
gnutls_x509_key_purpose_deinit(gnutls_x509_key_purposes_t p)2990 void gnutls_x509_key_purpose_deinit(gnutls_x509_key_purposes_t p)
2991 {
2992 	key_purposes_deinit(p);
2993 	gnutls_free(p);
2994 }
2995 
2996 /**
2997  * gnutls_x509_key_purpose_set:
2998  * @p: The key purposes
2999  * @oid: The object identifier of the key purpose
3000  *
3001  * This function will store the specified key purpose in the
3002  * purposes.
3003  *
3004  * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
3005  *
3006  * Since: 3.3.0
3007  **/
gnutls_x509_key_purpose_set(gnutls_x509_key_purposes_t p,const char * oid)3008 int gnutls_x509_key_purpose_set(gnutls_x509_key_purposes_t p, const char *oid)
3009 {
3010 	if (p->size + 1 > MAX_ENTRIES)
3011 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3012 
3013 	p->oid[p->size].data = (void*)gnutls_strdup(oid);
3014 	if (p->oid[p->size].data == NULL)
3015 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3016 
3017 	p->oid[p->size].size = strlen(oid);
3018 	p->size++;
3019 
3020 	return 0;
3021 }
3022 
3023 /**
3024  * gnutls_x509_key_purpose_get:
3025  * @p: The key purposes
3026  * @idx: The index of the key purpose to retrieve
3027  * @oid: Will hold the object identifier of the key purpose (to be treated as constant)
3028  *
3029  * This function will retrieve the specified by the index key purpose in the
3030  * purposes type. The object identifier will be a null terminated string.
3031  *
3032  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
3033  * if the index is out of bounds, otherwise a negative error value.
3034  *
3035  * Since: 3.3.0
3036  **/
gnutls_x509_key_purpose_get(gnutls_x509_key_purposes_t p,unsigned idx,gnutls_datum_t * oid)3037 int gnutls_x509_key_purpose_get(gnutls_x509_key_purposes_t p, unsigned idx, gnutls_datum_t *oid)
3038 {
3039 	if (idx >= p->size)
3040 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3041 
3042 	oid->data = p->oid[idx].data;
3043 	oid->size = p->oid[idx].size;
3044 
3045 	return 0;
3046 }
3047 
3048 /**
3049  * gnutls_x509_ext_import_key_purposes:
3050  * @ext: The DER-encoded extension data
3051  * @p: The key purposes
3052  * @flags: should be zero
3053  *
3054  * This function will extract the key purposes in the provided DER-encoded
3055  * ExtKeyUsageSyntax PKIX extension, to a %gnutls_x509_key_purposes_t type.
3056  * The data must be initialized.
3057  *
3058  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3059  *
3060  * Since: 3.3.0
3061  **/
gnutls_x509_ext_import_key_purposes(const gnutls_datum_t * ext,gnutls_x509_key_purposes_t p,unsigned int flags)3062 int gnutls_x509_ext_import_key_purposes(const gnutls_datum_t * ext,
3063 				     gnutls_x509_key_purposes_t p,
3064 				     unsigned int flags)
3065 {
3066 	char tmpstr[MAX_NAME_SIZE];
3067 	int result, ret;
3068 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3069 	gnutls_datum_t oid = {NULL, 0};
3070 	unsigned i;
3071 
3072 	result = asn1_create_element
3073 	    (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2);
3074 	if (result != ASN1_SUCCESS) {
3075 		gnutls_assert();
3076 		return _gnutls_asn2err(result);
3077 	}
3078 
3079 	result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
3080 	if (result != ASN1_SUCCESS) {
3081 		gnutls_assert();
3082 		ret = _gnutls_asn2err(result);
3083 		goto cleanup;
3084 	}
3085 
3086 	key_purposes_deinit(p);
3087 	i = 0;
3088 	p->size = 0;
3089 
3090 	for (;i<MAX_ENTRIES;i++) {
3091 		/* create a string like "?1"
3092 		 */
3093 		snprintf(tmpstr, sizeof(tmpstr), "?%u", i+1);
3094 
3095 		ret = _gnutls_x509_read_value(c2, tmpstr, &oid);
3096 		if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
3097 			break;
3098 		}
3099 
3100 		if (ret < 0) {
3101 			gnutls_assert();
3102 			goto cleanup;
3103 		}
3104 
3105 		p->oid[i].data = oid.data;
3106 		p->oid[i].size = oid.size;
3107 
3108 		oid.data = NULL;
3109 		oid.size = 0;
3110 		p->size++;
3111 	}
3112 
3113 	ret = 0;
3114  cleanup:
3115 	gnutls_free(oid.data);
3116 	asn1_delete_structure(&c2);
3117 
3118 	return ret;
3119 
3120 }
3121 
3122 /**
3123  * gnutls_x509_ext_export_key_purposes:
3124  * @p: The key purposes
3125  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
3126  *
3127  * This function will convert the key purposes type to a
3128  * DER-encoded PKIX ExtKeyUsageSyntax (2.5.29.37) extension. The output data in
3129  * @ext will be allocated using gnutls_malloc().
3130  *
3131  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3132  *
3133  * Since: 3.3.0
3134  **/
gnutls_x509_ext_export_key_purposes(gnutls_x509_key_purposes_t p,gnutls_datum_t * ext)3135 int gnutls_x509_ext_export_key_purposes(gnutls_x509_key_purposes_t p,
3136 				     gnutls_datum_t * ext)
3137 {
3138 	int result, ret;
3139 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3140 	unsigned i;
3141 
3142 	result = asn1_create_element
3143 	    (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2);
3144 	if (result != ASN1_SUCCESS) {
3145 		gnutls_assert();
3146 		return _gnutls_asn2err(result);
3147 	}
3148 
3149 	/* generate the extension.
3150 	 */
3151 	for (i=0;i<p->size;i++) {
3152 		/* 1. create a new element.
3153 		 */
3154 		result = asn1_write_value(c2, "", "NEW", 1);
3155 		if (result != ASN1_SUCCESS) {
3156 			gnutls_assert();
3157 			ret = _gnutls_asn2err(result);
3158 			goto cleanup;
3159 		}
3160 
3161 		/* 2. Add the OID.
3162 		 */
3163 		result = asn1_write_value(c2, "?LAST", p->oid[i].data, 1);
3164 		if (result != ASN1_SUCCESS) {
3165 			gnutls_assert();
3166 			ret = _gnutls_asn2err(result);
3167 			goto cleanup;
3168 		}
3169 	}
3170 
3171 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3172 	if (ret < 0) {
3173 		gnutls_assert();
3174 		goto cleanup;
3175 	}
3176 
3177 	ret = 0;
3178 
3179  cleanup:
3180 	asn1_delete_structure(&c2);
3181 	return ret;
3182 }
3183 
3184 /**
3185  * gnutls_ext_deinit:
3186  * @ext: The extensions structure
3187  *
3188  * This function will deinitialize an extensions structure.
3189  *
3190  * Since: 3.3.8
3191  **/
gnutls_x509_ext_deinit(gnutls_x509_ext_st * ext)3192 void gnutls_x509_ext_deinit(gnutls_x509_ext_st *ext)
3193 {
3194 	gnutls_free(ext->oid);
3195 	gnutls_free(ext->data.data);
3196 }
3197 
_gnutls_x509_decode_ext(const gnutls_datum_t * der,gnutls_x509_ext_st * out)3198 int _gnutls_x509_decode_ext(const gnutls_datum_t *der, gnutls_x509_ext_st *out)
3199 {
3200 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3201 	char str_critical[10];
3202 	char oid[MAX_OID_SIZE];
3203 	int result, len, ret;
3204 
3205 	memset(out, 0, sizeof(*out));
3206 
3207 	/* decode der */
3208 	result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extension", &c2);
3209 	if (result != ASN1_SUCCESS) {
3210 		gnutls_assert();
3211 		return _gnutls_asn2err(result);
3212 	}
3213 
3214 	result = _asn1_strict_der_decode(&c2, der->data, der->size, NULL);
3215 	if (result != ASN1_SUCCESS) {
3216 		gnutls_assert();
3217 		ret = _gnutls_asn2err(result);
3218 		goto cleanup;
3219 	}
3220 
3221 	len = sizeof(oid)-1;
3222 	result = asn1_read_value(c2, "extnID", oid, &len);
3223 	if (result != ASN1_SUCCESS) {
3224 		gnutls_assert();
3225 		ret = _gnutls_asn2err(result);
3226 		goto cleanup;
3227 	}
3228 
3229 	len = sizeof(str_critical)-1;
3230 	result = asn1_read_value(c2, "critical", str_critical, &len);
3231 	if (result != ASN1_SUCCESS) {
3232 		gnutls_assert();
3233 		ret = _gnutls_asn2err(result);
3234 		goto cleanup;
3235 	}
3236 
3237 	if (str_critical[0] == 'T')
3238 		out->critical = 1;
3239 	else
3240 		out->critical = 0;
3241 
3242 	ret = _gnutls_x509_read_value(c2, "extnValue", &out->data);
3243 	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
3244 		out->data.data = NULL;
3245 		out->data.size = 0;
3246 	} else if (ret < 0) {
3247 		gnutls_assert();
3248 		goto fail;
3249 	}
3250 
3251 	out->oid = gnutls_strdup(oid);
3252 	if (out->oid == NULL) {
3253 		ret = GNUTLS_E_MEMORY_ERROR;
3254 		goto fail;
3255 	}
3256 
3257 	ret = 0;
3258 	goto cleanup;
3259  fail:
3260 	memset(out, 0, sizeof(*out));
3261  cleanup:
3262 	asn1_delete_structure(&c2);
3263 	return ret;
3264 
3265 }
3266 
3267 /* flags can be zero or GNUTLS_EXT_FLAG_APPEND
3268  */
parse_tlsfeatures(ASN1_TYPE c2,gnutls_x509_tlsfeatures_t f,unsigned flags)3269 static int parse_tlsfeatures(ASN1_TYPE c2, gnutls_x509_tlsfeatures_t f, unsigned flags)
3270 {
3271 	char nptr[MAX_NAME_SIZE];
3272 	int result;
3273 	unsigned i, indx, j;
3274 	unsigned int feature;
3275 
3276 	if (!(flags & GNUTLS_EXT_FLAG_APPEND))
3277 		f->size = 0;
3278 
3279 	for (i = 1;; i++) {
3280 		unsigned skip = 0;
3281 		snprintf(nptr, sizeof(nptr), "?%u", i);
3282 
3283 		result = _gnutls_x509_read_uint(c2, nptr, &feature);
3284 
3285 		if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND || result == GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
3286 			break;
3287 		}
3288 		else if (result != GNUTLS_E_SUCCESS) {
3289 			gnutls_assert();
3290 			return _gnutls_asn2err(result);
3291 		}
3292 
3293 		if (feature > UINT16_MAX) {
3294 			gnutls_assert();
3295 			return GNUTLS_E_CERTIFICATE_ERROR;
3296 		}
3297 
3298 		/* skip duplicates */
3299 		for (j=0;j<f->size;j++) {
3300 			if (f->feature[j] == feature) {
3301 				skip = 1;
3302 				break;
3303 			}
3304 		}
3305 
3306 		if (!skip) {
3307 			if (f->size >= sizeof(f->feature)/sizeof(f->feature[0])) {
3308 				gnutls_assert();
3309 				return GNUTLS_E_INTERNAL_ERROR;
3310 			}
3311 
3312 			indx = f->size;
3313 			f->feature[indx] = feature;
3314 			f->size++;
3315 		}
3316 	}
3317 
3318 	return 0;
3319 }
3320 
3321 /**
3322  * gnutls_x509_ext_import_tlsfeatures:
3323  * @ext: The DER-encoded extension data
3324  * @f: The features structure
3325  * @flags: zero or %GNUTLS_EXT_FLAG_APPEND
3326  *
3327  * This function will export the features in the provided DER-encoded
3328  * TLS Features PKIX extension, to a %gnutls_x509_tlsfeatures_t type. @f
3329  * must be initialized.
3330  *
3331  * When the @flags is set to %GNUTLS_EXT_FLAG_APPEND,
3332  * then if the @features structure is empty this function will behave
3333  * identically as if the flag was not set. Otherwise if there are elements
3334  * in the @features structure then they will be merged with.
3335  *
3336  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3337  *
3338  * Since: 3.5.1
3339  **/
gnutls_x509_ext_import_tlsfeatures(const gnutls_datum_t * ext,gnutls_x509_tlsfeatures_t f,unsigned int flags)3340 int gnutls_x509_ext_import_tlsfeatures(const gnutls_datum_t * ext,
3341 				       gnutls_x509_tlsfeatures_t f,
3342 				       unsigned int flags)
3343 {
3344 	int ret;
3345 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3346 
3347 	if (ext->size == 0 || ext->data == NULL) {
3348 		gnutls_assert();
3349 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3350 	}
3351 
3352 	ret = asn1_create_element(_gnutls_get_pkix(),
3353 				  "PKIX1.TlsFeatures", &c2);
3354 	if (ret != ASN1_SUCCESS) {
3355 		gnutls_assert();
3356 		return _gnutls_asn2err(ret);
3357 	}
3358 
3359 	ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
3360 	if (ret != ASN1_SUCCESS) {
3361 		gnutls_assert();
3362 		ret = _gnutls_asn2err(ret);
3363 		goto cleanup;
3364 	}
3365 
3366 	ret = parse_tlsfeatures(c2, f, flags);
3367 	if (ret < 0) {
3368 		gnutls_assert();
3369 	}
3370 
3371  cleanup:
3372 	asn1_delete_structure(&c2);
3373 
3374 	return ret;
3375 }
3376 
3377 /**
3378  * gnutls_x509_ext_export_tlsfeatures:
3379  * @f: The features structure
3380  * @ext: The DER-encoded extension data; must be freed using gnutls_free().
3381  *
3382  * This function will convert the provided TLS features structure structure to a
3383  * DER-encoded TLS features PKIX extension. The output data in @ext will be allocated using
3384  * gnutls_malloc().
3385  *
3386  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3387  *
3388  * Since: 3.5.1
3389  **/
gnutls_x509_ext_export_tlsfeatures(gnutls_x509_tlsfeatures_t f,gnutls_datum_t * ext)3390 int gnutls_x509_ext_export_tlsfeatures(gnutls_x509_tlsfeatures_t f,
3391 					  gnutls_datum_t * ext)
3392 {
3393 	if (f == NULL) {
3394 		gnutls_assert();
3395 		return GNUTLS_E_INVALID_REQUEST;
3396 	}
3397 
3398 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
3399 	int ret;
3400 	unsigned i;
3401 
3402 	ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.TlsFeatures", &c2);
3403 	if (ret != ASN1_SUCCESS) {
3404 		gnutls_assert();
3405 		return _gnutls_asn2err(ret);
3406 	}
3407 
3408 	for (i = 0; i < f->size; ++i) {
3409 
3410 		ret = asn1_write_value(c2, "", "NEW", 1);
3411 		if (ret != ASN1_SUCCESS) {
3412 			gnutls_assert();
3413 			ret = _gnutls_asn2err(ret);
3414 			goto cleanup;
3415 		}
3416 
3417 		ret = _gnutls_x509_write_uint32(c2, "?LAST", f->feature[i]);
3418 		if (ret != GNUTLS_E_SUCCESS) {
3419 			gnutls_assert();
3420 			goto cleanup;
3421 		}
3422 	}
3423 
3424 	ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3425 	if (ret < 0) {
3426 		gnutls_assert();
3427 		goto cleanup;
3428 	}
3429 
3430 	ret = 0;
3431 
3432  cleanup:
3433 	asn1_delete_structure(&c2);
3434 	return ret;
3435 }
3436 
3437 /**
3438  * gnutls_x509_tlsfeatures_add:
3439  * @f: The TLS features
3440  * @feature: The feature to add
3441  *
3442  * This function will append a feature to the X.509 TLS features
3443  * extension structure.
3444  *
3445  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
3446  *   otherwise a negative error value.
3447  *
3448  * Since: 3.5.1
3449  **/
gnutls_x509_tlsfeatures_add(gnutls_x509_tlsfeatures_t f,unsigned int feature)3450 int gnutls_x509_tlsfeatures_add(gnutls_x509_tlsfeatures_t f, unsigned int feature)
3451 {
3452 	if (f == NULL) {
3453 		gnutls_assert();
3454 		return GNUTLS_E_INVALID_REQUEST;
3455 	}
3456 
3457 	if (feature > UINT16_MAX)
3458 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3459 
3460 	if (f->size >= sizeof(f->feature)/sizeof(f->feature[0]))
3461 		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
3462 
3463 	f->feature[f->size++] = feature;
3464 
3465 	return 0;
3466 }
3467