1 /*
2  * Copyright (C) 2003-2018 Free Software Foundation, Inc.
3  * Copyright (C) 2018 Red Hat, Inc.
4  *
5  * Authors: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <https://www.gnu.org/licenses/>
21  *
22  */
23 
24 /* Functions on X.509 Certificate parsing
25  */
26 
27 #include "gnutls_int.h"
28 #include <datum.h>
29 #include <global.h>
30 #include "errors.h"
31 #include <common.h>
32 #include <gnutls/x509-ext.h>
33 #include <x509.h>
34 #include <x509_b64.h>
35 #include <x509_int.h>
36 #include <libtasn1.h>
37 #include <pk.h>
38 #include <pkcs11_int.h>
39 #include "urls.h"
40 #include "system-keys.h"
41 #include "hash.h"
42 #include "hash-pjw-bare.h"
43 
crt_reinit(gnutls_x509_crt_t crt)44 static int crt_reinit(gnutls_x509_crt_t crt)
45 {
46 	int result;
47 
48 	_gnutls_free_datum(&crt->der);
49 	crt->raw_dn.size = 0;
50 	crt->raw_issuer_dn.size = 0;
51 	crt->raw_spki.size = 0;
52 
53 	asn1_delete_structure(&crt->cert);
54 
55 	result = asn1_create_element(_gnutls_get_pkix(),
56 				     "PKIX1.Certificate",
57 				     &crt->cert);
58 	if (result != ASN1_SUCCESS) {
59 		result = _gnutls_asn2err(result);
60 		gnutls_assert();
61 		return result;
62 	}
63 
64 	gnutls_subject_alt_names_deinit(crt->san);
65 	result = gnutls_subject_alt_names_init(&crt->san);
66 	if (result < 0) {
67 		gnutls_assert();
68 		return result;
69 	}
70 
71 	gnutls_subject_alt_names_deinit(crt->ian);
72 	result = gnutls_subject_alt_names_init(&crt->ian);
73 	if (result < 0) {
74 		gnutls_assert();
75 		return result;
76 	}
77 
78 	return 0;
79 }
80 
81 /**
82  * gnutls_x509_crt_equals - This function compares two gnutls_x509_crt_t certificates
83  * @cert1: The first certificate
84  * @cert2: The second certificate
85  *
86  * This function will compare two X.509 certificate structures.
87  *
88  * Returns: On equality non-zero is returned, otherwise zero.
89  *
90  * Since: 3.5.0
91  **/
gnutls_x509_crt_equals(gnutls_x509_crt_t cert1,gnutls_x509_crt_t cert2)92 unsigned gnutls_x509_crt_equals(gnutls_x509_crt_t cert1,
93 				gnutls_x509_crt_t cert2)
94 {
95 	int ret;
96 	bool result;
97 
98 	if (cert1->modified == 0 && cert2->modified == 0 &&
99 	    cert1->raw_dn.size > 0 && cert2->raw_dn.size > 0) {
100 		ret = _gnutls_is_same_dn(cert1, cert2);
101 		if (ret == 0)
102 			return 0;
103 	}
104 
105 	if (cert1->der.size == 0 || cert2->der.size == 0 ||
106 	    cert1->modified != 0 || cert2->modified != 0) {
107 		gnutls_datum_t tmp1, tmp2;
108 
109 		/* on uninitialized or modified certificates, we have to re-encode */
110 		ret =
111 		    gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER, &tmp1);
112 		if (ret < 0)
113 			return gnutls_assert_val(0);
114 
115 		ret =
116 		    gnutls_x509_crt_export2(cert2, GNUTLS_X509_FMT_DER, &tmp2);
117 		if (ret < 0) {
118 			gnutls_free(tmp1.data);
119 			return gnutls_assert_val(0);
120 		}
121 
122 		if ((tmp1.size == tmp2.size) &&
123 		    (memcmp(tmp1.data, tmp2.data, tmp1.size) == 0))
124 			result = 1;
125 		else
126 			result = 0;
127 
128 		gnutls_free(tmp1.data);
129 		gnutls_free(tmp2.data);
130 	} else {
131 		if ((cert1->der.size == cert2->der.size) &&
132 		    (memcmp(cert1->der.data, cert2->der.data, cert1->der.size) == 0))
133 			result = 1;
134 		else
135 			result = 0;
136 	}
137 
138 	return result;
139 }
140 
141 /**
142  * gnutls_x509_crt_equals2 - This function compares a gnutls_x509_crt_t cert with DER data
143  * @cert1: The first certificate
144  * @der: A DER encoded certificate
145  *
146  * This function will compare an X.509 certificate structures, with DER
147  * encoded certificate data.
148  *
149  * Returns: On equality non-zero is returned, otherwise zero.
150  *
151  * Since: 3.5.0
152  **/
153 unsigned
gnutls_x509_crt_equals2(gnutls_x509_crt_t cert1,const gnutls_datum_t * der)154 gnutls_x509_crt_equals2(gnutls_x509_crt_t cert1,
155 			const gnutls_datum_t * der)
156 {
157 	bool result;
158 
159 	if (cert1 == NULL || der == NULL)
160 		return 0;
161 
162 	if (cert1->der.size == 0 || cert1->modified) {
163 		gnutls_datum_t tmp1;
164 		int ret;
165 
166 		/* on uninitialized or modified certificates, we have to re-encode */
167 		ret =
168 		    gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER, &tmp1);
169 		if (ret < 0)
170 			return gnutls_assert_val(0);
171 
172 		if ((tmp1.size == der->size) &&
173 		    (memcmp(tmp1.data, der->data, tmp1.size) == 0))
174 			result = 1;
175 		else
176 			result = 0;
177 
178 		gnutls_free(tmp1.data);
179 	} else {
180 		if ((cert1->der.size == der->size) &&
181 		    (memcmp(cert1->der.data, der->data, cert1->der.size) == 0))
182 			result = 1;
183 		else
184 			result = 0;
185 	}
186 
187 	return result;
188 }
189 
190 /**
191  * gnutls_x509_crt_init:
192  * @cert: A pointer to the type to be initialized
193  *
194  * This function will initialize an X.509 certificate structure.
195  *
196  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
197  *   negative error value.
198  **/
gnutls_x509_crt_init(gnutls_x509_crt_t * cert)199 int gnutls_x509_crt_init(gnutls_x509_crt_t * cert)
200 {
201 	gnutls_x509_crt_t tmp;
202 	int result;
203 
204 	FAIL_IF_LIB_ERROR;
205 
206 	tmp =
207 	    gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
208 
209 	if (!tmp)
210 		return GNUTLS_E_MEMORY_ERROR;
211 
212 	result = asn1_create_element(_gnutls_get_pkix(),
213 				     "PKIX1.Certificate", &tmp->cert);
214 	if (result != ASN1_SUCCESS) {
215 		gnutls_assert();
216 		gnutls_free(tmp);
217 		return _gnutls_asn2err(result);
218 	}
219 
220 	result = gnutls_subject_alt_names_init(&tmp->san);
221 	if (result < 0) {
222 		gnutls_assert();
223 		asn1_delete_structure(&tmp->cert);
224 		gnutls_free(tmp);
225 		return result;
226 	}
227 
228 	result = gnutls_subject_alt_names_init(&tmp->ian);
229 	if (result < 0) {
230 		gnutls_assert();
231 		asn1_delete_structure(&tmp->cert);
232 		gnutls_subject_alt_names_deinit(tmp->san);
233 		gnutls_free(tmp);
234 		return result;
235 	}
236 
237 	/* If you add anything here, be sure to check if it has to be added
238 	   to gnutls_x509_crt_import as well. */
239 
240 	*cert = tmp;
241 
242 	return 0;		/* success */
243 }
244 
245 /*-
246  * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t type
247  * @dest: The data where to copy
248  * @src: The data to be copied
249  * @flags: zero or CRT_CPY_FAST
250  *
251  * This function will copy an X.509 certificate structure.
252  *
253  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
254  *   negative error value.
255  -*/
_gnutls_x509_crt_cpy(gnutls_x509_crt_t dest,gnutls_x509_crt_t src)256 int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
257 {
258 	int ret;
259 	gnutls_datum_t tmp;
260 	unsigned dealloc = 0;
261 
262 	if (src->der.size == 0 || src->modified) {
263 		ret =
264 		    gnutls_x509_crt_export2(src, GNUTLS_X509_FMT_DER, &tmp);
265 		if (ret < 0)
266 			return gnutls_assert_val(ret);
267 		dealloc = 1;
268 	} else {
269 		tmp.data = src->der.data;
270 		tmp.size = src->der.size;
271 	}
272 
273 	ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
274 
275 	if (dealloc) {
276 		gnutls_free(tmp.data);
277 	}
278 
279 	if (ret < 0)
280 		return gnutls_assert_val(ret);
281 
282 	return 0;
283 }
284 
285 /**
286  * gnutls_x509_crt_deinit:
287  * @cert: The data to be deinitialized
288  *
289  * This function will deinitialize a certificate structure.
290  **/
gnutls_x509_crt_deinit(gnutls_x509_crt_t cert)291 void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert)
292 {
293 	if (!cert)
294 		return;
295 
296 	if (cert->cert)
297 		asn1_delete_structure(&cert->cert);
298 	gnutls_free(cert->der.data);
299 	gnutls_subject_alt_names_deinit(cert->san);
300 	gnutls_subject_alt_names_deinit(cert->ian);
301 	gnutls_free(cert);
302 }
303 
compare_sig_algorithm(gnutls_x509_crt_t cert)304 static int compare_sig_algorithm(gnutls_x509_crt_t cert)
305 {
306 	int ret, len1, len2, result;
307 	char oid1[MAX_OID_SIZE];
308 	char oid2[MAX_OID_SIZE];
309 	gnutls_datum_t sp1 = {NULL, 0};
310 	gnutls_datum_t sp2 = {NULL, 0};
311 	unsigned empty1 = 0, empty2 = 0;
312 
313 	len1 = sizeof(oid1);
314 	result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm", oid1, &len1);
315 	if (result != ASN1_SUCCESS) {
316 		gnutls_assert();
317 		return _gnutls_asn2err(result);
318 	}
319 
320 	len2 = sizeof(oid2);
321 	result = asn1_read_value(cert->cert, "tbsCertificate.signature.algorithm", oid2, &len2);
322 	if (result != ASN1_SUCCESS) {
323 		gnutls_assert();
324 		return _gnutls_asn2err(result);
325 	}
326 
327 	if (len1 != len2 || memcmp(oid1, oid2, len1) != 0) {
328 		_gnutls_debug_log("signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n",
329 			oid1, oid2);
330 		gnutls_assert();
331 		return GNUTLS_E_CERTIFICATE_ERROR;
332 	}
333 
334 	/* compare the parameters */
335 	ret = _gnutls_x509_read_value(cert->cert, "signatureAlgorithm.parameters", &sp1);
336 	if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
337 		empty1 = 1;
338 	} else if (ret < 0) {
339 		gnutls_assert();
340 		return ret;
341 	}
342 
343 	ret = _gnutls_x509_read_value(cert->cert, "tbsCertificate.signature.parameters", &sp2);
344 	if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
345 		empty2 = 1;
346 	} else if (ret < 0) {
347 		gnutls_assert();
348 		return ret;
349 	}
350 
351 	/* handle equally empty parameters with missing parameters */
352 	if (sp1.size == 2 && memcmp(sp1.data, "\x05\x00", 2) == 0) {
353 		empty1 = 1;
354 		_gnutls_free_datum(&sp1);
355 	}
356 
357 	if (sp2.size == 2 && memcmp(sp2.data, "\x05\x00", 2) == 0) {
358 		empty2 = 1;
359 		_gnutls_free_datum(&sp2);
360 	}
361 
362 	if (empty1 != empty2 ||
363 	    sp1.size != sp2.size ||
364 	    (sp1.size > 0 && memcmp(sp1.data, sp2.data, sp1.size) != 0)) {
365 		gnutls_assert();
366 		ret = GNUTLS_E_CERTIFICATE_ERROR;
367 		goto cleanup;
368 	}
369 
370 	ret = 0;
371  cleanup:
372 	_gnutls_free_datum(&sp1);
373 	_gnutls_free_datum(&sp2);
374 	return ret;
375 }
376 
cache_alt_names(gnutls_x509_crt_t cert)377 static int cache_alt_names(gnutls_x509_crt_t cert)
378 {
379 	gnutls_datum_t tmpder = {NULL, 0};
380 	int ret;
381 
382 	/* pre-parse subject alt name */
383 	ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.17", 0, &tmpder, NULL);
384 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
385 		gnutls_free(tmpder.data);
386 		return gnutls_assert_val(ret);
387 	}
388 
389 	if (ret >= 0) {
390 		ret = gnutls_x509_ext_import_subject_alt_names(&tmpder, cert->san, 0);
391 		gnutls_free(tmpder.data);
392 		if (ret < 0)
393 			return gnutls_assert_val(ret);
394 	}
395 
396 	ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.18", 0, &tmpder, NULL);
397 	if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
398 		return gnutls_assert_val(ret);
399 
400 	if (ret >= 0) {
401 		ret = gnutls_x509_ext_import_subject_alt_names(&tmpder, cert->ian, 0);
402 		gnutls_free(tmpder.data);
403 		if (ret < 0)
404 			return gnutls_assert_val(ret);
405 	}
406 
407 	return 0;
408 }
409 
hcomparator(const void * v1,const void * v2)410 static bool hcomparator(const void *v1, const void *v2)
411 {
412 	return (strcmp(v1, v2)==0);
413 }
414 
hhasher(const void * entry,size_t n)415 static size_t hhasher(const void *entry, size_t n)
416 {
417 	const char *e = entry;
418 	if (e == NULL || e[0] == 0)
419 		return 0;
420 
421 	return hash_pjw_bare(e, strlen(e)) % n;
422 }
423 
_gnutls_check_cert_sanity(gnutls_x509_crt_t cert)424 int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert)
425 {
426 	int ret = 0, version;
427 	gnutls_datum_t exts;
428 	Hash_table *htable = NULL;
429 
430 	if (cert->flags & GNUTLS_X509_CRT_FLAG_IGNORE_SANITY)
431 		return 0;
432 
433 	/* enforce the rule that only version 3 certificates carry extensions */
434 	ret = gnutls_x509_crt_get_version(cert);
435 	if (ret < 0) {
436 		return gnutls_assert_val(ret);
437 	}
438 
439 	version = ret;
440 
441 	if (version < 3) {
442 		if (!cert->modified) {
443 			ret = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
444 				"tbsCertificate.extensions", &exts);
445 			if (ret >= 0 && exts.size > 0) {
446 				_gnutls_debug_log("error: extensions present in certificate with version %d\n", version);
447 				return gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
448 			}
449 		} else {
450 			if (cert->use_extensions) {
451 				_gnutls_debug_log("error: extensions set in certificate with version %d\n", version);
452 				return gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
453 			}
454 		}
455 	} else {
456 		/* Version is >= 3; ensure no duplicate extensions are
457 		 * present. */
458 		unsigned i;
459 		char oid[MAX_OID_SIZE];
460 		size_t oid_size;
461 		char *o;
462 
463 		htable = hash_initialize(16, NULL, hhasher, hcomparator, gnutls_free);
464 		if (htable == NULL)
465 			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
466 
467 		for (i=0;;i++) {
468 			oid_size = sizeof(oid);
469 			ret = gnutls_x509_crt_get_extension_info(cert, i, oid, &oid_size, NULL);
470 			if (ret < 0) {
471 				if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
472 					break;
473 				gnutls_assert();
474 				goto cleanup;
475 			}
476 			o = gnutls_strdup(oid);
477 			if (o == NULL) {
478 				ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
479 				goto cleanup;
480 			}
481 
482 			ret = hash_insert_if_absent(htable, o, NULL);
483 			if (ret == -1) {
484 				gnutls_free(o);
485 				ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
486 				goto cleanup;
487 			} else if (ret == 0) {
488 				/* duplicate */
489 				gnutls_free(o);
490 				_gnutls_debug_log("error: duplicate extension (%s) detected\n", oid);
491 				ret = gnutls_assert_val(GNUTLS_E_X509_DUPLICATE_EXTENSION);
492 				goto cleanup;
493 			}
494 		}
495 
496 		hash_free(htable);
497 		htable = NULL;
498 	}
499 
500 	if (version < 2) {
501 		char id[128];
502 		size_t id_size;
503 
504 		id_size = sizeof(id);
505 		ret = gnutls_x509_crt_get_subject_unique_id(cert, id, &id_size);
506 		if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
507 			_gnutls_debug_log("error: subjectUniqueID present in certificate with version %d\n", version);
508 			ret = gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
509 			goto cleanup;
510 		}
511 
512 		id_size = sizeof(id);
513 		ret = gnutls_x509_crt_get_issuer_unique_id(cert, id, &id_size);
514 		if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
515 			_gnutls_debug_log("error: subjectUniqueID present in certificate with version %d\n", version);
516 			ret = gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
517 			goto cleanup;
518 		}
519 	}
520 
521 	if (gnutls_x509_crt_get_expiration_time(cert) == -1 ||
522 	    gnutls_x509_crt_get_activation_time(cert) == -1) {
523 		_gnutls_debug_log("error: invalid expiration or activation time in certificate\n");
524 		ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_TIME_ERROR);
525 		goto cleanup;
526 	}
527 
528 	ret = 0;
529 
530  cleanup:
531 	if (htable)
532 		hash_free(htable);
533 	return ret;
534 }
535 
536 /**
537  * gnutls_x509_crt_import:
538  * @cert: The data to store the parsed certificate.
539  * @data: The DER or PEM encoded certificate.
540  * @format: One of DER or PEM
541  *
542  * This function will convert the given DER or PEM encoded Certificate
543  * to the native gnutls_x509_crt_t format. The output will be stored
544  * in @cert.
545  *
546  * If the Certificate is PEM encoded it should have a header of "X509
547  * CERTIFICATE", or "CERTIFICATE".
548  *
549  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
550  *   negative error value.
551  **/
552 int
gnutls_x509_crt_import(gnutls_x509_crt_t cert,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format)553 gnutls_x509_crt_import(gnutls_x509_crt_t cert,
554 		       const gnutls_datum_t * data,
555 		       gnutls_x509_crt_fmt_t format)
556 {
557 	int result;
558 
559 	if (cert == NULL) {
560 		gnutls_assert();
561 		return GNUTLS_E_INVALID_REQUEST;
562 	}
563 
564 	if (cert->expanded) {
565 		/* Any earlier _asn1_strict_der_decode will modify the ASN.1
566 		   structure, so we need to replace it with a fresh
567 		   structure. */
568 		result = crt_reinit(cert);
569 		if (result < 0) {
570 			gnutls_assert();
571 			goto cleanup;
572 		}
573 	}
574 
575 	/* If the Certificate is in PEM format then decode it
576 	 */
577 	if (format == GNUTLS_X509_FMT_PEM) {
578 		/* Try the first header */
579 		result =
580 		    _gnutls_fbase64_decode(PEM_X509_CERT2, data->data,
581 					   data->size, &cert->der);
582 
583 		if (result < 0) {
584 			/* try for the second header */
585 			result =
586 			    _gnutls_fbase64_decode(PEM_X509_CERT,
587 						   data->data, data->size,
588 						   &cert->der);
589 
590 			if (result < 0) {
591 				gnutls_assert();
592 				return result;
593 			}
594 		}
595 	} else {
596 		result = _gnutls_set_datum(&cert->der, data->data, data->size);
597 		if (result < 0) {
598 			gnutls_assert();
599 			return result;
600 		}
601 	}
602 
603 	cert->expanded = 1;
604 	cert->modified = 0;
605 
606 	result =
607 	    _asn1_strict_der_decode(&cert->cert, cert->der.data, cert->der.size, NULL);
608 	if (result != ASN1_SUCCESS) {
609 		result = _gnutls_asn2err(result);
610 		gnutls_assert();
611 		goto cleanup;
612 	}
613 
614 	result = compare_sig_algorithm(cert);
615 	if (result < 0) {
616 		gnutls_assert();
617 		goto cleanup;
618 	}
619 
620 	/* The following do not allocate but rather point to DER data */
621 	result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
622 					  "tbsCertificate.issuer.rdnSequence",
623 					  &cert->raw_issuer_dn);
624 	if (result < 0) {
625 		gnutls_assert();
626 		goto cleanup;
627 	}
628 
629 	result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
630 					  "tbsCertificate.subject.rdnSequence",
631 					  &cert->raw_dn);
632 	if (result < 0) {
633 		gnutls_assert();
634 		goto cleanup;
635 	}
636 
637 	result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
638 					  "tbsCertificate.subjectPublicKeyInfo",
639 					  &cert->raw_spki);
640 	if (result < 0) {
641 		gnutls_assert();
642 		goto cleanup;
643 	}
644 
645 	result = cache_alt_names(cert);
646 	if (result < 0) {
647 		gnutls_assert();
648 		goto cleanup;
649 	}
650 
651 	result = _gnutls_check_cert_sanity(cert);
652 	if (result < 0) {
653 		gnutls_assert();
654 		goto cleanup;
655 	}
656 
657 	/* Since we do not want to disable any extension
658 	 */
659 	cert->use_extensions = 1;
660 
661 	return 0;
662 
663       cleanup:
664 	_gnutls_free_datum(&cert->der);
665 	return result;
666 }
667 
668 
669 /**
670  * gnutls_x509_crt_get_issuer_dn:
671  * @cert: should contain a #gnutls_x509_crt_t type
672  * @buf: a pointer to a structure to hold the name (may be null)
673  * @buf_size: initially holds the size of @buf
674  *
675  * This function will copy the name of the Certificate issuer in the
676  * provided buffer. The name will be in the form
677  * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
678  * will be ASCII or UTF-8 encoded, depending on the certificate data.
679  *
680  * If @buf is null then only the size will be filled.
681  *
682  * This function does not output a fully RFC4514 compliant string, if
683  * that is required see gnutls_x509_crt_get_issuer_dn3().
684  *
685  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
686  *   long enough, and in that case the @buf_size will be updated
687  *   with the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if
688  *   the DN does not exist, or another error value on error. On success 0 is returned.
689  **/
690 int
gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert,char * buf,size_t * buf_size)691 gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert, char *buf,
692 			      size_t * buf_size)
693 {
694 	if (cert == NULL) {
695 		gnutls_assert();
696 		return GNUTLS_E_INVALID_REQUEST;
697 	}
698 
699 	return _gnutls_x509_parse_dn(cert->cert,
700 				     "tbsCertificate.issuer.rdnSequence",
701 				     buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
702 }
703 
704 /**
705  * gnutls_x509_crt_get_issuer_dn2:
706  * @cert: should contain a #gnutls_x509_crt_t type
707  * @dn: a pointer to a structure to hold the name
708  *
709  * This function will allocate buffer and copy the name of issuer of the Certificate.
710  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
711  * described in RFC4514. The output string will be ASCII or UTF-8
712  * encoded, depending on the certificate data.
713  *
714  * This function does not output a fully RFC4514 compliant string, if
715  * that is required see gnutls_x509_crt_get_issuer_dn3().
716  *
717  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
718  *   negative error value.
719  *
720  * Since: 3.1.10
721  **/
722 int
gnutls_x509_crt_get_issuer_dn2(gnutls_x509_crt_t cert,gnutls_datum_t * dn)723 gnutls_x509_crt_get_issuer_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
724 {
725 	if (cert == NULL) {
726 		gnutls_assert();
727 		return GNUTLS_E_INVALID_REQUEST;
728 	}
729 
730 	return _gnutls_x509_get_dn(cert->cert,
731 				   "tbsCertificate.issuer.rdnSequence",
732 				   dn, GNUTLS_X509_DN_FLAG_COMPAT);
733 }
734 
735 /**
736  * gnutls_x509_crt_get_issuer_dn3:
737  * @cert: should contain a #gnutls_x509_crt_t type
738  * @dn: a pointer to a structure to hold the name
739  * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
740  *
741  * This function will allocate buffer and copy the name of issuer of the Certificate.
742  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
743  * described in RFC4514. The output string will be ASCII or UTF-8
744  * encoded, depending on the certificate data.
745  *
746  * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
747  * format will match the format output by previous to 3.5.6 versions of GnuTLS
748  * which was not not fully RFC4514-compliant.
749  *
750  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
751  *   negative error value.
752  *
753  * Since: 3.5.7
754  **/
755 int
gnutls_x509_crt_get_issuer_dn3(gnutls_x509_crt_t cert,gnutls_datum_t * dn,unsigned flags)756 gnutls_x509_crt_get_issuer_dn3(gnutls_x509_crt_t cert, gnutls_datum_t *dn, unsigned flags)
757 {
758 	if (cert == NULL) {
759 		gnutls_assert();
760 		return GNUTLS_E_INVALID_REQUEST;
761 	}
762 
763 	return _gnutls_x509_get_dn(cert->cert,
764 				   "tbsCertificate.issuer.rdnSequence",
765 				   dn, flags);
766 }
767 
768 /**
769  * gnutls_x509_crt_get_issuer_dn_by_oid:
770  * @cert: should contain a #gnutls_x509_crt_t type
771  * @oid: holds an Object Identified in null terminated string
772  * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
773  * @raw_flag: If non-zero returns the raw DER data of the DN part.
774  * @buf: a pointer to a structure to hold the name (may be null)
775  * @buf_size: initially holds the size of @buf
776  *
777  * This function will extract the part of the name of the Certificate
778  * issuer specified by the given OID. The output, if the raw flag is not
779  * used, will be encoded as described in RFC4514. Thus a string that is
780  * ASCII or UTF-8 encoded, depending on the certificate data.
781  *
782  * Some helper macros with popular OIDs can be found in gnutls/x509.h
783  * If raw flag is (0), this function will only return known OIDs as
784  * text. Other OIDs will be DER encoded, as described in RFC4514 --
785  * in hex format with a '#' prefix.  You can check about known OIDs
786  * using gnutls_x509_dn_oid_known().
787  *
788  * If @buf is null then only the size will be filled. If the @raw_flag
789  * is not specified the output is always null terminated, although the
790  * @buf_size will not include the null character.
791  *
792  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
793  *   long enough, and in that case the @buf_size will be updated with
794  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
795  *   are no data in the current index. On success 0 is returned.
796  **/
797 int
gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,const char * oid,unsigned indx,unsigned int raw_flag,void * buf,size_t * buf_size)798 gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
799 				     const char *oid, unsigned indx,
800 				     unsigned int raw_flag, void *buf,
801 				     size_t * buf_size)
802 {
803 	gnutls_datum_t td;
804 	int ret;
805 
806 	if (cert == NULL) {
807 		gnutls_assert();
808 		return GNUTLS_E_INVALID_REQUEST;
809 	}
810 
811 	ret = _gnutls_x509_parse_dn_oid(cert->cert,
812 					"tbsCertificate.issuer.rdnSequence",
813 					oid, indx, raw_flag, &td);
814 	if (ret < 0)
815 		return gnutls_assert_val(ret);
816 
817 	return _gnutls_strdatum_to_buf(&td, buf, buf_size);
818 }
819 
820 /**
821  * gnutls_x509_crt_get_issuer_dn_oid:
822  * @cert: should contain a #gnutls_x509_crt_t type
823  * @indx: This specifies which OID to return. Use (0) to get the first one.
824  * @oid: a pointer to a buffer to hold the OID (may be null)
825  * @oid_size: initially holds the size of @oid
826  *
827  * This function will extract the OIDs of the name of the Certificate
828  * issuer specified by the given index.
829  *
830  * If @oid is null then only the size will be filled. The @oid
831  * returned will be null terminated, although @oid_size will not
832  * account for the trailing null.
833  *
834  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
835  *   long enough, and in that case the @buf_size will be updated with
836  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
837  *   are no data in the current index. On success 0 is returned.
838  **/
839 int
gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,unsigned indx,void * oid,size_t * oid_size)840 gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,
841 				  unsigned indx, void *oid, size_t * oid_size)
842 {
843 	if (cert == NULL) {
844 		gnutls_assert();
845 		return GNUTLS_E_INVALID_REQUEST;
846 	}
847 
848 	return _gnutls_x509_get_dn_oid(cert->cert,
849 				       "tbsCertificate.issuer.rdnSequence",
850 				       indx, oid, oid_size);
851 }
852 
853 /**
854  * gnutls_x509_crt_get_dn:
855  * @cert: should contain a #gnutls_x509_crt_t type
856  * @buf: a pointer to a structure to hold the name (may be null)
857  * @buf_size: initially holds the size of @buf
858  *
859  * This function will copy the name of the Certificate in the provided
860  * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
861  * described in RFC4514. The output string will be ASCII or UTF-8
862  * encoded, depending on the certificate data.
863  *
864  * If @buf is null then only the size will be filled.
865  *
866  * This function does not output a fully RFC4514 compliant string, if
867  * that is required see gnutls_x509_crt_get_dn3().
868  *
869  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
870  *   long enough, and in that case the @buf_size will be updated
871  *   with the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if
872  *   the DN does not exist, or another error value on error. On success 0 is returned.
873  **/
874 int
gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert,char * buf,size_t * buf_size)875 gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert, char *buf,
876 		       size_t * buf_size)
877 {
878 	if (cert == NULL) {
879 		gnutls_assert();
880 		return GNUTLS_E_INVALID_REQUEST;
881 	}
882 
883 	return _gnutls_x509_parse_dn(cert->cert,
884 				     "tbsCertificate.subject.rdnSequence",
885 				     buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
886 }
887 
888 /**
889  * gnutls_x509_crt_get_dn2:
890  * @cert: should contain a #gnutls_x509_crt_t type
891  * @dn: a pointer to a structure to hold the name
892  *
893  * This function will allocate buffer and copy the name of the Certificate.
894  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
895  * described in RFC4514. The output string will be ASCII or UTF-8
896  * encoded, depending on the certificate data.
897  *
898  * This function does not output a fully RFC4514 compliant string, if
899  * that is required see gnutls_x509_crt_get_dn3().
900  *
901  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
902  *   negative error value.
903  *
904  * Since: 3.1.10
905  **/
gnutls_x509_crt_get_dn2(gnutls_x509_crt_t cert,gnutls_datum_t * dn)906 int gnutls_x509_crt_get_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
907 {
908 	if (cert == NULL) {
909 		gnutls_assert();
910 		return GNUTLS_E_INVALID_REQUEST;
911 	}
912 
913 	return _gnutls_x509_get_dn(cert->cert,
914 				   "tbsCertificate.subject.rdnSequence",
915 				   dn, GNUTLS_X509_DN_FLAG_COMPAT);
916 }
917 
918 /**
919  * gnutls_x509_crt_get_dn3:
920  * @cert: should contain a #gnutls_x509_crt_t type
921  * @dn: a pointer to a structure to hold the name
922  * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
923  *
924  * This function will allocate buffer and copy the name of the Certificate.
925  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
926  * described in RFC4514. The output string will be ASCII or UTF-8
927  * encoded, depending on the certificate data.
928  *
929  * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
930  * format will match the format output by previous to 3.5.6 versions of GnuTLS
931  * which was not not fully RFC4514-compliant.
932  *
933  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
934  *   negative error value.
935  *
936  * Since: 3.5.7
937  **/
gnutls_x509_crt_get_dn3(gnutls_x509_crt_t cert,gnutls_datum_t * dn,unsigned flags)938 int gnutls_x509_crt_get_dn3(gnutls_x509_crt_t cert, gnutls_datum_t *dn, unsigned flags)
939 {
940 	if (cert == NULL) {
941 		gnutls_assert();
942 		return GNUTLS_E_INVALID_REQUEST;
943 	}
944 
945 	return _gnutls_x509_get_dn(cert->cert,
946 				   "tbsCertificate.subject.rdnSequence",
947 				   dn, flags);
948 }
949 
950 /**
951  * gnutls_x509_crt_get_dn_by_oid:
952  * @cert: should contain a #gnutls_x509_crt_t type
953  * @oid: holds an Object Identified in null terminated string
954  * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
955  * @raw_flag: If non-zero returns the raw DER data of the DN part.
956  * @buf: a pointer where the DN part will be copied (may be null).
957  * @buf_size: initially holds the size of @buf
958  *
959  * This function will extract the part of the name of the Certificate
960  * subject specified by the given OID. The output, if the raw flag is
961  * not used, will be encoded as described in RFC4514. Thus a string
962  * that is ASCII or UTF-8 encoded, depending on the certificate data.
963  *
964  * Some helper macros with popular OIDs can be found in gnutls/x509.h
965  * If raw flag is (0), this function will only return known OIDs as
966  * text. Other OIDs will be DER encoded, as described in RFC4514 --
967  * in hex format with a '#' prefix.  You can check about known OIDs
968  * using gnutls_x509_dn_oid_known().
969  *
970  * If @buf is null then only the size will be filled. If the @raw_flag
971  * is not specified the output is always null terminated, although the
972  * @buf_size will not include the null character.
973  *
974  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
975  *   long enough, and in that case the @buf_size will be updated with
976  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
977  *   are no data in the current index. On success 0 is returned.
978  **/
979 int
gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert,const char * oid,unsigned indx,unsigned int raw_flag,void * buf,size_t * buf_size)980 gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert, const char *oid,
981 			      unsigned indx, unsigned int raw_flag,
982 			      void *buf, size_t * buf_size)
983 {
984 	gnutls_datum_t td;
985 	int ret;
986 
987 	if (cert == NULL) {
988 		gnutls_assert();
989 		return GNUTLS_E_INVALID_REQUEST;
990 	}
991 
992 	ret = _gnutls_x509_parse_dn_oid(cert->cert,
993 					"tbsCertificate.subject.rdnSequence",
994 					oid, indx, raw_flag, &td);
995 	if (ret < 0)
996 		return gnutls_assert_val(ret);
997 
998 	return _gnutls_strdatum_to_buf(&td, buf, buf_size);
999 }
1000 
1001 /**
1002  * gnutls_x509_crt_get_dn_oid:
1003  * @cert: should contain a #gnutls_x509_crt_t type
1004  * @indx: This specifies which OID to return. Use (0) to get the first one.
1005  * @oid: a pointer to a buffer to hold the OID (may be null)
1006  * @oid_size: initially holds the size of @oid
1007  *
1008  * This function will extract the OIDs of the name of the Certificate
1009  * subject specified by the given index.
1010  *
1011  * If @oid is null then only the size will be filled. The @oid
1012  * returned will be null terminated, although @oid_size will not
1013  * account for the trailing null.
1014  *
1015  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1016  *   long enough, and in that case the @buf_size will be updated with
1017  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there
1018  *   are no data in the current index. On success 0 is returned.
1019  **/
1020 int
gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,unsigned indx,void * oid,size_t * oid_size)1021 gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,
1022 			   unsigned indx, void *oid, size_t * oid_size)
1023 {
1024 	if (cert == NULL) {
1025 		gnutls_assert();
1026 		return GNUTLS_E_INVALID_REQUEST;
1027 	}
1028 
1029 	return _gnutls_x509_get_dn_oid(cert->cert,
1030 				       "tbsCertificate.subject.rdnSequence",
1031 				       indx, oid, oid_size);
1032 }
1033 
1034 /**
1035  * gnutls_x509_crt_get_signature_algorithm:
1036  * @cert: should contain a #gnutls_x509_crt_t type
1037  *
1038  * This function will return a value of the #gnutls_sign_algorithm_t
1039  * enumeration that is the signature algorithm that has been used to
1040  * sign this certificate.
1041  *
1042  * Since 3.6.0 this function never returns a negative error code.
1043  * Error cases and unknown/unsupported signature algorithms are
1044  * mapped to %GNUTLS_SIGN_UNKNOWN.
1045  *
1046  * Returns: a #gnutls_sign_algorithm_t value
1047  **/
gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert)1048 int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert)
1049 {
1050 	return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(cert->cert,
1051 						    "signatureAlgorithm"));
1052 }
1053 
1054 /**
1055  * gnutls_x509_crt_get_signature_oid:
1056  * @cert: should contain a #gnutls_x509_crt_t type
1057  * @oid: a pointer to a buffer to hold the OID (may be null)
1058  * @oid_size: initially holds the size of @oid
1059  *
1060  * This function will return the OID of the signature algorithm
1061  * that has been used to sign this certificate. This is function
1062  * is useful in the case gnutls_x509_crt_get_signature_algorithm()
1063  * returned %GNUTLS_SIGN_UNKNOWN.
1064  *
1065  * Returns: zero or a negative error code on error.
1066  *
1067  * Since: 3.5.0
1068  **/
gnutls_x509_crt_get_signature_oid(gnutls_x509_crt_t cert,char * oid,size_t * oid_size)1069 int gnutls_x509_crt_get_signature_oid(gnutls_x509_crt_t cert, char *oid, size_t *oid_size)
1070 {
1071 	char str[MAX_OID_SIZE];
1072 	int len, result, ret;
1073 	gnutls_datum_t out;
1074 
1075 	len = sizeof(str);
1076 	result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm", str, &len);
1077 	if (result != ASN1_SUCCESS) {
1078 		gnutls_assert();
1079 		return _gnutls_asn2err(result);
1080 	}
1081 
1082 	out.data = (void*)str;
1083 	out.size = len;
1084 
1085 	ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
1086 	if (ret < 0) {
1087 		gnutls_assert();
1088 		return ret;
1089 	}
1090 
1091 	return 0;
1092 }
1093 
1094 /**
1095  * gnutls_x509_crt_get_pk_oid:
1096  * @cert: should contain a #gnutls_x509_crt_t type
1097  * @oid: a pointer to a buffer to hold the OID (may be null)
1098  * @oid_size: initially holds the size of @oid
1099  *
1100  * This function will return the OID of the public key algorithm
1101  * on that certificate. This is function
1102  * is useful in the case gnutls_x509_crt_get_pk_algorithm()
1103  * returned %GNUTLS_PK_UNKNOWN.
1104  *
1105  * Returns: zero or a negative error code on error.
1106  *
1107  * Since: 3.5.0
1108  **/
gnutls_x509_crt_get_pk_oid(gnutls_x509_crt_t cert,char * oid,size_t * oid_size)1109 int gnutls_x509_crt_get_pk_oid(gnutls_x509_crt_t cert, char *oid, size_t *oid_size)
1110 {
1111 	char str[MAX_OID_SIZE];
1112 	int len, result, ret;
1113 	gnutls_datum_t out;
1114 
1115 	len = sizeof(str);
1116 	result = asn1_read_value(cert->cert, "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", str, &len);
1117 	if (result != ASN1_SUCCESS) {
1118 		gnutls_assert();
1119 		return _gnutls_asn2err(result);
1120 	}
1121 
1122 	out.data = (void*)str;
1123 	out.size = len;
1124 
1125 	ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
1126 	if (ret < 0) {
1127 		gnutls_assert();
1128 		return ret;
1129 	}
1130 
1131 	return 0;
1132 }
1133 
1134 /**
1135  * gnutls_x509_crt_get_signature:
1136  * @cert: should contain a #gnutls_x509_crt_t type
1137  * @sig: a pointer where the signature part will be copied (may be null).
1138  * @sig_size: initially holds the size of @sig
1139  *
1140  * This function will extract the signature field of a certificate.
1141  *
1142  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1143  *   negative error value.
1144  **/
1145 int
gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,char * sig,size_t * sig_size)1146 gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
1147 			      char *sig, size_t * sig_size)
1148 {
1149 	gnutls_datum_t dsig = {NULL, 0};
1150 	int ret;
1151 
1152 	if (cert == NULL)
1153 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1154 
1155 	ret = _gnutls_x509_get_signature(cert->cert, "signature", &dsig);
1156 	if (ret < 0)
1157 		return gnutls_assert_val(ret);
1158 
1159 	ret = _gnutls_copy_data(&dsig, (uint8_t*)sig, sig_size);
1160 	if (ret < 0) {
1161 		gnutls_assert();
1162 		goto cleanup;
1163 	}
1164 
1165 	ret = 0;
1166  cleanup:
1167 	gnutls_free(dsig.data);
1168 	return ret;
1169 }
1170 
1171 /**
1172  * gnutls_x509_crt_get_version:
1173  * @cert: should contain a #gnutls_x509_crt_t type
1174  *
1175  * This function will return the version of the specified Certificate.
1176  *
1177  * Returns: version of certificate, or a negative error code on error.
1178  **/
gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)1179 int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)
1180 {
1181 	if (cert == NULL) {
1182 		gnutls_assert();
1183 		return GNUTLS_E_INVALID_REQUEST;
1184 	}
1185 
1186 	return _gnutls_x509_get_version(cert->cert, "tbsCertificate.version");
1187 }
1188 
1189 /**
1190  * gnutls_x509_crt_get_activation_time:
1191  * @cert: should contain a #gnutls_x509_crt_t type
1192  *
1193  * This function will return the time this Certificate was or will be
1194  * activated.
1195  *
1196  * Returns: activation time, or (time_t)-1 on error.
1197  **/
gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert)1198 time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert)
1199 {
1200 	if (cert == NULL) {
1201 		gnutls_assert();
1202 		return (time_t) - 1;
1203 	}
1204 
1205 	return _gnutls_x509_get_time(cert->cert,
1206 				     "tbsCertificate.validity.notBefore",
1207 				     0);
1208 }
1209 
1210 /**
1211  * gnutls_x509_crt_get_expiration_time:
1212  * @cert: should contain a #gnutls_x509_crt_t type
1213  *
1214  * This function will return the time this certificate was or will be
1215  * expired.
1216  *
1217  * Returns: expiration time, or (time_t)-1 on error.
1218  **/
gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert)1219 time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert)
1220 {
1221 	if (cert == NULL) {
1222 		gnutls_assert();
1223 		return (time_t) - 1;
1224 	}
1225 
1226 	return _gnutls_x509_get_time(cert->cert,
1227 				     "tbsCertificate.validity.notAfter",
1228 				     0);
1229 }
1230 
1231 /**
1232  * gnutls_x509_crt_get_private_key_usage_period:
1233  * @cert: should contain a #gnutls_x509_crt_t type
1234  * @activation: The activation time
1235  * @expiration: The expiration time
1236  * @critical: the extension status
1237  *
1238  * This function will return the expiration and activation
1239  * times of the private key of the certificate. It relies on
1240  * the PKIX extension 2.5.29.16 being present.
1241  *
1242  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1243  * if the extension is not present, otherwise a negative error value.
1244  **/
1245 int
gnutls_x509_crt_get_private_key_usage_period(gnutls_x509_crt_t cert,time_t * activation,time_t * expiration,unsigned int * critical)1246 gnutls_x509_crt_get_private_key_usage_period(gnutls_x509_crt_t cert,
1247 					     time_t * activation,
1248 					     time_t * expiration,
1249 					     unsigned int *critical)
1250 {
1251 	int ret;
1252 	gnutls_datum_t der = { NULL, 0 };
1253 
1254 	if (cert == NULL) {
1255 		gnutls_assert();
1256 		return GNUTLS_E_INVALID_REQUEST;
1257 	}
1258 
1259 	ret =
1260 	    _gnutls_x509_crt_get_extension(cert, "2.5.29.16", 0, &der,
1261 					   critical);
1262 	if (ret < 0)
1263 		return gnutls_assert_val(ret);
1264 
1265 	if (der.size == 0 || der.data == NULL)
1266 		return
1267 		    gnutls_assert_val
1268 		    (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1269 
1270 	ret = gnutls_x509_ext_import_private_key_usage_period(&der, activation, expiration);
1271 	if (ret < 0) {
1272 		gnutls_assert();
1273 		goto cleanup;
1274 	}
1275 
1276 	ret = 0;
1277 
1278       cleanup:
1279 	_gnutls_free_datum(&der);
1280 
1281 	return ret;
1282 }
1283 
1284 
1285 /**
1286  * gnutls_x509_crt_get_serial:
1287  * @cert: should contain a #gnutls_x509_crt_t type
1288  * @result: The place where the serial number will be copied
1289  * @result_size: Holds the size of the result field.
1290  *
1291  * This function will return the X.509 certificate's serial number.
1292  * This is obtained by the X509 Certificate serialNumber field. Serial
1293  * is not always a 32 or 64bit number. Some CAs use large serial
1294  * numbers, thus it may be wise to handle it as something uint8_t.
1295  *
1296  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1297  *   negative error value.
1298  **/
1299 int
gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert,void * result,size_t * result_size)1300 gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert, void *result,
1301 			   size_t * result_size)
1302 {
1303 	int ret, len;
1304 
1305 	if (cert == NULL) {
1306 		gnutls_assert();
1307 		return GNUTLS_E_INVALID_REQUEST;
1308 	}
1309 
1310 	len = *result_size;
1311 	ret =
1312 	    asn1_read_value(cert->cert, "tbsCertificate.serialNumber",
1313 			    result, &len);
1314 	*result_size = len;
1315 
1316 	if (ret != ASN1_SUCCESS) {
1317 		gnutls_assert();
1318 		return _gnutls_asn2err(ret);
1319 	}
1320 
1321 	return 0;
1322 }
1323 
1324 /**
1325  * gnutls_x509_crt_get_subject_key_id:
1326  * @cert: should contain a #gnutls_x509_crt_t type
1327  * @ret: The place where the identifier will be copied
1328  * @ret_size: Holds the size of the result field.
1329  * @critical: will be non-zero if the extension is marked as critical (may be null)
1330  *
1331  * This function will return the X.509v3 certificate's subject key
1332  * identifier.  This is obtained by the X.509 Subject Key identifier
1333  * extension field (2.5.29.14).
1334  *
1335  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1336  * if the extension is not present, otherwise a negative error value.
1337  **/
1338 int
gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert,void * ret,size_t * ret_size,unsigned int * critical)1339 gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert, void *ret,
1340 				   size_t * ret_size,
1341 				   unsigned int *critical)
1342 {
1343 	int result;
1344 	gnutls_datum_t id = {NULL,0};
1345 	gnutls_datum_t der = {NULL, 0};
1346 
1347 	if (cert == NULL) {
1348 		gnutls_assert();
1349 		return GNUTLS_E_INVALID_REQUEST;
1350 	}
1351 
1352 	if (ret == NULL)
1353 		*ret_size = 0;
1354 
1355 	if ((result =
1356 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &der,
1357 					    critical)) < 0) {
1358 		return result;
1359 	}
1360 
1361 	result = gnutls_x509_ext_import_subject_key_id(&der, &id);
1362 	if (result < 0) {
1363 		gnutls_assert();
1364 		goto cleanup;
1365 	}
1366 
1367 	result = _gnutls_copy_data(&id, ret, ret_size);
1368 	if (result < 0) {
1369 		gnutls_assert();
1370 		goto cleanup;
1371 	}
1372 
1373 	result = 0;
1374 
1375  cleanup:
1376 	gnutls_free(der.data);
1377 	gnutls_free(id.data);
1378 	return result;
1379 }
1380 
is_type_printable(int type)1381 inline static int is_type_printable(int type)
1382 {
1383 	if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1384 	    type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP ||
1385 	    type == GNUTLS_SAN_OTHERNAME || type == GNUTLS_SAN_REGISTERED_ID)
1386 		return 1;
1387 	else
1388 		return 0;
1389 }
1390 
1391 /**
1392  * gnutls_x509_crt_get_authority_key_gn_serial:
1393  * @cert: should contain a #gnutls_x509_crt_t type
1394  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1395  * @alt: is the place where the alternative name will be copied to
1396  * @alt_size: holds the size of alt.
1397  * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1398  * @serial: buffer to store the serial number (may be null)
1399  * @serial_size: Holds the size of the serial field (may be null)
1400  * @critical: will be non-zero if the extension is marked as critical (may be null)
1401  *
1402  * This function will return the X.509 authority key
1403  * identifier when stored as a general name (authorityCertIssuer)
1404  * and serial number.
1405  *
1406  * Because more than one general names might be stored
1407  * @seq can be used as a counter to request them all until
1408  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1409  *
1410  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1411  * if the extension is not present, otherwise a negative error value.
1412  *
1413  * Since: 3.0
1414  **/
1415 int
gnutls_x509_crt_get_authority_key_gn_serial(gnutls_x509_crt_t cert,unsigned int seq,void * alt,size_t * alt_size,unsigned int * alt_type,void * serial,size_t * serial_size,unsigned int * critical)1416 gnutls_x509_crt_get_authority_key_gn_serial(gnutls_x509_crt_t cert,
1417 					    unsigned int seq, void *alt,
1418 					    size_t * alt_size,
1419 					    unsigned int *alt_type,
1420 					    void *serial,
1421 					    size_t * serial_size,
1422 					    unsigned int *critical)
1423 {
1424 	int ret;
1425 	gnutls_datum_t der, san, iserial;
1426 	gnutls_x509_aki_t aki = NULL;
1427 	unsigned san_type;
1428 
1429 	if (cert == NULL) {
1430 		gnutls_assert();
1431 		return GNUTLS_E_INVALID_REQUEST;
1432 	}
1433 
1434 	if ((ret =
1435 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1436 					    critical)) < 0) {
1437 		return gnutls_assert_val(ret);
1438 	}
1439 
1440 	if (der.size == 0 || der.data == NULL) {
1441 		gnutls_assert();
1442 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1443 	}
1444 
1445 	ret = gnutls_x509_aki_init(&aki);
1446 	if (ret < 0) {
1447 		gnutls_assert();
1448 		goto cleanup;
1449 	}
1450 
1451 	ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1452 	if (ret < 0) {
1453 		gnutls_assert();
1454 		goto cleanup;
1455 	}
1456 
1457 	ret = gnutls_x509_aki_get_cert_issuer(aki, seq, &san_type, &san, NULL, &iserial);
1458 	if (ret < 0) {
1459 		gnutls_assert();
1460 		goto cleanup;
1461 	}
1462 
1463 	if (is_type_printable(san_type))
1464 		ret = _gnutls_copy_string(&san, alt, alt_size);
1465 	else
1466 		ret = _gnutls_copy_data(&san, alt, alt_size);
1467 	if (ret < 0) {
1468 		gnutls_assert();
1469 		goto cleanup;
1470 	}
1471 
1472 	if (alt_type)
1473 		*alt_type = san_type;
1474 
1475 	ret = _gnutls_copy_data(&iserial, serial, serial_size);
1476 	if (ret < 0) {
1477 		gnutls_assert();
1478 		goto cleanup;
1479 	}
1480 
1481 	ret = 0;
1482  cleanup:
1483 	if (aki != NULL)
1484 		gnutls_x509_aki_deinit(aki);
1485 	gnutls_free(der.data);
1486 	return ret;
1487 }
1488 
1489 /**
1490  * gnutls_x509_crt_get_authority_key_id:
1491  * @cert: should contain a #gnutls_x509_crt_t type
1492  * @id: The place where the identifier will be copied
1493  * @id_size: Holds the size of the id field.
1494  * @critical: will be non-zero if the extension is marked as critical (may be null)
1495  *
1496  * This function will return the X.509v3 certificate authority's key
1497  * identifier.  This is obtained by the X.509 Authority Key
1498  * identifier extension field (2.5.29.35). Note that this function
1499  * only returns the keyIdentifier field of the extension and
1500  * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
1501  * the name and serial number of the certificate. In that case
1502  * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
1503  *
1504  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1505  * if the extension is not present, otherwise a negative error value.
1506  **/
1507 int
gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert,void * id,size_t * id_size,unsigned int * critical)1508 gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert, void *id,
1509 				     size_t * id_size,
1510 				     unsigned int *critical)
1511 {
1512 	int ret;
1513 	gnutls_datum_t der, l_id;
1514 	gnutls_x509_aki_t aki = NULL;
1515 
1516 	if (cert == NULL) {
1517 		gnutls_assert();
1518 		return GNUTLS_E_INVALID_REQUEST;
1519 	}
1520 
1521 	if ((ret =
1522 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1523 					    critical)) < 0) {
1524 		return gnutls_assert_val(ret);
1525 	}
1526 
1527 	if (der.size == 0 || der.data == NULL) {
1528 		gnutls_assert();
1529 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1530 	}
1531 
1532 	ret = gnutls_x509_aki_init(&aki);
1533 	if (ret < 0) {
1534 		gnutls_assert();
1535 		goto cleanup;
1536 	}
1537 
1538 	ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1539 	if (ret < 0) {
1540 		gnutls_assert();
1541 		goto cleanup;
1542 	}
1543 
1544 	ret = gnutls_x509_aki_get_id(aki, &l_id);
1545 
1546 	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1547 		gnutls_datum_t serial;
1548 		ret = gnutls_x509_aki_get_cert_issuer(aki, 0, NULL, NULL, NULL, &serial);
1549 		if (ret >= 0) {
1550 			ret = gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1551 		} else {
1552 			ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1553 		}
1554 	}
1555 
1556 	if (ret < 0) {
1557 		gnutls_assert();
1558 		goto cleanup;
1559 	}
1560 
1561 	ret = _gnutls_copy_data(&l_id, id, id_size);
1562 	if (ret < 0) {
1563 		gnutls_assert();
1564 		goto cleanup;
1565 	}
1566 
1567 	ret = 0;
1568  cleanup:
1569 	if (aki != NULL)
1570 		gnutls_x509_aki_deinit(aki);
1571 	gnutls_free(der.data);
1572 	return ret;
1573 }
1574 
1575 /**
1576  * gnutls_x509_crt_get_pk_algorithm:
1577  * @cert: should contain a #gnutls_x509_crt_t type
1578  * @bits: if bits is non null it will hold the size of the parameters' in bits
1579  *
1580  * This function will return the public key algorithm of an X.509
1581  * certificate.
1582  *
1583  * If bits is non null, it should have enough size to hold the parameters
1584  * size in bits. For RSA the bits returned is the modulus.
1585  * For DSA the bits returned are of the public
1586  * exponent.
1587  *
1588  * Unknown/unsupported algorithms are mapped to %GNUTLS_PK_UNKNOWN.
1589  *
1590  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1591  * success, or a negative error code on error.
1592  **/
1593 int
gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,unsigned int * bits)1594 gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
1595 				 unsigned int *bits)
1596 {
1597 	int result;
1598 
1599 	if (cert == NULL) {
1600 		gnutls_assert();
1601 		return GNUTLS_E_INVALID_REQUEST;
1602 	}
1603 
1604 	if (bits)
1605 		*bits = 0;
1606 
1607 	result =
1608 	    _gnutls_x509_get_pk_algorithm(cert->cert,
1609 					  "tbsCertificate.subjectPublicKeyInfo",
1610 					  NULL,
1611 					  bits);
1612 
1613 	if (result < 0) {
1614 		gnutls_assert();
1615 		return result;
1616 	}
1617 
1618 	return result;
1619 }
1620 
1621 /**
1622  * gnutls_x509_crt_get_spki:
1623  * @cert: a certificate of type #gnutls_x509_crt_t
1624  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1625  * @flags: must be zero
1626  *
1627  * This function will return the public key information of an X.509
1628  * certificate. The provided @spki must be initialized.
1629  *
1630  * Since: 3.6.0
1631  **/
1632 int
gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert,gnutls_x509_spki_t spki,unsigned int flags)1633 gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert, gnutls_x509_spki_t spki, unsigned int flags)
1634 {
1635 	int result;
1636 	gnutls_x509_spki_st params;
1637 
1638 	if (cert == NULL) {
1639 		gnutls_assert();
1640 		return GNUTLS_E_INVALID_REQUEST;
1641 	}
1642 
1643 
1644 	spki->pk = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
1645 
1646 	memset(&params, 0, sizeof(params));
1647 
1648 	result = _gnutls_x509_crt_read_spki_params(cert, &params);
1649 	if (result < 0) {
1650 		gnutls_assert();
1651 		return result;
1652 	}
1653 
1654 	if (params.pk == GNUTLS_PK_UNKNOWN)
1655 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1656 
1657 	spki->rsa_pss_dig = params.rsa_pss_dig;
1658 	spki->salt_size = params.salt_size;
1659 
1660 	return 0;
1661 }
1662 
1663 /* returns the type and the name on success.
1664  * Type is also returned as a parameter in case of an error.
1665  *
1666  * @seq: in case of GeneralNames it will return the corresponding name.
1667  *       in case of GeneralName, it must be -1
1668  * @dname: the name returned
1669  * @ret_type: The type of the name
1670  * @othername_oid: if the name is otherName return the OID
1671  *
1672  */
1673 int
_gnutls_parse_general_name2(ASN1_TYPE src,const char * src_name,int seq,gnutls_datum_t * dname,unsigned int * ret_type,int othername_oid)1674 _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
1675 			   int seq, gnutls_datum_t *dname,
1676 			   unsigned int *ret_type, int othername_oid)
1677 {
1678 	int len, ret;
1679 	char nptr[MAX_NAME_SIZE];
1680 	int result;
1681 	gnutls_datum_t tmp = {NULL, 0};
1682 	char choice_type[128];
1683 	gnutls_x509_subject_alt_name_t type;
1684 
1685 	if (seq != -1) {
1686 		seq++;	/* 0->1, 1->2 etc */
1687 
1688 		if (src_name[0] != 0)
1689 			snprintf(nptr, sizeof(nptr), "%s.?%u", src_name, seq);
1690 		else
1691 			snprintf(nptr, sizeof(nptr), "?%u", seq);
1692 	} else {
1693 		snprintf(nptr, sizeof(nptr), "%s", src_name);
1694 	}
1695 
1696 	len = sizeof(choice_type);
1697 	result = asn1_read_value(src, nptr, choice_type, &len);
1698 	if (result == ASN1_VALUE_NOT_FOUND
1699 	    || result == ASN1_ELEMENT_NOT_FOUND) {
1700 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1701 	}
1702 
1703 	if (result != ASN1_SUCCESS) {
1704 		gnutls_assert();
1705 		return _gnutls_asn2err(result);
1706 	}
1707 
1708 	type = _gnutls_x509_san_find_type(choice_type);
1709 	if (type == (gnutls_x509_subject_alt_name_t) - 1) {
1710 		gnutls_assert();
1711 		return GNUTLS_E_X509_UNKNOWN_SAN;
1712 	}
1713 
1714 	if (ret_type)
1715 		*ret_type = type;
1716 
1717 	if (type == GNUTLS_SAN_OTHERNAME) {
1718 		if (othername_oid)
1719 			_gnutls_str_cat(nptr, sizeof(nptr),
1720 					".otherName.type-id");
1721 		else
1722 			_gnutls_str_cat(nptr, sizeof(nptr),
1723 					".otherName.value");
1724 
1725 		ret = _gnutls_x509_read_value(src, nptr, &tmp);
1726 		if (ret < 0) {
1727 			gnutls_assert();
1728 			return ret;
1729 		}
1730 
1731 		if (othername_oid) {
1732 			dname->size = tmp.size;
1733 			dname->data = tmp.data;
1734 		} else {
1735 			char oid[MAX_OID_SIZE];
1736 
1737 			if (src_name[0] != 0)
1738 				snprintf(nptr, sizeof(nptr),
1739 					 "%s.?%u.otherName.type-id",
1740 					 src_name, seq);
1741 			else
1742 				snprintf(nptr, sizeof(nptr),
1743 					 "?%u.otherName.type-id", seq);
1744 
1745 			len = sizeof(oid);
1746 
1747 			result = asn1_read_value(src, nptr, oid, &len);
1748 			if (result != ASN1_SUCCESS) {
1749 				gnutls_assert();
1750 				ret = _gnutls_asn2err(result);
1751 				goto cleanup;
1752 			}
1753 			if (len > 0) len--;
1754 
1755 			dname->size = tmp.size;
1756 			dname->data = tmp.data;
1757 		}
1758 	} else if (type == GNUTLS_SAN_DN) {
1759 		_gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
1760 		ret = _gnutls_x509_get_dn(src, nptr, dname, 0);
1761 		if (ret < 0) {
1762 			gnutls_assert();
1763 			goto cleanup;
1764 		}
1765 	} else if (othername_oid) {
1766 		gnutls_assert();
1767 		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1768 		goto cleanup;
1769 	} else {
1770 		_gnutls_str_cat(nptr, sizeof(nptr), ".");
1771 		_gnutls_str_cat(nptr, sizeof(nptr), choice_type);
1772 
1773 		ret = _gnutls_x509_read_null_value(src, nptr, &tmp);
1774 		if (ret < 0) {
1775 			gnutls_assert();
1776 			return ret;
1777 		}
1778 
1779 		if (type == GNUTLS_SAN_REGISTERED_ID && tmp.size > 0) {
1780 			/* see #805; OIDs contain the null termination byte */
1781 			assert(tmp.data[tmp.size-1] == 0);
1782 			tmp.size--;
1783 		}
1784 
1785 		/* _gnutls_x509_read_value() null terminates */
1786 		dname->size = tmp.size;
1787 		dname->data = tmp.data;
1788 	}
1789 
1790 	return type;
1791 
1792  cleanup:
1793 	gnutls_free(tmp.data);
1794 	return ret;
1795 }
1796 
1797 /* returns the type and the name on success.
1798  * Type is also returned as a parameter in case of an error.
1799  */
1800 int
_gnutls_parse_general_name(ASN1_TYPE src,const char * src_name,int seq,void * name,size_t * name_size,unsigned int * ret_type,int othername_oid)1801 _gnutls_parse_general_name(ASN1_TYPE src, const char *src_name,
1802 			   int seq, void *name, size_t * name_size,
1803 			   unsigned int *ret_type, int othername_oid)
1804 {
1805 	int ret;
1806 	gnutls_datum_t res = {NULL,0};
1807 	unsigned type;
1808 
1809 	ret = _gnutls_parse_general_name2(src, src_name, seq, &res, ret_type, othername_oid);
1810 	if (ret < 0)
1811 		return gnutls_assert_val(ret);
1812 
1813 	type = ret;
1814 
1815 	if (is_type_printable(type)) {
1816 		ret = _gnutls_copy_string(&res, name, name_size);
1817 	} else {
1818 		ret = _gnutls_copy_data(&res, name, name_size);
1819 	}
1820 
1821 	if (ret < 0) {
1822 		gnutls_assert();
1823 		goto cleanup;
1824 	}
1825 
1826 	ret = type;
1827 cleanup:
1828 	gnutls_free(res.data);
1829 	return ret;
1830 }
1831 
1832 static int
get_alt_name(gnutls_subject_alt_names_t san,unsigned int seq,uint8_t * alt,size_t * alt_size,unsigned int * alt_type,unsigned int * critical,int othername_oid)1833 get_alt_name(gnutls_subject_alt_names_t san,
1834 	     unsigned int seq, uint8_t *alt,
1835 	     size_t * alt_size, unsigned int *alt_type,
1836 	     unsigned int *critical, int othername_oid)
1837 {
1838 	int ret;
1839 	gnutls_datum_t ooid = {NULL, 0};
1840 	gnutls_datum_t oname;
1841 	gnutls_datum_t virt = {NULL, 0};
1842 	unsigned int type;
1843 
1844 	if (san == NULL) {
1845 		gnutls_assert();
1846 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1847 	}
1848 
1849 	if (alt == NULL)
1850 		*alt_size = 0;
1851 
1852 	ret = gnutls_subject_alt_names_get(san, seq, &type, &oname, &ooid);
1853 	if (ret < 0) {
1854 		gnutls_assert();
1855 		goto cleanup;
1856 	}
1857 
1858 	if (othername_oid && type == GNUTLS_SAN_OTHERNAME && ooid.data) {
1859 		unsigned vtype;
1860 		ret = gnutls_x509_othername_to_virtual((char*)ooid.data, &oname, &vtype, &virt);
1861 		if (ret >= 0) {
1862 			type = vtype;
1863 			oname.data = virt.data;
1864 			oname.size = virt.size;
1865 		}
1866 	}
1867 
1868 	if (alt_type)
1869 		*alt_type = type;
1870 
1871 	if (othername_oid) {
1872 		ret = _gnutls_copy_string(&ooid, alt, alt_size);
1873 	} else {
1874 		if (is_type_printable(type)) {
1875 			ret = _gnutls_copy_string(&oname, alt, alt_size);
1876 		} else {
1877 			ret = _gnutls_copy_data(&oname, alt, alt_size);
1878 		}
1879 	}
1880 
1881 	if (ret < 0) {
1882 		gnutls_assert();
1883 		goto cleanup;
1884 	}
1885 
1886 	ret = type;
1887 cleanup:
1888 	gnutls_free(virt.data);
1889 
1890 	return ret;
1891 }
1892 
1893 /**
1894  * gnutls_x509_crt_get_subject_alt_name:
1895  * @cert: should contain a #gnutls_x509_crt_t type
1896  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1897  * @san: is the place where the alternative name will be copied to
1898  * @san_size: holds the size of san.
1899  * @critical: will be non-zero if the extension is marked as critical (may be null)
1900  *
1901  * This function retrieves the Alternative Name (2.5.29.17), contained
1902  * in the given certificate in the X509v3 Certificate Extensions.
1903  *
1904  * When the SAN type is otherName, it will extract the data in the
1905  * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1906  * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1907  * the corresponding OID and the "virtual" SAN types (e.g.,
1908  * %GNUTLS_SAN_OTHERNAME_XMPP).
1909  *
1910  * If an otherName OID is known, the data will be decoded.  Otherwise
1911  * the returned data will be DER encoded, and you will have to decode
1912  * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr SAN is
1913  * recognized.
1914  *
1915  * Returns: the alternative subject name type on success, one of the
1916  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1917  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1918  *   hold the value.  In that case @san_size will be updated with the
1919  *   required size.  If the certificate does not have an Alternative
1920  *   name with the specified sequence number then
1921  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1922  **/
1923 int
gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,unsigned int seq,void * san,size_t * san_size,unsigned int * critical)1924 gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
1925 				     unsigned int seq, void *san,
1926 				     size_t * san_size,
1927 				     unsigned int *critical)
1928 {
1929 	return get_alt_name(cert->san, seq, san, san_size, NULL,
1930 			    critical, 0);
1931 }
1932 
1933 /**
1934  * gnutls_x509_crt_get_issuer_alt_name:
1935  * @cert: should contain a #gnutls_x509_crt_t type
1936  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1937  * @ian: is the place where the alternative name will be copied to
1938  * @ian_size: holds the size of ian.
1939  * @critical: will be non-zero if the extension is marked as critical (may be null)
1940  *
1941  * This function retrieves the Issuer Alternative Name (2.5.29.18),
1942  * contained in the given certificate in the X509v3 Certificate
1943  * Extensions.
1944  *
1945  * When the SAN type is otherName, it will extract the data in the
1946  * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1947  * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1948  * the corresponding OID and the "virtual" SAN types (e.g.,
1949  * %GNUTLS_SAN_OTHERNAME_XMPP).
1950  *
1951  * If an otherName OID is known, the data will be decoded.  Otherwise
1952  * the returned data will be DER encoded, and you will have to decode
1953  * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr Issuer
1954  * AltName is recognized.
1955  *
1956  * Returns: the alternative issuer name type on success, one of the
1957  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1958  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1959  *   to hold the value.  In that case @ian_size will be updated with
1960  *   the required size.  If the certificate does not have an
1961  *   Alternative name with the specified sequence number then
1962  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1963  *
1964  * Since: 2.10.0
1965  **/
1966 int
gnutls_x509_crt_get_issuer_alt_name(gnutls_x509_crt_t cert,unsigned int seq,void * ian,size_t * ian_size,unsigned int * critical)1967 gnutls_x509_crt_get_issuer_alt_name(gnutls_x509_crt_t cert,
1968 				    unsigned int seq, void *ian,
1969 				    size_t * ian_size,
1970 				    unsigned int *critical)
1971 {
1972 	return get_alt_name(cert->ian, seq, ian, ian_size, NULL,
1973 			    critical, 0);
1974 }
1975 
1976 /**
1977  * gnutls_x509_crt_get_subject_alt_name2:
1978  * @cert: should contain a #gnutls_x509_crt_t type
1979  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1980  * @san: is the place where the alternative name will be copied to
1981  * @san_size: holds the size of ret.
1982  * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1983  * @critical: will be non-zero if the extension is marked as critical (may be null)
1984  *
1985  * This function will return the alternative names, contained in the
1986  * given certificate. It is the same as
1987  * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1988  * will return the type of the alternative name in @san_type even if
1989  * the function fails for some reason (i.e.  the buffer provided is
1990  * not enough).
1991  *
1992  * Returns: the alternative subject name type on success, one of the
1993  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1994  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1995  *   to hold the value.  In that case @san_size will be updated with
1996  *   the required size.  If the certificate does not have an
1997  *   Alternative name with the specified sequence number then
1998  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1999  **/
2000 int
gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,unsigned int seq,void * san,size_t * san_size,unsigned int * san_type,unsigned int * critical)2001 gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,
2002 				      unsigned int seq, void *san,
2003 				      size_t * san_size,
2004 				      unsigned int *san_type,
2005 				      unsigned int *critical)
2006 {
2007 	return get_alt_name(cert->san, seq, san, san_size,
2008 			    san_type, critical, 0);
2009 }
2010 
2011 /**
2012  * gnutls_x509_crt_get_issuer_alt_name2:
2013  * @cert: should contain a #gnutls_x509_crt_t type
2014  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2015  * @ian: is the place where the alternative name will be copied to
2016  * @ian_size: holds the size of ret.
2017  * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
2018  * @critical: will be non-zero if the extension is marked as critical (may be null)
2019  *
2020  * This function will return the alternative names, contained in the
2021  * given certificate. It is the same as
2022  * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
2023  * will return the type of the alternative name in @ian_type even if
2024  * the function fails for some reason (i.e.  the buffer provided is
2025  * not enough).
2026  *
2027  * Returns: the alternative issuer name type on success, one of the
2028  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
2029  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
2030  *   to hold the value.  In that case @ian_size will be updated with
2031  *   the required size.  If the certificate does not have an
2032  *   Alternative name with the specified sequence number then
2033  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2034  *
2035  * Since: 2.10.0
2036  *
2037  **/
2038 int
gnutls_x509_crt_get_issuer_alt_name2(gnutls_x509_crt_t cert,unsigned int seq,void * ian,size_t * ian_size,unsigned int * ian_type,unsigned int * critical)2039 gnutls_x509_crt_get_issuer_alt_name2(gnutls_x509_crt_t cert,
2040 				     unsigned int seq, void *ian,
2041 				     size_t * ian_size,
2042 				     unsigned int *ian_type,
2043 				     unsigned int *critical)
2044 {
2045 	return get_alt_name(cert->ian, seq, ian, ian_size,
2046 			    ian_type, critical, 0);
2047 }
2048 
2049 /**
2050  * gnutls_x509_crt_get_subject_alt_othername_oid:
2051  * @cert: should contain a #gnutls_x509_crt_t type
2052  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2053  * @oid: is the place where the otherName OID will be copied to
2054  * @oid_size: holds the size of ret.
2055  *
2056  * This function will extract the type OID of an otherName Subject
2057  * Alternative Name, contained in the given certificate, and return
2058  * the type as an enumerated element.
2059  *
2060  * This function is only useful if
2061  * gnutls_x509_crt_get_subject_alt_name() returned
2062  * %GNUTLS_SAN_OTHERNAME.
2063  *
2064  * If @oid is null then only the size will be filled. The @oid
2065  * returned will be null terminated, although @oid_size will not
2066  * account for the trailing null.
2067  *
2068  * Returns: the alternative subject name type on success, one of the
2069  * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
2070  * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
2071  * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
2072  * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
2073  * @ian_size is not large enough to hold the value.  In that case
2074  * @ian_size will be updated with the required size.  If the
2075  * certificate does not have an Alternative name with the specified
2076  * sequence number and with the otherName type then
2077  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2078  **/
2079 int
gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,unsigned int seq,void * oid,size_t * oid_size)2080 gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,
2081 					      unsigned int seq,
2082 					      void *oid, size_t * oid_size)
2083 {
2084 	return get_alt_name(cert->san, seq, oid, oid_size, NULL,
2085 			    NULL, 1);
2086 }
2087 
2088 /**
2089  * gnutls_x509_crt_get_issuer_alt_othername_oid:
2090  * @cert: should contain a #gnutls_x509_crt_t type
2091  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
2092  * @ret: is the place where the otherName OID will be copied to
2093  * @ret_size: holds the size of ret.
2094  *
2095  * This function will extract the type OID of an otherName Subject
2096  * Alternative Name, contained in the given certificate, and return
2097  * the type as an enumerated element.
2098  *
2099  * If @oid is null then only the size will be filled. The @oid
2100  * returned will be null terminated, although @oid_size will not
2101  * account for the trailing null.
2102  *
2103  * This function is only useful if
2104  * gnutls_x509_crt_get_issuer_alt_name() returned
2105  * %GNUTLS_SAN_OTHERNAME.
2106  *
2107  * Returns: the alternative issuer name type on success, one of the
2108  * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
2109  * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
2110  * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
2111  * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
2112  * @ret_size is not large enough to hold the value.  In that case
2113  * @ret_size will be updated with the required size.  If the
2114  * certificate does not have an Alternative name with the specified
2115  * sequence number and with the otherName type then
2116  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2117  *
2118  * Since: 2.10.0
2119  **/
2120 int
gnutls_x509_crt_get_issuer_alt_othername_oid(gnutls_x509_crt_t cert,unsigned int seq,void * ret,size_t * ret_size)2121 gnutls_x509_crt_get_issuer_alt_othername_oid(gnutls_x509_crt_t cert,
2122 					     unsigned int seq,
2123 					     void *ret, size_t * ret_size)
2124 {
2125 	return get_alt_name(cert->ian, seq, ret, ret_size, NULL,
2126 			    NULL, 1);
2127 }
2128 
2129 /**
2130  * gnutls_x509_crt_get_basic_constraints:
2131  * @cert: should contain a #gnutls_x509_crt_t type
2132  * @critical: will be non-zero if the extension is marked as critical
2133  * @ca: pointer to output integer indicating CA status, may be NULL,
2134  *   value is 1 if the certificate CA flag is set, 0 otherwise.
2135  * @pathlen: pointer to output integer indicating path length (may be
2136  *   NULL), non-negative error codes indicate a present pathLenConstraint
2137  *   field and the actual value, -1 indicate that the field is absent.
2138  *
2139  * This function will read the certificate's basic constraints, and
2140  * return the certificates CA status.  It reads the basicConstraints
2141  * X.509 extension (2.5.29.19).
2142  *
2143  * Returns: If the certificate is a CA a positive value will be
2144  * returned, or (0) if the certificate does not have CA flag set.  A
2145  * negative error code may be returned in case of errors.  If the
2146  * certificate does not contain the basicConstraints extension
2147  * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2148  **/
2149 int
gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,unsigned int * critical,unsigned int * ca,int * pathlen)2150 gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
2151 				      unsigned int *critical,
2152 				      unsigned int *ca, int *pathlen)
2153 {
2154 	int result;
2155 	gnutls_datum_t basicConstraints;
2156 	unsigned int tmp_ca;
2157 
2158 	if (cert == NULL) {
2159 		gnutls_assert();
2160 		return GNUTLS_E_INVALID_REQUEST;
2161 	}
2162 
2163 	if ((result =
2164 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.19", 0,
2165 					    &basicConstraints,
2166 					    critical)) < 0) {
2167 		return result;
2168 	}
2169 
2170 	if (basicConstraints.size == 0 || basicConstraints.data == NULL) {
2171 		gnutls_assert();
2172 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2173 	}
2174 
2175 	result = gnutls_x509_ext_import_basic_constraints(&basicConstraints, &tmp_ca, pathlen);
2176 	if (ca)
2177 		*ca = tmp_ca;
2178 
2179 	_gnutls_free_datum(&basicConstraints);
2180 
2181 	if (result < 0) {
2182 		gnutls_assert();
2183 		return result;
2184 	}
2185 
2186 	return tmp_ca;
2187 }
2188 
2189 /**
2190  * gnutls_x509_crt_get_ca_status:
2191  * @cert: should contain a #gnutls_x509_crt_t type
2192  * @critical: will be non-zero if the extension is marked as critical
2193  *
2194  * This function will return certificates CA status, by reading the
2195  * basicConstraints X.509 extension (2.5.29.19). If the certificate is
2196  * a CA a positive value will be returned, or (0) if the certificate
2197  * does not have CA flag set.
2198  *
2199  * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
2200  * pathLenConstraint field too.
2201  *
2202  * Returns: If the certificate is a CA a positive value will be
2203  * returned, or (0) if the certificate does not have CA flag set.  A
2204  * negative error code may be returned in case of errors.  If the
2205  * certificate does not contain the basicConstraints extension
2206  * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2207  **/
2208 int
gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,unsigned int * critical)2209 gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
2210 			      unsigned int *critical)
2211 {
2212 	int pathlen;
2213 	unsigned int ca;
2214 	return gnutls_x509_crt_get_basic_constraints(cert, critical, &ca,
2215 						     &pathlen);
2216 }
2217 
2218 /**
2219  * gnutls_x509_crt_get_key_usage:
2220  * @cert: should contain a #gnutls_x509_crt_t type
2221  * @key_usage: where the key usage bits will be stored
2222  * @critical: will be non-zero if the extension is marked as critical
2223  *
2224  * This function will return certificate's key usage, by reading the
2225  * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
2226  * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
2227  * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
2228  * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
2229  * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
2230  * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
2231  *
2232  * Returns: zero on success, or a negative error code in case of
2233  *   parsing error.  If the certificate does not contain the keyUsage
2234  *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
2235  *   returned.
2236  **/
2237 int
gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,unsigned int * key_usage,unsigned int * critical)2238 gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
2239 			      unsigned int *key_usage,
2240 			      unsigned int *critical)
2241 {
2242 	int result;
2243 	gnutls_datum_t keyUsage;
2244 
2245 	if (cert == NULL) {
2246 		gnutls_assert();
2247 		return GNUTLS_E_INVALID_REQUEST;
2248 	}
2249 
2250 	if ((result =
2251 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.15", 0,
2252 					    &keyUsage, critical)) < 0) {
2253 		return result;
2254 	}
2255 
2256 	if (keyUsage.size == 0 || keyUsage.data == NULL) {
2257 		gnutls_assert();
2258 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2259 	}
2260 
2261 	result = gnutls_x509_ext_import_key_usage(&keyUsage, key_usage);
2262 	_gnutls_free_datum(&keyUsage);
2263 
2264 	if (result < 0) {
2265 		gnutls_assert();
2266 		return result;
2267 	}
2268 
2269 	return 0;
2270 }
2271 
2272 /**
2273  * gnutls_x509_crt_get_inhibit_anypolicy:
2274  * @cert: should contain a #gnutls_x509_crt_t type
2275  * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable.
2276  * @critical: will be non-zero if the extension is marked as critical
2277  *
2278  * This function will return certificate's value of the SkipCerts, i.e.,
2279  * the Inhibit anyPolicy X.509 extension (2.5.29.54).
2280  *
2281  * The returned value is the number of additional certificates that
2282  * may appear in the path before the anyPolicy is no longer acceptable.
2283 
2284  * Returns: zero on success, or a negative error code in case of
2285  *   parsing error.  If the certificate does not contain the Inhibit anyPolicy
2286  *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
2287  *   returned.
2288  *
2289  * Since: 3.6.0
2290  **/
2291 int
gnutls_x509_crt_get_inhibit_anypolicy(gnutls_x509_crt_t cert,unsigned int * skipcerts,unsigned int * critical)2292 gnutls_x509_crt_get_inhibit_anypolicy(gnutls_x509_crt_t cert,
2293 			      unsigned int *skipcerts,
2294 			      unsigned int *critical)
2295 {
2296 	int ret;
2297 	gnutls_datum_t ext;
2298 
2299 	if (cert == NULL) {
2300 		gnutls_assert();
2301 		return GNUTLS_E_INVALID_REQUEST;
2302 	}
2303 
2304 	if ((ret =
2305 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.54", 0,
2306 					    &ext, critical)) < 0) {
2307 		return ret;
2308 	}
2309 
2310 	if (ext.size == 0 || ext.data == NULL) {
2311 		gnutls_assert();
2312 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2313 	}
2314 
2315 	ret = gnutls_x509_ext_import_key_usage(&ext, skipcerts);
2316 	_gnutls_free_datum(&ext);
2317 
2318 	if (ret < 0) {
2319 		gnutls_assert();
2320 		return ret;
2321 	}
2322 
2323 	return 0;
2324 }
2325 
2326 /**
2327  * gnutls_x509_crt_get_proxy:
2328  * @cert: should contain a #gnutls_x509_crt_t type
2329  * @critical: will be non-zero if the extension is marked as critical
2330  * @pathlen: pointer to output integer indicating path length (may be
2331  *   NULL), non-negative error codes indicate a present pCPathLenConstraint
2332  *   field and the actual value, -1 indicate that the field is absent.
2333  * @policyLanguage: output variable with OID of policy language
2334  * @policy: output variable with policy data
2335  * @sizeof_policy: output variable size of policy data
2336  *
2337  * This function will get information from a proxy certificate.  It
2338  * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
2339  *
2340  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2341  *   otherwise a negative error code is returned.
2342  **/
2343 int
gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert,unsigned int * critical,int * pathlen,char ** policyLanguage,char ** policy,size_t * sizeof_policy)2344 gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert,
2345 			  unsigned int *critical,
2346 			  int *pathlen,
2347 			  char **policyLanguage,
2348 			  char **policy, size_t * sizeof_policy)
2349 {
2350 	int result;
2351 	gnutls_datum_t proxyCertInfo;
2352 
2353 	if (cert == NULL) {
2354 		gnutls_assert();
2355 		return GNUTLS_E_INVALID_REQUEST;
2356 	}
2357 
2358 	if ((result =
2359 	     _gnutls_x509_crt_get_extension(cert, "1.3.6.1.5.5.7.1.14", 0,
2360 					    &proxyCertInfo, critical)) < 0)
2361 	{
2362 		return result;
2363 	}
2364 
2365 	if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL) {
2366 		gnutls_assert();
2367 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2368 	}
2369 
2370 	result = gnutls_x509_ext_import_proxy(&proxyCertInfo, pathlen,
2371 							policyLanguage,
2372 							policy,
2373 							sizeof_policy);
2374 	_gnutls_free_datum(&proxyCertInfo);
2375 	if (result < 0) {
2376 		gnutls_assert();
2377 		return result;
2378 	}
2379 
2380 	return 0;
2381 }
2382 
2383 
2384 /**
2385  * gnutls_x509_policy_release:
2386  * @policy: a certificate policy
2387  *
2388  * This function will deinitialize all memory associated with the provided
2389  * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
2390  *
2391  * Since: 3.1.5
2392  **/
gnutls_x509_policy_release(struct gnutls_x509_policy_st * policy)2393 void gnutls_x509_policy_release(struct gnutls_x509_policy_st *policy)
2394 {
2395 	unsigned i;
2396 
2397 	gnutls_free(policy->oid);
2398 	for (i = 0; i < policy->qualifiers; i++)
2399 		gnutls_free(policy->qualifier[i].data);
2400 }
2401 
2402 
2403 /**
2404  * gnutls_x509_crt_get_policy:
2405  * @crt: should contain a #gnutls_x509_crt_t type
2406  * @indx: This specifies which policy to return. Use (0) to get the first one.
2407  * @policy: A pointer to a policy structure.
2408  * @critical: will be non-zero if the extension is marked as critical
2409  *
2410  * This function will extract the certificate policy (extension 2.5.29.32)
2411  * specified by the given index.
2412  *
2413  * The policy returned by this function must be deinitialized by using
2414  * gnutls_x509_policy_release().
2415  *
2416  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2417  * if the extension is not present, otherwise a negative error value.
2418  *
2419  * Since: 3.1.5
2420  **/
2421 int
gnutls_x509_crt_get_policy(gnutls_x509_crt_t crt,unsigned indx,struct gnutls_x509_policy_st * policy,unsigned int * critical)2422 gnutls_x509_crt_get_policy(gnutls_x509_crt_t crt, unsigned indx,
2423 			   struct gnutls_x509_policy_st *policy,
2424 			   unsigned int *critical)
2425 {
2426 	gnutls_datum_t tmpd = { NULL, 0 };
2427 	int ret;
2428 	gnutls_x509_policies_t policies = NULL;
2429 
2430 	if (crt == NULL) {
2431 		gnutls_assert();
2432 		return GNUTLS_E_INVALID_REQUEST;
2433 	}
2434 
2435 	memset(policy, 0, sizeof(*policy));
2436 
2437 	ret = gnutls_x509_policies_init(&policies);
2438 	if (ret < 0)
2439 		return gnutls_assert_val(ret);
2440 
2441 	if ((ret =
2442 	     _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &tmpd,
2443 					    critical)) < 0) {
2444 		goto cleanup;
2445 	}
2446 
2447 	if (tmpd.size == 0 || tmpd.data == NULL) {
2448 		gnutls_assert();
2449 		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2450 		goto cleanup;
2451 	}
2452 
2453 	ret = gnutls_x509_ext_import_policies(&tmpd, policies, 0);
2454 	if (ret < 0) {
2455 		gnutls_assert();
2456 		goto cleanup;
2457 	}
2458 
2459 	ret = gnutls_x509_policies_get(policies, indx, policy);
2460 	if (ret < 0) {
2461 		gnutls_assert();
2462 		goto cleanup;
2463 	}
2464 
2465 	_gnutls_x509_policies_erase(policies, indx);
2466 
2467 	ret = 0;
2468 
2469  cleanup:
2470 	if (policies != NULL)
2471 		gnutls_x509_policies_deinit(policies);
2472 	_gnutls_free_datum(&tmpd);
2473 
2474 	return ret;
2475 }
2476 
2477 
2478 /**
2479  * gnutls_x509_crt_get_extension_by_oid:
2480  * @cert: should contain a #gnutls_x509_crt_t type
2481  * @oid: holds an Object Identified in null terminated string
2482  * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2483  * @buf: a pointer to a structure to hold the name (may be null)
2484  * @buf_size: initially holds the size of @buf
2485  * @critical: will be non-zero if the extension is marked as critical
2486  *
2487  * This function will return the extension specified by the OID in the
2488  * certificate.  The extensions will be returned as binary data DER
2489  * encoded, in the provided buffer.
2490  *
2491  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2492  *   otherwise a negative error code is returned. If the certificate does not
2493  *   contain the specified extension
2494  *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2495  **/
2496 int
gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,const char * oid,unsigned indx,void * buf,size_t * buf_size,unsigned int * critical)2497 gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,
2498 				     const char *oid, unsigned indx,
2499 				     void *buf, size_t * buf_size,
2500 				     unsigned int *critical)
2501 {
2502 	int result;
2503 	gnutls_datum_t output;
2504 
2505 	if (cert == NULL) {
2506 		gnutls_assert();
2507 		return GNUTLS_E_INVALID_REQUEST;
2508 	}
2509 
2510 	if ((result =
2511 	     _gnutls_x509_crt_get_extension(cert, oid, indx, &output,
2512 					    critical)) < 0) {
2513 		gnutls_assert();
2514 		return result;
2515 	}
2516 
2517 	if (output.size == 0 || output.data == NULL) {
2518 		gnutls_assert();
2519 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2520 	}
2521 
2522 	if (output.size > (unsigned int) *buf_size) {
2523 		*buf_size = output.size;
2524 		_gnutls_free_datum(&output);
2525 		return GNUTLS_E_SHORT_MEMORY_BUFFER;
2526 	}
2527 
2528 	*buf_size = output.size;
2529 
2530 	if (buf)
2531 		memcpy(buf, output.data, output.size);
2532 
2533 	_gnutls_free_datum(&output);
2534 
2535 	return 0;
2536 }
2537 
2538 /**
2539  * gnutls_x509_crt_get_extension_by_oid2:
2540  * @cert: should contain a #gnutls_x509_crt_t type
2541  * @oid: holds an Object Identified in null terminated string
2542  * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
2543  * @output: will hold the allocated extension data
2544  * @critical: will be non-zero if the extension is marked as critical
2545  *
2546  * This function will return the extension specified by the OID in the
2547  * certificate.  The extensions will be returned as binary data DER
2548  * encoded, in the provided buffer.
2549  *
2550  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2551  *   otherwise a negative error code is returned. If the certificate does not
2552  *   contain the specified extension
2553  *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2554  *
2555  * Since: 3.3.8
2556  **/
2557 int
gnutls_x509_crt_get_extension_by_oid2(gnutls_x509_crt_t cert,const char * oid,unsigned indx,gnutls_datum_t * output,unsigned int * critical)2558 gnutls_x509_crt_get_extension_by_oid2(gnutls_x509_crt_t cert,
2559 				     const char *oid, unsigned indx,
2560 				     gnutls_datum_t *output,
2561 				     unsigned int *critical)
2562 {
2563 	int ret;
2564 
2565 	if (cert == NULL) {
2566 		gnutls_assert();
2567 		return GNUTLS_E_INVALID_REQUEST;
2568 	}
2569 
2570 	if ((ret =
2571 	     _gnutls_x509_crt_get_extension(cert, oid, indx, output,
2572 					    critical)) < 0) {
2573 		gnutls_assert();
2574 		return ret;
2575 	}
2576 
2577 	if (output->size == 0 || output->data == NULL) {
2578 		gnutls_assert();
2579 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2580 	}
2581 
2582 	return 0;
2583 }
2584 
2585 /**
2586  * gnutls_x509_crt_get_extension_oid:
2587  * @cert: should contain a #gnutls_x509_crt_t type
2588  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2589  * @oid: a pointer to a structure to hold the OID (may be null)
2590  * @oid_size: initially holds the size of @oid
2591  *
2592  * This function will return the requested extension OID in the certificate.
2593  * The extension OID will be stored as a string in the provided buffer.
2594  *
2595  * The @oid returned will be null terminated, although @oid_size will not
2596  * account for the trailing null.
2597  *
2598  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2599  *   otherwise a negative error code is returned.  If you have reached the
2600  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2601  *   will be returned.
2602  **/
2603 int
gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert,unsigned indx,void * oid,size_t * oid_size)2604 gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert, unsigned indx,
2605 				  void *oid, size_t * oid_size)
2606 {
2607 	int result;
2608 
2609 	if (cert == NULL) {
2610 		gnutls_assert();
2611 		return GNUTLS_E_INVALID_REQUEST;
2612 	}
2613 
2614 	result =
2615 	    _gnutls_x509_crt_get_extension_oid(cert, indx, oid, oid_size);
2616 	if (result < 0) {
2617 		return result;
2618 	}
2619 
2620 	return 0;
2621 
2622 }
2623 
2624 /**
2625  * gnutls_x509_crt_get_extension_info:
2626  * @cert: should contain a #gnutls_x509_crt_t type
2627  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2628  * @oid: a pointer to a structure to hold the OID
2629  * @oid_size: initially holds the maximum size of @oid, on return
2630  *   holds actual size of @oid.
2631  * @critical: output variable with critical flag, may be NULL.
2632  *
2633  * This function will return the requested extension OID in the
2634  * certificate, and the critical flag for it.  The extension OID will
2635  * be stored as a string in the provided buffer.  Use
2636  * gnutls_x509_crt_get_extension() to extract the data.
2637  *
2638  * If the buffer provided is not long enough to hold the output, then
2639  * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2640  * returned. The @oid returned will be null terminated, although
2641  * @oid_size will not account for the trailing null (the latter is not
2642  * true for GnuTLS prior to 3.6.0).
2643  *
2644  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2645  *   otherwise a negative error code is returned.  If you have reached the
2646  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2647  *   will be returned.
2648  **/
2649 int
gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert,unsigned indx,void * oid,size_t * oid_size,unsigned int * critical)2650 gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert, unsigned indx,
2651 				   void *oid, size_t * oid_size,
2652 				   unsigned int *critical)
2653 {
2654 	int result;
2655 	char str_critical[10];
2656 	char name[MAX_NAME_SIZE];
2657 	int len;
2658 
2659 	if (!cert) {
2660 		gnutls_assert();
2661 		return GNUTLS_E_INVALID_REQUEST;
2662 	}
2663 
2664 	snprintf(name, sizeof(name),
2665 		 "tbsCertificate.extensions.?%u.extnID", indx + 1);
2666 
2667 	len = *oid_size;
2668 	result = asn1_read_value(cert->cert, name, oid, &len);
2669 	*oid_size = len;
2670 
2671 	if (result == ASN1_ELEMENT_NOT_FOUND)
2672 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2673 	else if (result != ASN1_SUCCESS) {
2674 		gnutls_assert();
2675 		return _gnutls_asn2err(result);
2676 	}
2677 
2678 	/* remove any trailing null */
2679 	if (oid && len > 0 && ((uint8_t*)oid)[len-1] == 0)
2680 		(*oid_size)--;
2681 
2682 	if (critical) {
2683 		snprintf(name, sizeof(name),
2684 			 "tbsCertificate.extensions.?%u.critical", indx + 1);
2685 		len = sizeof(str_critical);
2686 		result = asn1_read_value(cert->cert, name, str_critical, &len);
2687 		if (result != ASN1_SUCCESS) {
2688 			gnutls_assert();
2689 			return _gnutls_asn2err(result);
2690 		}
2691 
2692 		if (str_critical[0] == 'T')
2693 			*critical = 1;
2694 		else
2695 			*critical = 0;
2696 	}
2697 
2698 	return 0;
2699 
2700 }
2701 
2702 /**
2703  * gnutls_x509_crt_get_extension_data:
2704  * @cert: should contain a #gnutls_x509_crt_t type
2705  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2706  * @data: a pointer to a structure to hold the data (may be null)
2707  * @sizeof_data: initially holds the size of @data
2708  *
2709  * This function will return the requested extension data in the
2710  * certificate.  The extension data will be stored in the
2711  * provided buffer.
2712  *
2713  * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2714  * critical flag.  Use gnutls_x509_crt_get_extension_by_oid() instead,
2715  * if you want to get data indexed by the extension OID rather than
2716  * sequence.
2717  *
2718  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2719  *   otherwise a negative error code is returned.  If you have reached the
2720  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2721  *   will be returned.
2722  **/
2723 int
gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert,unsigned indx,void * data,size_t * sizeof_data)2724 gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert, unsigned indx,
2725 				   void *data, size_t * sizeof_data)
2726 {
2727 	int result, len;
2728 	char name[MAX_NAME_SIZE];
2729 
2730 	if (!cert) {
2731 		gnutls_assert();
2732 		return GNUTLS_E_INVALID_REQUEST;
2733 	}
2734 
2735 	snprintf(name, sizeof(name),
2736 		 "tbsCertificate.extensions.?%u.extnValue", indx + 1);
2737 
2738 	len = *sizeof_data;
2739 	result = asn1_read_value(cert->cert, name, data, &len);
2740 	*sizeof_data = len;
2741 
2742 	if (result == ASN1_ELEMENT_NOT_FOUND) {
2743 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2744 	} else if (result == ASN1_MEM_ERROR && data == NULL) {
2745 		/* normally we should return GNUTLS_E_SHORT_MEMORY_BUFFER,
2746 		 * but we haven't done that for long time, so use
2747 		 * backwards compatible behavior */
2748 		return 0;
2749 	} else if (result != ASN1_SUCCESS) {
2750 		gnutls_assert();
2751 		return _gnutls_asn2err(result);
2752 	}
2753 
2754 	return 0;
2755 }
2756 
2757 /**
2758  * gnutls_x509_crt_get_raw_issuer_dn:
2759  * @cert: should contain a #gnutls_x509_crt_t type
2760  * @dn: will hold the starting point of the DN
2761  *
2762  * This function will return a pointer to the DER encoded DN structure
2763  * and the length. This points to allocated data that must be free'd using gnutls_free().
2764  *
2765  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2766  *   negative error value.or a negative error code on error.
2767  *
2768  **/
2769 int
gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,gnutls_datum_t * dn)2770 gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,
2771 				  gnutls_datum_t * dn)
2772 {
2773 	if (cert->raw_issuer_dn.size > 0 && cert->modified == 0) {
2774 		return _gnutls_set_datum(dn, cert->raw_issuer_dn.data,
2775 					 cert->raw_issuer_dn.size);
2776 	} else {
2777 		return _gnutls_x509_get_raw_field(cert->cert, "tbsCertificate.issuer.rdnSequence", dn);
2778 	}
2779 }
2780 
2781 /**
2782  * gnutls_x509_crt_get_raw_dn:
2783  * @cert: should contain a #gnutls_x509_crt_t type
2784  * @dn: will hold the starting point of the DN
2785  *
2786  * This function will return a pointer to the DER encoded DN structure and
2787  * the length. This points to allocated data that must be free'd using gnutls_free().
2788  *
2789  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2790  *   negative error value. or a negative error code on error.
2791  *
2792  **/
gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert,gnutls_datum_t * dn)2793 int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
2794 {
2795 	if (cert->raw_dn.size > 0 && cert->modified == 0) {
2796 		return _gnutls_set_datum(dn, cert->raw_dn.data, cert->raw_dn.size);
2797 	} else {
2798 		return _gnutls_x509_get_raw_field(cert->cert, "tbsCertificate.subject.rdnSequence", dn);
2799 	}
2800 }
2801 
2802 static int
get_dn(gnutls_x509_crt_t cert,const char * whom,gnutls_x509_dn_t * dn,unsigned subject)2803 get_dn(gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn, unsigned subject)
2804 {
2805 	gnutls_x509_dn_st *store;
2806 
2807 	if (subject)
2808 		store = &cert->dn;
2809 	else
2810 		store = &cert->idn;
2811 
2812 	store->asn = asn1_find_node(cert->cert, whom);
2813 	if (!store->asn)
2814 		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2815 
2816 	*dn = store;
2817 
2818 	return 0;
2819 }
2820 
2821 /**
2822  * gnutls_x509_crt_get_subject:
2823  * @cert: should contain a #gnutls_x509_crt_t type
2824  * @dn: output variable with pointer to uint8_t DN.
2825  *
2826  * Return the Certificate's Subject DN as a %gnutls_x509_dn_t data type,
2827  * that can be decoded using gnutls_x509_dn_get_rdn_ava().
2828  *
2829  * Note that @dn should be treated as constant. Because it points
2830  * into the @cert object, you should not use @dn after @cert is
2831  * deallocated.
2832  *
2833  * Returns: Returns 0 on success, or an error code.
2834  **/
2835 int
gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert,gnutls_x509_dn_t * dn)2836 gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2837 {
2838 	return get_dn(cert, "tbsCertificate.subject.rdnSequence", dn, 1);
2839 }
2840 
2841 /**
2842  * gnutls_x509_crt_get_issuer:
2843  * @cert: should contain a #gnutls_x509_crt_t type
2844  * @dn: output variable with pointer to uint8_t DN
2845  *
2846  * Return the Certificate's Issuer DN as a %gnutls_x509_dn_t data type,
2847  * that can be decoded using gnutls_x509_dn_get_rdn_ava().
2848  *
2849  * Note that @dn should be treated as constant. Because it points
2850  * into the @cert object, you should not use @dn after @cert is
2851  * deallocated.
2852  *
2853  * Returns: Returns 0 on success, or an error code.
2854  **/
2855 int
gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert,gnutls_x509_dn_t * dn)2856 gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2857 {
2858 	return get_dn(cert, "tbsCertificate.issuer.rdnSequence", dn, 0);
2859 }
2860 
2861 /**
2862  * gnutls_x509_crt_get_fingerprint:
2863  * @cert: should contain a #gnutls_x509_crt_t type
2864  * @algo: is a digest algorithm
2865  * @buf: a pointer to a structure to hold the fingerprint (may be null)
2866  * @buf_size: initially holds the size of @buf
2867  *
2868  * This function will calculate and copy the certificate's fingerprint
2869  * in the provided buffer. The fingerprint is a hash of the DER-encoded
2870  * data of the certificate.
2871  *
2872  * If the buffer is null then only the size will be filled.
2873  *
2874  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2875  *   not long enough, and in that case the *buf_size will be updated
2876  *   with the required size.  On success 0 is returned.
2877  **/
2878 int
gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,gnutls_digest_algorithm_t algo,void * buf,size_t * buf_size)2879 gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,
2880 				gnutls_digest_algorithm_t algo,
2881 				void *buf, size_t * buf_size)
2882 {
2883 	uint8_t *cert_buf;
2884 	int cert_buf_size;
2885 	int result;
2886 	gnutls_datum_t tmp;
2887 
2888 	if (buf_size == 0 || cert == NULL) {
2889 		return GNUTLS_E_INVALID_REQUEST;
2890 	}
2891 
2892 	cert_buf_size = 0;
2893 	result = asn1_der_coding(cert->cert, "", NULL, &cert_buf_size, NULL);
2894 	if (result != ASN1_MEM_ERROR) {
2895 		gnutls_assert();
2896 		return _gnutls_asn2err(result);
2897 	}
2898 
2899 	cert_buf = gnutls_malloc(cert_buf_size);
2900 	if (cert_buf == NULL) {
2901 		gnutls_assert();
2902 		return GNUTLS_E_MEMORY_ERROR;
2903 	}
2904 
2905 	result =
2906 	    asn1_der_coding(cert->cert, "", cert_buf, &cert_buf_size,
2907 			    NULL);
2908 
2909 	if (result != ASN1_SUCCESS) {
2910 		gnutls_assert();
2911 		gnutls_free(cert_buf);
2912 		return _gnutls_asn2err(result);
2913 	}
2914 
2915 	tmp.data = cert_buf;
2916 	tmp.size = cert_buf_size;
2917 
2918 	result = gnutls_fingerprint(algo, &tmp, buf, buf_size);
2919 	gnutls_free(cert_buf);
2920 
2921 	return result;
2922 }
2923 
2924 /**
2925  * gnutls_x509_crt_export:
2926  * @cert: Holds the certificate
2927  * @format: the format of output params. One of PEM or DER.
2928  * @output_data: will contain a certificate PEM or DER encoded
2929  * @output_data_size: holds the size of output_data (and will be
2930  *   replaced by the actual size of parameters)
2931  *
2932  * This function will export the certificate to DER or PEM format.
2933  *
2934  * If the buffer provided is not long enough to hold the output, then
2935  * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2936  * be returned.
2937  *
2938  * If the structure is PEM encoded, it will have a header
2939  * of "BEGIN CERTIFICATE".
2940  *
2941  * Returns: In case of failure a negative error code will be
2942  *   returned, and 0 on success.
2943  **/
2944 int
gnutls_x509_crt_export(gnutls_x509_crt_t cert,gnutls_x509_crt_fmt_t format,void * output_data,size_t * output_data_size)2945 gnutls_x509_crt_export(gnutls_x509_crt_t cert,
2946 		       gnutls_x509_crt_fmt_t format, void *output_data,
2947 		       size_t * output_data_size)
2948 {
2949 	gnutls_datum_t out;
2950 	int ret;
2951 
2952 	ret = gnutls_x509_crt_export2(cert, format, &out);
2953 	if (ret < 0)
2954 		return gnutls_assert_val(ret);
2955 
2956 	if (format == GNUTLS_X509_FMT_PEM)
2957 		ret = _gnutls_copy_string(&out, (uint8_t*)output_data, output_data_size);
2958 	else
2959 		ret = _gnutls_copy_data(&out, (uint8_t*)output_data, output_data_size);
2960 	if (ret < 0) {
2961 		gnutls_assert();
2962 		goto cleanup;
2963 	}
2964 
2965 	ret = 0;
2966  cleanup:
2967 	gnutls_free(out.data);
2968 	return ret;
2969 }
2970 
2971 /**
2972  * gnutls_x509_crt_export2:
2973  * @cert: Holds the certificate
2974  * @format: the format of output params. One of PEM or DER.
2975  * @out: will contain a certificate PEM or DER encoded
2976  *
2977  * This function will export the certificate to DER or PEM format.
2978  * The output buffer is allocated using gnutls_malloc().
2979  *
2980  * If the structure is PEM encoded, it will have a header
2981  * of "BEGIN CERTIFICATE".
2982  *
2983  * Returns: In case of failure a negative error code will be
2984  *   returned, and 0 on success.
2985  *
2986  * Since: 3.1.3
2987  **/
2988 int
gnutls_x509_crt_export2(gnutls_x509_crt_t cert,gnutls_x509_crt_fmt_t format,gnutls_datum_t * out)2989 gnutls_x509_crt_export2(gnutls_x509_crt_t cert,
2990 			gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
2991 {
2992 	if (cert == NULL) {
2993 		gnutls_assert();
2994 		return GNUTLS_E_INVALID_REQUEST;
2995 	}
2996 
2997 	if (!cert->modified && cert->der.size) {
2998 		if (format == GNUTLS_X509_FMT_DER)
2999 			return _gnutls_set_datum(out, cert->der.data, cert->der.size);
3000 		else {
3001 			int ret = _gnutls_fbase64_encode(PEM_X509_CERT2,
3002 							 cert->der.data,
3003 							 cert->der.size,
3004 							 out);
3005 			if (ret < 0)
3006 				return ret;
3007 			return 0;
3008 		}
3009 	}
3010 
3011 	return _gnutls_x509_export_int2(cert->cert, format, PEM_X509_CERT2,
3012 					out);
3013 }
3014 
3015 int
_gnutls_get_key_id(gnutls_pk_params_st * params,unsigned char * output_data,size_t * output_data_size,unsigned flags)3016 _gnutls_get_key_id(gnutls_pk_params_st * params,
3017 		   unsigned char *output_data, size_t * output_data_size,
3018 		   unsigned flags)
3019 {
3020 	int ret = 0;
3021 	gnutls_datum_t der = { NULL, 0 };
3022 	gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
3023 	unsigned int digest_len;
3024 
3025 	if ((flags & GNUTLS_KEYID_USE_SHA512) || (flags & GNUTLS_KEYID_USE_BEST_KNOWN))
3026 		hash = GNUTLS_DIG_SHA512;
3027 	else if (flags & GNUTLS_KEYID_USE_SHA256)
3028 		hash = GNUTLS_DIG_SHA256;
3029 
3030 	digest_len =
3031 	    _gnutls_hash_get_algo_len(hash_to_entry(hash));
3032 
3033 	if (output_data == NULL || *output_data_size < digest_len) {
3034 		gnutls_assert();
3035 		*output_data_size = digest_len;
3036 		return GNUTLS_E_SHORT_MEMORY_BUFFER;
3037 	}
3038 
3039 	ret = _gnutls_x509_encode_PKI_params(&der, params);
3040 	if (ret < 0)
3041 		return gnutls_assert_val(ret);
3042 
3043 	ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
3044 	if (ret < 0) {
3045 		gnutls_assert();
3046 		goto cleanup;
3047 	}
3048 	*output_data_size = digest_len;
3049 
3050 	ret = 0;
3051 
3052       cleanup:
3053 
3054 	_gnutls_free_datum(&der);
3055 	return ret;
3056 }
3057 
3058 /**
3059  * gnutls_x509_crt_get_key_id:
3060  * @crt: Holds the certificate
3061  * @flags: should be one of the flags from %gnutls_keyid_flags_t
3062  * @output_data: will contain the key ID
3063  * @output_data_size: holds the size of output_data (and will be
3064  *   replaced by the actual size of parameters)
3065  *
3066  * This function will return a unique ID that depends on the public
3067  * key parameters. This ID can be used in checking whether a
3068  * certificate corresponds to the given private key.
3069  *
3070  * If the buffer provided is not long enough to hold the output, then
3071  * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
3072  * be returned.  The output will normally be a SHA-1 hash output,
3073  * which is 20 bytes.
3074  *
3075  * Returns: In case of failure a negative error code will be
3076  *   returned, and 0 on success.
3077  **/
3078 int
gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt,unsigned int flags,unsigned char * output_data,size_t * output_data_size)3079 gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt, unsigned int flags,
3080 			   unsigned char *output_data,
3081 			   size_t * output_data_size)
3082 {
3083 	int ret = 0;
3084 	gnutls_pk_params_st params;
3085 
3086 	if (crt == NULL) {
3087 		gnutls_assert();
3088 		return GNUTLS_E_INVALID_REQUEST;
3089 	}
3090 
3091 	/* initializes params */
3092 	ret = _gnutls_x509_crt_get_mpis(crt, &params);
3093 	if (ret < 0) {
3094 		gnutls_assert();
3095 		return ret;
3096 	}
3097 
3098 	ret =
3099 	    _gnutls_get_key_id(&params, output_data, output_data_size, flags);
3100 
3101 	gnutls_pk_params_release(&params);
3102 
3103 	return ret;
3104 }
3105 
3106 static int
crl_issuer_matches(gnutls_x509_crl_t crl,gnutls_x509_crt_t cert)3107 crl_issuer_matches(gnutls_x509_crl_t crl, gnutls_x509_crt_t cert)
3108 {
3109 	if (_gnutls_x509_compare_raw_dn
3110 	    (&crl->raw_issuer_dn, &cert->raw_issuer_dn) != 0)
3111 		return 1;
3112 	else
3113 		return 0;
3114 }
3115 
3116 /* This is exactly as gnutls_x509_crt_check_revocation() except that
3117  * it calls func.
3118  */
3119 int
_gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,const gnutls_x509_crl_t * crl_list,int crl_list_length,gnutls_verify_output_function func)3120 _gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3121 				  const gnutls_x509_crl_t * crl_list,
3122 				  int crl_list_length,
3123 				  gnutls_verify_output_function func)
3124 {
3125 	uint8_t serial[128];
3126 	uint8_t cert_serial[128];
3127 	size_t serial_size, cert_serial_size;
3128 	int ret, j;
3129 	gnutls_x509_crl_iter_t iter = NULL;
3130 
3131 	if (cert == NULL) {
3132 		gnutls_assert();
3133 		return GNUTLS_E_INVALID_REQUEST;
3134 	}
3135 
3136 	for (j = 0; j < crl_list_length; j++) {	/* do for all the crls */
3137 
3138 		/* Step 1. check if issuer's DN match
3139 		 */
3140 		ret = crl_issuer_matches(crl_list[j], cert);
3141 		if (ret == 0) {
3142 			/* issuers do not match so don't even
3143 			 * bother checking.
3144 			 */
3145 			gnutls_assert();
3146 			continue;
3147 		}
3148 
3149 		/* Step 2. Read the certificate's serial number
3150 		 */
3151 		cert_serial_size = sizeof(cert_serial);
3152 		ret =
3153 		    gnutls_x509_crt_get_serial(cert, cert_serial,
3154 					       &cert_serial_size);
3155 		if (ret < 0) {
3156 			gnutls_assert();
3157 			return ret;
3158 		}
3159 
3160 		/* Step 3. cycle through the CRL serials and compare with
3161 		 *   certificate serial we have.
3162 		 */
3163 
3164 		iter = NULL;
3165 		do {
3166 			serial_size = sizeof(serial);
3167 			ret =
3168 			    gnutls_x509_crl_iter_crt_serial(crl_list[j],
3169 							    &iter,
3170 							    serial,
3171 							    &serial_size,
3172 							    NULL);
3173 			if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
3174 				break;
3175 			} else if (ret < 0) {
3176 				gnutls_assert();
3177 				goto fail;
3178 			}
3179 
3180 			if (serial_size == cert_serial_size) {
3181 				if (memcmp
3182 				    (serial, cert_serial,
3183 				     serial_size) == 0) {
3184 					/* serials match */
3185 					if (func)
3186 						func(cert, NULL,
3187 						     crl_list[j],
3188 						     GNUTLS_CERT_REVOKED |
3189 						     GNUTLS_CERT_INVALID);
3190 					ret = 1;	/* revoked! */
3191 					goto fail;
3192 				}
3193 			}
3194 		} while(1);
3195 
3196 		gnutls_x509_crl_iter_deinit(iter);
3197 		iter = NULL;
3198 
3199 		if (func)
3200 			func(cert, NULL, crl_list[j], 0);
3201 
3202 	}
3203 	return 0;		/* not revoked. */
3204 
3205  fail:
3206 	gnutls_x509_crl_iter_deinit(iter);
3207 	return ret;
3208 }
3209 
3210 
3211 /**
3212  * gnutls_x509_crt_check_revocation:
3213  * @cert: should contain a #gnutls_x509_crt_t type
3214  * @crl_list: should contain a list of gnutls_x509_crl_t types
3215  * @crl_list_length: the length of the crl_list
3216  *
3217  * This function will check if the given certificate is
3218  * revoked.  It is assumed that the CRLs have been verified before.
3219  *
3220  * Returns: 0 if the certificate is NOT revoked, and 1 if it is.  A
3221  * negative error code is returned on error.
3222  **/
3223 int
gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,const gnutls_x509_crl_t * crl_list,unsigned crl_list_length)3224 gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
3225 				 const gnutls_x509_crl_t * crl_list,
3226 				 unsigned crl_list_length)
3227 {
3228 	return _gnutls_x509_crt_check_revocation(cert, crl_list,
3229 						 crl_list_length, NULL);
3230 }
3231 
3232 /**
3233  * gnutls_x509_crt_check_key_purpose:
3234  * @cert: should contain a #gnutls_x509_crt_t type
3235  * @purpose: a key purpose OID (e.g., %GNUTLS_KP_CODE_SIGNING)
3236  * @flags: zero or %GNUTLS_KP_FLAG_DISALLOW_ANY
3237  *
3238  * This function will check whether the given certificate matches
3239  * the provided key purpose. If @flags contains %GNUTLS_KP_FLAG_ALLOW_ANY then
3240  * it a certificate marked for any purpose will not match.
3241  *
3242  * Returns: zero if the key purpose doesn't match, and non-zero otherwise.
3243  *
3244  * Since: 3.5.6
3245  **/
3246 unsigned
gnutls_x509_crt_check_key_purpose(gnutls_x509_crt_t cert,const char * purpose,unsigned flags)3247 gnutls_x509_crt_check_key_purpose(gnutls_x509_crt_t cert,
3248 				 const char *purpose,
3249 				 unsigned flags)
3250 {
3251 	return _gnutls_check_key_purpose(cert, purpose, (flags&GNUTLS_KP_FLAG_DISALLOW_ANY)?1:0);
3252 }
3253 
3254 /**
3255  * gnutls_x509_crt_get_preferred_hash_algorithm:
3256  * @crt: Holds the certificate
3257  * @hash: The result of the call with the hash algorithm used for signature
3258  * @mand: If non-zero it means that the algorithm MUST use this hash. May be %NULL.
3259  *
3260  * This function will read the certificate and return the appropriate digest
3261  * algorithm to use for signing with this certificate. Some certificates (i.e.
3262  * DSA might not be able to sign without the preferred algorithm).
3263  *
3264  * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
3265  *
3266  * Returns: the 0 if the hash algorithm is found. A negative error code is
3267  * returned on error.
3268  *
3269  * Since: 2.12.0
3270  **/
3271 int
gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,gnutls_digest_algorithm_t * hash,unsigned int * mand)3272 gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,
3273 					     gnutls_digest_algorithm_t *
3274 					     hash, unsigned int *mand)
3275 {
3276 	int ret;
3277 	gnutls_pubkey_t pubkey;
3278 
3279 	if (crt == NULL) {
3280 		gnutls_assert();
3281 		return GNUTLS_E_INVALID_REQUEST;
3282 	}
3283 
3284 	ret = gnutls_pubkey_init(&pubkey);
3285 	if (ret < 0)
3286 		return gnutls_assert_val(ret);
3287 
3288 	ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3289 	if (ret < 0) {
3290 		gnutls_assert();
3291 		goto cleanup;
3292 	}
3293 
3294 	ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, hash, mand);
3295 	if (ret < 0) {
3296 		gnutls_assert();
3297 		goto cleanup;
3298 	}
3299 
3300  cleanup:
3301 	gnutls_pubkey_deinit(pubkey);
3302 	return ret;
3303 }
3304 
3305 /**
3306  * gnutls_x509_crt_get_crl_dist_points:
3307  * @cert: should contain a #gnutls_x509_crt_t type
3308  * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
3309  * @san: is the place where the distribution point will be copied to
3310  * @san_size: holds the size of ret.
3311  * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
3312  * @critical: will be non-zero if the extension is marked as critical (may be null)
3313  *
3314  * This function retrieves the CRL distribution points (2.5.29.31),
3315  * contained in the given certificate in the X509v3 Certificate
3316  * Extensions.
3317  *
3318  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
3319  *   @ret_size is not enough to hold the distribution point, or the
3320  *   type of the distribution point if everything was ok. The type is
3321  *   one of the enumerated %gnutls_x509_subject_alt_name_t.  If the
3322  *   certificate does not have an Alternative name with the specified
3323  *   sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
3324  *   returned.
3325  **/
3326 int
gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,unsigned int seq,void * san,size_t * san_size,unsigned int * reason_flags,unsigned int * critical)3327 gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
3328 				    unsigned int seq, void *san,
3329 				    size_t * san_size,
3330 				    unsigned int *reason_flags,
3331 				    unsigned int *critical)
3332 {
3333 	int ret;
3334 	gnutls_datum_t dist_points = { NULL, 0 };
3335 	unsigned type;
3336 	gnutls_x509_crl_dist_points_t cdp = NULL;
3337 	gnutls_datum_t t_san;
3338 
3339 	if (cert == NULL) {
3340 		gnutls_assert();
3341 		return GNUTLS_E_INVALID_REQUEST;
3342 	}
3343 
3344 	ret = gnutls_x509_crl_dist_points_init(&cdp);
3345 	if (ret < 0)
3346 		return gnutls_assert_val(ret);
3347 
3348 	if (reason_flags)
3349 		*reason_flags = 0;
3350 
3351 	ret =
3352 	    _gnutls_x509_crt_get_extension(cert, "2.5.29.31", 0,
3353 					   &dist_points, critical);
3354 	if (ret < 0) {
3355 		gnutls_assert();
3356 		goto cleanup;
3357 	}
3358 
3359 	if (dist_points.size == 0 || dist_points.data == NULL) {
3360 		gnutls_assert();
3361 		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3362 		goto cleanup;
3363 	}
3364 
3365 	ret = gnutls_x509_ext_import_crl_dist_points(&dist_points, cdp, 0);
3366 	if (ret < 0) {
3367 		gnutls_assert();
3368 		goto cleanup;
3369 	}
3370 
3371 	ret = gnutls_x509_crl_dist_points_get(cdp, seq, &type, &t_san, reason_flags);
3372 	if (ret < 0) {
3373 		gnutls_assert();
3374 		goto cleanup;
3375 	}
3376 
3377 	ret = _gnutls_copy_string(&t_san, san, san_size);
3378 	if (ret < 0) {
3379 		gnutls_assert();
3380 		goto cleanup;
3381 	}
3382 
3383 	ret = type;
3384 
3385  cleanup:
3386 	_gnutls_free_datum(&dist_points);
3387 	if (cdp != NULL)
3388 		gnutls_x509_crl_dist_points_deinit(cdp);
3389 
3390 	return ret;
3391 }
3392 
3393 /**
3394  * gnutls_x509_crt_get_key_purpose_oid:
3395  * @cert: should contain a #gnutls_x509_crt_t type
3396  * @indx: This specifies which OID to return. Use (0) to get the first one.
3397  * @oid: a pointer to a buffer to hold the OID (may be null)
3398  * @oid_size: initially holds the size of @oid
3399  * @critical: output flag to indicate criticality of extension
3400  *
3401  * This function will extract the key purpose OIDs of the Certificate
3402  * specified by the given index.  These are stored in the Extended Key
3403  * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
3404  * human readable names.
3405  *
3406  * If @oid is null then only the size will be filled. The @oid
3407  * returned will be null terminated, although @oid_size will not
3408  * account for the trailing null.
3409  *
3410  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
3411  *   not long enough, and in that case the *oid_size will be updated
3412  *   with the required size.  On success 0 is returned.
3413  **/
3414 int
gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert,unsigned indx,void * oid,size_t * oid_size,unsigned int * critical)3415 gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert,
3416 				    unsigned indx, void *oid, size_t * oid_size,
3417 				    unsigned int *critical)
3418 {
3419 	int ret;
3420 	gnutls_datum_t ext;
3421 	gnutls_x509_key_purposes_t p = NULL;
3422 	gnutls_datum_t out;
3423 
3424 	if (cert == NULL) {
3425 		gnutls_assert();
3426 		return GNUTLS_E_INVALID_REQUEST;
3427 	}
3428 
3429 	if (oid)
3430 		memset(oid, 0, *oid_size);
3431 	else
3432 		*oid_size = 0;
3433 
3434 	if ((ret =
3435 	     _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &ext,
3436 					    critical)) < 0) {
3437 		return ret;
3438 	}
3439 
3440 	if (ext.size == 0 || ext.data == NULL) {
3441 		gnutls_assert();
3442 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3443 	}
3444 
3445 	ret = gnutls_x509_key_purpose_init(&p);
3446 	if (ret < 0) {
3447 		gnutls_assert();
3448 		goto cleanup;
3449 	}
3450 
3451 	ret = gnutls_x509_ext_import_key_purposes(&ext, p, 0);
3452 	if (ret < 0) {
3453 		gnutls_assert();
3454 		goto cleanup;
3455 	}
3456 
3457 	ret = gnutls_x509_key_purpose_get(p, indx, &out);
3458 	if (ret < 0) {
3459 		gnutls_assert();
3460 		goto cleanup;
3461 	}
3462 
3463 	ret = _gnutls_copy_string(&out, oid, oid_size);
3464 	if (ret < 0) {
3465 		gnutls_assert();
3466 		goto cleanup;
3467 	}
3468 
3469 	ret = 0;
3470 
3471  cleanup:
3472 	gnutls_free(ext.data);
3473 	if (p!=NULL)
3474 		gnutls_x509_key_purpose_deinit(p);
3475 	return ret;
3476 }
3477 
3478 /**
3479  * gnutls_x509_crt_get_pk_rsa_raw:
3480  * @crt: Holds the certificate
3481  * @m: will hold the modulus
3482  * @e: will hold the public exponent
3483  *
3484  * This function will export the RSA public key's parameters found in
3485  * the given structure.  The new parameters will be allocated using
3486  * gnutls_malloc() and will be stored in the appropriate datum.
3487  *
3488  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3489  **/
3490 int
gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt,gnutls_datum_t * m,gnutls_datum_t * e)3491 gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt,
3492 			       gnutls_datum_t * m, gnutls_datum_t * e)
3493 {
3494 	int ret;
3495 	gnutls_pubkey_t pubkey;
3496 
3497 	if (crt == NULL) {
3498 		gnutls_assert();
3499 		return GNUTLS_E_INVALID_REQUEST;
3500 	}
3501 
3502 	ret = gnutls_pubkey_init(&pubkey);
3503 	if (ret < 0)
3504 		return gnutls_assert_val(ret);
3505 
3506 	ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3507 	if (ret < 0) {
3508 		gnutls_assert();
3509 		goto cleanup;
3510 	}
3511 
3512 	ret = gnutls_pubkey_export_rsa_raw(pubkey, m, e);
3513 	if (ret < 0) {
3514 		gnutls_assert();
3515 		goto cleanup;
3516 	}
3517 
3518  cleanup:
3519 	gnutls_pubkey_deinit(pubkey);
3520 	return ret;
3521 }
3522 
3523 /**
3524  * gnutls_x509_crt_get_pk_ecc_raw:
3525  * @crt: Holds the certificate
3526  * @curve: will hold the curve
3527  * @x: will hold the x-coordinate
3528  * @y: will hold the y-coordinate
3529  *
3530  * This function will export the ECC public key's parameters found in
3531  * the given certificate.  The new parameters will be allocated using
3532  * gnutls_malloc() and will be stored in the appropriate datum.
3533  *
3534  * In EdDSA curves the @y parameter will be %NULL and the other parameters
3535  * will be in the native format for the curve.
3536  *
3537  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3538  *
3539  * Since: 3.4.1
3540  **/
3541 int
gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,gnutls_ecc_curve_t * curve,gnutls_datum_t * x,gnutls_datum_t * y)3542 gnutls_x509_crt_get_pk_ecc_raw(gnutls_x509_crt_t crt,
3543 			       gnutls_ecc_curve_t *curve,
3544 			       gnutls_datum_t *x, gnutls_datum_t *y)
3545 {
3546 	int ret;
3547 	gnutls_pubkey_t pubkey;
3548 
3549 	if (crt == NULL) {
3550 		gnutls_assert();
3551 		return GNUTLS_E_INVALID_REQUEST;
3552 	}
3553 
3554 	ret = gnutls_pubkey_init(&pubkey);
3555 	if (ret < 0)
3556 		return gnutls_assert_val(ret);
3557 
3558 	ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3559 	if (ret < 0) {
3560 		gnutls_assert();
3561 		goto cleanup;
3562 	}
3563 
3564 	ret = gnutls_pubkey_export_ecc_raw(pubkey, curve, x, y);
3565 	if (ret < 0) {
3566 		gnutls_assert();
3567 		goto cleanup;
3568 	}
3569 
3570  cleanup:
3571 	gnutls_pubkey_deinit(pubkey);
3572 	return ret;
3573 }
3574 
3575 /**
3576  * gnutls_x509_crt_get_pk_gost_raw:
3577  * @crt: Holds the certificate
3578  * @curve: will hold the curve
3579  * @digest: will hold the digest
3580  * @paramset: will hold the GOST parameter set ID
3581  * @x: will hold the x-coordinate
3582  * @y: will hold the y-coordinate
3583  *
3584  * This function will export the GOST public key's parameters found in
3585  * the given certificate.  The new parameters will be allocated using
3586  * gnutls_malloc() and will be stored in the appropriate datum.
3587  *
3588  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3589  *
3590  * Since: 3.6.3
3591  **/
3592 int
gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,gnutls_ecc_curve_t * curve,gnutls_digest_algorithm_t * digest,gnutls_gost_paramset_t * paramset,gnutls_datum_t * x,gnutls_datum_t * y)3593 gnutls_x509_crt_get_pk_gost_raw(gnutls_x509_crt_t crt,
3594 				gnutls_ecc_curve_t *curve,
3595 				gnutls_digest_algorithm_t *digest,
3596 				gnutls_gost_paramset_t *paramset,
3597 				gnutls_datum_t *x, gnutls_datum_t *y)
3598 {
3599 	int ret;
3600 	gnutls_pubkey_t pubkey;
3601 
3602 	if (crt == NULL) {
3603 		gnutls_assert();
3604 		return GNUTLS_E_INVALID_REQUEST;
3605 	}
3606 
3607 	ret = gnutls_pubkey_init(&pubkey);
3608 	if (ret < 0)
3609 		return gnutls_assert_val(ret);
3610 
3611 	ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3612 	if (ret < 0) {
3613 		gnutls_assert();
3614 		goto cleanup;
3615 	}
3616 
3617 	ret = gnutls_pubkey_export_gost_raw2(pubkey, curve, digest,
3618 					     paramset, x, y, 0);
3619 	if (ret < 0) {
3620 		gnutls_assert();
3621 		goto cleanup;
3622 	}
3623 
3624  cleanup:
3625 	gnutls_pubkey_deinit(pubkey);
3626 	return ret;
3627 }
3628 
3629 /**
3630  * gnutls_x509_crt_get_pk_dsa_raw:
3631  * @crt: Holds the certificate
3632  * @p: will hold the p
3633  * @q: will hold the q
3634  * @g: will hold the g
3635  * @y: will hold the y
3636  *
3637  * This function will export the DSA public key's parameters found in
3638  * the given certificate.  The new parameters will be allocated using
3639  * gnutls_malloc() and will be stored in the appropriate datum.
3640  *
3641  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3642  **/
3643 int
gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * g,gnutls_datum_t * y)3644 gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt,
3645 			       gnutls_datum_t * p, gnutls_datum_t * q,
3646 			       gnutls_datum_t * g, gnutls_datum_t * y)
3647 {
3648 	int ret;
3649 	gnutls_pubkey_t pubkey;
3650 
3651 	if (crt == NULL) {
3652 		gnutls_assert();
3653 		return GNUTLS_E_INVALID_REQUEST;
3654 	}
3655 
3656 	ret = gnutls_pubkey_init(&pubkey);
3657 	if (ret < 0)
3658 		return gnutls_assert_val(ret);
3659 
3660 	ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3661 	if (ret < 0) {
3662 		gnutls_assert();
3663 		goto cleanup;
3664 	}
3665 
3666 	ret = gnutls_pubkey_export_dsa_raw(pubkey, p, q, g, y);
3667 	if (ret < 0) {
3668 		gnutls_assert();
3669 		goto cleanup;
3670 	}
3671 
3672  cleanup:
3673 	gnutls_pubkey_deinit(pubkey);
3674 	return ret;
3675 }
3676 
3677 /**
3678  * gnutls_x509_crt_list_import2:
3679  * @certs: Will hold the parsed certificate list.
3680  * @size: It will contain the size of the list.
3681  * @data: The PEM encoded certificate.
3682  * @format: One of DER or PEM.
3683  * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3684  *
3685  * This function will convert the given PEM encoded certificate list
3686  * to the native gnutls_x509_crt_t format. The output will be stored
3687  * in @certs which will be allocated and initialized.
3688  *
3689  * If the Certificate is PEM encoded it should have a header of "X509
3690  * CERTIFICATE", or "CERTIFICATE".
3691  *
3692  * To deinitialize @certs, you need to deinitialize each crt structure
3693  * independently, and use gnutls_free() at @certs.
3694  *
3695  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3696  *
3697  * Since: 3.0
3698  **/
3699 int
gnutls_x509_crt_list_import2(gnutls_x509_crt_t ** certs,unsigned int * size,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,unsigned int flags)3700 gnutls_x509_crt_list_import2(gnutls_x509_crt_t ** certs,
3701 			     unsigned int *size,
3702 			     const gnutls_datum_t * data,
3703 			     gnutls_x509_crt_fmt_t format,
3704 			     unsigned int flags)
3705 {
3706 	unsigned int init = 1024;
3707 	int ret;
3708 
3709 	*certs = gnutls_malloc(sizeof(gnutls_x509_crt_t) * init);
3710 	if (*certs == NULL) {
3711 		gnutls_assert();
3712 		return GNUTLS_E_MEMORY_ERROR;
3713 	}
3714 
3715 	ret =
3716 	    gnutls_x509_crt_list_import(*certs, &init, data, format,
3717 					flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3718 	if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
3719 		*certs =
3720 		    gnutls_realloc_fast(*certs,
3721 					sizeof(gnutls_x509_crt_t) * init);
3722 		if (*certs == NULL) {
3723 			gnutls_assert();
3724 			return GNUTLS_E_MEMORY_ERROR;
3725 		}
3726 
3727 		ret =
3728 		    gnutls_x509_crt_list_import(*certs, &init, data,
3729 						format, flags);
3730 	}
3731 
3732 	if (ret < 0) {
3733 		gnutls_free(*certs);
3734 		return ret;
3735 	}
3736 
3737 	*size = init;
3738 	return 0;
3739 }
3740 
3741 /**
3742  * gnutls_x509_crt_list_import:
3743  * @certs: Indicates where the parsed list will be copied to. Must not be initialized.
3744  * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
3745  * @data: The PEM encoded certificate.
3746  * @format: One of DER or PEM.
3747  * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
3748  *
3749  * This function will convert the given PEM encoded certificate list
3750  * to the native gnutls_x509_crt_t format. The output will be stored
3751  * in @certs.  They will be automatically initialized.
3752  *
3753  * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause
3754  * import to fail if the certificates in the provided buffer are more
3755  * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED
3756  * flag will cause the function to fail if the provided list is not
3757  * sorted from subject to issuer.
3758  *
3759  * If the Certificate is PEM encoded it should have a header of "X509
3760  * CERTIFICATE", or "CERTIFICATE".
3761  *
3762  * Returns: the number of certificates read or a negative error value.
3763  **/
3764 int
gnutls_x509_crt_list_import(gnutls_x509_crt_t * certs,unsigned int * cert_max,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,unsigned int flags)3765 gnutls_x509_crt_list_import(gnutls_x509_crt_t * certs,
3766 			    unsigned int *cert_max,
3767 			    const gnutls_datum_t * data,
3768 			    gnutls_x509_crt_fmt_t format,
3769 			    unsigned int flags)
3770 {
3771 	int size;
3772 	const char *ptr;
3773 	gnutls_datum_t tmp;
3774 	int ret, nocopy = 0;
3775 	unsigned int count = 0, j, copied = 0;
3776 
3777 	if (format == GNUTLS_X509_FMT_DER) {
3778 		if (*cert_max < 1) {
3779 			*cert_max = 1;
3780 			return GNUTLS_E_SHORT_MEMORY_BUFFER;
3781 		}
3782 
3783 		count = 1;	/* import only the first one */
3784 
3785 		ret = gnutls_x509_crt_init(&certs[0]);
3786 		if (ret < 0) {
3787 			gnutls_assert();
3788 			goto error;
3789 		}
3790 
3791 		ret = gnutls_x509_crt_import(certs[0], data, format);
3792 		if (ret < 0) {
3793 			gnutls_assert();
3794 			goto error;
3795 		}
3796 
3797 		*cert_max = 1;
3798 		return 1;
3799 	}
3800 
3801 	/* move to the certificate
3802 	 */
3803 	ptr = memmem(data->data, data->size,
3804 		     PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
3805 	if (ptr == NULL)
3806 		ptr = memmem(data->data, data->size,
3807 			     PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);
3808 
3809 	if (ptr == NULL)
3810 		return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3811 
3812 	count = 0;
3813 
3814 	do {
3815 		if (count >= *cert_max) {
3816 			if (!
3817 			    (flags &
3818 			     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3819 				break;
3820 			else
3821 				nocopy = 1;
3822 		}
3823 
3824 		if (!nocopy) {
3825 			ret = gnutls_x509_crt_init(&certs[count]);
3826 			if (ret < 0) {
3827 				gnutls_assert();
3828 				goto error;
3829 			}
3830 
3831 			tmp.data = (void *) ptr;
3832 			tmp.size =
3833 			    data->size - (ptr - (char *) data->data);
3834 
3835 			ret =
3836 			    gnutls_x509_crt_import(certs[count], &tmp,
3837 						   GNUTLS_X509_FMT_PEM);
3838 			if (ret < 0) {
3839 				count++;
3840 				gnutls_assert();
3841 				goto error;
3842 			}
3843 
3844 			copied++;
3845 		}
3846 
3847 		/* now we move ptr after the pem header
3848 		 */
3849 		ptr++;
3850 		/* find the next certificate (if any)
3851 		 */
3852 		size = data->size - (ptr - (char *) data->data);
3853 
3854 		if (size > 0) {
3855 			char *ptr2;
3856 
3857 			ptr2 =
3858 			    memmem(ptr, size, PEM_CERT_SEP,
3859 				   sizeof(PEM_CERT_SEP) - 1);
3860 			if (ptr2 == NULL)
3861 				ptr2 = memmem(ptr, size, PEM_CERT_SEP2,
3862 					      sizeof(PEM_CERT_SEP2) - 1);
3863 
3864 			ptr = ptr2;
3865 		} else
3866 			ptr = NULL;
3867 
3868 		count++;
3869 	}
3870 	while (ptr != NULL);
3871 
3872 	*cert_max = count;
3873 
3874 	if (nocopy == 0) {
3875 		if (flags & GNUTLS_X509_CRT_LIST_SORT && *cert_max > 1) {
3876 			gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
3877 			gnutls_x509_crt_t *s;
3878 
3879 			s = _gnutls_sort_clist(sorted, certs, cert_max, gnutls_x509_crt_deinit);
3880 			if (s == certs) {
3881 				gnutls_assert();
3882 				ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
3883 				goto error;
3884 			}
3885 
3886 			count = *cert_max;
3887 			if (s == sorted) {
3888 				memcpy(certs, s, (*cert_max)*sizeof(gnutls_x509_crt_t));
3889 			}
3890 		}
3891 
3892 		if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) {
3893 			ret = _gnutls_check_if_sorted(certs, *cert_max);
3894 			if (ret < 0) {
3895 				gnutls_assert();
3896 				goto error;
3897 			}
3898 		}
3899 
3900 		return count;
3901 	} else {
3902 		count = copied;
3903 		ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
3904 	}
3905 
3906       error:
3907 	for (j = 0; j < count; j++)
3908 		gnutls_x509_crt_deinit(certs[j]);
3909 	return ret;
3910 }
3911 
3912 /**
3913  * gnutls_x509_crt_get_subject_unique_id:
3914  * @crt: Holds the certificate
3915  * @buf: user allocated memory buffer, will hold the unique id
3916  * @buf_size: size of user allocated memory buffer (on input), will hold
3917  * actual size of the unique ID on return.
3918  *
3919  * This function will extract the subjectUniqueID value (if present) for
3920  * the given certificate.
3921  *
3922  * If the user allocated memory buffer is not large enough to hold the
3923  * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3924  * returned, and buf_size will be set to the actual length.
3925  *
3926  * This function had a bug prior to 3.4.8 that prevented the setting
3927  * of %NULL @buf to discover the @buf_size. To use this function safely
3928  * with the older versions the @buf must be a valid buffer that can hold
3929  * at least a single byte if @buf_size is zero.
3930  *
3931  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3932  **/
3933 int
gnutls_x509_crt_get_subject_unique_id(gnutls_x509_crt_t crt,char * buf,size_t * buf_size)3934 gnutls_x509_crt_get_subject_unique_id(gnutls_x509_crt_t crt, char *buf,
3935 				      size_t * buf_size)
3936 {
3937 	int result;
3938 	gnutls_datum_t datum = { NULL, 0 };
3939 
3940 	result =
3941 	    _gnutls_x509_read_value(crt->cert,
3942 				    "tbsCertificate.subjectUniqueID",
3943 				    &datum);
3944 	if (result < 0)
3945 		return gnutls_assert_val(result);
3946 
3947 	if (datum.size > *buf_size) {	/* then we're not going to fit */
3948 		*buf_size = datum.size;
3949 		result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3950 	} else {
3951 		*buf_size = datum.size;
3952 		memcpy(buf, datum.data, datum.size);
3953 	}
3954 
3955 	_gnutls_free_datum(&datum);
3956 
3957 	return result;
3958 }
3959 
3960 /**
3961  * gnutls_x509_crt_get_issuer_unique_id:
3962  * @crt: Holds the certificate
3963  * @buf: user allocated memory buffer, will hold the unique id
3964  * @buf_size: size of user allocated memory buffer (on input), will hold
3965  * actual size of the unique ID on return.
3966  *
3967  * This function will extract the issuerUniqueID value (if present) for
3968  * the given certificate.
3969  *
3970  * If the user allocated memory buffer is not large enough to hold the
3971  * full subjectUniqueID, then a GNUTLS_E_SHORT_MEMORY_BUFFER error will be
3972  * returned, and buf_size will be set to the actual length.
3973  *
3974  * This function had a bug prior to 3.4.8 that prevented the setting
3975  * of %NULL @buf to discover the @buf_size. To use this function safely
3976  * with the older versions the @buf must be a valid buffer that can hold
3977  * at least a single byte if @buf_size is zero.
3978  *
3979  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
3980  *
3981  * Since: 2.12.0
3982  **/
3983 int
gnutls_x509_crt_get_issuer_unique_id(gnutls_x509_crt_t crt,char * buf,size_t * buf_size)3984 gnutls_x509_crt_get_issuer_unique_id(gnutls_x509_crt_t crt, char *buf,
3985 				     size_t * buf_size)
3986 {
3987 	int result;
3988 	gnutls_datum_t datum = { NULL, 0 };
3989 
3990 	result =
3991 	    _gnutls_x509_read_value(crt->cert,
3992 				    "tbsCertificate.issuerUniqueID",
3993 				    &datum);
3994 	if (result < 0)
3995 		return gnutls_assert_val(result);
3996 
3997 	if (datum.size > *buf_size) {	/* then we're not going to fit */
3998 		*buf_size = datum.size;
3999 		result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4000 	} else {
4001 		*buf_size = datum.size;
4002 		memcpy(buf, datum.data, datum.size);
4003 	}
4004 
4005 	_gnutls_free_datum(&datum);
4006 
4007 	return result;
4008 }
4009 
4010 static int
legacy_parse_aia(ASN1_TYPE src,unsigned int seq,int what,gnutls_datum_t * data)4011 legacy_parse_aia(ASN1_TYPE src,
4012 		  unsigned int seq, int what, gnutls_datum_t * data)
4013 {
4014 	int len;
4015 	char nptr[MAX_NAME_SIZE];
4016 	int result;
4017 	gnutls_datum_t d;
4018 	const char *oid = NULL;
4019 
4020 	seq++;			/* 0->1, 1->2 etc */
4021 	switch (what) {
4022 	case GNUTLS_IA_ACCESSMETHOD_OID:
4023 		snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4024 		break;
4025 
4026 	case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
4027 		snprintf(nptr, sizeof(nptr), "?%u.accessLocation", seq);
4028 		break;
4029 
4030 	case GNUTLS_IA_CAISSUERS_URI:
4031 		oid = GNUTLS_OID_AD_CAISSUERS;
4032 		FALLTHROUGH;
4033 
4034 	case GNUTLS_IA_OCSP_URI:
4035 		if (oid == NULL)
4036 			oid = GNUTLS_OID_AD_OCSP;
4037 		{
4038 			char tmpoid[MAX_OID_SIZE];
4039 			snprintf(nptr, sizeof(nptr), "?%u.accessMethod",
4040 				 seq);
4041 			len = sizeof(tmpoid);
4042 			result = asn1_read_value(src, nptr, tmpoid, &len);
4043 
4044 			if (result == ASN1_VALUE_NOT_FOUND
4045 			    || result == ASN1_ELEMENT_NOT_FOUND)
4046 				return
4047 				    gnutls_assert_val
4048 				    (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4049 
4050 			if (result != ASN1_SUCCESS) {
4051 				gnutls_assert();
4052 				return _gnutls_asn2err(result);
4053 			}
4054 			if ((unsigned) len != strlen(oid) + 1
4055 			    || memcmp(tmpoid, oid, len) != 0)
4056 				return
4057 				    gnutls_assert_val
4058 				    (GNUTLS_E_UNKNOWN_ALGORITHM);
4059 		}
4060 		FALLTHROUGH;
4061 
4062 	case GNUTLS_IA_URI:
4063 		snprintf(nptr, sizeof(nptr),
4064 			 "?%u.accessLocation.uniformResourceIdentifier",
4065 			 seq);
4066 		break;
4067 
4068 	default:
4069 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4070 	}
4071 
4072 	len = 0;
4073 	result = asn1_read_value(src, nptr, NULL, &len);
4074 	if (result == ASN1_VALUE_NOT_FOUND
4075 	    || result == ASN1_ELEMENT_NOT_FOUND)
4076 		return
4077 		    gnutls_assert_val
4078 		    (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4079 
4080 	if (result != ASN1_MEM_ERROR) {
4081 		gnutls_assert();
4082 		return _gnutls_asn2err(result);
4083 	}
4084 
4085 	d.size = len;
4086 
4087 	d.data = gnutls_malloc(d.size);
4088 	if (d.data == NULL)
4089 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
4090 
4091 	result = asn1_read_value(src, nptr, d.data, &len);
4092 	if (result != ASN1_SUCCESS) {
4093 		gnutls_assert();
4094 		gnutls_free(d.data);
4095 		return _gnutls_asn2err(result);
4096 	}
4097 
4098 	if (data) {
4099 		data->data = d.data;
4100 		data->size = d.size;
4101 	} else
4102 		gnutls_free(d.data);
4103 
4104 	return 0;
4105 }
4106 
4107 /**
4108  * gnutls_x509_crt_get_authority_info_access:
4109  * @crt: Holds the certificate
4110  * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
4111  * @what: what data to get, a #gnutls_info_access_what_t type.
4112  * @data: output data to be freed with gnutls_free().
4113  * @critical: pointer to output integer that is set to non-zero if the extension is marked as critical (may be %NULL)
4114  *
4115  * Note that a simpler API to access the authority info data is provided
4116  * by gnutls_x509_aia_get() and gnutls_x509_ext_import_aia().
4117  *
4118  * This function extracts the Authority Information Access (AIA)
4119  * extension, see RFC 5280 section 4.2.2.1 for more information.  The
4120  * AIA extension holds a sequence of AccessDescription (AD) data.
4121  *
4122  * The @seq input parameter is used to indicate which member of the
4123  * sequence the caller is interested in.  The first member is 0, the
4124  * second member 1 and so on.  When the @seq value is out of bounds,
4125  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
4126  *
4127  * The type of data returned in @data is specified via @what which
4128  * should be #gnutls_info_access_what_t values.
4129  *
4130  * If @what is %GNUTLS_IA_ACCESSMETHOD_OID then @data will hold the
4131  * accessMethod OID (e.g., "1.3.6.1.5.5.7.48.1").
4132  *
4133  * If @what is %GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, @data will
4134  * hold the accessLocation GeneralName type (e.g.,
4135  * "uniformResourceIdentifier").
4136  *
4137  * If @what is %GNUTLS_IA_URI, @data will hold the accessLocation URI
4138  * data.  Requesting this @what value leads to an error if the
4139  * accessLocation is not of the "uniformResourceIdentifier" type.
4140  *
4141  * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
4142  * Requesting this @what value leads to an error if the accessMethod
4143  * is not 1.3.6.1.5.5.7.48.1 aka OCSP, or if accessLocation is not of
4144  * the "uniformResourceIdentifier" type. In that case %GNUTLS_E_UNKNOWN_ALGORITHM
4145  * will be returned, and @seq should be increased and this function
4146  * called again.
4147  *
4148  * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
4149  * URI.  Requesting this @what value leads to an error if the
4150  * accessMethod is not 1.3.6.1.5.5.7.48.2 aka caIssuers, or if
4151  * accessLocation is not of the "uniformResourceIdentifier" type.
4152  * In that case handle as in %GNUTLS_IA_OCSP_URI.
4153  *
4154  * More @what values may be allocated in the future as needed.
4155  *
4156  * If @data is NULL, the function does the same without storing the
4157  * output data, that is, it will set @critical and do error checking
4158  * as usual.
4159  *
4160  * The value of the critical flag is returned in *@critical.  Supply a
4161  * NULL @critical if you want the function to make sure the extension
4162  * is non-critical, as required by RFC 5280.
4163  *
4164  * Returns: %GNUTLS_E_SUCCESS on success, %GNUTLS_E_INVALID_REQUEST on
4165  * invalid @crt, %GNUTLS_E_CONSTRAINT_ERROR if the extension is
4166  * incorrectly marked as critical (use a non-NULL @critical to
4167  * override), %GNUTLS_E_UNKNOWN_ALGORITHM if the requested OID does
4168  * not match (e.g., when using %GNUTLS_IA_OCSP_URI), otherwise a
4169  * negative error code.
4170  *
4171  * Since: 3.0
4172  **/
4173 int
gnutls_x509_crt_get_authority_info_access(gnutls_x509_crt_t crt,unsigned int seq,int what,gnutls_datum_t * data,unsigned int * critical)4174 gnutls_x509_crt_get_authority_info_access(gnutls_x509_crt_t crt,
4175 					  unsigned int seq,
4176 					  int what,
4177 					  gnutls_datum_t * data,
4178 					  unsigned int *critical)
4179 {
4180 	int ret;
4181 	gnutls_datum_t aia;
4182 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
4183 
4184 	if (crt == NULL) {
4185 		gnutls_assert();
4186 		return GNUTLS_E_INVALID_REQUEST;
4187 	}
4188 
4189 	if ((ret =
4190 	     _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia,
4191 					    critical)) < 0)
4192 		return ret;
4193 
4194 	if (aia.size == 0 || aia.data == NULL) {
4195 		gnutls_assert();
4196 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
4197 	}
4198 
4199 	if (critical && *critical)
4200 		return GNUTLS_E_CONSTRAINT_ERROR;
4201 
4202 	ret = asn1_create_element(_gnutls_get_pkix(),
4203 				  "PKIX1.AuthorityInfoAccessSyntax", &c2);
4204 	if (ret != ASN1_SUCCESS) {
4205 		gnutls_assert();
4206 		_gnutls_free_datum(&aia);
4207 		return _gnutls_asn2err(ret);
4208 	}
4209 
4210 	ret = _asn1_strict_der_decode(&c2, aia.data, aia.size, NULL);
4211 	/* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
4212 	_gnutls_free_datum(&aia);
4213 	if (ret != ASN1_SUCCESS) {
4214 		gnutls_assert();
4215 		asn1_delete_structure(&c2);
4216 		return _gnutls_asn2err(ret);
4217 	}
4218 
4219 	ret = legacy_parse_aia(c2, seq, what, data);
4220 
4221 	asn1_delete_structure(&c2);
4222 	if (ret < 0)
4223 		gnutls_assert();
4224 
4225 	return ret;
4226 }
4227 
4228 /**
4229  * gnutls_x509_crt_set_pin_function:
4230  * @crt: The certificate structure
4231  * @fn: the callback
4232  * @userdata: data associated with the callback
4233  *
4234  * This function will set a callback function to be used when
4235  * it is required to access a protected object. This function overrides
4236  * the global function set using gnutls_pkcs11_set_pin_function().
4237  *
4238  * Note that this callback is currently used only during the import
4239  * of a PKCS #11 certificate with gnutls_x509_crt_import_url().
4240  *
4241  * Since: 3.1.0
4242  *
4243  **/
gnutls_x509_crt_set_pin_function(gnutls_x509_crt_t crt,gnutls_pin_callback_t fn,void * userdata)4244 void gnutls_x509_crt_set_pin_function(gnutls_x509_crt_t crt,
4245 				      gnutls_pin_callback_t fn,
4246 				      void *userdata)
4247 {
4248 	if (crt) {
4249 		crt->pin.cb = fn;
4250 		crt->pin.data = userdata;
4251 	}
4252 }
4253 
4254 /**
4255  * gnutls_x509_crt_import_url:
4256  * @crt: A certificate of type #gnutls_x509_crt_t
4257  * @url: A PKCS 11 url
4258  * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4259  *
4260  * This function will import a certificate present in a PKCS#11 token
4261  * or any type of back-end that supports URLs.
4262  *
4263  * In previous versions of gnutls this function was named
4264  * gnutls_x509_crt_import_pkcs11_url, and the old name is
4265  * an alias to this one.
4266  *
4267  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4268  *   negative error value.
4269  *
4270  * Since: 3.4.0
4271  **/
4272 int
gnutls_x509_crt_import_url(gnutls_x509_crt_t crt,const char * url,unsigned int flags)4273 gnutls_x509_crt_import_url(gnutls_x509_crt_t crt,
4274 			   const char *url, unsigned int flags)
4275 {
4276 	int ret;
4277 	unsigned i;
4278 
4279 	for (i=0;i<_gnutls_custom_urls_size;i++) {
4280 		if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
4281 			if (_gnutls_custom_urls[i].import_crt) {
4282 				ret = _gnutls_custom_urls[i].import_crt(crt, url, flags);
4283 				goto cleanup;
4284 			}
4285 			break;
4286 		}
4287 	}
4288 
4289 	if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
4290 		ret = _gnutls_x509_crt_import_system_url(crt, url);
4291 #ifdef ENABLE_PKCS11
4292 	} else if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
4293 			ret = _gnutls_x509_crt_import_pkcs11_url(crt, url, flags);
4294 #endif
4295 	} else {
4296 		ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4297 	}
4298 
4299  cleanup:
4300 	return ret;
4301 }
4302 
4303 /**
4304  * gnutls_x509_crt_list_import_url:
4305  * @certs: Will hold the allocated certificate list.
4306  * @size: It will contain the size of the list.
4307  * @url: A PKCS 11 url
4308  * @pin_fn: a PIN callback if not globally set
4309  * @pin_fn_userdata: parameter for the PIN callback
4310  * @flags: One of GNUTLS_PKCS11_OBJ_* flags for PKCS#11 URLs or zero otherwise
4311  *
4312  * This function will import a certificate chain present in a PKCS#11 token
4313  * or any type of back-end that supports URLs. The certificates
4314  * must be deinitialized afterwards using gnutls_x509_crt_deinit()
4315  * and the returned pointer must be freed using gnutls_free().
4316  *
4317  * The URI provided must be the first certificate in the chain; subsequent
4318  * certificates will be retrieved using gnutls_pkcs11_get_raw_issuer() or
4319  * equivalent functionality for the supported URI.
4320  *
4321  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
4322  *   negative error value.
4323  *
4324  * Since: 3.6.3
4325  **/
4326 int
gnutls_x509_crt_list_import_url(gnutls_x509_crt_t ** certs,unsigned int * size,const char * url,gnutls_pin_callback_t pin_fn,void * pin_fn_userdata,unsigned int flags)4327 gnutls_x509_crt_list_import_url(gnutls_x509_crt_t **certs,
4328 				unsigned int *size,
4329 				const char *url,
4330 				gnutls_pin_callback_t pin_fn,
4331 				void *pin_fn_userdata,
4332 				unsigned int flags)
4333 {
4334 	int ret;
4335 	unsigned i;
4336 	gnutls_x509_crt_t crts[DEFAULT_MAX_VERIFY_DEPTH];
4337 	gnutls_datum_t issuer = {NULL, 0};
4338 	unsigned total = 0;
4339 
4340 	memset(crts, 0, sizeof(crts));
4341 
4342 	ret = gnutls_x509_crt_init(&crts[0]);
4343 	if (ret < 0)
4344 		return gnutls_assert_val(ret);
4345 
4346 	gnutls_x509_crt_set_pin_function(crts[0], pin_fn, pin_fn_userdata);
4347 
4348 	total = 1;
4349 
4350 	ret = gnutls_x509_crt_import_url(crts[0], url, flags);
4351 	if (ret < 0) {
4352 		gnutls_assert();
4353 		goto cleanup;
4354 	}
4355 
4356 	for (i=1;i<DEFAULT_MAX_VERIFY_DEPTH;i++) {
4357 		ret = _gnutls_get_raw_issuer(url, crts[i-1], &issuer, flags|GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_ANY);
4358 		if (ret < 0) {
4359 			issuer.data = NULL;
4360 			break;
4361 		}
4362 
4363 		if (gnutls_x509_crt_equals2(crts[i-1], &issuer)) {
4364 			gnutls_free(issuer.data);
4365 			break;
4366 		}
4367 
4368 		ret = gnutls_x509_crt_init(&crts[i]);
4369 		if (ret < 0) {
4370 			gnutls_assert();
4371 			goto cleanup;
4372 		}
4373 
4374 		total++;
4375 
4376 		gnutls_x509_crt_set_pin_function(crts[i], pin_fn, pin_fn_userdata);
4377 
4378 		ret = gnutls_x509_crt_import(crts[i], &issuer, GNUTLS_X509_FMT_DER);
4379 		if (ret < 0) {
4380 			gnutls_assert();
4381 			goto cleanup;
4382 		}
4383 
4384 		gnutls_free(issuer.data);
4385 	}
4386 
4387 	*certs = gnutls_malloc(total*sizeof(gnutls_x509_crt_t));
4388 	if (*certs == NULL) {
4389 		ret = GNUTLS_E_MEMORY_ERROR;
4390 		goto cleanup;
4391 	}
4392 
4393 	memcpy(*certs, crts, total*sizeof(gnutls_x509_crt_t));
4394 	*size = total;
4395 
4396 	return 0;
4397  cleanup:
4398 	gnutls_free(issuer.data);
4399 	for (i=0;i<total;i++)
4400 		gnutls_x509_crt_deinit(crts[i]);
4401 
4402 	return ret;
4403 }
4404 
4405 /*-
4406  * gnutls_x509_crt_verify_data3:
4407  * @crt: Holds the certificate to verify with
4408  * @algo: The signature algorithm used
4409  * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4410  * @data: holds the signed data
4411  * @signature: contains the signature
4412  *
4413  * This function will verify the given signed data, using the
4414  * parameters from the certificate.
4415  *
4416  * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4417  * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4418  * or not yet activated certificate and zero or positive code on success.
4419  *
4420  * Since: 3.5.6
4421  -*/
4422 int
gnutls_x509_crt_verify_data3(gnutls_x509_crt_t crt,gnutls_sign_algorithm_t algo,gnutls_typed_vdata_st * vdata,unsigned int vdata_size,const gnutls_datum_t * data,const gnutls_datum_t * signature,unsigned int flags)4423 gnutls_x509_crt_verify_data3(gnutls_x509_crt_t crt,
4424 			     gnutls_sign_algorithm_t algo,
4425 			     gnutls_typed_vdata_st *vdata,
4426 			     unsigned int vdata_size,
4427 			     const gnutls_datum_t *data,
4428 			     const gnutls_datum_t *signature,
4429 			     unsigned int flags)
4430 {
4431 	int ret;
4432 	gnutls_pubkey_t pubkey;
4433 
4434 	if (crt == NULL) {
4435 		gnutls_assert();
4436 		return GNUTLS_E_INVALID_REQUEST;
4437 	}
4438 
4439 
4440 	ret = gnutls_pubkey_init(&pubkey);
4441 	if (ret < 0)
4442 		return gnutls_assert_val(ret);
4443 
4444 	ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
4445 	if (ret < 0)
4446 		return gnutls_assert_val(ret);
4447 
4448 	ret = gnutls_pubkey_verify_data2(pubkey, algo, flags, data, signature);
4449 	gnutls_pubkey_deinit(pubkey);
4450 
4451 	if (ret >= 0) {
4452 		time_t now = gnutls_time(0);
4453 		int res;
4454 		unsigned usage, i;
4455 
4456 		if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) ||
4457 		    !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
4458 			if (now > gnutls_x509_crt_get_expiration_time(crt)) {
4459 				return gnutls_assert_val(GNUTLS_E_EXPIRED);
4460 			}
4461 
4462 			if (now < gnutls_x509_crt_get_activation_time(crt)) {
4463 				return gnutls_assert_val(GNUTLS_E_NOT_YET_ACTIVATED);
4464 			}
4465 		}
4466 
4467 		res = gnutls_x509_crt_get_key_usage(crt, &usage, NULL);
4468 		if (res >= 0) {
4469 			if (!(usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
4470 				return gnutls_assert_val(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4471 			}
4472 		}
4473 
4474 		for (i=0;i<vdata_size;i++) {
4475 			if (vdata[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
4476 				res = _gnutls_check_key_purpose(crt, (char *)vdata[i].data, 0);
4477 				if (res == 0)
4478 					return gnutls_assert_val(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4479 				break;
4480 			}
4481 		}
4482 	}
4483 
4484 	return ret;
4485 }
4486 
4487 /**
4488  * gnutls_x509_crt_verify_data2:
4489  * @crt: Holds the certificate to verify with
4490  * @algo: The signature algorithm used
4491  * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
4492  * @data: holds the signed data
4493  * @signature: contains the signature
4494  *
4495  * This function will verify the given signed data, using the
4496  * parameters from the certificate.
4497  *
4498  * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
4499  * is returned, %GNUTLS_E_EXPIRED or %GNUTLS_E_NOT_YET_ACTIVATED on expired
4500  * or not yet activated certificate and zero or positive code on success.
4501  *
4502  * Note that since GnuTLS 3.5.6 this function introduces checks in the
4503  * end certificate (@crt), including time checks and key usage checks.
4504  *
4505  * Since: 3.4.0
4506  **/
4507 int
gnutls_x509_crt_verify_data2(gnutls_x509_crt_t crt,gnutls_sign_algorithm_t algo,unsigned int flags,const gnutls_datum_t * data,const gnutls_datum_t * signature)4508 gnutls_x509_crt_verify_data2(gnutls_x509_crt_t crt,
4509 			   gnutls_sign_algorithm_t algo,
4510 			   unsigned int flags,
4511 			   const gnutls_datum_t *data,
4512 			   const gnutls_datum_t *signature)
4513 {
4514 	return gnutls_x509_crt_verify_data3(crt, algo, NULL, 0,
4515 				data, signature, flags);
4516 }
4517 
4518 /**
4519  * gnutls_x509_crt_set_flags:
4520  * @cert: A type #gnutls_x509_crt_t
4521  * @flags: flags from the %gnutls_x509_crt_flags
4522  *
4523  * This function will set flags for the specified certificate.
4524  * Currently this is useful for the %GNUTLS_X509_CRT_FLAG_IGNORE_SANITY
4525  * which allows importing certificates even if they have known issues.
4526  *
4527  * Since: 3.6.0
4528  *
4529  **/
gnutls_x509_crt_set_flags(gnutls_x509_crt_t cert,unsigned int flags)4530 void gnutls_x509_crt_set_flags(gnutls_x509_crt_t cert,
4531 				   unsigned int flags)
4532 {
4533 	cert->flags = flags;
4534 }
4535 
4536