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