Line data Source code
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 :
44 14 : static int crt_reinit(gnutls_x509_crt_t crt)
45 : {
46 14 : int result;
47 :
48 14 : _gnutls_free_datum(&crt->der);
49 14 : crt->raw_dn.size = 0;
50 14 : crt->raw_issuer_dn.size = 0;
51 14 : crt->raw_spki.size = 0;
52 :
53 14 : asn1_delete_structure(&crt->cert);
54 :
55 14 : result = asn1_create_element(_gnutls_get_pkix(),
56 : "PKIX1.Certificate",
57 : &crt->cert);
58 14 : if (result != ASN1_SUCCESS) {
59 0 : result = _gnutls_asn2err(result);
60 0 : gnutls_assert();
61 0 : return result;
62 : }
63 :
64 14 : gnutls_subject_alt_names_deinit(crt->san);
65 14 : result = gnutls_subject_alt_names_init(&crt->san);
66 14 : if (result < 0) {
67 0 : gnutls_assert();
68 0 : return result;
69 : }
70 :
71 14 : gnutls_subject_alt_names_deinit(crt->ian);
72 14 : result = gnutls_subject_alt_names_init(&crt->ian);
73 14 : if (result < 0) {
74 0 : gnutls_assert();
75 0 : 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 : **/
92 4993 : unsigned gnutls_x509_crt_equals(gnutls_x509_crt_t cert1,
93 : gnutls_x509_crt_t cert2)
94 : {
95 4993 : int ret;
96 4993 : bool result;
97 :
98 4993 : if (cert1->modified == 0 && cert2->modified == 0 &&
99 4987 : cert1->raw_dn.size > 0 && cert2->raw_dn.size > 0) {
100 4987 : ret = _gnutls_is_same_dn(cert1, cert2);
101 4987 : if (ret == 0)
102 : return 0;
103 : }
104 :
105 2037 : if (cert1->der.size == 0 || cert2->der.size == 0 ||
106 2037 : cert1->modified != 0 || cert2->modified != 0) {
107 6 : gnutls_datum_t tmp1, tmp2;
108 :
109 : /* on uninitialized or modified certificates, we have to re-encode */
110 6 : ret =
111 6 : gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER, &tmp1);
112 6 : if (ret < 0)
113 0 : return gnutls_assert_val(0);
114 :
115 6 : ret =
116 6 : gnutls_x509_crt_export2(cert2, GNUTLS_X509_FMT_DER, &tmp2);
117 6 : if (ret < 0) {
118 0 : gnutls_free(tmp1.data);
119 0 : return gnutls_assert_val(0);
120 : }
121 :
122 6 : if ((tmp1.size == tmp2.size) &&
123 4 : (memcmp(tmp1.data, tmp2.data, tmp1.size) == 0))
124 : result = 1;
125 : else
126 2 : result = 0;
127 :
128 6 : gnutls_free(tmp1.data);
129 6 : gnutls_free(tmp2.data);
130 : } else {
131 2031 : if ((cert1->der.size == cert2->der.size) &&
132 2023 : (memcmp(cert1->der.data, cert2->der.data, cert1->der.size) == 0))
133 : result = 1;
134 : else
135 23 : result = 0;
136 : }
137 :
138 2037 : 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
154 26 : gnutls_x509_crt_equals2(gnutls_x509_crt_t cert1,
155 : const gnutls_datum_t * der)
156 : {
157 26 : bool result;
158 :
159 26 : if (cert1 == NULL || der == NULL)
160 : return 0;
161 :
162 26 : if (cert1->der.size == 0 || cert1->modified) {
163 0 : gnutls_datum_t tmp1;
164 0 : int ret;
165 :
166 : /* on uninitialized or modified certificates, we have to re-encode */
167 0 : ret =
168 0 : gnutls_x509_crt_export2(cert1, GNUTLS_X509_FMT_DER, &tmp1);
169 0 : if (ret < 0)
170 0 : return gnutls_assert_val(0);
171 :
172 0 : if ((tmp1.size == der->size) &&
173 0 : (memcmp(tmp1.data, der->data, tmp1.size) == 0))
174 : result = 1;
175 : else
176 0 : result = 0;
177 :
178 0 : gnutls_free(tmp1.data);
179 : } else {
180 26 : if ((cert1->der.size == der->size) &&
181 13 : (memcmp(cert1->der.data, der->data, cert1->der.size) == 0))
182 : result = 1;
183 : else
184 13 : result = 0;
185 : }
186 :
187 26 : 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 : **/
199 31508 : int gnutls_x509_crt_init(gnutls_x509_crt_t * cert)
200 : {
201 31508 : gnutls_x509_crt_t tmp;
202 31508 : int result;
203 :
204 31508 : FAIL_IF_LIB_ERROR;
205 :
206 31507 : tmp =
207 31507 : gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
208 :
209 31507 : if (!tmp)
210 : return GNUTLS_E_MEMORY_ERROR;
211 :
212 31507 : result = asn1_create_element(_gnutls_get_pkix(),
213 : "PKIX1.Certificate", &tmp->cert);
214 31507 : if (result != ASN1_SUCCESS) {
215 0 : gnutls_assert();
216 0 : gnutls_free(tmp);
217 0 : return _gnutls_asn2err(result);
218 : }
219 :
220 31507 : result = gnutls_subject_alt_names_init(&tmp->san);
221 31507 : if (result < 0) {
222 0 : gnutls_assert();
223 0 : asn1_delete_structure(&tmp->cert);
224 0 : gnutls_free(tmp);
225 0 : return result;
226 : }
227 :
228 31507 : result = gnutls_subject_alt_names_init(&tmp->ian);
229 31507 : if (result < 0) {
230 0 : gnutls_assert();
231 0 : asn1_delete_structure(&tmp->cert);
232 0 : gnutls_subject_alt_names_deinit(tmp->san);
233 0 : gnutls_free(tmp);
234 0 : 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 31507 : *cert = tmp;
241 :
242 31507 : 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 : -*/
256 36 : int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
257 : {
258 36 : int ret;
259 36 : gnutls_datum_t tmp;
260 36 : unsigned dealloc = 0;
261 :
262 36 : if (src->der.size == 0 || src->modified) {
263 0 : ret =
264 0 : gnutls_x509_crt_export2(src, GNUTLS_X509_FMT_DER, &tmp);
265 0 : if (ret < 0)
266 0 : return gnutls_assert_val(ret);
267 : dealloc = 1;
268 : } else {
269 36 : tmp.data = src->der.data;
270 36 : tmp.size = src->der.size;
271 : }
272 :
273 36 : ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
274 :
275 36 : if (dealloc) {
276 0 : gnutls_free(tmp.data);
277 : }
278 :
279 36 : if (ret < 0)
280 0 : 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 : **/
291 30598 : void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert)
292 : {
293 30598 : if (!cert)
294 : return;
295 :
296 30592 : if (cert->cert)
297 29851 : asn1_delete_structure(&cert->cert);
298 30592 : gnutls_free(cert->der.data);
299 30592 : gnutls_subject_alt_names_deinit(cert->san);
300 30592 : gnutls_subject_alt_names_deinit(cert->ian);
301 30592 : gnutls_free(cert);
302 : }
303 :
304 30613 : static int compare_sig_algorithm(gnutls_x509_crt_t cert)
305 : {
306 30613 : int ret, len1, len2, result;
307 30613 : char oid1[MAX_OID_SIZE];
308 30613 : char oid2[MAX_OID_SIZE];
309 30613 : gnutls_datum_t sp1 = {NULL, 0};
310 30613 : gnutls_datum_t sp2 = {NULL, 0};
311 30613 : unsigned empty1 = 0, empty2 = 0;
312 :
313 30613 : len1 = sizeof(oid1);
314 30613 : result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm", oid1, &len1);
315 30613 : if (result != ASN1_SUCCESS) {
316 8 : gnutls_assert();
317 8 : return _gnutls_asn2err(result);
318 : }
319 :
320 30605 : len2 = sizeof(oid2);
321 30605 : result = asn1_read_value(cert->cert, "tbsCertificate.signature.algorithm", oid2, &len2);
322 30605 : if (result != ASN1_SUCCESS) {
323 5 : gnutls_assert();
324 5 : return _gnutls_asn2err(result);
325 : }
326 :
327 30600 : if (len1 != len2 || memcmp(oid1, oid2, len1) != 0) {
328 26 : _gnutls_debug_log("signatureAlgorithm.algorithm differs from tbsCertificate.signature.algorithm: %s, %s\n",
329 : oid1, oid2);
330 26 : gnutls_assert();
331 26 : return GNUTLS_E_CERTIFICATE_ERROR;
332 : }
333 :
334 : /* compare the parameters */
335 30574 : ret = _gnutls_x509_read_value(cert->cert, "signatureAlgorithm.parameters", &sp1);
336 30574 : if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
337 : empty1 = 1;
338 24885 : } else if (ret < 0) {
339 0 : gnutls_assert();
340 0 : return ret;
341 : }
342 :
343 30574 : ret = _gnutls_x509_read_value(cert->cert, "tbsCertificate.signature.parameters", &sp2);
344 30574 : if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
345 : empty2 = 1;
346 24887 : } else if (ret < 0) {
347 0 : gnutls_assert();
348 0 : return ret;
349 : }
350 :
351 : /* handle equally empty parameters with missing parameters */
352 30574 : if (sp1.size == 2 && memcmp(sp1.data, "\x05\x00", 2) == 0) {
353 24348 : empty1 = 1;
354 24348 : _gnutls_free_datum(&sp1);
355 : }
356 :
357 30574 : if (sp2.size == 2 && memcmp(sp2.data, "\x05\x00", 2) == 0) {
358 24434 : empty2 = 1;
359 24434 : _gnutls_free_datum(&sp2);
360 : }
361 :
362 30574 : if (empty1 != empty2 ||
363 30486 : sp1.size != sp2.size ||
364 450 : (sp1.size > 0 && memcmp(sp1.data, sp2.data, sp1.size) != 0)) {
365 90 : gnutls_assert();
366 90 : ret = GNUTLS_E_CERTIFICATE_ERROR;
367 90 : goto cleanup;
368 : }
369 :
370 : ret = 0;
371 30574 : cleanup:
372 30574 : _gnutls_free_datum(&sp1);
373 30574 : _gnutls_free_datum(&sp2);
374 30574 : return ret;
375 : }
376 :
377 30484 : static int cache_alt_names(gnutls_x509_crt_t cert)
378 : {
379 30484 : gnutls_datum_t tmpder = {NULL, 0};
380 30484 : int ret;
381 :
382 : /* pre-parse subject alt name */
383 30484 : ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.17", 0, &tmpder, NULL);
384 30484 : if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
385 4 : gnutls_free(tmpder.data);
386 4 : return gnutls_assert_val(ret);
387 : }
388 :
389 30480 : if (ret >= 0) {
390 15310 : ret = gnutls_x509_ext_import_subject_alt_names(&tmpder, cert->san, 0);
391 15310 : gnutls_free(tmpder.data);
392 15310 : if (ret < 0)
393 21 : return gnutls_assert_val(ret);
394 : }
395 :
396 30459 : ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.18", 0, &tmpder, NULL);
397 30459 : if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
398 3 : return gnutls_assert_val(ret);
399 :
400 30456 : if (ret >= 0) {
401 508 : ret = gnutls_x509_ext_import_subject_alt_names(&tmpder, cert->ian, 0);
402 508 : gnutls_free(tmpder.data);
403 508 : if (ret < 0)
404 15 : return gnutls_assert_val(ret);
405 : }
406 :
407 : return 0;
408 : }
409 :
410 1356 : static bool hcomparator(const void *v1, const void *v2)
411 : {
412 1356 : return (strcmp(v1, v2)==0);
413 : }
414 :
415 134511 : static size_t hhasher(const void *entry, size_t n)
416 : {
417 134511 : const char *e = entry;
418 134511 : if (e == NULL || e[0] == 0)
419 : return 0;
420 :
421 134511 : return hash_pjw_bare(e, strlen(e)) % n;
422 : }
423 :
424 30534 : int _gnutls_check_cert_sanity(gnutls_x509_crt_t cert)
425 : {
426 30534 : int ret = 0, version;
427 30534 : gnutls_datum_t exts;
428 30534 : Hash_table *htable = NULL;
429 :
430 30534 : 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 30012 : ret = gnutls_x509_crt_get_version(cert);
435 30012 : if (ret < 0) {
436 263 : return gnutls_assert_val(ret);
437 : }
438 :
439 29749 : version = ret;
440 :
441 29749 : if (version < 3) {
442 627 : if (!cert->modified) {
443 624 : ret = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
444 : "tbsCertificate.extensions", &exts);
445 624 : if (ret >= 0 && exts.size > 0) {
446 7 : _gnutls_debug_log("error: extensions present in certificate with version %d\n", version);
447 7 : return gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
448 : }
449 : } else {
450 3 : if (cert->use_extensions) {
451 2 : _gnutls_debug_log("error: extensions set in certificate with version %d\n", version);
452 2 : 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 29122 : unsigned i;
459 29122 : char oid[MAX_OID_SIZE];
460 29122 : size_t oid_size;
461 29122 : char *o;
462 :
463 29122 : htable = hash_initialize(16, NULL, hhasher, hcomparator, gnutls_free);
464 29122 : if (htable == NULL)
465 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
466 :
467 134099 : for (i=0;;i++) {
468 163221 : oid_size = sizeof(oid);
469 163221 : ret = gnutls_x509_crt_get_extension_info(cert, i, oid, &oid_size, NULL);
470 163221 : if (ret < 0) {
471 28710 : if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
472 : break;
473 0 : gnutls_assert();
474 0 : goto cleanup;
475 : }
476 134511 : o = gnutls_strdup(oid);
477 134511 : if (o == NULL) {
478 0 : ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
479 0 : goto cleanup;
480 : }
481 :
482 134511 : ret = hash_insert_if_absent(htable, o, NULL);
483 134511 : if (ret == -1) {
484 0 : gnutls_free(o);
485 0 : ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
486 0 : goto cleanup;
487 134511 : } else if (ret == 0) {
488 : /* duplicate */
489 412 : gnutls_free(o);
490 412 : _gnutls_debug_log("error: duplicate extension (%s) detected\n", oid);
491 412 : ret = gnutls_assert_val(GNUTLS_E_X509_DUPLICATE_EXTENSION);
492 412 : goto cleanup;
493 : }
494 : }
495 :
496 28710 : hash_free(htable);
497 28710 : htable = NULL;
498 : }
499 :
500 29328 : if (version < 2) {
501 407 : char id[128];
502 407 : size_t id_size;
503 :
504 407 : id_size = sizeof(id);
505 407 : ret = gnutls_x509_crt_get_subject_unique_id(cert, id, &id_size);
506 407 : if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
507 8 : _gnutls_debug_log("error: subjectUniqueID present in certificate with version %d\n", version);
508 8 : ret = gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
509 8 : goto cleanup;
510 : }
511 :
512 399 : id_size = sizeof(id);
513 399 : ret = gnutls_x509_crt_get_issuer_unique_id(cert, id, &id_size);
514 399 : if (ret >= 0 || ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
515 9 : _gnutls_debug_log("error: subjectUniqueID present in certificate with version %d\n", version);
516 9 : ret = gnutls_assert_val(GNUTLS_E_X509_CERTIFICATE_ERROR);
517 9 : goto cleanup;
518 : }
519 : }
520 :
521 58545 : if (gnutls_x509_crt_get_expiration_time(cert) == -1 ||
522 29234 : gnutls_x509_crt_get_activation_time(cert) == -1) {
523 118 : _gnutls_debug_log("error: invalid expiration or activation time in certificate\n");
524 118 : ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_TIME_ERROR);
525 118 : goto cleanup;
526 : }
527 :
528 : ret = 0;
529 :
530 412 : cleanup:
531 135 : if (htable)
532 412 : 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
553 31415 : gnutls_x509_crt_import(gnutls_x509_crt_t cert,
554 : const gnutls_datum_t * data,
555 : gnutls_x509_crt_fmt_t format)
556 : {
557 31415 : int result;
558 :
559 31415 : if (cert == NULL) {
560 0 : gnutls_assert();
561 0 : return GNUTLS_E_INVALID_REQUEST;
562 : }
563 :
564 31415 : 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 14 : result = crt_reinit(cert);
569 14 : if (result < 0) {
570 0 : gnutls_assert();
571 0 : goto cleanup;
572 : }
573 : }
574 :
575 : /* If the Certificate is in PEM format then decode it
576 : */
577 31415 : if (format == GNUTLS_X509_FMT_PEM) {
578 : /* Try the first header */
579 13217 : result =
580 26434 : _gnutls_fbase64_decode(PEM_X509_CERT2, data->data,
581 13217 : data->size, &cert->der);
582 :
583 13217 : if (result < 0) {
584 : /* try for the second header */
585 2663 : result =
586 5326 : _gnutls_fbase64_decode(PEM_X509_CERT,
587 2663 : data->data, data->size,
588 : &cert->der);
589 :
590 2663 : if (result < 0) {
591 61 : gnutls_assert();
592 61 : return result;
593 : }
594 : }
595 : } else {
596 18198 : result = _gnutls_set_datum(&cert->der, data->data, data->size);
597 18198 : if (result < 0) {
598 0 : gnutls_assert();
599 0 : return result;
600 : }
601 : }
602 :
603 31354 : cert->expanded = 1;
604 31354 : cert->modified = 0;
605 :
606 31354 : result =
607 31354 : _asn1_strict_der_decode(&cert->cert, cert->der.data, cert->der.size, NULL);
608 31354 : if (result != ASN1_SUCCESS) {
609 741 : result = _gnutls_asn2err(result);
610 741 : gnutls_assert();
611 741 : goto cleanup;
612 : }
613 :
614 30613 : result = compare_sig_algorithm(cert);
615 30613 : if (result < 0) {
616 129 : gnutls_assert();
617 129 : goto cleanup;
618 : }
619 :
620 : /* The following do not allocate but rather point to DER data */
621 30484 : result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
622 : "tbsCertificate.issuer.rdnSequence",
623 : &cert->raw_issuer_dn);
624 30484 : if (result < 0) {
625 0 : gnutls_assert();
626 0 : goto cleanup;
627 : }
628 :
629 30484 : result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
630 : "tbsCertificate.subject.rdnSequence",
631 : &cert->raw_dn);
632 30484 : if (result < 0) {
633 0 : gnutls_assert();
634 0 : goto cleanup;
635 : }
636 :
637 30484 : result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
638 : "tbsCertificate.subjectPublicKeyInfo",
639 : &cert->raw_spki);
640 30484 : if (result < 0) {
641 0 : gnutls_assert();
642 0 : goto cleanup;
643 : }
644 :
645 30484 : result = cache_alt_names(cert);
646 30484 : if (result < 0) {
647 43 : gnutls_assert();
648 43 : goto cleanup;
649 : }
650 :
651 30441 : result = _gnutls_check_cert_sanity(cert);
652 30441 : if (result < 0) {
653 816 : gnutls_assert();
654 816 : goto cleanup;
655 : }
656 :
657 : /* Since we do not want to disable any extension
658 : */
659 29625 : cert->use_extensions = 1;
660 :
661 29625 : return 0;
662 :
663 1729 : cleanup:
664 1729 : _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
691 0 : gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert, char *buf,
692 : size_t * buf_size)
693 : {
694 0 : if (cert == NULL) {
695 0 : gnutls_assert();
696 0 : return GNUTLS_E_INVALID_REQUEST;
697 : }
698 :
699 0 : 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
723 0 : gnutls_x509_crt_get_issuer_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
724 : {
725 0 : if (cert == NULL) {
726 0 : gnutls_assert();
727 0 : return GNUTLS_E_INVALID_REQUEST;
728 : }
729 :
730 0 : 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
756 2141 : gnutls_x509_crt_get_issuer_dn3(gnutls_x509_crt_t cert, gnutls_datum_t *dn, unsigned flags)
757 : {
758 2141 : if (cert == NULL) {
759 0 : gnutls_assert();
760 0 : return GNUTLS_E_INVALID_REQUEST;
761 : }
762 :
763 2141 : 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
798 0 : 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 0 : gnutls_datum_t td;
804 0 : int ret;
805 :
806 0 : if (cert == NULL) {
807 0 : gnutls_assert();
808 0 : return GNUTLS_E_INVALID_REQUEST;
809 : }
810 :
811 0 : ret = _gnutls_x509_parse_dn_oid(cert->cert,
812 : "tbsCertificate.issuer.rdnSequence",
813 : oid, indx, raw_flag, &td);
814 0 : if (ret < 0)
815 0 : return gnutls_assert_val(ret);
816 :
817 0 : 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
840 0 : gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,
841 : unsigned indx, void *oid, size_t * oid_size)
842 : {
843 0 : if (cert == NULL) {
844 0 : gnutls_assert();
845 0 : return GNUTLS_E_INVALID_REQUEST;
846 : }
847 :
848 0 : 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
875 1 : gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert, char *buf,
876 : size_t * buf_size)
877 : {
878 1 : if (cert == NULL) {
879 0 : gnutls_assert();
880 0 : return GNUTLS_E_INVALID_REQUEST;
881 : }
882 :
883 1 : 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 : **/
906 118 : int gnutls_x509_crt_get_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
907 : {
908 118 : if (cert == NULL) {
909 0 : gnutls_assert();
910 0 : return GNUTLS_E_INVALID_REQUEST;
911 : }
912 :
913 118 : 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 : **/
938 2475 : int gnutls_x509_crt_get_dn3(gnutls_x509_crt_t cert, gnutls_datum_t *dn, unsigned flags)
939 : {
940 2475 : if (cert == NULL) {
941 0 : gnutls_assert();
942 0 : return GNUTLS_E_INVALID_REQUEST;
943 : }
944 :
945 2475 : 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
980 2653 : 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 2653 : gnutls_datum_t td;
985 2653 : int ret;
986 :
987 2653 : if (cert == NULL) {
988 0 : gnutls_assert();
989 0 : return GNUTLS_E_INVALID_REQUEST;
990 : }
991 :
992 2653 : ret = _gnutls_x509_parse_dn_oid(cert->cert,
993 : "tbsCertificate.subject.rdnSequence",
994 : oid, indx, raw_flag, &td);
995 2653 : if (ret < 0)
996 57 : return gnutls_assert_val(ret);
997 :
998 2596 : 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
1021 0 : gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,
1022 : unsigned indx, void *oid, size_t * oid_size)
1023 : {
1024 0 : if (cert == NULL) {
1025 0 : gnutls_assert();
1026 0 : return GNUTLS_E_INVALID_REQUEST;
1027 : }
1028 :
1029 0 : 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 : **/
1048 2932 : int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert)
1049 : {
1050 2932 : 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 : **/
1069 16 : int gnutls_x509_crt_get_signature_oid(gnutls_x509_crt_t cert, char *oid, size_t *oid_size)
1070 : {
1071 16 : char str[MAX_OID_SIZE];
1072 16 : int len, result, ret;
1073 16 : gnutls_datum_t out;
1074 :
1075 16 : len = sizeof(str);
1076 16 : result = asn1_read_value(cert->cert, "signatureAlgorithm.algorithm", str, &len);
1077 16 : if (result != ASN1_SUCCESS) {
1078 1 : gnutls_assert();
1079 1 : return _gnutls_asn2err(result);
1080 : }
1081 :
1082 15 : out.data = (void*)str;
1083 15 : out.size = len;
1084 :
1085 15 : ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
1086 15 : if (ret < 0) {
1087 0 : gnutls_assert();
1088 0 : 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 : **/
1109 85 : int gnutls_x509_crt_get_pk_oid(gnutls_x509_crt_t cert, char *oid, size_t *oid_size)
1110 : {
1111 85 : char str[MAX_OID_SIZE];
1112 85 : int len, result, ret;
1113 85 : gnutls_datum_t out;
1114 :
1115 85 : len = sizeof(str);
1116 85 : result = asn1_read_value(cert->cert, "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", str, &len);
1117 85 : if (result != ASN1_SUCCESS) {
1118 0 : gnutls_assert();
1119 0 : return _gnutls_asn2err(result);
1120 : }
1121 :
1122 85 : out.data = (void*)str;
1123 85 : out.size = len;
1124 :
1125 85 : ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
1126 85 : if (ret < 0) {
1127 0 : gnutls_assert();
1128 0 : 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
1146 1544 : gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
1147 : char *sig, size_t * sig_size)
1148 : {
1149 1544 : gnutls_datum_t dsig = {NULL, 0};
1150 1544 : int ret;
1151 :
1152 1544 : if (cert == NULL)
1153 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1154 :
1155 1544 : ret = _gnutls_x509_get_signature(cert->cert, "signature", &dsig);
1156 1544 : if (ret < 0)
1157 50 : return gnutls_assert_val(ret);
1158 :
1159 1494 : ret = _gnutls_copy_data(&dsig, (uint8_t*)sig, sig_size);
1160 1494 : if (ret < 0) {
1161 747 : gnutls_assert();
1162 747 : goto cleanup;
1163 : }
1164 :
1165 : ret = 0;
1166 1494 : cleanup:
1167 1494 : gnutls_free(dsig.data);
1168 1494 : 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 : **/
1179 37286 : int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)
1180 : {
1181 37286 : if (cert == NULL) {
1182 0 : gnutls_assert();
1183 0 : return GNUTLS_E_INVALID_REQUEST;
1184 : }
1185 :
1186 37286 : 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 : **/
1198 33790 : time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert)
1199 : {
1200 33790 : if (cert == NULL) {
1201 0 : gnutls_assert();
1202 0 : return (time_t) - 1;
1203 : }
1204 :
1205 33790 : 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 : **/
1219 33885 : time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert)
1220 : {
1221 33885 : if (cert == NULL) {
1222 0 : gnutls_assert();
1223 0 : return (time_t) - 1;
1224 : }
1225 :
1226 33885 : 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
1246 0 : 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 0 : int ret;
1252 0 : gnutls_datum_t der = { NULL, 0 };
1253 :
1254 0 : if (cert == NULL) {
1255 0 : gnutls_assert();
1256 0 : return GNUTLS_E_INVALID_REQUEST;
1257 : }
1258 :
1259 0 : ret =
1260 0 : _gnutls_x509_crt_get_extension(cert, "2.5.29.16", 0, &der,
1261 : critical);
1262 0 : if (ret < 0)
1263 0 : return gnutls_assert_val(ret);
1264 :
1265 0 : if (der.size == 0 || der.data == NULL)
1266 0 : return
1267 0 : gnutls_assert_val
1268 : (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1269 :
1270 0 : ret = gnutls_x509_ext_import_private_key_usage_period(&der, activation, expiration);
1271 0 : if (ret < 0) {
1272 0 : gnutls_assert();
1273 0 : goto cleanup;
1274 : }
1275 :
1276 : ret = 0;
1277 :
1278 0 : cleanup:
1279 0 : _gnutls_free_datum(&der);
1280 :
1281 0 : 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
1300 3202 : gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert, void *result,
1301 : size_t * result_size)
1302 : {
1303 3202 : int ret, len;
1304 :
1305 3202 : if (cert == NULL) {
1306 0 : gnutls_assert();
1307 0 : return GNUTLS_E_INVALID_REQUEST;
1308 : }
1309 :
1310 3202 : len = *result_size;
1311 3202 : ret =
1312 3202 : asn1_read_value(cert->cert, "tbsCertificate.serialNumber",
1313 : result, &len);
1314 3202 : *result_size = len;
1315 :
1316 3202 : if (ret != ASN1_SUCCESS) {
1317 6 : gnutls_assert();
1318 6 : 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
1339 3287 : 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 3287 : int result;
1344 3287 : gnutls_datum_t id = {NULL,0};
1345 3287 : gnutls_datum_t der = {NULL, 0};
1346 :
1347 3287 : if (cert == NULL) {
1348 0 : gnutls_assert();
1349 0 : return GNUTLS_E_INVALID_REQUEST;
1350 : }
1351 :
1352 3287 : if (ret == NULL)
1353 0 : *ret_size = 0;
1354 :
1355 6574 : if ((result =
1356 3287 : _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &der,
1357 : critical)) < 0) {
1358 : return result;
1359 : }
1360 :
1361 3247 : result = gnutls_x509_ext_import_subject_key_id(&der, &id);
1362 3247 : if (result < 0) {
1363 0 : gnutls_assert();
1364 0 : goto cleanup;
1365 : }
1366 :
1367 3247 : result = _gnutls_copy_data(&id, ret, ret_size);
1368 3247 : if (result < 0) {
1369 0 : gnutls_assert();
1370 0 : goto cleanup;
1371 : }
1372 :
1373 : result = 0;
1374 :
1375 3247 : cleanup:
1376 3247 : gnutls_free(der.data);
1377 3247 : gnutls_free(id.data);
1378 3247 : return result;
1379 : }
1380 :
1381 10126 : inline static int is_type_printable(int type)
1382 : {
1383 10126 : if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
1384 10126 : type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP ||
1385 258 : type == GNUTLS_SAN_OTHERNAME || type == GNUTLS_SAN_REGISTERED_ID)
1386 : return 1;
1387 : else
1388 257 : 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
1416 0 : 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 0 : int ret;
1425 0 : gnutls_datum_t der, san, iserial;
1426 0 : gnutls_x509_aki_t aki = NULL;
1427 0 : unsigned san_type;
1428 :
1429 0 : if (cert == NULL) {
1430 0 : gnutls_assert();
1431 0 : return GNUTLS_E_INVALID_REQUEST;
1432 : }
1433 :
1434 0 : if ((ret =
1435 0 : _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1436 : critical)) < 0) {
1437 0 : return gnutls_assert_val(ret);
1438 : }
1439 :
1440 0 : if (der.size == 0 || der.data == NULL) {
1441 0 : gnutls_assert();
1442 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1443 : }
1444 :
1445 0 : ret = gnutls_x509_aki_init(&aki);
1446 0 : if (ret < 0) {
1447 0 : gnutls_assert();
1448 0 : goto cleanup;
1449 : }
1450 :
1451 0 : ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1452 0 : if (ret < 0) {
1453 0 : gnutls_assert();
1454 0 : goto cleanup;
1455 : }
1456 :
1457 0 : ret = gnutls_x509_aki_get_cert_issuer(aki, seq, &san_type, &san, NULL, &iserial);
1458 0 : if (ret < 0) {
1459 0 : gnutls_assert();
1460 0 : goto cleanup;
1461 : }
1462 :
1463 0 : if (is_type_printable(san_type))
1464 0 : ret = _gnutls_copy_string(&san, alt, alt_size);
1465 : else
1466 0 : ret = _gnutls_copy_data(&san, alt, alt_size);
1467 0 : if (ret < 0) {
1468 0 : gnutls_assert();
1469 0 : goto cleanup;
1470 : }
1471 :
1472 0 : if (alt_type)
1473 0 : *alt_type = san_type;
1474 :
1475 0 : ret = _gnutls_copy_data(&iserial, serial, serial_size);
1476 0 : if (ret < 0) {
1477 0 : gnutls_assert();
1478 0 : goto cleanup;
1479 : }
1480 :
1481 : ret = 0;
1482 0 : cleanup:
1483 0 : if (aki != NULL)
1484 0 : gnutls_x509_aki_deinit(aki);
1485 0 : gnutls_free(der.data);
1486 0 : 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
1508 3644 : 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 3644 : int ret;
1513 3644 : gnutls_datum_t der, l_id;
1514 3644 : gnutls_x509_aki_t aki = NULL;
1515 :
1516 3644 : if (cert == NULL) {
1517 0 : gnutls_assert();
1518 0 : return GNUTLS_E_INVALID_REQUEST;
1519 : }
1520 :
1521 7288 : if ((ret =
1522 3644 : _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1523 : critical)) < 0) {
1524 448 : return gnutls_assert_val(ret);
1525 : }
1526 :
1527 3196 : if (der.size == 0 || der.data == NULL) {
1528 0 : gnutls_assert();
1529 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1530 : }
1531 :
1532 3196 : ret = gnutls_x509_aki_init(&aki);
1533 3196 : if (ret < 0) {
1534 0 : gnutls_assert();
1535 0 : goto cleanup;
1536 : }
1537 :
1538 3196 : ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1539 3196 : if (ret < 0) {
1540 12 : gnutls_assert();
1541 12 : goto cleanup;
1542 : }
1543 :
1544 3184 : ret = gnutls_x509_aki_get_id(aki, &l_id);
1545 :
1546 3184 : if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1547 73 : gnutls_datum_t serial;
1548 73 : ret = gnutls_x509_aki_get_cert_issuer(aki, 0, NULL, NULL, NULL, &serial);
1549 73 : if (ret >= 0) {
1550 71 : ret = gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1551 : } else {
1552 2 : ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1553 : }
1554 : }
1555 :
1556 3184 : if (ret < 0) {
1557 73 : gnutls_assert();
1558 73 : goto cleanup;
1559 : }
1560 :
1561 3111 : ret = _gnutls_copy_data(&l_id, id, id_size);
1562 3111 : if (ret < 0) {
1563 0 : gnutls_assert();
1564 0 : goto cleanup;
1565 : }
1566 :
1567 : ret = 0;
1568 3196 : cleanup:
1569 3196 : if (aki != NULL)
1570 3196 : gnutls_x509_aki_deinit(aki);
1571 3196 : gnutls_free(der.data);
1572 3196 : 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
1594 24396 : gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
1595 : unsigned int *bits)
1596 : {
1597 24396 : int result;
1598 :
1599 24396 : if (cert == NULL) {
1600 0 : gnutls_assert();
1601 0 : return GNUTLS_E_INVALID_REQUEST;
1602 : }
1603 :
1604 24396 : if (bits)
1605 21994 : *bits = 0;
1606 :
1607 24396 : result =
1608 24396 : _gnutls_x509_get_pk_algorithm(cert->cert,
1609 : "tbsCertificate.subjectPublicKeyInfo",
1610 : NULL,
1611 : bits);
1612 :
1613 24396 : if (result < 0) {
1614 318 : gnutls_assert();
1615 318 : 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
1633 1 : gnutls_x509_crt_get_spki(gnutls_x509_crt_t cert, gnutls_x509_spki_t spki, unsigned int flags)
1634 : {
1635 1 : int result;
1636 1 : gnutls_x509_spki_st params;
1637 :
1638 1 : if (cert == NULL) {
1639 0 : gnutls_assert();
1640 0 : return GNUTLS_E_INVALID_REQUEST;
1641 : }
1642 :
1643 :
1644 1 : spki->pk = gnutls_x509_crt_get_pk_algorithm(cert, NULL);
1645 :
1646 1 : memset(¶ms, 0, sizeof(params));
1647 :
1648 1 : result = _gnutls_x509_crt_read_spki_params(cert, ¶ms);
1649 1 : if (result < 0) {
1650 0 : gnutls_assert();
1651 0 : return result;
1652 : }
1653 :
1654 1 : if (params.pk == GNUTLS_PK_UNKNOWN)
1655 0 : return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1656 :
1657 1 : spki->rsa_pss_dig = params.rsa_pss_dig;
1658 1 : spki->salt_size = params.salt_size;
1659 :
1660 1 : 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
1674 54609 : _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 54609 : int len, ret;
1679 54609 : char nptr[MAX_NAME_SIZE];
1680 54609 : int result;
1681 54609 : gnutls_datum_t tmp = {NULL, 0};
1682 54609 : char choice_type[128];
1683 54609 : gnutls_x509_subject_alt_name_t type;
1684 :
1685 54609 : if (seq != -1) {
1686 53855 : seq++; /* 0->1, 1->2 etc */
1687 :
1688 53855 : if (src_name[0] != 0)
1689 5097 : snprintf(nptr, sizeof(nptr), "%s.?%u", src_name, seq);
1690 : else
1691 48758 : snprintf(nptr, sizeof(nptr), "?%u", seq);
1692 : } else {
1693 754 : snprintf(nptr, sizeof(nptr), "%s", src_name);
1694 : }
1695 :
1696 54609 : len = sizeof(choice_type);
1697 54609 : result = asn1_read_value(src, nptr, choice_type, &len);
1698 54609 : if (result == ASN1_VALUE_NOT_FOUND
1699 54609 : || result == ASN1_ELEMENT_NOT_FOUND) {
1700 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1701 : }
1702 :
1703 33564 : if (result != ASN1_SUCCESS) {
1704 0 : gnutls_assert();
1705 0 : return _gnutls_asn2err(result);
1706 : }
1707 :
1708 33564 : type = _gnutls_x509_san_find_type(choice_type);
1709 33564 : if (type == (gnutls_x509_subject_alt_name_t) - 1) {
1710 2 : gnutls_assert();
1711 2 : return GNUTLS_E_X509_UNKNOWN_SAN;
1712 : }
1713 :
1714 33562 : if (ret_type)
1715 32283 : *ret_type = type;
1716 :
1717 33562 : if (type == GNUTLS_SAN_OTHERNAME) {
1718 2566 : if (othername_oid)
1719 1279 : _gnutls_str_cat(nptr, sizeof(nptr),
1720 : ".otherName.type-id");
1721 : else
1722 1287 : _gnutls_str_cat(nptr, sizeof(nptr),
1723 : ".otherName.value");
1724 :
1725 2566 : ret = _gnutls_x509_read_value(src, nptr, &tmp);
1726 2566 : if (ret < 0) {
1727 7 : gnutls_assert();
1728 7 : return ret;
1729 : }
1730 :
1731 2559 : if (othername_oid) {
1732 1279 : dname->size = tmp.size;
1733 1279 : dname->data = tmp.data;
1734 : } else {
1735 1280 : char oid[MAX_OID_SIZE];
1736 :
1737 1280 : if (src_name[0] != 0)
1738 1 : snprintf(nptr, sizeof(nptr),
1739 : "%s.?%u.otherName.type-id",
1740 : src_name, seq);
1741 : else
1742 1279 : snprintf(nptr, sizeof(nptr),
1743 : "?%u.otherName.type-id", seq);
1744 :
1745 1280 : len = sizeof(oid);
1746 :
1747 1280 : result = asn1_read_value(src, nptr, oid, &len);
1748 1280 : if (result != ASN1_SUCCESS) {
1749 1 : gnutls_assert();
1750 1 : ret = _gnutls_asn2err(result);
1751 1 : goto cleanup;
1752 : }
1753 1279 : if (len > 0) len--;
1754 :
1755 1279 : dname->size = tmp.size;
1756 1279 : dname->data = tmp.data;
1757 : }
1758 30996 : } else if (type == GNUTLS_SAN_DN) {
1759 1536 : _gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
1760 1536 : ret = _gnutls_x509_get_dn(src, nptr, dname, 0);
1761 1536 : if (ret < 0) {
1762 9 : gnutls_assert();
1763 9 : goto cleanup;
1764 : }
1765 29460 : } else if (othername_oid) {
1766 0 : gnutls_assert();
1767 0 : ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1768 0 : goto cleanup;
1769 : } else {
1770 29460 : _gnutls_str_cat(nptr, sizeof(nptr), ".");
1771 29460 : _gnutls_str_cat(nptr, sizeof(nptr), choice_type);
1772 :
1773 29460 : ret = _gnutls_x509_read_null_value(src, nptr, &tmp);
1774 29460 : if (ret < 0) {
1775 5 : gnutls_assert();
1776 5 : return ret;
1777 : }
1778 :
1779 29455 : if (type == GNUTLS_SAN_REGISTERED_ID && tmp.size > 0) {
1780 : /* see #805; OIDs contain the null termination byte */
1781 38 : assert(tmp.data[tmp.size-1] == 0);
1782 38 : tmp.size--;
1783 : }
1784 :
1785 : /* _gnutls_x509_read_value() null terminates */
1786 29455 : dname->size = tmp.size;
1787 29455 : dname->data = tmp.data;
1788 : }
1789 :
1790 33540 : return type;
1791 :
1792 10 : cleanup:
1793 10 : gnutls_free(tmp.data);
1794 10 : 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
1801 2 : _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 2 : int ret;
1806 2 : gnutls_datum_t res = {NULL,0};
1807 2 : unsigned type;
1808 :
1809 2 : ret = _gnutls_parse_general_name2(src, src_name, seq, &res, ret_type, othername_oid);
1810 2 : if (ret < 0)
1811 0 : return gnutls_assert_val(ret);
1812 :
1813 2 : type = ret;
1814 :
1815 2 : if (is_type_printable(type)) {
1816 2 : ret = _gnutls_copy_string(&res, name, name_size);
1817 : } else {
1818 0 : ret = _gnutls_copy_data(&res, name, name_size);
1819 : }
1820 :
1821 2 : if (ret < 0) {
1822 0 : gnutls_assert();
1823 0 : goto cleanup;
1824 : }
1825 :
1826 : ret = type;
1827 2 : cleanup:
1828 2 : gnutls_free(res.data);
1829 2 : return ret;
1830 : }
1831 :
1832 : static int
1833 21816 : 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 21816 : int ret;
1839 21816 : gnutls_datum_t ooid = {NULL, 0};
1840 21816 : gnutls_datum_t oname;
1841 21816 : gnutls_datum_t virt = {NULL, 0};
1842 21816 : unsigned int type;
1843 :
1844 21816 : if (san == NULL) {
1845 0 : gnutls_assert();
1846 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1847 : }
1848 :
1849 21816 : if (alt == NULL)
1850 0 : *alt_size = 0;
1851 :
1852 21816 : ret = gnutls_subject_alt_names_get(san, seq, &type, &oname, &ooid);
1853 21816 : if (ret < 0) {
1854 11692 : gnutls_assert();
1855 11692 : goto cleanup;
1856 : }
1857 :
1858 10124 : if (othername_oid && type == GNUTLS_SAN_OTHERNAME && ooid.data) {
1859 0 : unsigned vtype;
1860 0 : ret = gnutls_x509_othername_to_virtual((char*)ooid.data, &oname, &vtype, &virt);
1861 0 : if (ret >= 0) {
1862 0 : type = vtype;
1863 0 : oname.data = virt.data;
1864 0 : oname.size = virt.size;
1865 : }
1866 : }
1867 :
1868 10124 : if (alt_type)
1869 35 : *alt_type = type;
1870 :
1871 10124 : if (othername_oid) {
1872 0 : ret = _gnutls_copy_string(&ooid, alt, alt_size);
1873 : } else {
1874 10124 : if (is_type_printable(type)) {
1875 9867 : ret = _gnutls_copy_string(&oname, alt, alt_size);
1876 : } else {
1877 257 : ret = _gnutls_copy_data(&oname, alt, alt_size);
1878 : }
1879 : }
1880 :
1881 10124 : if (ret < 0) {
1882 10 : gnutls_assert();
1883 10 : goto cleanup;
1884 : }
1885 :
1886 10114 : ret = type;
1887 21816 : cleanup:
1888 21816 : gnutls_free(virt.data);
1889 :
1890 21816 : 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
1924 21762 : 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 21762 : 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
1967 3 : 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 3 : 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
2001 51 : 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 51 : 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
2039 0 : 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 0 : 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
2080 0 : 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 0 : 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
2121 0 : 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 0 : 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
2150 5915 : gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
2151 : unsigned int *critical,
2152 : unsigned int *ca, int *pathlen)
2153 : {
2154 5915 : int result;
2155 5915 : gnutls_datum_t basicConstraints;
2156 5915 : unsigned int tmp_ca;
2157 :
2158 5915 : if (cert == NULL) {
2159 0 : gnutls_assert();
2160 0 : return GNUTLS_E_INVALID_REQUEST;
2161 : }
2162 :
2163 11830 : if ((result =
2164 5915 : _gnutls_x509_crt_get_extension(cert, "2.5.29.19", 0,
2165 : &basicConstraints,
2166 : critical)) < 0) {
2167 : return result;
2168 : }
2169 :
2170 5835 : if (basicConstraints.size == 0 || basicConstraints.data == NULL) {
2171 0 : gnutls_assert();
2172 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2173 : }
2174 :
2175 5835 : result = gnutls_x509_ext_import_basic_constraints(&basicConstraints, &tmp_ca, pathlen);
2176 5835 : if (ca)
2177 5835 : *ca = tmp_ca;
2178 :
2179 5835 : _gnutls_free_datum(&basicConstraints);
2180 :
2181 5835 : if (result < 0) {
2182 26 : gnutls_assert();
2183 26 : return result;
2184 : }
2185 :
2186 5809 : 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
2209 4285 : gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
2210 : unsigned int *critical)
2211 : {
2212 4285 : int pathlen;
2213 4285 : unsigned int ca;
2214 4285 : 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
2238 19811 : gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
2239 : unsigned int *key_usage,
2240 : unsigned int *critical)
2241 : {
2242 19811 : int result;
2243 19811 : gnutls_datum_t keyUsage;
2244 :
2245 19811 : if (cert == NULL) {
2246 0 : gnutls_assert();
2247 0 : return GNUTLS_E_INVALID_REQUEST;
2248 : }
2249 :
2250 39622 : if ((result =
2251 19811 : _gnutls_x509_crt_get_extension(cert, "2.5.29.15", 0,
2252 : &keyUsage, critical)) < 0) {
2253 : return result;
2254 : }
2255 :
2256 18308 : if (keyUsage.size == 0 || keyUsage.data == NULL) {
2257 0 : gnutls_assert();
2258 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2259 : }
2260 :
2261 18308 : result = gnutls_x509_ext_import_key_usage(&keyUsage, key_usage);
2262 18308 : _gnutls_free_datum(&keyUsage);
2263 :
2264 18308 : if (result < 0) {
2265 44 : gnutls_assert();
2266 44 : 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
2292 0 : gnutls_x509_crt_get_inhibit_anypolicy(gnutls_x509_crt_t cert,
2293 : unsigned int *skipcerts,
2294 : unsigned int *critical)
2295 : {
2296 0 : int ret;
2297 0 : gnutls_datum_t ext;
2298 :
2299 0 : if (cert == NULL) {
2300 0 : gnutls_assert();
2301 0 : return GNUTLS_E_INVALID_REQUEST;
2302 : }
2303 :
2304 0 : if ((ret =
2305 0 : _gnutls_x509_crt_get_extension(cert, "2.5.29.54", 0,
2306 : &ext, critical)) < 0) {
2307 : return ret;
2308 : }
2309 :
2310 0 : if (ext.size == 0 || ext.data == NULL) {
2311 0 : gnutls_assert();
2312 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2313 : }
2314 :
2315 0 : ret = gnutls_x509_ext_import_key_usage(&ext, skipcerts);
2316 0 : _gnutls_free_datum(&ext);
2317 :
2318 0 : if (ret < 0) {
2319 0 : gnutls_assert();
2320 0 : 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
2344 939 : 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 939 : int result;
2351 939 : gnutls_datum_t proxyCertInfo;
2352 :
2353 939 : if (cert == NULL) {
2354 0 : gnutls_assert();
2355 0 : return GNUTLS_E_INVALID_REQUEST;
2356 : }
2357 :
2358 1878 : if ((result =
2359 939 : _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 0 : if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL) {
2366 0 : gnutls_assert();
2367 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2368 : }
2369 :
2370 0 : result = gnutls_x509_ext_import_proxy(&proxyCertInfo, pathlen,
2371 : policyLanguage,
2372 : policy,
2373 : sizeof_policy);
2374 0 : _gnutls_free_datum(&proxyCertInfo);
2375 0 : if (result < 0) {
2376 0 : gnutls_assert();
2377 0 : 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 : **/
2393 414 : void gnutls_x509_policy_release(struct gnutls_x509_policy_st *policy)
2394 : {
2395 414 : unsigned i;
2396 :
2397 414 : gnutls_free(policy->oid);
2398 615 : for (i = 0; i < policy->qualifiers; i++)
2399 201 : gnutls_free(policy->qualifier[i].data);
2400 414 : }
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
2422 0 : 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 0 : gnutls_datum_t tmpd = { NULL, 0 };
2427 0 : int ret;
2428 0 : gnutls_x509_policies_t policies = NULL;
2429 :
2430 0 : if (crt == NULL) {
2431 0 : gnutls_assert();
2432 0 : return GNUTLS_E_INVALID_REQUEST;
2433 : }
2434 :
2435 0 : memset(policy, 0, sizeof(*policy));
2436 :
2437 0 : ret = gnutls_x509_policies_init(&policies);
2438 0 : if (ret < 0)
2439 0 : return gnutls_assert_val(ret);
2440 :
2441 0 : if ((ret =
2442 0 : _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &tmpd,
2443 : critical)) < 0) {
2444 0 : goto cleanup;
2445 : }
2446 :
2447 0 : if (tmpd.size == 0 || tmpd.data == NULL) {
2448 0 : gnutls_assert();
2449 0 : ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2450 0 : goto cleanup;
2451 : }
2452 :
2453 0 : ret = gnutls_x509_ext_import_policies(&tmpd, policies, 0);
2454 0 : if (ret < 0) {
2455 0 : gnutls_assert();
2456 0 : goto cleanup;
2457 : }
2458 :
2459 0 : ret = gnutls_x509_policies_get(policies, indx, policy);
2460 0 : if (ret < 0) {
2461 0 : gnutls_assert();
2462 0 : goto cleanup;
2463 : }
2464 :
2465 0 : _gnutls_x509_policies_erase(policies, indx);
2466 :
2467 0 : ret = 0;
2468 :
2469 0 : cleanup:
2470 0 : if (policies != NULL)
2471 0 : gnutls_x509_policies_deinit(policies);
2472 0 : _gnutls_free_datum(&tmpd);
2473 :
2474 0 : 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
2497 0 : 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 0 : int result;
2503 0 : gnutls_datum_t output;
2504 :
2505 0 : if (cert == NULL) {
2506 0 : gnutls_assert();
2507 0 : return GNUTLS_E_INVALID_REQUEST;
2508 : }
2509 :
2510 0 : if ((result =
2511 0 : _gnutls_x509_crt_get_extension(cert, oid, indx, &output,
2512 : critical)) < 0) {
2513 0 : gnutls_assert();
2514 0 : return result;
2515 : }
2516 :
2517 0 : if (output.size == 0 || output.data == NULL) {
2518 0 : gnutls_assert();
2519 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2520 : }
2521 :
2522 0 : if (output.size > (unsigned int) *buf_size) {
2523 0 : *buf_size = output.size;
2524 0 : _gnutls_free_datum(&output);
2525 0 : return GNUTLS_E_SHORT_MEMORY_BUFFER;
2526 : }
2527 :
2528 0 : *buf_size = output.size;
2529 :
2530 0 : if (buf)
2531 0 : memcpy(buf, output.data, output.size);
2532 :
2533 0 : _gnutls_free_datum(&output);
2534 :
2535 0 : 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
2558 0 : 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 0 : int ret;
2564 :
2565 0 : if (cert == NULL) {
2566 0 : gnutls_assert();
2567 0 : return GNUTLS_E_INVALID_REQUEST;
2568 : }
2569 :
2570 0 : if ((ret =
2571 0 : _gnutls_x509_crt_get_extension(cert, oid, indx, output,
2572 : critical)) < 0) {
2573 0 : gnutls_assert();
2574 0 : return ret;
2575 : }
2576 :
2577 0 : if (output->size == 0 || output->data == NULL) {
2578 0 : gnutls_assert();
2579 0 : 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
2604 0 : gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert, unsigned indx,
2605 : void *oid, size_t * oid_size)
2606 : {
2607 0 : int result;
2608 :
2609 0 : if (cert == NULL) {
2610 0 : gnutls_assert();
2611 0 : return GNUTLS_E_INVALID_REQUEST;
2612 : }
2613 :
2614 0 : result =
2615 0 : _gnutls_x509_crt_get_extension_oid(cert, indx, oid, oid_size);
2616 0 : if (result < 0) {
2617 0 : 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
2650 180361 : 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 180361 : int result;
2655 180361 : char str_critical[10];
2656 180361 : char name[MAX_NAME_SIZE];
2657 180361 : int len;
2658 :
2659 180361 : if (!cert) {
2660 0 : gnutls_assert();
2661 0 : return GNUTLS_E_INVALID_REQUEST;
2662 : }
2663 :
2664 180361 : snprintf(name, sizeof(name),
2665 : "tbsCertificate.extensions.?%u.extnID", indx + 1);
2666 :
2667 180361 : len = *oid_size;
2668 180361 : result = asn1_read_value(cert->cert, name, oid, &len);
2669 180361 : *oid_size = len;
2670 :
2671 180361 : if (result == ASN1_ELEMENT_NOT_FOUND)
2672 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2673 148646 : else if (result != ASN1_SUCCESS) {
2674 1 : gnutls_assert();
2675 1 : return _gnutls_asn2err(result);
2676 : }
2677 :
2678 : /* remove any trailing null */
2679 148645 : if (oid && len > 0 && ((uint8_t*)oid)[len-1] == 0)
2680 148645 : (*oid_size)--;
2681 :
2682 148645 : if (critical) {
2683 14133 : snprintf(name, sizeof(name),
2684 : "tbsCertificate.extensions.?%u.critical", indx + 1);
2685 14133 : len = sizeof(str_critical);
2686 14133 : result = asn1_read_value(cert->cert, name, str_critical, &len);
2687 14133 : if (result != ASN1_SUCCESS) {
2688 0 : gnutls_assert();
2689 0 : return _gnutls_asn2err(result);
2690 : }
2691 :
2692 14133 : if (str_critical[0] == 'T')
2693 4662 : *critical = 1;
2694 : else
2695 9471 : *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
2724 1 : gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert, unsigned indx,
2725 : void *data, size_t * sizeof_data)
2726 : {
2727 1 : int result, len;
2728 1 : char name[MAX_NAME_SIZE];
2729 :
2730 1 : if (!cert) {
2731 0 : gnutls_assert();
2732 0 : return GNUTLS_E_INVALID_REQUEST;
2733 : }
2734 :
2735 1 : snprintf(name, sizeof(name),
2736 : "tbsCertificate.extensions.?%u.extnValue", indx + 1);
2737 :
2738 1 : len = *sizeof_data;
2739 1 : result = asn1_read_value(cert->cert, name, data, &len);
2740 1 : *sizeof_data = len;
2741 :
2742 1 : if (result == ASN1_ELEMENT_NOT_FOUND) {
2743 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2744 1 : } 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 0 : } else if (result != ASN1_SUCCESS) {
2750 0 : gnutls_assert();
2751 0 : 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
2770 67 : gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,
2771 : gnutls_datum_t * dn)
2772 : {
2773 67 : if (cert->raw_issuer_dn.size > 0 && cert->modified == 0) {
2774 65 : return _gnutls_set_datum(dn, cert->raw_issuer_dn.data,
2775 : cert->raw_issuer_dn.size);
2776 : } else {
2777 2 : 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 : **/
2793 6 : int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
2794 : {
2795 6 : if (cert->raw_dn.size > 0 && cert->modified == 0) {
2796 2 : return _gnutls_set_datum(dn, cert->raw_dn.data, cert->raw_dn.size);
2797 : } else {
2798 4 : return _gnutls_x509_get_raw_field(cert->cert, "tbsCertificate.subject.rdnSequence", dn);
2799 : }
2800 : }
2801 :
2802 : static int
2803 3 : get_dn(gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn, unsigned subject)
2804 : {
2805 3 : gnutls_x509_dn_st *store;
2806 :
2807 3 : if (subject)
2808 2 : store = &cert->dn;
2809 : else
2810 1 : store = &cert->idn;
2811 :
2812 3 : store->asn = asn1_find_node(cert->cert, whom);
2813 3 : if (!store->asn)
2814 : return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2815 :
2816 3 : *dn = store;
2817 :
2818 3 : 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
2836 2 : gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2837 : {
2838 2 : 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
2856 1 : gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2857 : {
2858 1 : 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
2879 1582 : 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 1582 : uint8_t *cert_buf;
2884 1582 : int cert_buf_size;
2885 1582 : int result;
2886 1582 : gnutls_datum_t tmp;
2887 :
2888 1582 : if (buf_size == 0 || cert == NULL) {
2889 : return GNUTLS_E_INVALID_REQUEST;
2890 : }
2891 :
2892 1582 : cert_buf_size = 0;
2893 1582 : result = asn1_der_coding(cert->cert, "", NULL, &cert_buf_size, NULL);
2894 1582 : if (result != ASN1_MEM_ERROR) {
2895 1 : gnutls_assert();
2896 1 : return _gnutls_asn2err(result);
2897 : }
2898 :
2899 1581 : cert_buf = gnutls_malloc(cert_buf_size);
2900 1581 : if (cert_buf == NULL) {
2901 0 : gnutls_assert();
2902 0 : return GNUTLS_E_MEMORY_ERROR;
2903 : }
2904 :
2905 1581 : result =
2906 1581 : asn1_der_coding(cert->cert, "", cert_buf, &cert_buf_size,
2907 : NULL);
2908 :
2909 1581 : if (result != ASN1_SUCCESS) {
2910 0 : gnutls_assert();
2911 0 : gnutls_free(cert_buf);
2912 0 : return _gnutls_asn2err(result);
2913 : }
2914 :
2915 1581 : tmp.data = cert_buf;
2916 1581 : tmp.size = cert_buf_size;
2917 :
2918 1581 : result = gnutls_fingerprint(algo, &tmp, buf, buf_size);
2919 1581 : gnutls_free(cert_buf);
2920 :
2921 1581 : 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
2945 468 : 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 468 : gnutls_datum_t out;
2950 468 : int ret;
2951 :
2952 468 : ret = gnutls_x509_crt_export2(cert, format, &out);
2953 468 : if (ret < 0)
2954 0 : return gnutls_assert_val(ret);
2955 :
2956 468 : if (format == GNUTLS_X509_FMT_PEM)
2957 229 : ret = _gnutls_copy_string(&out, (uint8_t*)output_data, output_data_size);
2958 : else
2959 239 : ret = _gnutls_copy_data(&out, (uint8_t*)output_data, output_data_size);
2960 468 : if (ret < 0) {
2961 234 : gnutls_assert();
2962 234 : goto cleanup;
2963 : }
2964 :
2965 : ret = 0;
2966 468 : cleanup:
2967 468 : gnutls_free(out.data);
2968 468 : 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
2989 18738 : gnutls_x509_crt_export2(gnutls_x509_crt_t cert,
2990 : gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
2991 : {
2992 18738 : if (cert == NULL) {
2993 0 : gnutls_assert();
2994 0 : return GNUTLS_E_INVALID_REQUEST;
2995 : }
2996 :
2997 18738 : if (!cert->modified && cert->der.size) {
2998 18629 : if (format == GNUTLS_X509_FMT_DER)
2999 17880 : return _gnutls_set_datum(out, cert->der.data, cert->der.size);
3000 : else {
3001 1498 : int ret = _gnutls_fbase64_encode(PEM_X509_CERT2,
3002 749 : cert->der.data,
3003 : cert->der.size,
3004 : out);
3005 749 : if (ret < 0)
3006 : return ret;
3007 749 : return 0;
3008 : }
3009 : }
3010 :
3011 109 : return _gnutls_x509_export_int2(cert->cert, format, PEM_X509_CERT2,
3012 : out);
3013 : }
3014 :
3015 : int
3016 4238 : _gnutls_get_key_id(gnutls_pk_params_st * params,
3017 : unsigned char *output_data, size_t * output_data_size,
3018 : unsigned flags)
3019 : {
3020 4238 : int ret = 0;
3021 4238 : gnutls_datum_t der = { NULL, 0 };
3022 4238 : gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
3023 4238 : unsigned int digest_len;
3024 :
3025 4238 : if ((flags & GNUTLS_KEYID_USE_SHA512) || (flags & GNUTLS_KEYID_USE_BEST_KNOWN))
3026 : hash = GNUTLS_DIG_SHA512;
3027 4237 : else if (flags & GNUTLS_KEYID_USE_SHA256)
3028 1946 : hash = GNUTLS_DIG_SHA256;
3029 :
3030 8476 : digest_len =
3031 4238 : _gnutls_hash_get_algo_len(hash_to_entry(hash));
3032 :
3033 4238 : if (output_data == NULL || *output_data_size < digest_len) {
3034 4 : gnutls_assert();
3035 4 : *output_data_size = digest_len;
3036 4 : return GNUTLS_E_SHORT_MEMORY_BUFFER;
3037 : }
3038 :
3039 4234 : ret = _gnutls_x509_encode_PKI_params(&der, params);
3040 4234 : if (ret < 0)
3041 7 : return gnutls_assert_val(ret);
3042 :
3043 4227 : ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
3044 4227 : if (ret < 0) {
3045 0 : gnutls_assert();
3046 0 : goto cleanup;
3047 : }
3048 4227 : *output_data_size = digest_len;
3049 :
3050 4227 : ret = 0;
3051 :
3052 4227 : cleanup:
3053 :
3054 4227 : _gnutls_free_datum(&der);
3055 4227 : 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
3079 3955 : 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 3955 : int ret = 0;
3084 3955 : gnutls_pk_params_st params;
3085 :
3086 3955 : if (crt == NULL) {
3087 0 : gnutls_assert();
3088 0 : return GNUTLS_E_INVALID_REQUEST;
3089 : }
3090 :
3091 : /* initializes params */
3092 3955 : ret = _gnutls_x509_crt_get_mpis(crt, ¶ms);
3093 3955 : if (ret < 0) {
3094 23 : gnutls_assert();
3095 23 : return ret;
3096 : }
3097 :
3098 3932 : ret =
3099 3932 : _gnutls_get_key_id(¶ms, output_data, output_data_size, flags);
3100 :
3101 3932 : gnutls_pk_params_release(¶ms);
3102 :
3103 3932 : return ret;
3104 : }
3105 :
3106 : static int
3107 136 : crl_issuer_matches(gnutls_x509_crl_t crl, gnutls_x509_crt_t cert)
3108 : {
3109 136 : if (_gnutls_x509_compare_raw_dn
3110 136 : (&crl->raw_issuer_dn, &cert->raw_issuer_dn) != 0)
3111 : return 1;
3112 : else
3113 0 : return 0;
3114 : }
3115 :
3116 : /* This is exactly as gnutls_x509_crt_check_revocation() except that
3117 : * it calls func.
3118 : */
3119 : int
3120 869 : _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 869 : uint8_t serial[128];
3126 869 : uint8_t cert_serial[128];
3127 869 : size_t serial_size, cert_serial_size;
3128 869 : int ret, j;
3129 869 : gnutls_x509_crl_iter_t iter = NULL;
3130 :
3131 869 : if (cert == NULL) {
3132 0 : gnutls_assert();
3133 0 : return GNUTLS_E_INVALID_REQUEST;
3134 : }
3135 :
3136 998 : 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 136 : ret = crl_issuer_matches(crl_list[j], cert);
3141 136 : if (ret == 0) {
3142 : /* issuers do not match so don't even
3143 : * bother checking.
3144 : */
3145 0 : gnutls_assert();
3146 0 : continue;
3147 : }
3148 :
3149 : /* Step 2. Read the certificate's serial number
3150 : */
3151 136 : cert_serial_size = sizeof(cert_serial);
3152 136 : ret =
3153 136 : gnutls_x509_crt_get_serial(cert, cert_serial,
3154 : &cert_serial_size);
3155 136 : if (ret < 0) {
3156 0 : gnutls_assert();
3157 0 : return ret;
3158 : }
3159 :
3160 : /* Step 3. cycle through the CRL serials and compare with
3161 : * certificate serial we have.
3162 : */
3163 :
3164 136 : iter = NULL;
3165 191 : do {
3166 191 : serial_size = sizeof(serial);
3167 191 : ret =
3168 191 : gnutls_x509_crl_iter_crt_serial(crl_list[j],
3169 : &iter,
3170 : serial,
3171 : &serial_size,
3172 : NULL);
3173 191 : if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
3174 : break;
3175 62 : } else if (ret < 0) {
3176 0 : gnutls_assert();
3177 0 : goto fail;
3178 : }
3179 :
3180 62 : if (serial_size == cert_serial_size) {
3181 42 : if (memcmp
3182 : (serial, cert_serial,
3183 : serial_size) == 0) {
3184 : /* serials match */
3185 7 : if (func)
3186 6 : func(cert, NULL,
3187 : crl_list[j],
3188 : GNUTLS_CERT_REVOKED |
3189 : GNUTLS_CERT_INVALID);
3190 7 : ret = 1; /* revoked! */
3191 7 : goto fail;
3192 : }
3193 : }
3194 : } while(1);
3195 :
3196 129 : gnutls_x509_crl_iter_deinit(iter);
3197 129 : iter = NULL;
3198 :
3199 129 : if (func)
3200 127 : func(cert, NULL, crl_list[j], 0);
3201 :
3202 : }
3203 : return 0; /* not revoked. */
3204 :
3205 7 : fail:
3206 7 : gnutls_x509_crl_iter_deinit(iter);
3207 7 : 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
3224 210 : 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 210 : 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
3247 2 : gnutls_x509_crt_check_key_purpose(gnutls_x509_crt_t cert,
3248 : const char *purpose,
3249 : unsigned flags)
3250 : {
3251 2 : 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
3272 4 : gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,
3273 : gnutls_digest_algorithm_t *
3274 : hash, unsigned int *mand)
3275 : {
3276 4 : int ret;
3277 4 : gnutls_pubkey_t pubkey;
3278 :
3279 4 : if (crt == NULL) {
3280 0 : gnutls_assert();
3281 0 : return GNUTLS_E_INVALID_REQUEST;
3282 : }
3283 :
3284 4 : ret = gnutls_pubkey_init(&pubkey);
3285 4 : if (ret < 0)
3286 0 : return gnutls_assert_val(ret);
3287 :
3288 4 : ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3289 4 : if (ret < 0) {
3290 0 : gnutls_assert();
3291 0 : goto cleanup;
3292 : }
3293 :
3294 4 : ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, hash, mand);
3295 4 : if (ret < 0) {
3296 0 : gnutls_assert();
3297 0 : goto cleanup;
3298 : }
3299 :
3300 4 : cleanup:
3301 4 : gnutls_pubkey_deinit(pubkey);
3302 4 : 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
3327 0 : 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 0 : int ret;
3334 0 : gnutls_datum_t dist_points = { NULL, 0 };
3335 0 : unsigned type;
3336 0 : gnutls_x509_crl_dist_points_t cdp = NULL;
3337 0 : gnutls_datum_t t_san;
3338 :
3339 0 : if (cert == NULL) {
3340 0 : gnutls_assert();
3341 0 : return GNUTLS_E_INVALID_REQUEST;
3342 : }
3343 :
3344 0 : ret = gnutls_x509_crl_dist_points_init(&cdp);
3345 0 : if (ret < 0)
3346 0 : return gnutls_assert_val(ret);
3347 :
3348 0 : if (reason_flags)
3349 0 : *reason_flags = 0;
3350 :
3351 0 : ret =
3352 0 : _gnutls_x509_crt_get_extension(cert, "2.5.29.31", 0,
3353 : &dist_points, critical);
3354 0 : if (ret < 0) {
3355 0 : gnutls_assert();
3356 0 : goto cleanup;
3357 : }
3358 :
3359 0 : if (dist_points.size == 0 || dist_points.data == NULL) {
3360 0 : gnutls_assert();
3361 0 : ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3362 0 : goto cleanup;
3363 : }
3364 :
3365 0 : ret = gnutls_x509_ext_import_crl_dist_points(&dist_points, cdp, 0);
3366 0 : if (ret < 0) {
3367 0 : gnutls_assert();
3368 0 : goto cleanup;
3369 : }
3370 :
3371 0 : ret = gnutls_x509_crl_dist_points_get(cdp, seq, &type, &t_san, reason_flags);
3372 0 : if (ret < 0) {
3373 0 : gnutls_assert();
3374 0 : goto cleanup;
3375 : }
3376 :
3377 0 : ret = _gnutls_copy_string(&t_san, san, san_size);
3378 0 : if (ret < 0) {
3379 0 : gnutls_assert();
3380 0 : goto cleanup;
3381 : }
3382 :
3383 0 : ret = type;
3384 :
3385 0 : cleanup:
3386 0 : _gnutls_free_datum(&dist_points);
3387 0 : if (cdp != NULL)
3388 0 : 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
3415 674 : 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 674 : int ret;
3420 674 : gnutls_datum_t ext;
3421 674 : gnutls_x509_key_purposes_t p = NULL;
3422 674 : gnutls_datum_t out;
3423 :
3424 674 : if (cert == NULL) {
3425 0 : gnutls_assert();
3426 0 : return GNUTLS_E_INVALID_REQUEST;
3427 : }
3428 :
3429 674 : if (oid)
3430 670 : memset(oid, 0, *oid_size);
3431 : else
3432 4 : *oid_size = 0;
3433 :
3434 1348 : if ((ret =
3435 674 : _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &ext,
3436 : critical)) < 0) {
3437 : return ret;
3438 : }
3439 :
3440 379 : if (ext.size == 0 || ext.data == NULL) {
3441 0 : gnutls_assert();
3442 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3443 : }
3444 :
3445 379 : ret = gnutls_x509_key_purpose_init(&p);
3446 379 : if (ret < 0) {
3447 0 : gnutls_assert();
3448 0 : goto cleanup;
3449 : }
3450 :
3451 379 : ret = gnutls_x509_ext_import_key_purposes(&ext, p, 0);
3452 379 : if (ret < 0) {
3453 0 : gnutls_assert();
3454 0 : goto cleanup;
3455 : }
3456 :
3457 379 : ret = gnutls_x509_key_purpose_get(p, indx, &out);
3458 379 : if (ret < 0) {
3459 20 : gnutls_assert();
3460 20 : goto cleanup;
3461 : }
3462 :
3463 359 : ret = _gnutls_copy_string(&out, oid, oid_size);
3464 359 : if (ret < 0) {
3465 2 : gnutls_assert();
3466 2 : goto cleanup;
3467 : }
3468 :
3469 : ret = 0;
3470 :
3471 379 : cleanup:
3472 379 : gnutls_free(ext.data);
3473 379 : if (p!=NULL)
3474 379 : 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
3491 0 : gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt,
3492 : gnutls_datum_t * m, gnutls_datum_t * e)
3493 : {
3494 0 : int ret;
3495 0 : gnutls_pubkey_t pubkey;
3496 :
3497 0 : if (crt == NULL) {
3498 0 : gnutls_assert();
3499 0 : return GNUTLS_E_INVALID_REQUEST;
3500 : }
3501 :
3502 0 : ret = gnutls_pubkey_init(&pubkey);
3503 0 : if (ret < 0)
3504 0 : return gnutls_assert_val(ret);
3505 :
3506 0 : ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3507 0 : if (ret < 0) {
3508 0 : gnutls_assert();
3509 0 : goto cleanup;
3510 : }
3511 :
3512 0 : ret = gnutls_pubkey_export_rsa_raw(pubkey, m, e);
3513 0 : if (ret < 0) {
3514 0 : gnutls_assert();
3515 0 : goto cleanup;
3516 : }
3517 :
3518 0 : cleanup:
3519 0 : gnutls_pubkey_deinit(pubkey);
3520 0 : 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
3542 86 : 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 86 : int ret;
3547 86 : gnutls_pubkey_t pubkey;
3548 :
3549 86 : if (crt == NULL) {
3550 0 : gnutls_assert();
3551 0 : return GNUTLS_E_INVALID_REQUEST;
3552 : }
3553 :
3554 86 : ret = gnutls_pubkey_init(&pubkey);
3555 86 : if (ret < 0)
3556 0 : return gnutls_assert_val(ret);
3557 :
3558 86 : ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3559 86 : if (ret < 0) {
3560 1 : gnutls_assert();
3561 1 : goto cleanup;
3562 : }
3563 :
3564 85 : ret = gnutls_pubkey_export_ecc_raw(pubkey, curve, x, y);
3565 85 : if (ret < 0) {
3566 0 : gnutls_assert();
3567 0 : goto cleanup;
3568 : }
3569 :
3570 85 : cleanup:
3571 86 : gnutls_pubkey_deinit(pubkey);
3572 86 : 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
3593 24 : 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 24 : int ret;
3600 24 : gnutls_pubkey_t pubkey;
3601 :
3602 24 : if (crt == NULL) {
3603 0 : gnutls_assert();
3604 0 : return GNUTLS_E_INVALID_REQUEST;
3605 : }
3606 :
3607 24 : ret = gnutls_pubkey_init(&pubkey);
3608 24 : if (ret < 0)
3609 0 : return gnutls_assert_val(ret);
3610 :
3611 24 : ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3612 24 : if (ret < 0) {
3613 0 : gnutls_assert();
3614 0 : goto cleanup;
3615 : }
3616 :
3617 24 : ret = gnutls_pubkey_export_gost_raw2(pubkey, curve, digest,
3618 : paramset, x, y, 0);
3619 24 : if (ret < 0) {
3620 0 : gnutls_assert();
3621 0 : goto cleanup;
3622 : }
3623 :
3624 24 : cleanup:
3625 24 : gnutls_pubkey_deinit(pubkey);
3626 24 : 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
3644 0 : 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 0 : int ret;
3649 0 : gnutls_pubkey_t pubkey;
3650 :
3651 0 : if (crt == NULL) {
3652 0 : gnutls_assert();
3653 0 : return GNUTLS_E_INVALID_REQUEST;
3654 : }
3655 :
3656 0 : ret = gnutls_pubkey_init(&pubkey);
3657 0 : if (ret < 0)
3658 0 : return gnutls_assert_val(ret);
3659 :
3660 0 : ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
3661 0 : if (ret < 0) {
3662 0 : gnutls_assert();
3663 0 : goto cleanup;
3664 : }
3665 :
3666 0 : ret = gnutls_pubkey_export_dsa_raw(pubkey, p, q, g, y);
3667 0 : if (ret < 0) {
3668 0 : gnutls_assert();
3669 0 : goto cleanup;
3670 : }
3671 :
3672 0 : cleanup:
3673 0 : gnutls_pubkey_deinit(pubkey);
3674 0 : 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
3700 2485 : 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 2485 : unsigned int init = 1024;
3707 2485 : int ret;
3708 :
3709 2485 : *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t) * init);
3710 2485 : if (*certs == NULL) {
3711 0 : gnutls_assert();
3712 0 : return GNUTLS_E_MEMORY_ERROR;
3713 : }
3714 :
3715 2485 : ret =
3716 2485 : gnutls_x509_crt_list_import(*certs, &init, data, format,
3717 : flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
3718 2485 : if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
3719 0 : *certs =
3720 0 : gnutls_realloc_fast(*certs,
3721 : sizeof(gnutls_x509_crt_t) * init);
3722 0 : if (*certs == NULL) {
3723 0 : gnutls_assert();
3724 0 : return GNUTLS_E_MEMORY_ERROR;
3725 : }
3726 :
3727 0 : ret =
3728 0 : gnutls_x509_crt_list_import(*certs, &init, data,
3729 : format, flags);
3730 : }
3731 :
3732 2485 : if (ret < 0) {
3733 979 : gnutls_free(*certs);
3734 979 : return ret;
3735 : }
3736 :
3737 1506 : *size = init;
3738 1506 : 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
3765 2651 : 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 2651 : int size;
3772 2651 : const char *ptr;
3773 2651 : gnutls_datum_t tmp;
3774 2651 : int ret, nocopy = 0;
3775 2651 : unsigned int count = 0, j, copied = 0;
3776 :
3777 2651 : if (format == GNUTLS_X509_FMT_DER) {
3778 902 : if (*cert_max < 1) {
3779 0 : *cert_max = 1;
3780 0 : return GNUTLS_E_SHORT_MEMORY_BUFFER;
3781 : }
3782 :
3783 902 : count = 1; /* import only the first one */
3784 :
3785 902 : ret = gnutls_x509_crt_init(&certs[0]);
3786 902 : if (ret < 0) {
3787 0 : gnutls_assert();
3788 0 : goto error;
3789 : }
3790 :
3791 902 : ret = gnutls_x509_crt_import(certs[0], data, format);
3792 902 : if (ret < 0) {
3793 620 : gnutls_assert();
3794 620 : goto error;
3795 : }
3796 :
3797 282 : *cert_max = 1;
3798 282 : return 1;
3799 : }
3800 :
3801 : /* move to the certificate
3802 : */
3803 1749 : ptr = memmem(data->data, data->size,
3804 : PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
3805 1749 : if (ptr == NULL)
3806 130 : ptr = memmem(data->data, data->size,
3807 : PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);
3808 :
3809 1749 : if (ptr == NULL)
3810 116 : return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
3811 :
3812 : count = 0;
3813 :
3814 8622 : do {
3815 8622 : if (count >= *cert_max) {
3816 17 : if (!
3817 17 : (flags &
3818 : GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
3819 : break;
3820 : else
3821 : nocopy = 1;
3822 : }
3823 :
3824 8605 : if (!nocopy) {
3825 8605 : ret = gnutls_x509_crt_init(&certs[count]);
3826 8605 : if (ret < 0) {
3827 0 : gnutls_assert();
3828 0 : goto error;
3829 : }
3830 :
3831 8605 : tmp.data = (void *) ptr;
3832 8605 : tmp.size =
3833 8605 : data->size - (ptr - (char *) data->data);
3834 :
3835 8605 : ret =
3836 8605 : gnutls_x509_crt_import(certs[count], &tmp,
3837 : GNUTLS_X509_FMT_PEM);
3838 8605 : if (ret < 0) {
3839 243 : count++;
3840 243 : gnutls_assert();
3841 243 : goto error;
3842 : }
3843 :
3844 8362 : copied++;
3845 : }
3846 :
3847 : /* now we move ptr after the pem header
3848 : */
3849 8376 : ptr++;
3850 : /* find the next certificate (if any)
3851 : */
3852 8376 : size = data->size - (ptr - (char *) data->data);
3853 :
3854 8376 : if (size > 0) {
3855 8376 : char *ptr2;
3856 :
3857 8376 : ptr2 =
3858 8376 : memmem(ptr, size, PEM_CERT_SEP,
3859 : sizeof(PEM_CERT_SEP) - 1);
3860 8376 : if (ptr2 == NULL)
3861 1636 : ptr2 = memmem(ptr, size, PEM_CERT_SEP2,
3862 : sizeof(PEM_CERT_SEP2) - 1);
3863 :
3864 8376 : ptr = ptr2;
3865 : } else
3866 : ptr = NULL;
3867 :
3868 8376 : count++;
3869 : }
3870 8376 : while (ptr != NULL);
3871 :
3872 1390 : *cert_max = count;
3873 :
3874 1390 : if (nocopy == 0) {
3875 1385 : if (flags & GNUTLS_X509_CRT_LIST_SORT && *cert_max > 1) {
3876 9 : gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
3877 9 : gnutls_x509_crt_t *s;
3878 :
3879 9 : s = _gnutls_sort_clist(sorted, certs, cert_max, gnutls_x509_crt_deinit);
3880 9 : if (s == certs) {
3881 0 : gnutls_assert();
3882 0 : ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
3883 0 : goto error;
3884 : }
3885 :
3886 9 : count = *cert_max;
3887 9 : if (s == sorted) {
3888 9 : memcpy(certs, s, (*cert_max)*sizeof(gnutls_x509_crt_t));
3889 : }
3890 : }
3891 :
3892 1385 : if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) {
3893 25 : ret = _gnutls_check_if_sorted(certs, *cert_max);
3894 25 : if (ret < 0) {
3895 1 : gnutls_assert();
3896 1 : goto error;
3897 : }
3898 : }
3899 :
3900 1384 : return count;
3901 : } else {
3902 : count = copied;
3903 : ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
3904 : }
3905 :
3906 869 : error:
3907 2232 : for (j = 0; j < count; j++)
3908 1363 : 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
3934 1288 : gnutls_x509_crt_get_subject_unique_id(gnutls_x509_crt_t crt, char *buf,
3935 : size_t * buf_size)
3936 : {
3937 1288 : int result;
3938 1288 : gnutls_datum_t datum = { NULL, 0 };
3939 :
3940 1288 : result =
3941 1288 : _gnutls_x509_read_value(crt->cert,
3942 : "tbsCertificate.subjectUniqueID",
3943 : &datum);
3944 1288 : if (result < 0)
3945 1333 : return gnutls_assert_val(result);
3946 :
3947 19 : if (datum.size > *buf_size) { /* then we're not going to fit */
3948 6 : *buf_size = datum.size;
3949 6 : result = GNUTLS_E_SHORT_MEMORY_BUFFER;
3950 : } else {
3951 13 : *buf_size = datum.size;
3952 13 : memcpy(buf, datum.data, datum.size);
3953 : }
3954 :
3955 19 : _gnutls_free_datum(&datum);
3956 :
3957 19 : 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
3984 1280 : gnutls_x509_crt_get_issuer_unique_id(gnutls_x509_crt_t crt, char *buf,
3985 : size_t * buf_size)
3986 : {
3987 1280 : int result;
3988 1280 : gnutls_datum_t datum = { NULL, 0 };
3989 :
3990 1280 : result =
3991 1280 : _gnutls_x509_read_value(crt->cert,
3992 : "tbsCertificate.issuerUniqueID",
3993 : &datum);
3994 1280 : if (result < 0)
3995 1319 : return gnutls_assert_val(result);
3996 :
3997 25 : if (datum.size > *buf_size) { /* then we're not going to fit */
3998 6 : *buf_size = datum.size;
3999 6 : result = GNUTLS_E_SHORT_MEMORY_BUFFER;
4000 : } else {
4001 19 : *buf_size = datum.size;
4002 19 : memcpy(buf, datum.data, datum.size);
4003 : }
4004 :
4005 25 : _gnutls_free_datum(&datum);
4006 :
4007 25 : return result;
4008 : }
4009 :
4010 : static int
4011 15 : legacy_parse_aia(ASN1_TYPE src,
4012 : unsigned int seq, int what, gnutls_datum_t * data)
4013 : {
4014 15 : int len;
4015 15 : char nptr[MAX_NAME_SIZE];
4016 15 : int result;
4017 15 : gnutls_datum_t d;
4018 15 : const char *oid = NULL;
4019 :
4020 15 : seq++; /* 0->1, 1->2 etc */
4021 15 : switch (what) {
4022 3 : case GNUTLS_IA_ACCESSMETHOD_OID:
4023 3 : snprintf(nptr, sizeof(nptr), "?%u.accessMethod", seq);
4024 3 : break;
4025 :
4026 3 : case GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE:
4027 3 : snprintf(nptr, sizeof(nptr), "?%u.accessLocation", seq);
4028 3 : break;
4029 :
4030 : case GNUTLS_IA_CAISSUERS_URI:
4031 : oid = GNUTLS_OID_AD_CAISSUERS;
4032 6 : FALLTHROUGH;
4033 :
4034 : case GNUTLS_IA_OCSP_URI:
4035 6 : if (oid == NULL)
4036 6 : oid = GNUTLS_OID_AD_OCSP;
4037 : {
4038 7 : char tmpoid[MAX_OID_SIZE];
4039 7 : snprintf(nptr, sizeof(nptr), "?%u.accessMethod",
4040 : seq);
4041 7 : len = sizeof(tmpoid);
4042 7 : result = asn1_read_value(src, nptr, tmpoid, &len);
4043 :
4044 7 : if (result == ASN1_VALUE_NOT_FOUND
4045 7 : || result == ASN1_ELEMENT_NOT_FOUND)
4046 0 : return
4047 0 : gnutls_assert_val
4048 : (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4049 :
4050 7 : if (result != ASN1_SUCCESS) {
4051 0 : gnutls_assert();
4052 0 : return _gnutls_asn2err(result);
4053 : }
4054 7 : if ((unsigned) len != strlen(oid) + 1
4055 7 : || memcmp(tmpoid, oid, len) != 0)
4056 0 : return
4057 0 : gnutls_assert_val
4058 : (GNUTLS_E_UNKNOWN_ALGORITHM);
4059 : }
4060 8 : FALLTHROUGH;
4061 :
4062 : case GNUTLS_IA_URI:
4063 8 : snprintf(nptr, sizeof(nptr),
4064 : "?%u.accessLocation.uniformResourceIdentifier",
4065 : seq);
4066 8 : break;
4067 :
4068 : default:
4069 1 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4070 : }
4071 :
4072 14 : len = 0;
4073 14 : result = asn1_read_value(src, nptr, NULL, &len);
4074 14 : if (result == ASN1_VALUE_NOT_FOUND
4075 14 : || result == ASN1_ELEMENT_NOT_FOUND)
4076 1 : return
4077 1 : gnutls_assert_val
4078 : (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
4079 :
4080 13 : if (result != ASN1_MEM_ERROR) {
4081 0 : gnutls_assert();
4082 0 : return _gnutls_asn2err(result);
4083 : }
4084 :
4085 13 : d.size = len;
4086 :
4087 13 : d.data = gnutls_malloc(d.size);
4088 13 : if (d.data == NULL)
4089 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
4090 :
4091 13 : result = asn1_read_value(src, nptr, d.data, &len);
4092 13 : if (result != ASN1_SUCCESS) {
4093 0 : gnutls_assert();
4094 0 : gnutls_free(d.data);
4095 0 : return _gnutls_asn2err(result);
4096 : }
4097 :
4098 13 : if (data) {
4099 10 : data->data = d.data;
4100 10 : data->size = d.size;
4101 : } else
4102 3 : 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
4174 16 : 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 16 : int ret;
4181 16 : gnutls_datum_t aia;
4182 16 : ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
4183 :
4184 16 : if (crt == NULL) {
4185 1 : gnutls_assert();
4186 1 : return GNUTLS_E_INVALID_REQUEST;
4187 : }
4188 :
4189 30 : if ((ret =
4190 15 : _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &aia,
4191 : critical)) < 0)
4192 : return ret;
4193 :
4194 15 : if (aia.size == 0 || aia.data == NULL) {
4195 0 : gnutls_assert();
4196 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
4197 : }
4198 :
4199 15 : if (critical && *critical)
4200 : return GNUTLS_E_CONSTRAINT_ERROR;
4201 :
4202 15 : ret = asn1_create_element(_gnutls_get_pkix(),
4203 : "PKIX1.AuthorityInfoAccessSyntax", &c2);
4204 15 : if (ret != ASN1_SUCCESS) {
4205 0 : gnutls_assert();
4206 0 : _gnutls_free_datum(&aia);
4207 0 : return _gnutls_asn2err(ret);
4208 : }
4209 :
4210 15 : ret = _asn1_strict_der_decode(&c2, aia.data, aia.size, NULL);
4211 : /* asn1_print_structure (stdout, c2, "", ASN1_PRINT_ALL); */
4212 15 : _gnutls_free_datum(&aia);
4213 15 : if (ret != ASN1_SUCCESS) {
4214 0 : gnutls_assert();
4215 0 : asn1_delete_structure(&c2);
4216 0 : return _gnutls_asn2err(ret);
4217 : }
4218 :
4219 15 : ret = legacy_parse_aia(c2, seq, what, data);
4220 :
4221 15 : asn1_delete_structure(&c2);
4222 15 : if (ret < 0)
4223 2 : 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 : **/
4244 25 : void gnutls_x509_crt_set_pin_function(gnutls_x509_crt_t crt,
4245 : gnutls_pin_callback_t fn,
4246 : void *userdata)
4247 : {
4248 25 : if (crt) {
4249 25 : crt->pin.cb = fn;
4250 25 : crt->pin.data = userdata;
4251 : }
4252 25 : }
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
4273 28 : gnutls_x509_crt_import_url(gnutls_x509_crt_t crt,
4274 : const char *url, unsigned int flags)
4275 : {
4276 28 : int ret;
4277 28 : unsigned i;
4278 :
4279 28 : for (i=0;i<_gnutls_custom_urls_size;i++) {
4280 0 : if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
4281 0 : if (_gnutls_custom_urls[i].import_crt) {
4282 0 : ret = _gnutls_custom_urls[i].import_crt(crt, url, flags);
4283 0 : goto cleanup;
4284 : }
4285 : break;
4286 : }
4287 : }
4288 :
4289 28 : if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
4290 0 : ret = _gnutls_x509_crt_import_system_url(crt, url);
4291 : #ifdef ENABLE_PKCS11
4292 28 : } else if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
4293 28 : ret = _gnutls_x509_crt_import_pkcs11_url(crt, url, flags);
4294 : #endif
4295 : } else {
4296 0 : ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
4297 : }
4298 :
4299 28 : cleanup:
4300 28 : 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
4327 6 : 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 6 : int ret;
4335 6 : unsigned i;
4336 6 : gnutls_x509_crt_t crts[DEFAULT_MAX_VERIFY_DEPTH];
4337 6 : gnutls_datum_t issuer = {NULL, 0};
4338 6 : unsigned total = 0;
4339 :
4340 6 : memset(crts, 0, sizeof(crts));
4341 :
4342 6 : ret = gnutls_x509_crt_init(&crts[0]);
4343 6 : if (ret < 0)
4344 0 : return gnutls_assert_val(ret);
4345 :
4346 6 : gnutls_x509_crt_set_pin_function(crts[0], pin_fn, pin_fn_userdata);
4347 :
4348 6 : total = 1;
4349 :
4350 6 : ret = gnutls_x509_crt_import_url(crts[0], url, flags);
4351 6 : if (ret < 0) {
4352 3 : gnutls_assert();
4353 3 : goto cleanup;
4354 : }
4355 :
4356 15 : for (i=1;i<DEFAULT_MAX_VERIFY_DEPTH;i++) {
4357 15 : ret = _gnutls_get_raw_issuer(url, crts[i-1], &issuer, flags|GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_ANY);
4358 15 : if (ret < 0) {
4359 0 : issuer.data = NULL;
4360 0 : break;
4361 : }
4362 :
4363 15 : if (gnutls_x509_crt_equals2(crts[i-1], &issuer)) {
4364 3 : gnutls_free(issuer.data);
4365 3 : break;
4366 : }
4367 :
4368 12 : ret = gnutls_x509_crt_init(&crts[i]);
4369 12 : if (ret < 0) {
4370 0 : gnutls_assert();
4371 0 : goto cleanup;
4372 : }
4373 :
4374 12 : total++;
4375 :
4376 12 : gnutls_x509_crt_set_pin_function(crts[i], pin_fn, pin_fn_userdata);
4377 :
4378 12 : ret = gnutls_x509_crt_import(crts[i], &issuer, GNUTLS_X509_FMT_DER);
4379 12 : if (ret < 0) {
4380 0 : gnutls_assert();
4381 0 : goto cleanup;
4382 : }
4383 :
4384 12 : gnutls_free(issuer.data);
4385 : }
4386 :
4387 3 : *certs = gnutls_malloc(total*sizeof(gnutls_x509_crt_t));
4388 3 : if (*certs == NULL) {
4389 0 : ret = GNUTLS_E_MEMORY_ERROR;
4390 0 : goto cleanup;
4391 : }
4392 :
4393 3 : memcpy(*certs, crts, total*sizeof(gnutls_x509_crt_t));
4394 3 : *size = total;
4395 :
4396 3 : return 0;
4397 3 : cleanup:
4398 3 : gnutls_free(issuer.data);
4399 6 : for (i=0;i<total;i++)
4400 3 : 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
4423 50 : 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 50 : int ret;
4432 50 : gnutls_pubkey_t pubkey;
4433 :
4434 50 : if (crt == NULL) {
4435 0 : gnutls_assert();
4436 0 : return GNUTLS_E_INVALID_REQUEST;
4437 : }
4438 :
4439 :
4440 50 : ret = gnutls_pubkey_init(&pubkey);
4441 50 : if (ret < 0)
4442 0 : return gnutls_assert_val(ret);
4443 :
4444 50 : ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
4445 50 : if (ret < 0)
4446 0 : return gnutls_assert_val(ret);
4447 :
4448 50 : ret = gnutls_pubkey_verify_data2(pubkey, algo, flags, data, signature);
4449 50 : gnutls_pubkey_deinit(pubkey);
4450 :
4451 50 : if (ret >= 0) {
4452 39 : time_t now = gnutls_time(0);
4453 39 : int res;
4454 39 : unsigned usage, i;
4455 :
4456 39 : if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) ||
4457 : !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
4458 39 : if (now > gnutls_x509_crt_get_expiration_time(crt)) {
4459 3 : return gnutls_assert_val(GNUTLS_E_EXPIRED);
4460 : }
4461 :
4462 38 : if (now < gnutls_x509_crt_get_activation_time(crt)) {
4463 2 : return gnutls_assert_val(GNUTLS_E_NOT_YET_ACTIVATED);
4464 : }
4465 : }
4466 :
4467 36 : res = gnutls_x509_crt_get_key_usage(crt, &usage, NULL);
4468 36 : if (res >= 0) {
4469 32 : if (!(usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
4470 0 : return gnutls_assert_val(GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE);
4471 : }
4472 : }
4473 :
4474 36 : for (i=0;i<vdata_size;i++) {
4475 2 : if (vdata[i].type == GNUTLS_DT_KEY_PURPOSE_OID) {
4476 2 : res = _gnutls_check_key_purpose(crt, (char *)vdata[i].data, 0);
4477 2 : if (res == 0)
4478 0 : 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
4508 39 : 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 39 : 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 : **/
4530 645 : void gnutls_x509_crt_set_flags(gnutls_x509_crt_t cert,
4531 : unsigned int flags)
4532 : {
4533 645 : cert->flags = flags;
4534 645 : }
4535 :
|