gnutls_x509_crt_get_authority_info_access: doc update
[gnutls:gnutls.git] / lib / x509 / x509.c
1 /*
2  * Copyright (C) 2003-2014 Free Software Foundation, Inc.
3  * Authors: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
4  *
5  * This file is part of GnuTLS.
6  *
7  * The GnuTLS is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>
19  *
20  */
21
22 /* Functions on X.509 Certificate parsing
23  */
24
25 #include <gnutls_int.h>
26 #include <gnutls_datum.h>
27 #include <gnutls_global.h>
28 #include <gnutls_errors.h>
29 #include <common.h>
30 #include <gnutls/x509-ext.h>
31 #include <gnutls_x509.h>
32 #include <x509_b64.h>
33 #include <x509_int.h>
34 #include <libtasn1.h>
35 #include <gnutls_pk.h>
36 #include <pkcs11_int.h>
37 #include "urls.h"
38 #include "system-keys.h"
39
40 static int crt_reinit(gnutls_x509_crt_t crt)
41 {
42         int result;
43
44         crt->raw_dn.size = 0;
45         crt->raw_issuer_dn.size = 0;
46
47         asn1_delete_structure(&crt->cert);
48
49         result = asn1_create_element(_gnutls_get_pkix(),
50                                      "PKIX1.Certificate",
51                                      &crt->cert);
52         if (result != ASN1_SUCCESS) {
53                 result = _gnutls_asn2err(result);
54                 gnutls_assert();
55                 return result;
56         }
57
58         return 0;
59 }
60
61 /**
62  * gnutls_x509_crt_init:
63  * @cert: The structure to be initialized
64  *
65  * This function will initialize an X.509 certificate structure.
66  *
67  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
68  *   negative error value.
69  **/
70 int gnutls_x509_crt_init(gnutls_x509_crt_t * cert)
71 {
72         gnutls_x509_crt_t tmp;
73
74         FAIL_IF_LIB_ERROR;
75
76         tmp =
77             gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
78         int result;
79
80         if (!tmp)
81                 return GNUTLS_E_MEMORY_ERROR;
82
83         result = asn1_create_element(_gnutls_get_pkix(),
84                                      "PKIX1.Certificate", &tmp->cert);
85         if (result != ASN1_SUCCESS) {
86                 gnutls_assert();
87                 gnutls_free(tmp);
88                 return _gnutls_asn2err(result);
89         }
90
91         /* If you add anything here, be sure to check if it has to be added
92            to gnutls_x509_crt_import as well. */
93
94         *cert = tmp;
95
96         return 0;               /* success */
97 }
98
99 /*-
100  * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t structure
101  * @dest: The structure where to copy
102  * @src: The structure to be copied
103  *
104  * This function will copy an X.509 certificate structure.
105  *
106  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
107  *   negative error value.
108  -*/
109 int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
110 {
111         int ret;
112         size_t der_size = 0;
113         uint8_t *der;
114         gnutls_datum_t tmp;
115
116         ret =
117             gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, NULL,
118                                    &der_size);
119         if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
120                 gnutls_assert();
121                 return ret;
122         }
123
124         der = gnutls_malloc(der_size);
125         if (der == NULL) {
126                 gnutls_assert();
127                 return GNUTLS_E_MEMORY_ERROR;
128         }
129
130         ret =
131             gnutls_x509_crt_export(src, GNUTLS_X509_FMT_DER, der,
132                                    &der_size);
133         if (ret < 0) {
134                 gnutls_assert();
135                 gnutls_free(der);
136                 return ret;
137         }
138
139         tmp.data = der;
140         tmp.size = der_size;
141         ret = gnutls_x509_crt_import(dest, &tmp, GNUTLS_X509_FMT_DER);
142
143         gnutls_free(der);
144
145         if (ret < 0) {
146                 gnutls_assert();
147                 return ret;
148         }
149
150         return 0;
151 }
152
153 /**
154  * gnutls_x509_crt_deinit:
155  * @cert: The structure to be deinitialized
156  *
157  * This function will deinitialize a certificate structure.
158  **/
159 void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert)
160 {
161         if (!cert)
162                 return;
163
164         if (cert->cert)
165                 asn1_delete_structure(&cert->cert);
166         gnutls_free(cert->der.data);
167         gnutls_free(cert);
168 }
169
170 /**
171  * gnutls_x509_crt_import:
172  * @cert: The structure to store the parsed certificate.
173  * @data: The DER or PEM encoded certificate.
174  * @format: One of DER or PEM
175  *
176  * This function will convert the given DER or PEM encoded Certificate
177  * to the native gnutls_x509_crt_t format. The output will be stored
178  * in @cert.
179  *
180  * If the Certificate is PEM encoded it should have a header of "X509
181  * CERTIFICATE", or "CERTIFICATE".
182  *
183  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
184  *   negative error value.
185  **/
186 int
187 gnutls_x509_crt_import(gnutls_x509_crt_t cert,
188                        const gnutls_datum_t * data,
189                        gnutls_x509_crt_fmt_t format)
190 {
191         int result = 0;
192         int version;
193
194         if (cert == NULL) {
195                 gnutls_assert();
196                 return GNUTLS_E_INVALID_REQUEST;
197         }
198
199         if (cert->der.data) {
200                 gnutls_free(cert->der.data);
201                 cert->der.data = NULL;
202         }
203
204         /* If the Certificate is in PEM format then decode it
205          */
206         if (format == GNUTLS_X509_FMT_PEM) {
207                 /* Try the first header */
208                 result =
209                     _gnutls_fbase64_decode(PEM_X509_CERT2, data->data,
210                                            data->size, &cert->der);
211
212                 if (result <= 0) {
213                         /* try for the second header */
214                         result =
215                             _gnutls_fbase64_decode(PEM_X509_CERT,
216                                                    data->data, data->size,
217                                                    &cert->der);
218
219                         if (result < 0) {
220                                 gnutls_assert();
221                                 return result;
222                         }
223                 }
224         } else {
225                 result = _gnutls_set_datum(&cert->der, data->data, data->size);
226                 if (result < 0) {
227                         gnutls_assert();
228                         return result;
229                 }
230         }
231
232         if (cert->expanded) {
233                 /* Any earlier asn1_der_decoding will modify the ASN.1
234                    structure, so we need to replace it with a fresh
235                    structure. */
236                 result = crt_reinit(cert);
237                 if (result < 0) {
238                         gnutls_assert();
239                         goto cleanup;
240                 }
241         }
242
243         cert->expanded = 1;
244
245         result =
246             asn1_der_decoding(&cert->cert, cert->der.data, cert->der.size, NULL);
247         if (result != ASN1_SUCCESS) {
248                 result = _gnutls_asn2err(result);
249                 gnutls_assert();
250                 goto cleanup;
251         }
252
253         result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
254                                           "tbsCertificate.issuer.rdnSequence",
255                                           &cert->raw_issuer_dn);
256         if (result < 0) {
257                 gnutls_assert();
258                 goto cleanup;
259         }
260
261         result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
262                                           "tbsCertificate.subject.rdnSequence",
263                                           &cert->raw_dn);
264         if (result < 0) {
265                 gnutls_assert();
266                 goto cleanup;
267         }
268
269         result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
270                                           "tbsCertificate.subjectPublicKeyInfo",
271                                           &cert->raw_spki);
272         if (result < 0) {
273                 gnutls_assert();
274                 goto cleanup;
275         }
276
277         /* enforce the rule that only version 3 certificates carry extensions */
278         version = gnutls_x509_crt_get_version(cert);
279         if (version < 3) {
280                 gnutls_datum_t exts;
281                 result = _gnutls_x509_get_raw_field2(cert->cert, &cert->der,
282                         "tbsCertificate.extensions", &exts);
283                 if (result >= 0 && exts.size > 0) {
284                         gnutls_assert();
285                         _gnutls_debug_log("error: extensions present in certificate with version %d\n", version);
286                         result = GNUTLS_E_X509_CERTIFICATE_ERROR;
287                         goto cleanup;
288                 }
289         }
290
291         /* Since we do not want to disable any extension
292          */
293         cert->use_extensions = 1;
294
295         return 0;
296
297       cleanup:
298         _gnutls_free_datum(&cert->der);
299         return result;
300 }
301
302
303 /**
304  * gnutls_x509_crt_get_issuer_dn:
305  * @cert: should contain a #gnutls_x509_crt_t structure
306  * @buf: a pointer to a structure to hold the name (may be null)
307  * @buf_size: initially holds the size of @buf
308  *
309  * This function will copy the name of the Certificate issuer in the
310  * provided buffer. The name will be in the form
311  * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC4514. The output string
312  * will be ASCII or UTF-8 encoded, depending on the certificate data.
313  *
314  * If @buf is null then only the size will be filled. 
315  *
316  * Returns: GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
317  * long enough, and in that case the @buf_size will be updated with
318  * the required size.  On success 0 is returned.
319  **/
320 int
321 gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert, char *buf,
322                               size_t * buf_size)
323 {
324         if (cert == NULL) {
325                 gnutls_assert();
326                 return GNUTLS_E_INVALID_REQUEST;
327         }
328
329         return _gnutls_x509_parse_dn(cert->cert,
330                                      "tbsCertificate.issuer.rdnSequence",
331                                      buf, buf_size);
332 }
333
334 /**
335  * gnutls_x509_crt_get_issuer_dn2:
336  * @cert: should contain a #gnutls_x509_crt_t structure
337  * @dn: a pointer to a structure to hold the name
338  *
339  * This function will allocate buffer and copy the name of issuer of the Certificate.
340  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
341  * described in RFC4514. The output string will be ASCII or UTF-8
342  * encoded, depending on the certificate data.
343  *
344  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
345  *   negative error value. and a negative error code on error.
346  *
347  * Since: 3.1.10
348  **/
349 int
350 gnutls_x509_crt_get_issuer_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
351 {
352         if (cert == NULL) {
353                 gnutls_assert();
354                 return GNUTLS_E_INVALID_REQUEST;
355         }
356
357         return _gnutls_x509_get_dn(cert->cert,
358                                    "tbsCertificate.issuer.rdnSequence",
359                                    dn);
360 }
361
362 /**
363  * gnutls_x509_crt_get_issuer_dn_by_oid:
364  * @cert: should contain a #gnutls_x509_crt_t structure
365  * @oid: holds an Object Identified in null terminated string
366  * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
367  * @raw_flag: If non-zero returns the raw DER data of the DN part.
368  * @buf: a pointer to a structure to hold the name (may be null)
369  * @buf_size: initially holds the size of @buf
370  *
371  * This function will extract the part of the name of the Certificate
372  * issuer specified by the given OID. The output, if the raw flag is not
373  * used, will be encoded as described in RFC4514. Thus a string that is
374  * ASCII or UTF-8 encoded, depending on the certificate data.
375  *
376  * Some helper macros with popular OIDs can be found in gnutls/x509.h
377  * If raw flag is (0), this function will only return known OIDs as
378  * text. Other OIDs will be DER encoded, as described in RFC4514 --
379  * in hex format with a '#' prefix.  You can check about known OIDs
380  * using gnutls_x509_dn_oid_known().
381  *
382  * If @buf is null then only the size will be filled. If the @raw_flag
383  * is not specified the output is always null terminated, although the
384  * @buf_size will not include the null character.
385  *
386  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
387  *   long enough, and in that case the @buf_size will be updated with
388  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there 
389  *   are no data in the current index. On success 0 is returned.
390  **/
391 int
392 gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
393                                      const char *oid, int indx,
394                                      unsigned int raw_flag, void *buf,
395                                      size_t * buf_size)
396 {
397         gnutls_datum_t td;
398         int ret;
399
400         if (cert == NULL) {
401                 gnutls_assert();
402                 return GNUTLS_E_INVALID_REQUEST;
403         }
404
405         ret = _gnutls_x509_parse_dn_oid(cert->cert,
406                                         "tbsCertificate.issuer.rdnSequence",
407                                         oid, indx, raw_flag, &td);
408         if (ret < 0)
409                 return gnutls_assert_val(ret);
410
411         return _gnutls_strdatum_to_buf(&td, buf, buf_size);
412 }
413
414 /**
415  * gnutls_x509_crt_get_issuer_dn_oid:
416  * @cert: should contain a #gnutls_x509_crt_t structure
417  * @indx: This specifies which OID to return. Use (0) to get the first one.
418  * @oid: a pointer to a buffer to hold the OID (may be null)
419  * @oid_size: initially holds the size of @oid
420  *
421  * This function will extract the OIDs of the name of the Certificate
422  * issuer specified by the given index.
423  *
424  * If @oid is null then only the size will be filled. The @oid
425  * returned will be null terminated, although @oid_size will not
426  * account for the trailing null.
427  *
428  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
429  *   long enough, and in that case the @buf_size will be updated with
430  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there 
431  *   are no data in the current index. On success 0 is returned.
432  **/
433 int
434 gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,
435                                   int indx, void *oid, size_t * oid_size)
436 {
437         if (cert == NULL) {
438                 gnutls_assert();
439                 return GNUTLS_E_INVALID_REQUEST;
440         }
441
442         return _gnutls_x509_get_dn_oid(cert->cert,
443                                        "tbsCertificate.issuer.rdnSequence",
444                                        indx, oid, oid_size);
445 }
446
447 /**
448  * gnutls_x509_crt_get_dn:
449  * @cert: should contain a #gnutls_x509_crt_t structure
450  * @buf: a pointer to a structure to hold the name (may be null)
451  * @buf_size: initially holds the size of @buf
452  *
453  * This function will copy the name of the Certificate in the provided
454  * buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
455  * described in RFC4514. The output string will be ASCII or UTF-8
456  * encoded, depending on the certificate data.
457  *
458  * If @buf is null then only the size will be filled. 
459  *
460  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
461  *   long enough, and in that case the @buf_size will be updated
462  *   with the required size.  On success 0 is returned.
463  **/
464 int
465 gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert, char *buf,
466                        size_t * buf_size)
467 {
468         if (cert == NULL) {
469                 gnutls_assert();
470                 return GNUTLS_E_INVALID_REQUEST;
471         }
472
473         return _gnutls_x509_parse_dn(cert->cert,
474                                      "tbsCertificate.subject.rdnSequence",
475                                      buf, buf_size);
476 }
477
478 /**
479  * gnutls_x509_crt_get_dn2:
480  * @cert: should contain a #gnutls_x509_crt_t structure
481  * @dn: a pointer to a structure to hold the name
482  *
483  * This function will allocate buffer and copy the name of the Certificate.
484  * The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
485  * described in RFC4514. The output string will be ASCII or UTF-8
486  * encoded, depending on the certificate data.
487  *
488  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
489  *   negative error value. and a negative error code on error.
490  *
491  * Since: 3.1.10
492  **/
493 int gnutls_x509_crt_get_dn2(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
494 {
495         if (cert == NULL) {
496                 gnutls_assert();
497                 return GNUTLS_E_INVALID_REQUEST;
498         }
499
500         return _gnutls_x509_get_dn(cert->cert,
501                                    "tbsCertificate.subject.rdnSequence",
502                                    dn);
503 }
504
505 /**
506  * gnutls_x509_crt_get_dn_by_oid:
507  * @cert: should contain a #gnutls_x509_crt_t structure
508  * @oid: holds an Object Identified in null terminated string
509  * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
510  * @raw_flag: If non-zero returns the raw DER data of the DN part.
511  * @buf: a pointer where the DN part will be copied (may be null).
512  * @buf_size: initially holds the size of @buf
513  *
514  * This function will extract the part of the name of the Certificate
515  * subject specified by the given OID. The output, if the raw flag is
516  * not used, will be encoded as described in RFC4514. Thus a string
517  * that is ASCII or UTF-8 encoded, depending on the certificate data.
518  *
519  * Some helper macros with popular OIDs can be found in gnutls/x509.h
520  * If raw flag is (0), this function will only return known OIDs as
521  * text. Other OIDs will be DER encoded, as described in RFC4514 --
522  * in hex format with a '#' prefix.  You can check about known OIDs
523  * using gnutls_x509_dn_oid_known().
524  *
525  * If @buf is null then only the size will be filled. If the @raw_flag
526  * is not specified the output is always null terminated, although the
527  * @buf_size will not include the null character.
528  *
529  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
530  *   long enough, and in that case the @buf_size will be updated with
531  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there 
532  *   are no data in the current index. On success 0 is returned.
533  **/
534 int
535 gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert, const char *oid,
536                               int indx, unsigned int raw_flag,
537                               void *buf, size_t * buf_size)
538 {
539         gnutls_datum_t td;
540         int ret;
541
542         if (cert == NULL) {
543                 gnutls_assert();
544                 return GNUTLS_E_INVALID_REQUEST;
545         }
546
547         ret = _gnutls_x509_parse_dn_oid(cert->cert,
548                                         "tbsCertificate.subject.rdnSequence",
549                                         oid, indx, raw_flag, &td);
550         if (ret < 0)
551                 return gnutls_assert_val(ret);
552
553         return _gnutls_strdatum_to_buf(&td, buf, buf_size);
554 }
555
556 /**
557  * gnutls_x509_crt_get_dn_oid:
558  * @cert: should contain a #gnutls_x509_crt_t structure
559  * @indx: This specifies which OID to return. Use (0) to get the first one.
560  * @oid: a pointer to a buffer to hold the OID (may be null)
561  * @oid_size: initially holds the size of @oid
562  *
563  * This function will extract the OIDs of the name of the Certificate
564  * subject specified by the given index.
565  *
566  * If @oid is null then only the size will be filled. The @oid
567  * returned will be null terminated, although @oid_size will not
568  * account for the trailing null.
569  *
570  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
571  *   long enough, and in that case the @buf_size will be updated with
572  *   the required size. %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if there 
573  *   are no data in the current index. On success 0 is returned.
574  **/
575 int
576 gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,
577                            int indx, void *oid, size_t * oid_size)
578 {
579         if (cert == NULL) {
580                 gnutls_assert();
581                 return GNUTLS_E_INVALID_REQUEST;
582         }
583
584         return _gnutls_x509_get_dn_oid(cert->cert,
585                                        "tbsCertificate.subject.rdnSequence",
586                                        indx, oid, oid_size);
587 }
588
589 /**
590  * gnutls_x509_crt_get_signature_algorithm:
591  * @cert: should contain a #gnutls_x509_crt_t structure
592  *
593  * This function will return a value of the #gnutls_sign_algorithm_t
594  * enumeration that is the signature algorithm that has been used to
595  * sign this certificate.
596  *
597  * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
598  *   error.
599  **/
600 int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert)
601 {
602         return _gnutls_x509_get_signature_algorithm(cert->cert,
603                                                     "signatureAlgorithm.algorithm");
604 }
605
606 /**
607  * gnutls_x509_crt_get_signature:
608  * @cert: should contain a #gnutls_x509_crt_t structure
609  * @sig: a pointer where the signature part will be copied (may be null).
610  * @sig_size: initially holds the size of @sig
611  *
612  * This function will extract the signature field of a certificate.
613  *
614  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
615  *   negative error value. and a negative error code on error.
616  **/
617 int
618 gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
619                               char *sig, size_t * sig_size)
620 {
621         gnutls_datum_t dsig = {NULL, 0};
622         int ret;
623
624         if (cert == NULL)
625                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
626
627         ret = _gnutls_x509_get_signature(cert->cert, "signature", &dsig);
628         if (ret < 0)
629                 return gnutls_assert_val(ret);
630
631         ret = _gnutls_copy_data(&dsig, (uint8_t*)sig, sig_size);
632         if (ret < 0) {
633                 gnutls_assert();
634                 goto cleanup;
635         }
636
637         ret = 0;
638  cleanup:
639         gnutls_free(dsig.data);
640         return ret;
641 }
642
643 /**
644  * gnutls_x509_crt_get_version:
645  * @cert: should contain a #gnutls_x509_crt_t structure
646  *
647  * This function will return the version of the specified Certificate.
648  *
649  * Returns: version of certificate, or a negative error code on error.
650  **/
651 int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)
652 {
653         uint8_t version[8];
654         int len, result;
655
656         if (cert == NULL) {
657                 gnutls_assert();
658                 return GNUTLS_E_INVALID_REQUEST;
659         }
660
661         len = sizeof(version);
662         if ((result =
663              asn1_read_value(cert->cert, "tbsCertificate.version", version,
664                              &len)) != ASN1_SUCCESS) {
665
666                 if (result == ASN1_ELEMENT_NOT_FOUND)
667                         return 1;       /* the DEFAULT version */
668                 gnutls_assert();
669                 return _gnutls_asn2err(result);
670         }
671
672         return (int) version[0] + 1;
673 }
674
675 /**
676  * gnutls_x509_crt_get_activation_time:
677  * @cert: should contain a #gnutls_x509_crt_t structure
678  *
679  * This function will return the time this Certificate was or will be
680  * activated.
681  *
682  * Returns: activation time, or (time_t)-1 on error.
683  **/
684 time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert)
685 {
686         if (cert == NULL) {
687                 gnutls_assert();
688                 return (time_t) - 1;
689         }
690
691         return _gnutls_x509_get_time(cert->cert,
692                                      "tbsCertificate.validity.notBefore",
693                                      0);
694 }
695
696 /**
697  * gnutls_x509_crt_get_expiration_time:
698  * @cert: should contain a #gnutls_x509_crt_t structure
699  *
700  * This function will return the time this Certificate was or will be
701  * expired.
702  *
703  * The no well defined expiration time can be checked against with the
704  * %GNUTLS_X509_NO_WELL_DEFINED_EXPIRATION macro.
705  *
706  * Returns: expiration time, or (time_t)-1 on error.
707  **/
708 time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert)
709 {
710         if (cert == NULL) {
711                 gnutls_assert();
712                 return (time_t) - 1;
713         }
714
715         return _gnutls_x509_get_time(cert->cert,
716                                      "tbsCertificate.validity.notAfter",
717                                      0);
718 }
719
720 /**
721  * gnutls_x509_crt_get_private_key_usage_period:
722  * @cert: should contain a #gnutls_x509_crt_t structure
723  * @activation: The activation time
724  * @expiration: The expiration time
725  * @critical: the extension status
726  *
727  * This function will return the expiration and activation
728  * times of the private key of the certificate. It relies on
729  * the PKIX extension 2.5.29.16 being present.
730  *
731  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
732  * if the extension is not present, otherwise a negative error value.
733  **/
734 int
735 gnutls_x509_crt_get_private_key_usage_period(gnutls_x509_crt_t cert,
736                                              time_t * activation,
737                                              time_t * expiration,
738                                              unsigned int *critical)
739 {
740         int ret;
741         gnutls_datum_t der = { NULL, 0 };
742
743         if (cert == NULL) {
744                 gnutls_assert();
745                 return GNUTLS_E_INVALID_REQUEST;
746         }
747
748         ret =
749             _gnutls_x509_crt_get_extension(cert, "2.5.29.16", 0, &der,
750                                            critical);
751         if (ret < 0)
752                 return gnutls_assert_val(ret);
753
754         if (der.size == 0 || der.data == NULL)
755                 return
756                     gnutls_assert_val
757                     (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
758
759         ret = gnutls_x509_ext_import_private_key_usage_period(&der, activation, expiration);
760         if (ret < 0) {
761                 gnutls_assert();
762                 goto cleanup;
763         }
764
765         ret = 0;
766
767       cleanup:
768         _gnutls_free_datum(&der);
769
770         return ret;
771 }
772
773
774 /**
775  * gnutls_x509_crt_get_serial:
776  * @cert: should contain a #gnutls_x509_crt_t structure
777  * @result: The place where the serial number will be copied
778  * @result_size: Holds the size of the result field.
779  *
780  * This function will return the X.509 certificate's serial number.
781  * This is obtained by the X509 Certificate serialNumber field. Serial
782  * is not always a 32 or 64bit number. Some CAs use large serial
783  * numbers, thus it may be wise to handle it as something uint8_t.
784  *
785  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
786  *   negative error value.
787  **/
788 int
789 gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert, void *result,
790                            size_t * result_size)
791 {
792         int ret, len;
793
794         if (cert == NULL) {
795                 gnutls_assert();
796                 return GNUTLS_E_INVALID_REQUEST;
797         }
798
799         len = *result_size;
800         ret =
801             asn1_read_value(cert->cert, "tbsCertificate.serialNumber",
802                             result, &len);
803         *result_size = len;
804
805         if (ret != ASN1_SUCCESS) {
806                 gnutls_assert();
807                 return _gnutls_asn2err(ret);
808         }
809
810         return 0;
811 }
812
813 /**
814  * gnutls_x509_crt_get_subject_key_id:
815  * @cert: should contain a #gnutls_x509_crt_t structure
816  * @ret: The place where the identifier will be copied
817  * @ret_size: Holds the size of the result field.
818  * @critical: will be non-zero if the extension is marked as critical (may be null)
819  *
820  * This function will return the X.509v3 certificate's subject key
821  * identifier.  This is obtained by the X.509 Subject Key identifier
822  * extension field (2.5.29.14).
823  *
824  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
825  * if the extension is not present, otherwise a negative error value.
826  **/
827 int
828 gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert, void *ret,
829                                    size_t * ret_size,
830                                    unsigned int *critical)
831 {
832         int result;
833         gnutls_datum_t id = {NULL,0};
834         gnutls_datum_t der = {NULL, 0};
835
836         if (cert == NULL) {
837                 gnutls_assert();
838                 return GNUTLS_E_INVALID_REQUEST;
839         }
840
841         if (ret == NULL)
842                 *ret_size = 0;
843
844         if ((result =
845              _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &der,
846                                             critical)) < 0) {
847                 return result;
848         }
849
850         result = gnutls_x509_ext_import_subject_key_id(&der, &id);
851         if (result < 0) {
852                 gnutls_assert();
853                 goto cleanup;
854         }
855
856         result = _gnutls_copy_data(&id, ret, ret_size);
857         if (result < 0) {
858                 gnutls_assert();
859                 goto cleanup;
860         }
861
862         result = 0;
863
864  cleanup:
865         gnutls_free(der.data);
866         gnutls_free(id.data);
867         return result;
868 }
869
870 inline static int is_type_printable(int type)
871 {
872         if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME ||
873             type == GNUTLS_SAN_URI || type == GNUTLS_SAN_OTHERNAME_XMPP ||
874             type == GNUTLS_SAN_OTHERNAME)
875                 return 1;
876         else
877                 return 0;
878 }
879
880 /**
881  * gnutls_x509_crt_get_authority_key_gn_serial:
882  * @cert: should contain a #gnutls_x509_crt_t structure
883  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
884  * @alt: is the place where the alternative name will be copied to
885  * @alt_size: holds the size of alt.
886  * @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
887  * @serial: buffer to store the serial number (may be null)
888  * @serial_size: Holds the size of the serial field (may be null)
889  * @critical: will be non-zero if the extension is marked as critical (may be null)
890  *
891  * This function will return the X.509 authority key
892  * identifier when stored as a general name (authorityCertIssuer) 
893  * and serial number.
894  *
895  * Because more than one general names might be stored
896  * @seq can be used as a counter to request them all until 
897  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
898  *
899  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
900  * if the extension is not present, otherwise a negative error value.
901  *
902  * Since: 3.0
903  **/
904 int
905 gnutls_x509_crt_get_authority_key_gn_serial(gnutls_x509_crt_t cert,
906                                             unsigned int seq, void *alt,
907                                             size_t * alt_size,
908                                             unsigned int *alt_type,
909                                             void *serial,
910                                             size_t * serial_size,
911                                             unsigned int *critical)
912 {
913         int ret;
914         gnutls_datum_t der, san, iserial;
915         gnutls_x509_aki_t aki = NULL;
916         unsigned san_type;
917
918         if (cert == NULL) {
919                 gnutls_assert();
920                 return GNUTLS_E_INVALID_REQUEST;
921         }
922
923         if ((ret =
924              _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
925                                             critical)) < 0) {
926                 return gnutls_assert_val(ret);
927         }
928
929         if (der.size == 0 || der.data == NULL) {
930                 gnutls_assert();
931                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
932         }
933
934         ret = gnutls_x509_aki_init(&aki);
935         if (ret < 0) {
936                 gnutls_assert();
937                 goto cleanup;
938         }
939
940         ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
941         if (ret < 0) {
942                 gnutls_assert();
943                 goto cleanup;
944         }
945
946         ret = gnutls_x509_aki_get_cert_issuer(aki, seq, &san_type, &san, NULL, &iserial);
947         if (ret < 0) {
948                 gnutls_assert();
949                 goto cleanup;
950         }
951
952         if (is_type_printable(san_type))
953                 ret = _gnutls_copy_string(&san, alt, alt_size);
954         else
955                 ret = _gnutls_copy_data(&san, alt, alt_size);
956         if (ret < 0) {
957                 gnutls_assert();
958                 goto cleanup;
959         }
960
961         if (alt_type)
962                 *alt_type = san_type;
963
964         ret = _gnutls_copy_data(&iserial, serial, serial_size);
965         if (ret < 0) {
966                 gnutls_assert();
967                 goto cleanup;
968         }
969
970         ret = 0;
971  cleanup:
972         if (aki != NULL)
973                 gnutls_x509_aki_deinit(aki);
974         gnutls_free(der.data);
975         return ret;
976 }
977
978 /**
979  * gnutls_x509_crt_get_authority_key_id:
980  * @cert: should contain a #gnutls_x509_crt_t structure
981  * @id: The place where the identifier will be copied
982  * @id_size: Holds the size of the id field.
983  * @critical: will be non-zero if the extension is marked as critical (may be null)
984  *
985  * This function will return the X.509v3 certificate authority's key
986  * identifier.  This is obtained by the X.509 Authority Key
987  * identifier extension field (2.5.29.35). Note that this function
988  * only returns the keyIdentifier field of the extension and
989  * %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
990  * the name and serial number of the certificate. In that case
991  * gnutls_x509_crt_get_authority_key_gn_serial() may be used.
992  *
993  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
994  * if the extension is not present, otherwise a negative error value.
995  **/
996 int
997 gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert, void *id,
998                                      size_t * id_size,
999                                      unsigned int *critical)
1000 {
1001         int ret;
1002         gnutls_datum_t der, l_id;
1003         gnutls_x509_aki_t aki = NULL;
1004
1005         if (cert == NULL) {
1006                 gnutls_assert();
1007                 return GNUTLS_E_INVALID_REQUEST;
1008         }
1009
1010         if ((ret =
1011              _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &der,
1012                                             critical)) < 0) {
1013                 return gnutls_assert_val(ret);
1014         }
1015
1016         if (der.size == 0 || der.data == NULL) {
1017                 gnutls_assert();
1018                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1019         }
1020
1021         ret = gnutls_x509_aki_init(&aki);
1022         if (ret < 0) {
1023                 gnutls_assert();
1024                 goto cleanup;
1025         }
1026
1027         ret = gnutls_x509_ext_import_authority_key_id(&der, aki, 0);
1028         if (ret < 0) {
1029                 gnutls_assert();
1030                 goto cleanup;
1031         }
1032
1033         ret = gnutls_x509_aki_get_id(aki, &l_id);
1034
1035         if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1036                 gnutls_datum_t serial;
1037                 ret = gnutls_x509_aki_get_cert_issuer(aki, 0, NULL, NULL, NULL, &serial);
1038                 if (ret >= 0) {
1039                         ret = gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
1040                 } else {
1041                         ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1042                 }
1043         }
1044
1045         if (ret < 0) {
1046                 gnutls_assert();
1047                 goto cleanup;
1048         }
1049
1050         ret = _gnutls_copy_data(&l_id, id, id_size);
1051         if (ret < 0) {
1052                 gnutls_assert();
1053                 goto cleanup;
1054         }
1055
1056         ret = 0;
1057  cleanup:
1058         if (aki != NULL)
1059                 gnutls_x509_aki_deinit(aki);
1060         gnutls_free(der.data);
1061         return ret;
1062 }
1063
1064 /**
1065  * gnutls_x509_crt_get_pk_algorithm:
1066  * @cert: should contain a #gnutls_x509_crt_t structure
1067  * @bits: if bits is non null it will hold the size of the parameters' in bits
1068  *
1069  * This function will return the public key algorithm of an X.509
1070  * certificate.
1071  *
1072  * If bits is non null, it should have enough size to hold the parameters
1073  * size in bits. For RSA the bits returned is the modulus.
1074  * For DSA the bits returned are of the public
1075  * exponent.
1076  *
1077  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1078  * success, or a negative error code on error.
1079  **/
1080 int
1081 gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
1082                                  unsigned int *bits)
1083 {
1084         int result;
1085
1086         if (cert == NULL) {
1087                 gnutls_assert();
1088                 return GNUTLS_E_INVALID_REQUEST;
1089         }
1090
1091         if (bits)
1092                 *bits = 0;
1093
1094         result =
1095             _gnutls_x509_get_pk_algorithm(cert->cert,
1096                                           "tbsCertificate.subjectPublicKeyInfo",
1097                                           bits);
1098
1099         if (result < 0) {
1100                 gnutls_assert();
1101                 return result;
1102         }
1103
1104         return result;
1105
1106 }
1107
1108 /* returns the type and the name on success.
1109  * Type is also returned as a parameter in case of an error.
1110  *
1111  * @seq: in case of GeneralNames it will return the corresponding name.
1112  *       in case of GeneralName, it must be -1
1113  * @dname: the name returned
1114  * @ret_type: The type of the name
1115  * @othername_oid: if the name is otherName return the OID
1116  *
1117  */
1118 int
1119 _gnutls_parse_general_name2(ASN1_TYPE src, const char *src_name,
1120                            int seq, gnutls_datum_t *dname, 
1121                            unsigned int *ret_type, int othername_oid)
1122 {
1123         int len, ret;
1124         char nptr[ASN1_MAX_NAME_SIZE];
1125         int result;
1126         gnutls_datum_t tmp = {NULL, 0};
1127         char choice_type[128];
1128         gnutls_x509_subject_alt_name_t type;
1129
1130         if (seq != -1) {
1131                 seq++;  /* 0->1, 1->2 etc */
1132
1133                 if (src_name[0] != 0)
1134                         snprintf(nptr, sizeof(nptr), "%s.?%u", src_name, seq);
1135                 else
1136                         snprintf(nptr, sizeof(nptr), "?%u", seq);
1137         } else {
1138                 snprintf(nptr, sizeof(nptr), "%s", src_name);
1139         }
1140
1141         len = sizeof(choice_type);
1142         result = asn1_read_value(src, nptr, choice_type, &len);
1143
1144         if (result == ASN1_VALUE_NOT_FOUND
1145             || result == ASN1_ELEMENT_NOT_FOUND) {
1146                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1147         }
1148
1149         if (result != ASN1_SUCCESS) {
1150                 gnutls_assert();
1151                 return _gnutls_asn2err(result);
1152         }
1153
1154         type = _gnutls_x509_san_find_type(choice_type);
1155         if (type == (gnutls_x509_subject_alt_name_t) - 1) {
1156                 gnutls_assert();
1157                 return GNUTLS_E_X509_UNKNOWN_SAN;
1158         }
1159
1160         if (ret_type)
1161                 *ret_type = type;
1162
1163         if (type == GNUTLS_SAN_OTHERNAME) {
1164                 if (othername_oid)
1165                         _gnutls_str_cat(nptr, sizeof(nptr),
1166                                         ".otherName.type-id");
1167                 else
1168                         _gnutls_str_cat(nptr, sizeof(nptr),
1169                                         ".otherName.value");
1170
1171                 ret = _gnutls_x509_read_value(src, nptr, &tmp);
1172                 if (ret < 0) {
1173                         gnutls_assert();
1174                         return ret;
1175                 }
1176
1177                 if (othername_oid) {
1178                         dname->size = tmp.size;
1179                         dname->data = tmp.data;
1180                 } else {
1181                         char oid[MAX_OID_SIZE];
1182
1183                         if (src_name[0] != 0)
1184                                 snprintf(nptr, sizeof(nptr),
1185                                          "%s.?%u.otherName.type-id",
1186                                          src_name, seq);
1187                         else
1188                                 snprintf(nptr, sizeof(nptr),
1189                                          "?%u.otherName.type-id", seq);
1190
1191                         len = sizeof(oid);
1192
1193                         result = asn1_read_value(src, nptr, oid, &len);
1194                         if (result != ASN1_SUCCESS) {
1195                                 gnutls_assert();
1196                                 ret = _gnutls_asn2err(result);
1197                                 goto cleanup;
1198                         }
1199                         if (len > 0) len--;
1200
1201                         dname->size = tmp.size;
1202                         dname->data = tmp.data;
1203                 }
1204         } else if (type == GNUTLS_SAN_DN) {
1205                 _gnutls_str_cat(nptr, sizeof(nptr), ".directoryName");
1206                 ret = _gnutls_x509_get_dn(src, nptr, dname);
1207                 if (ret < 0) {
1208                         gnutls_assert();
1209                         goto cleanup;
1210                 }
1211         } else if (othername_oid) {
1212                 gnutls_assert();
1213                 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1214                 goto cleanup;
1215         } else {
1216                 _gnutls_str_cat(nptr, sizeof(nptr), ".");
1217                 _gnutls_str_cat(nptr, sizeof(nptr), choice_type);
1218
1219                 ret = _gnutls_x509_read_value(src, nptr, &tmp);
1220                 if (ret < 0) {
1221                         gnutls_assert();
1222                         return ret;
1223                 }
1224
1225                 /* _gnutls_x509_read_value() null terminates */
1226                 dname->size = tmp.size;
1227                 dname->data = tmp.data;
1228         }
1229
1230         return type;
1231
1232  cleanup:
1233         gnutls_free(tmp.data);
1234         return ret;
1235 }
1236
1237 /* returns the type and the name on success.
1238  * Type is also returned as a parameter in case of an error.
1239  */
1240 int
1241 _gnutls_parse_general_name(ASN1_TYPE src, const char *src_name,
1242                            int seq, void *name, size_t * name_size,
1243                            unsigned int *ret_type, int othername_oid)
1244 {
1245         int ret;
1246         gnutls_datum_t res = {NULL,0};
1247         unsigned type;
1248
1249         ret = _gnutls_parse_general_name2(src, src_name, seq, &res, ret_type, othername_oid);
1250         if (ret < 0)
1251                 return gnutls_assert_val(ret);
1252
1253         type = ret;
1254
1255         if (is_type_printable(type)) {
1256                 ret = _gnutls_copy_string(&res, name, name_size);
1257         } else {
1258                 ret = _gnutls_copy_data(&res, name, name_size);
1259         }
1260
1261         if (ret < 0) {
1262                 gnutls_assert();
1263                 goto cleanup;
1264         }
1265
1266         ret = type;
1267 cleanup:
1268         gnutls_free(res.data);
1269         return ret;
1270 }
1271
1272 static int
1273 get_alt_name(gnutls_x509_crt_t cert, const char *extension_id,
1274              unsigned int seq, uint8_t *alt,
1275              size_t * alt_size, unsigned int *alt_type,
1276              unsigned int *critical, int othername_oid)
1277 {
1278         int ret;
1279         gnutls_datum_t dnsname = {NULL, 0};
1280         gnutls_datum_t ooid = {NULL, 0};
1281         gnutls_datum_t res;
1282         gnutls_subject_alt_names_t sans = NULL;
1283         unsigned int type;
1284
1285         if (cert == NULL) {
1286                 gnutls_assert();
1287                 return GNUTLS_E_INVALID_REQUEST;
1288         }
1289
1290         if (alt == NULL)
1291                 *alt_size = 0;
1292
1293         if ((ret =
1294              _gnutls_x509_crt_get_extension(cert, extension_id, 0,
1295                                             &dnsname, critical)) < 0) {
1296                 return ret;
1297         }
1298
1299         if (dnsname.size == 0 || dnsname.data == NULL) {
1300                 gnutls_assert();
1301                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1302         }
1303
1304         ret = gnutls_subject_alt_names_init(&sans);
1305         if (ret < 0) {
1306                 gnutls_assert();
1307                 goto cleanup;
1308         }
1309
1310         ret = gnutls_x509_ext_import_subject_alt_names(&dnsname, sans, 0);
1311         if (ret < 0) {
1312                 gnutls_assert();
1313                 goto cleanup;
1314         }
1315
1316         ret = gnutls_subject_alt_names_get(sans, seq, &type, &res, &ooid);
1317         if (ret < 0) {
1318                 gnutls_assert();
1319                 goto cleanup;
1320         }
1321
1322         if (othername_oid && type == GNUTLS_SAN_OTHERNAME) {
1323                 unsigned vtype;
1324                 gnutls_datum_t virt;
1325                 ret = gnutls_x509_othername_to_virtual((char*)ooid.data, &res, &vtype, &virt);
1326                 if (ret >= 0) {
1327                         type = vtype;
1328                         gnutls_free(res.data);
1329                         res.data = virt.data;
1330                         res.size = virt.size;
1331                 }
1332         }
1333
1334         if (alt_type)
1335                 *alt_type = type;
1336
1337         if (othername_oid) {
1338                 ret = _gnutls_copy_string(&ooid, alt, alt_size);
1339         } else {
1340                 if (is_type_printable(type)) {
1341                         ret = _gnutls_copy_string(&res, alt, alt_size);
1342                 } else {
1343                         ret = _gnutls_copy_data(&res, alt, alt_size);
1344                 }
1345         }
1346
1347         if (ret < 0) {
1348                 gnutls_assert();
1349                 goto cleanup;
1350         }
1351
1352         ret = type;
1353 cleanup:
1354         gnutls_free(dnsname.data);
1355         if (sans != NULL)
1356                 gnutls_subject_alt_names_deinit(sans);
1357
1358         return ret;
1359 }
1360
1361 /**
1362  * gnutls_x509_crt_get_subject_alt_name:
1363  * @cert: should contain a #gnutls_x509_crt_t structure
1364  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1365  * @san: is the place where the alternative name will be copied to
1366  * @san_size: holds the size of san.
1367  * @critical: will be non-zero if the extension is marked as critical (may be null)
1368  *
1369  * This function retrieves the Alternative Name (2.5.29.17), contained
1370  * in the given certificate in the X509v3 Certificate Extensions.
1371  *
1372  * When the SAN type is otherName, it will extract the data in the
1373  * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1374  * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1375  * the corresponding OID and the "virtual" SAN types (e.g.,
1376  * %GNUTLS_SAN_OTHERNAME_XMPP).
1377  *
1378  * If an otherName OID is known, the data will be decoded.  Otherwise
1379  * the returned data will be DER encoded, and you will have to decode
1380  * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr SAN is
1381  * recognized.
1382  *
1383  * Returns: the alternative subject name type on success, one of the
1384  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1385  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough to
1386  *   hold the value.  In that case @san_size will be updated with the
1387  *   required size.  If the certificate does not have an Alternative
1388  *   name with the specified sequence number then
1389  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1390  **/
1391 int
1392 gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
1393                                      unsigned int seq, void *san,
1394                                      size_t * san_size,
1395                                      unsigned int *critical)
1396 {
1397         return get_alt_name(cert, "2.5.29.17", seq, san, san_size, NULL,
1398                             critical, 0);
1399 }
1400
1401 /**
1402  * gnutls_x509_crt_get_issuer_alt_name:
1403  * @cert: should contain a #gnutls_x509_crt_t structure
1404  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1405  * @ian: is the place where the alternative name will be copied to
1406  * @ian_size: holds the size of ian.
1407  * @critical: will be non-zero if the extension is marked as critical (may be null)
1408  *
1409  * This function retrieves the Issuer Alternative Name (2.5.29.18),
1410  * contained in the given certificate in the X509v3 Certificate
1411  * Extensions.
1412  *
1413  * When the SAN type is otherName, it will extract the data in the
1414  * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1415  * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1416  * the corresponding OID and the "virtual" SAN types (e.g.,
1417  * %GNUTLS_SAN_OTHERNAME_XMPP).
1418  *
1419  * If an otherName OID is known, the data will be decoded.  Otherwise
1420  * the returned data will be DER encoded, and you will have to decode
1421  * it yourself.  Currently, only the RFC 3920 id-on-xmppAddr Issuer
1422  * AltName is recognized.
1423  *
1424  * Returns: the alternative issuer name type on success, one of the
1425  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1426  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1427  *   to hold the value.  In that case @ian_size will be updated with
1428  *   the required size.  If the certificate does not have an
1429  *   Alternative name with the specified sequence number then
1430  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1431  *
1432  * Since: 2.10.0
1433  **/
1434 int
1435 gnutls_x509_crt_get_issuer_alt_name(gnutls_x509_crt_t cert,
1436                                     unsigned int seq, void *ian,
1437                                     size_t * ian_size,
1438                                     unsigned int *critical)
1439 {
1440         return get_alt_name(cert, "2.5.29.18", seq, ian, ian_size, NULL,
1441                             critical, 0);
1442 }
1443
1444 /**
1445  * gnutls_x509_crt_get_subject_alt_name2:
1446  * @cert: should contain a #gnutls_x509_crt_t structure
1447  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1448  * @san: is the place where the alternative name will be copied to
1449  * @san_size: holds the size of ret.
1450  * @san_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1451  * @critical: will be non-zero if the extension is marked as critical (may be null)
1452  *
1453  * This function will return the alternative names, contained in the
1454  * given certificate. It is the same as
1455  * gnutls_x509_crt_get_subject_alt_name() except for the fact that it
1456  * will return the type of the alternative name in @san_type even if
1457  * the function fails for some reason (i.e.  the buffer provided is
1458  * not enough).
1459  *
1460  * Returns: the alternative subject name type on success, one of the
1461  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1462  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @san_size is not large enough
1463  *   to hold the value.  In that case @san_size will be updated with
1464  *   the required size.  If the certificate does not have an
1465  *   Alternative name with the specified sequence number then
1466  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1467  **/
1468 int
1469 gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,
1470                                       unsigned int seq, void *san,
1471                                       size_t * san_size,
1472                                       unsigned int *san_type,
1473                                       unsigned int *critical)
1474 {
1475         return get_alt_name(cert, "2.5.29.17", seq, san, san_size,
1476                             san_type, critical, 0);
1477 }
1478
1479 /**
1480  * gnutls_x509_crt_get_issuer_alt_name2:
1481  * @cert: should contain a #gnutls_x509_crt_t structure
1482  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1483  * @ian: is the place where the alternative name will be copied to
1484  * @ian_size: holds the size of ret.
1485  * @ian_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1486  * @critical: will be non-zero if the extension is marked as critical (may be null)
1487  *
1488  * This function will return the alternative names, contained in the
1489  * given certificate. It is the same as
1490  * gnutls_x509_crt_get_issuer_alt_name() except for the fact that it
1491  * will return the type of the alternative name in @ian_type even if
1492  * the function fails for some reason (i.e.  the buffer provided is
1493  * not enough).
1494  *
1495  * Returns: the alternative issuer name type on success, one of the
1496  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1497  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ian_size is not large enough
1498  *   to hold the value.  In that case @ian_size will be updated with
1499  *   the required size.  If the certificate does not have an
1500  *   Alternative name with the specified sequence number then
1501  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1502  *
1503  * Since: 2.10.0
1504  *
1505  **/
1506 int
1507 gnutls_x509_crt_get_issuer_alt_name2(gnutls_x509_crt_t cert,
1508                                      unsigned int seq, void *ian,
1509                                      size_t * ian_size,
1510                                      unsigned int *ian_type,
1511                                      unsigned int *critical)
1512 {
1513         return get_alt_name(cert, "2.5.29.18", seq, ian, ian_size,
1514                             ian_type, critical, 0);
1515 }
1516
1517 /**
1518  * gnutls_x509_crt_get_subject_alt_othername_oid:
1519  * @cert: should contain a #gnutls_x509_crt_t structure
1520  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1521  * @oid: is the place where the otherName OID will be copied to
1522  * @oid_size: holds the size of ret.
1523  *
1524  * This function will extract the type OID of an otherName Subject
1525  * Alternative Name, contained in the given certificate, and return
1526  * the type as an enumerated element.
1527  *
1528  * This function is only useful if
1529  * gnutls_x509_crt_get_subject_alt_name() returned
1530  * %GNUTLS_SAN_OTHERNAME.
1531  *
1532  * If @oid is null then only the size will be filled. The @oid
1533  * returned will be null terminated, although @oid_size will not
1534  * account for the trailing null.
1535  *
1536  * Returns: the alternative subject name type on success, one of the
1537  * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
1538  * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1539  * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1540  * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1541  * @ian_size is not large enough to hold the value.  In that case
1542  * @ian_size will be updated with the required size.  If the
1543  * certificate does not have an Alternative name with the specified
1544  * sequence number and with the otherName type then
1545  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1546  **/
1547 int
1548 gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,
1549                                               unsigned int seq,
1550                                               void *oid, size_t * oid_size)
1551 {
1552         return get_alt_name(cert, "2.5.29.17", seq, oid, oid_size, NULL,
1553                             NULL, 1);
1554 }
1555
1556 /**
1557  * gnutls_x509_crt_get_issuer_alt_othername_oid:
1558  * @cert: should contain a #gnutls_x509_crt_t structure
1559  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1560  * @ret: is the place where the otherName OID will be copied to
1561  * @ret_size: holds the size of ret.
1562  *
1563  * This function will extract the type OID of an otherName Subject
1564  * Alternative Name, contained in the given certificate, and return
1565  * the type as an enumerated element.
1566  *
1567  * If @oid is null then only the size will be filled. The @oid
1568  * returned will be null terminated, although @oid_size will not
1569  * account for the trailing null.
1570  *
1571  * This function is only useful if
1572  * gnutls_x509_crt_get_issuer_alt_name() returned
1573  * %GNUTLS_SAN_OTHERNAME.
1574  *
1575  * Returns: the alternative issuer name type on success, one of the
1576  * enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs, it
1577  * will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1578  * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1579  * unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1580  * @ret_size is not large enough to hold the value.  In that case
1581  * @ret_size will be updated with the required size.  If the
1582  * certificate does not have an Alternative name with the specified
1583  * sequence number and with the otherName type then
1584  * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1585  *
1586  * Since: 2.10.0
1587  **/
1588 int
1589 gnutls_x509_crt_get_issuer_alt_othername_oid(gnutls_x509_crt_t cert,
1590                                              unsigned int seq,
1591                                              void *ret, size_t * ret_size)
1592 {
1593         return get_alt_name(cert, "2.5.29.18", seq, ret, ret_size, NULL,
1594                             NULL, 1);
1595 }
1596
1597 /**
1598  * gnutls_x509_crt_get_basic_constraints:
1599  * @cert: should contain a #gnutls_x509_crt_t structure
1600  * @critical: will be non-zero if the extension is marked as critical
1601  * @ca: pointer to output integer indicating CA status, may be NULL,
1602  *   value is 1 if the certificate CA flag is set, 0 otherwise.
1603  * @pathlen: pointer to output integer indicating path length (may be
1604  *   NULL), non-negative error codes indicate a present pathLenConstraint
1605  *   field and the actual value, -1 indicate that the field is absent.
1606  *
1607  * This function will read the certificate's basic constraints, and
1608  * return the certificates CA status.  It reads the basicConstraints
1609  * X.509 extension (2.5.29.19).
1610  *
1611  * Returns: If the certificate is a CA a positive value will be
1612  * returned, or (0) if the certificate does not have CA flag set.  A
1613  * negative error code may be returned in case of errors.  If the
1614  * certificate does not contain the basicConstraints extension
1615  * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1616  **/
1617 int
1618 gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
1619                                       unsigned int *critical,
1620                                       unsigned int *ca, int *pathlen)
1621 {
1622         int result;
1623         gnutls_datum_t basicConstraints;
1624         unsigned int tmp_ca;
1625
1626         if (cert == NULL) {
1627                 gnutls_assert();
1628                 return GNUTLS_E_INVALID_REQUEST;
1629         }
1630
1631         if ((result =
1632              _gnutls_x509_crt_get_extension(cert, "2.5.29.19", 0,
1633                                             &basicConstraints,
1634                                             critical)) < 0) {
1635                 return result;
1636         }
1637
1638         if (basicConstraints.size == 0 || basicConstraints.data == NULL) {
1639                 gnutls_assert();
1640                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1641         }
1642
1643         result = gnutls_x509_ext_import_basic_constraints(&basicConstraints, &tmp_ca, pathlen);
1644         if (ca)
1645                 *ca = tmp_ca;
1646
1647         _gnutls_free_datum(&basicConstraints);
1648
1649         if (result < 0) {
1650                 gnutls_assert();
1651                 return result;
1652         }
1653
1654         return tmp_ca;
1655 }
1656
1657 /**
1658  * gnutls_x509_crt_get_ca_status:
1659  * @cert: should contain a #gnutls_x509_crt_t structure
1660  * @critical: will be non-zero if the extension is marked as critical
1661  *
1662  * This function will return certificates CA status, by reading the
1663  * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1664  * a CA a positive value will be returned, or (0) if the certificate
1665  * does not have CA flag set.
1666  *
1667  * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1668  * pathLenConstraint field too.
1669  *
1670  * Returns: If the certificate is a CA a positive value will be
1671  * returned, or (0) if the certificate does not have CA flag set.  A
1672  * negative error code may be returned in case of errors.  If the
1673  * certificate does not contain the basicConstraints extension
1674  * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1675  **/
1676 int
1677 gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
1678                               unsigned int *critical)
1679 {
1680         int pathlen;
1681         unsigned int ca;
1682         return gnutls_x509_crt_get_basic_constraints(cert, critical, &ca,
1683                                                      &pathlen);
1684 }
1685
1686 /**
1687  * gnutls_x509_crt_get_key_usage:
1688  * @cert: should contain a #gnutls_x509_crt_t structure
1689  * @key_usage: where the key usage bits will be stored
1690  * @critical: will be non-zero if the extension is marked as critical
1691  *
1692  * This function will return certificate's key usage, by reading the
1693  * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1694  * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1695  * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1696  * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1697  * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1698  * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1699  *
1700  * Returns: the certificate key usage, or a negative error code in case of
1701  *   parsing error.  If the certificate does not contain the keyUsage
1702  *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1703  *   returned.
1704  **/
1705 int
1706 gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
1707                               unsigned int *key_usage,
1708                               unsigned int *critical)
1709 {
1710         int result;
1711         gnutls_datum_t keyUsage;
1712
1713         if (cert == NULL) {
1714                 gnutls_assert();
1715                 return GNUTLS_E_INVALID_REQUEST;
1716         }
1717
1718         if ((result =
1719              _gnutls_x509_crt_get_extension(cert, "2.5.29.15", 0,
1720                                             &keyUsage, critical)) < 0) {
1721                 return result;
1722         }
1723
1724         if (keyUsage.size == 0 || keyUsage.data == NULL) {
1725                 gnutls_assert();
1726                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1727         }
1728
1729         result = gnutls_x509_ext_import_key_usage(&keyUsage, key_usage);
1730         _gnutls_free_datum(&keyUsage);
1731
1732         if (result < 0) {
1733                 gnutls_assert();
1734                 return result;
1735         }
1736
1737         return 0;
1738 }
1739
1740 /**
1741  * gnutls_x509_crt_get_proxy:
1742  * @cert: should contain a #gnutls_x509_crt_t structure
1743  * @critical: will be non-zero if the extension is marked as critical
1744  * @pathlen: pointer to output integer indicating path length (may be
1745  *   NULL), non-negative error codes indicate a present pCPathLenConstraint
1746  *   field and the actual value, -1 indicate that the field is absent.
1747  * @policyLanguage: output variable with OID of policy language
1748  * @policy: output variable with policy data
1749  * @sizeof_policy: output variable size of policy data
1750  *
1751  * This function will get information from a proxy certificate.  It
1752  * reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1753  *
1754  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1755  *   otherwise a negative error code is returned.
1756  **/
1757 int
1758 gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert,
1759                           unsigned int *critical,
1760                           int *pathlen,
1761                           char **policyLanguage,
1762                           char **policy, size_t * sizeof_policy)
1763 {
1764         int result;
1765         gnutls_datum_t proxyCertInfo;
1766
1767         if (cert == NULL) {
1768                 gnutls_assert();
1769                 return GNUTLS_E_INVALID_REQUEST;
1770         }
1771
1772         if ((result =
1773              _gnutls_x509_crt_get_extension(cert, "1.3.6.1.5.5.7.1.14", 0,
1774                                             &proxyCertInfo, critical)) < 0)
1775         {
1776                 return result;
1777         }
1778
1779         if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL) {
1780                 gnutls_assert();
1781                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1782         }
1783
1784         result = gnutls_x509_ext_import_proxy(&proxyCertInfo, pathlen,
1785                                                         policyLanguage,
1786                                                         policy,
1787                                                         sizeof_policy);
1788         _gnutls_free_datum(&proxyCertInfo);
1789         if (result < 0) {
1790                 gnutls_assert();
1791                 return result;
1792         }
1793
1794         return 0;
1795 }
1796
1797 /**
1798  * gnutls_x509_policy_release:
1799  * @policy: a certificate policy
1800  *
1801  * This function will deinitialize all memory associated with the provided
1802  * @policy. The policy is allocated using gnutls_x509_crt_get_policy().
1803  *
1804  * Since: 3.1.5
1805  **/
1806 void gnutls_x509_policy_release(struct gnutls_x509_policy_st *policy)
1807 {
1808         unsigned i;
1809
1810         gnutls_free(policy->oid);
1811         for (i = 0; i < policy->qualifiers; i++)
1812                 gnutls_free(policy->qualifier[i].data);
1813 }
1814
1815
1816 /**
1817  * gnutls_x509_crt_get_policy:
1818  * @crt: should contain a #gnutls_x509_crt_t structure
1819  * @indx: This specifies which policy to return. Use (0) to get the first one.
1820  * @policy: A pointer to a policy structure.
1821  * @critical: will be non-zero if the extension is marked as critical
1822  *
1823  * This function will extract the certificate policy (extension 2.5.29.32) 
1824  * specified by the given index. 
1825  *
1826  * The policy returned by this function must be deinitialized by using
1827  * gnutls_x509_policy_release().
1828  *
1829  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1830  * if the extension is not present, otherwise a negative error value.
1831  *
1832  * Since: 3.1.5
1833  **/
1834 int
1835 gnutls_x509_crt_get_policy(gnutls_x509_crt_t crt, int indx,
1836                            struct gnutls_x509_policy_st *policy,
1837                            unsigned int *critical)
1838 {
1839         gnutls_datum_t tmpd = { NULL, 0 };
1840         int ret;
1841         gnutls_x509_policies_t policies = NULL;
1842
1843         if (crt == NULL) {
1844                 gnutls_assert();
1845                 return GNUTLS_E_INVALID_REQUEST;
1846         }
1847
1848         memset(policy, 0, sizeof(*policy));
1849
1850         ret = gnutls_x509_policies_init(&policies);
1851         if (ret < 0)
1852                 return gnutls_assert_val(ret);
1853
1854         if ((ret =
1855              _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0, &tmpd,
1856                                             critical)) < 0) {
1857                 goto cleanup;
1858         }
1859
1860         if (tmpd.size == 0 || tmpd.data == NULL) {
1861                 gnutls_assert();
1862                 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1863                 goto cleanup;
1864         }
1865
1866         ret = gnutls_x509_ext_import_policies(&tmpd, policies, 0);
1867         if (ret < 0) {
1868                 gnutls_assert();
1869                 goto cleanup;
1870         }
1871
1872         ret = gnutls_x509_policies_get(policies, indx, policy);
1873         if (ret < 0) {
1874                 gnutls_assert();
1875                 goto cleanup;
1876         }
1877
1878         _gnutls_x509_policies_erase(policies, indx);
1879
1880         ret = 0;
1881
1882  cleanup:
1883         if (policies != NULL)
1884                 gnutls_x509_policies_deinit(policies);
1885         _gnutls_free_datum(&tmpd);
1886
1887         return ret;
1888 }
1889
1890
1891 /**
1892  * gnutls_x509_crt_get_extension_by_oid:
1893  * @cert: should contain a #gnutls_x509_crt_t structure
1894  * @oid: holds an Object Identified in null terminated string
1895  * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
1896  * @buf: a pointer to a structure to hold the name (may be null)
1897  * @buf_size: initially holds the size of @buf
1898  * @critical: will be non-zero if the extension is marked as critical
1899  *
1900  * This function will return the extension specified by the OID in the
1901  * certificate.  The extensions will be returned as binary data DER
1902  * encoded, in the provided buffer.
1903  *
1904  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1905  *   otherwise a negative error code is returned. If the certificate does not
1906  *   contain the specified extension
1907  *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1908  **/
1909 int
1910 gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,
1911                                      const char *oid, int indx,
1912                                      void *buf, size_t * buf_size,
1913                                      unsigned int *critical)
1914 {
1915         int result;
1916         gnutls_datum_t output;
1917
1918         if (cert == NULL) {
1919                 gnutls_assert();
1920                 return GNUTLS_E_INVALID_REQUEST;
1921         }
1922
1923         if ((result =
1924              _gnutls_x509_crt_get_extension(cert, oid, indx, &output,
1925                                             critical)) < 0) {
1926                 gnutls_assert();
1927                 return result;
1928         }
1929
1930         if (output.size == 0 || output.data == NULL) {
1931                 gnutls_assert();
1932                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1933         }
1934
1935         if (output.size > (unsigned int) *buf_size) {
1936                 *buf_size = output.size;
1937                 _gnutls_free_datum(&output);
1938                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1939         }
1940
1941         *buf_size = output.size;
1942
1943         if (buf)
1944                 memcpy(buf, output.data, output.size);
1945
1946         _gnutls_free_datum(&output);
1947
1948         return 0;
1949 }
1950
1951 /**
1952  * gnutls_x509_crt_get_extension_by_oid2:
1953  * @cert: should contain a #gnutls_x509_crt_t structure
1954  * @oid: holds an Object Identified in null terminated string
1955  * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use (0) to get the first one.
1956  * @output: will hold the allocated extension data
1957  * @critical: will be non-zero if the extension is marked as critical
1958  *
1959  * This function will return the extension specified by the OID in the
1960  * certificate.  The extensions will be returned as binary data DER
1961  * encoded, in the provided buffer.
1962  *
1963  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1964  *   otherwise a negative error code is returned. If the certificate does not
1965  *   contain the specified extension
1966  *   GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1967  *
1968  * Since: 3.3.8
1969  **/
1970 int
1971 gnutls_x509_crt_get_extension_by_oid2(gnutls_x509_crt_t cert,
1972                                      const char *oid, int indx,
1973                                      gnutls_datum_t *output,
1974                                      unsigned int *critical)
1975 {
1976         int ret;
1977         
1978         if (cert == NULL) {
1979                 gnutls_assert();
1980                 return GNUTLS_E_INVALID_REQUEST;
1981         }
1982
1983         if ((ret =
1984              _gnutls_x509_crt_get_extension(cert, oid, indx, output,
1985                                             critical)) < 0) {
1986                 gnutls_assert();
1987                 return ret;
1988         }
1989
1990         if (output->size == 0 || output->data == NULL) {
1991                 gnutls_assert();
1992                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1993         }
1994
1995         return 0;
1996 }
1997
1998 /**
1999  * gnutls_x509_crt_get_extension_oid:
2000  * @cert: should contain a #gnutls_x509_crt_t structure
2001  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2002  * @oid: a pointer to a structure to hold the OID (may be null)
2003  * @oid_size: initially holds the size of @oid
2004  *
2005  * This function will return the requested extension OID in the certificate.
2006  * The extension OID will be stored as a string in the provided buffer.
2007  *
2008  * The @oid returned will be null terminated, although @oid_size will not
2009  * account for the trailing null.
2010  *
2011  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2012  *   otherwise a negative error code is returned.  If you have reached the
2013  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2014  *   will be returned.
2015  **/
2016 int
2017 gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert, int indx,
2018                                   void *oid, size_t * oid_size)
2019 {
2020         int result;
2021
2022         if (cert == NULL) {
2023                 gnutls_assert();
2024                 return GNUTLS_E_INVALID_REQUEST;
2025         }
2026
2027         result =
2028             _gnutls_x509_crt_get_extension_oid(cert, indx, oid, oid_size);
2029         if (result < 0) {
2030                 return result;
2031         }
2032
2033         return 0;
2034
2035 }
2036
2037 /**
2038  * gnutls_x509_crt_get_extension_info:
2039  * @cert: should contain a #gnutls_x509_crt_t structure
2040  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2041  * @oid: a pointer to a structure to hold the OID
2042  * @oid_size: initially holds the maximum size of @oid, on return
2043  *   holds actual size of @oid.
2044  * @critical: output variable with critical flag, may be NULL.
2045  *
2046  * This function will return the requested extension OID in the
2047  * certificate, and the critical flag for it.  The extension OID will
2048  * be stored as a string in the provided buffer.  Use
2049  * gnutls_x509_crt_get_extension() to extract the data.
2050  *
2051  * If the buffer provided is not long enough to hold the output, then
2052  * @oid_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
2053  * returned. The @oid returned will be null terminated, although 
2054  * @oid_size will not account for the trailing null.
2055  *
2056  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2057  *   otherwise a negative error code is returned.  If you have reached the
2058  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2059  *   will be returned.
2060  **/
2061 int
2062 gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert, int indx,
2063                                    void *oid, size_t * oid_size,
2064                                    unsigned int *critical)
2065 {
2066         int result;
2067         char str_critical[10];
2068         char name[ASN1_MAX_NAME_SIZE];
2069         int len;
2070
2071         if (!cert) {
2072                 gnutls_assert();
2073                 return GNUTLS_E_INVALID_REQUEST;
2074         }
2075
2076         snprintf(name, sizeof(name),
2077                  "tbsCertificate.extensions.?%u.extnID", indx + 1);
2078
2079         len = *oid_size;
2080         result = asn1_read_value(cert->cert, name, oid, &len);
2081         *oid_size = len;
2082
2083         if (result == ASN1_ELEMENT_NOT_FOUND)
2084                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2085         else if (result != ASN1_SUCCESS) {
2086                 gnutls_assert();
2087                 return _gnutls_asn2err(result);
2088         }
2089
2090         snprintf(name, sizeof(name),
2091                  "tbsCertificate.extensions.?%u.critical", indx + 1);
2092         len = sizeof(str_critical);
2093         result = asn1_read_value(cert->cert, name, str_critical, &len);
2094         if (result != ASN1_SUCCESS) {
2095                 gnutls_assert();
2096                 return _gnutls_asn2err(result);
2097         }
2098
2099         if (critical) {
2100                 if (str_critical[0] == 'T')
2101                         *critical = 1;
2102                 else
2103                         *critical = 0;
2104         }
2105
2106         return 0;
2107
2108 }
2109
2110 /**
2111  * gnutls_x509_crt_get_extension_data:
2112  * @cert: should contain a #gnutls_x509_crt_t structure
2113  * @indx: Specifies which extension OID to send. Use (0) to get the first one.
2114  * @data: a pointer to a structure to hold the data (may be null)
2115  * @sizeof_data: initially holds the size of @data
2116  *
2117  * This function will return the requested extension data in the
2118  * certificate.  The extension data will be stored in the
2119  * provided buffer.
2120  *
2121  * Use gnutls_x509_crt_get_extension_info() to extract the OID and
2122  * critical flag.  Use gnutls_x509_crt_get_extension_by_oid() instead,
2123  * if you want to get data indexed by the extension OID rather than
2124  * sequence.
2125  *
2126  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2127  *   otherwise a negative error code is returned.  If you have reached the
2128  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2129  *   will be returned.
2130  **/
2131 int
2132 gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert, int indx,
2133                                    void *data, size_t * sizeof_data)
2134 {
2135         int result, len;
2136         char name[ASN1_MAX_NAME_SIZE];
2137
2138         if (!cert) {
2139                 gnutls_assert();
2140                 return GNUTLS_E_INVALID_REQUEST;
2141         }
2142
2143         snprintf(name, sizeof(name),
2144                  "tbsCertificate.extensions.?%u.extnValue", indx + 1);
2145
2146         len = *sizeof_data;
2147         result = asn1_read_value(cert->cert, name, data, &len);
2148         *sizeof_data = len;
2149
2150         if (result == ASN1_ELEMENT_NOT_FOUND) {
2151                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2152         } else if (result == ASN1_MEM_ERROR && data == NULL) {
2153                 /* normally we should return GNUTLS_E_SHORT_MEMORY_BUFFER,
2154                  * but we haven't done that for long time, so use
2155                  * backwards compatible behavior */
2156                 return 0;
2157         } else if (result != ASN1_SUCCESS) {
2158                 gnutls_assert();
2159                 return _gnutls_asn2err(result);
2160         }
2161
2162         return 0;
2163 }
2164
2165 /**
2166  * gnutls_x509_crt_get_raw_issuer_dn:
2167  * @cert: should contain a #gnutls_x509_crt_t structure
2168  * @dn: will hold the starting point of the DN
2169  *
2170  * This function will return a pointer to the DER encoded DN structure
2171  * and the length. This points to allocated data that must be free'd using gnutls_free().
2172  *
2173  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2174  *   negative error value.or a negative error code on error.
2175  *
2176  **/
2177 int
2178 gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,
2179                                   gnutls_datum_t * dn)
2180 {
2181         if (cert->raw_issuer_dn.size > 0) {
2182                 return _gnutls_set_datum(dn, cert->raw_issuer_dn.data,
2183                                          cert->raw_issuer_dn.size);
2184         } else {
2185                 return _gnutls_x509_get_raw_field(cert->cert, "tbsCertificate.issuer.rdnSequence", dn);
2186         }
2187 }
2188
2189 /**
2190  * gnutls_x509_crt_get_raw_dn:
2191  * @cert: should contain a #gnutls_x509_crt_t structure
2192  * @dn: will hold the starting point of the DN
2193  *
2194  * This function will return a pointer to the DER encoded DN structure and
2195  * the length. This points to allocated data that must be free'd using gnutls_free().
2196  *
2197  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2198  *   negative error value. or a negative error code on error.
2199  *
2200  **/
2201 int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert, gnutls_datum_t * dn)
2202 {
2203         if (cert->raw_dn.size > 0) {
2204                 return _gnutls_set_datum(dn, cert->raw_dn.data, cert->raw_dn.size);
2205         } else {
2206                 return _gnutls_x509_get_raw_field(cert->cert, "tbsCertificate.subject.rdnSequence", dn);
2207         }
2208 }
2209
2210 static int
2211 get_dn(gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
2212 {
2213         *dn = asn1_find_node(cert->cert, whom);
2214         if (!*dn)
2215                 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2216         return 0;
2217 }
2218
2219 /**
2220  * gnutls_x509_crt_get_subject:
2221  * @cert: should contain a #gnutls_x509_crt_t structure
2222  * @dn: output variable with pointer to uint8_t DN.
2223  *
2224  * Return the Certificate's Subject DN as a %gnutls_x509_dn_t data type,
2225  * that can be decoded using gnutls_x509_dn_get_rdn_ava(). 
2226  *
2227  * Note that @dn should be treated as constant. Because it points 
2228  * into the @cert object, you should not use @dn after @cert is
2229  * deallocated.
2230  *
2231  * Returns: Returns 0 on success, or an error code.
2232  **/
2233 int
2234 gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2235 {
2236         return get_dn(cert, "tbsCertificate.subject.rdnSequence", dn);
2237 }
2238
2239 /**
2240  * gnutls_x509_crt_get_issuer:
2241  * @cert: should contain a #gnutls_x509_crt_t structure
2242  * @dn: output variable with pointer to uint8_t DN
2243  *
2244  * Return the Certificate's Issuer DN as a %gnutls_x509_dn_t data type,
2245  * that can be decoded using gnutls_x509_dn_get_rdn_ava(). 
2246  *
2247  * Note that @dn should be treated as constant. Because it points 
2248  * into the @cert object, you should not use @dn after @cert is
2249  * deallocated.
2250  *
2251  * Returns: Returns 0 on success, or an error code.
2252  **/
2253 int
2254 gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
2255 {
2256         return get_dn(cert, "tbsCertificate.issuer.rdnSequence", dn);
2257 }
2258
2259 /**
2260  * gnutls_x509_dn_get_rdn_ava:
2261  * @dn: a pointer to DN
2262  * @irdn: index of RDN
2263  * @iava: index of AVA.
2264  * @ava: Pointer to structure which will hold output information.
2265  *
2266  * Get pointers to data within the DN. The format of the @ava structure
2267  * is shown below.
2268  *
2269  *  struct gnutls_x509_ava_st {
2270  *    gnutls_datum_t oid;
2271  *    gnutls_datum_t value;
2272  *    unsigned long value_tag;
2273  *  };
2274  *
2275  * The X.509 distinguished name is a sequence of sequences of strings
2276  * and this is what the @irdn and @iava indexes model.
2277  *
2278  * Note that @ava will contain pointers into the @dn structure which
2279  * in turns points to the original certificate. Thus you should not
2280  * modify any data or deallocate any of those.
2281  *
2282  * This is a low-level function that requires the caller to do the
2283  * value conversions when necessary (e.g. from UCS-2).
2284  *
2285  * Returns: Returns 0 on success, or an error code.
2286  **/
2287 int
2288 gnutls_x509_dn_get_rdn_ava(gnutls_x509_dn_t dn,
2289                            int irdn, int iava, gnutls_x509_ava_st * ava)
2290 {
2291         ASN1_TYPE rdn, elem;
2292         ASN1_DATA_NODE vnode;
2293         long len;
2294         int lenlen, remlen, ret;
2295         char rbuf[ASN1_MAX_NAME_SIZE];
2296         unsigned char cls;
2297         const unsigned char *ptr;
2298
2299         iava++;
2300         irdn++;                 /* 0->1, 1->2 etc */
2301
2302         snprintf(rbuf, sizeof(rbuf), "rdnSequence.?%d.?%d", irdn, iava);
2303         rdn = asn1_find_node(dn, rbuf);
2304         if (!rdn) {
2305                 gnutls_assert();
2306                 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2307         }
2308
2309         snprintf(rbuf, sizeof(rbuf), "?%d.type", iava);
2310         elem = asn1_find_node(rdn, rbuf);
2311         if (!elem) {
2312                 gnutls_assert();
2313                 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2314         }
2315
2316         ret = asn1_read_node_value(elem, &vnode);
2317         if (ret != ASN1_SUCCESS) {
2318                 gnutls_assert();
2319                 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2320         }
2321
2322         ava->oid.data = (void *) vnode.value;
2323         ava->oid.size = vnode.value_len;
2324
2325         snprintf(rbuf, sizeof(rbuf), "?%d.value", iava);
2326         elem = asn1_find_node(rdn, rbuf);
2327         if (!elem) {
2328                 gnutls_assert();
2329                 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2330         }
2331
2332         ret = asn1_read_node_value(elem, &vnode);
2333         if (ret != ASN1_SUCCESS) {
2334                 gnutls_assert();
2335                 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
2336         }
2337         /* The value still has the previous tag's length bytes, plus the
2338          * current value's tag and length bytes. Decode them.
2339          */
2340
2341         ptr = vnode.value;
2342         remlen = vnode.value_len;
2343         len = asn1_get_length_der(ptr, remlen, &lenlen);
2344         if (len < 0) {
2345                 gnutls_assert();
2346                 return GNUTLS_E_ASN1_DER_ERROR;
2347         }
2348
2349         ptr += lenlen;
2350         remlen -= lenlen;
2351         ret =
2352             asn1_get_tag_der(ptr, remlen, &cls, &lenlen, &ava->value_tag);
2353         if (ret) {
2354                 gnutls_assert();
2355                 return _gnutls_asn2err(ret);
2356         }
2357
2358         ptr += lenlen;
2359         remlen -= lenlen;
2360
2361         {
2362                 signed long tmp;
2363
2364                 tmp = asn1_get_length_der(ptr, remlen, &lenlen);
2365                 if (tmp < 0) {
2366                         gnutls_assert();
2367                         return GNUTLS_E_ASN1_DER_ERROR;
2368                 }
2369                 ava->value.size = tmp;
2370         }
2371         ava->value.data = (void *) (ptr + lenlen);
2372
2373         return 0;
2374 }
2375
2376 /**
2377  * gnutls_x509_crt_get_fingerprint:
2378  * @cert: should contain a #gnutls_x509_crt_t structure
2379  * @algo: is a digest algorithm
2380  * @buf: a pointer to a structure to hold the fingerprint (may be null)
2381  * @buf_size: initially holds the size of @buf
2382  *
2383  * This function will calculate and copy the certificate's fingerprint
2384  * in the provided buffer. The fingerprint is a hash of the DER-encoded
2385  * data of the certificate.
2386  *
2387  * If the buffer is null then only the size will be filled.
2388  *
2389  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2390  *   not long enough, and in that case the *buf_size will be updated
2391  *   with the required size.  On success 0 is returned.
2392  **/
2393 int
2394 gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,
2395                                 gnutls_digest_algorithm_t algo,
2396                                 void *buf, size_t * buf_size)
2397 {
2398         uint8_t *cert_buf;
2399         int cert_buf_size;
2400         int result;
2401         gnutls_datum_t tmp;
2402
2403         if (buf_size == 0 || cert == NULL) {
2404                 return GNUTLS_E_INVALID_REQUEST;
2405         }
2406
2407         cert_buf_size = 0;
2408         result = asn1_der_coding(cert->cert, "", NULL, &cert_buf_size, NULL);
2409         if (result != ASN1_MEM_ERROR) {
2410                 gnutls_assert();
2411                 return _gnutls_asn2err(result);
2412         }
2413
2414         cert_buf = gnutls_malloc(cert_buf_size);
2415         if (cert_buf == NULL) {
2416                 gnutls_assert();
2417                 return GNUTLS_E_MEMORY_ERROR;
2418         }
2419
2420         result =
2421             asn1_der_coding(cert->cert, "", cert_buf, &cert_buf_size,
2422                             NULL);
2423
2424         if (result != ASN1_SUCCESS) {
2425                 gnutls_assert();
2426                 gnutls_free(cert_buf);
2427                 return _gnutls_asn2err(result);
2428         }
2429
2430         tmp.data = cert_buf;
2431         tmp.size = cert_buf_size;
2432
2433         result = gnutls_fingerprint(algo, &tmp, buf, buf_size);
2434         gnutls_free(cert_buf);
2435
2436         return result;
2437 }
2438
2439 /**
2440  * gnutls_x509_crt_export:
2441  * @cert: Holds the certificate
2442  * @format: the format of output params. One of PEM or DER.
2443  * @output_data: will contain a certificate PEM or DER encoded
2444  * @output_data_size: holds the size of output_data (and will be
2445  *   replaced by the actual size of parameters)
2446  *
2447  * This function will export the certificate to DER or PEM format.
2448  *
2449  * If the buffer provided is not long enough to hold the output, then
2450  * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2451  * be returned.
2452  *
2453  * If the structure is PEM encoded, it will have a header
2454  * of "BEGIN CERTIFICATE".
2455  *
2456  * Returns: In case of failure a negative error code will be
2457  *   returned, and 0 on success.
2458  **/
2459 int
2460 gnutls_x509_crt_export(gnutls_x509_crt_t cert,
2461                        gnutls_x509_crt_fmt_t format, void *output_data,
2462                        size_t * output_data_size)
2463 {
2464         if (cert == NULL) {
2465                 gnutls_assert();
2466                 return GNUTLS_E_INVALID_REQUEST;
2467         }
2468
2469         return _gnutls_x509_export_int(cert->cert, format, PEM_X509_CERT2,
2470                                        output_data, output_data_size);
2471 }
2472
2473 /**
2474  * gnutls_x509_crt_export2:
2475  * @cert: Holds the certificate
2476  * @format: the format of output params. One of PEM or DER.
2477  * @out: will contain a certificate PEM or DER encoded
2478  *
2479  * This function will export the certificate to DER or PEM format.
2480  * The output buffer is allocated using gnutls_malloc().
2481  *
2482  * If the structure is PEM encoded, it will have a header
2483  * of "BEGIN CERTIFICATE".
2484  *
2485  * Returns: In case of failure a negative error code will be
2486  *   returned, and 0 on success.
2487  *
2488  * Since: 3.1.3
2489  **/
2490 int
2491 gnutls_x509_crt_export2(gnutls_x509_crt_t cert,
2492                         gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
2493 {
2494         if (cert == NULL) {
2495                 gnutls_assert();
2496                 return GNUTLS_E_INVALID_REQUEST;
2497         }
2498
2499         return _gnutls_x509_export_int2(cert->cert, format, PEM_X509_CERT2,
2500                                         out);
2501 }
2502
2503 int
2504 _gnutls_get_key_id(gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
2505                    unsigned char *output_data, size_t * output_data_size)
2506 {
2507         int ret = 0;
2508         gnutls_datum_t der = { NULL, 0 };
2509         const gnutls_digest_algorithm_t hash = GNUTLS_DIG_SHA1;
2510         unsigned int digest_len =
2511             _gnutls_hash_get_algo_len(hash_to_entry(hash));
2512
2513         if (output_data == NULL || *output_data_size < digest_len) {
2514                 gnutls_assert();
2515                 *output_data_size = digest_len;
2516                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2517         }
2518
2519         ret = _gnutls_x509_encode_PKI_params(&der, pk, params);
2520         if (ret < 0)
2521                 return gnutls_assert_val(ret);
2522
2523         ret = _gnutls_hash_fast(hash, der.data, der.size, output_data);
2524         if (ret < 0) {
2525                 gnutls_assert();
2526                 goto cleanup;
2527         }
2528         *output_data_size = digest_len;
2529
2530         ret = 0;
2531
2532       cleanup:
2533
2534         _gnutls_free_datum(&der);
2535         return ret;
2536 }
2537
2538 /**
2539  * gnutls_x509_crt_get_key_id:
2540  * @crt: Holds the certificate
2541  * @flags: should be 0 for now
2542  * @output_data: will contain the key ID
2543  * @output_data_size: holds the size of output_data (and will be
2544  *   replaced by the actual size of parameters)
2545  *
2546  * This function will return a unique ID that depends on the public
2547  * key parameters. This ID can be used in checking whether a
2548  * certificate corresponds to the given private key.
2549  *
2550  * If the buffer provided is not long enough to hold the output, then
2551  * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2552  * be returned.  The output will normally be a SHA-1 hash output,
2553  * which is 20 bytes.
2554  *
2555  * Returns: In case of failure a negative error code will be
2556  *   returned, and 0 on success.
2557  **/
2558 int
2559 gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt, unsigned int flags,
2560                            unsigned char *output_data,
2561                            size_t * output_data_size)
2562 {
2563         int pk, ret = 0;
2564         gnutls_pk_params_st params;
2565
2566         if (crt == NULL) {
2567                 gnutls_assert();
2568                 return GNUTLS_E_INVALID_REQUEST;
2569         }
2570
2571         pk = gnutls_x509_crt_get_pk_algorithm(crt, NULL);
2572         if (pk < 0) {
2573                 gnutls_assert();
2574                 return pk;
2575         }
2576
2577         ret = _gnutls_x509_crt_get_mpis(crt, &params);
2578         if (ret < 0) {
2579                 gnutls_assert();
2580                 return ret;
2581         }
2582
2583         ret =
2584             _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2585
2586         gnutls_pk_params_release(&params);
2587
2588         return ret;
2589 }
2590
2591 static int
2592 crl_issuer_matches(gnutls_x509_crl_t crl, gnutls_x509_crt_t cert)
2593 {
2594         if (_gnutls_x509_compare_raw_dn
2595             (&crl->raw_issuer_dn, &cert->raw_issuer_dn) != 0)
2596                 return 1;
2597         else
2598                 return 0;
2599 }
2600
2601 /* This is exactly as gnutls_x509_crt_check_revocation() except that
2602  * it calls func.
2603  */
2604 int
2605 _gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
2606                                   const gnutls_x509_crl_t * crl_list,
2607                                   int crl_list_length,
2608                                   gnutls_verify_output_function func)
2609 {
2610         uint8_t serial[128];
2611         uint8_t cert_serial[128];
2612         size_t serial_size, cert_serial_size;
2613         int ret, j;
2614         gnutls_x509_crl_iter_t iter = NULL;
2615
2616         if (cert == NULL) {
2617                 gnutls_assert();
2618                 return GNUTLS_E_INVALID_REQUEST;
2619         }
2620
2621         for (j = 0; j < crl_list_length; j++) { /* do for all the crls */
2622
2623                 /* Step 1. check if issuer's DN match
2624                  */
2625                 ret = crl_issuer_matches(crl_list[j], cert);
2626                 if (ret == 0) {
2627                         /* issuers do not match so don't even
2628                          * bother checking.
2629                          */
2630                         gnutls_assert();
2631                         continue;
2632                 }
2633
2634                 /* Step 2. Read the certificate's serial number
2635                  */
2636                 cert_serial_size = sizeof(cert_serial);
2637                 ret =
2638                     gnutls_x509_crt_get_serial(cert, cert_serial,
2639                                                &cert_serial_size);
2640                 if (ret < 0) {
2641                         gnutls_assert();
2642                         return ret;
2643                 }
2644
2645                 /* Step 3. cycle through the CRL serials and compare with
2646                  *   certificate serial we have.
2647                  */
2648
2649                 iter = NULL;
2650                 do {
2651                         serial_size = sizeof(serial);
2652                         ret =
2653                             gnutls_x509_crl_iter_crt_serial(crl_list[j],
2654                                                             &iter,
2655                                                             serial,
2656                                                             &serial_size,
2657                                                             NULL);
2658                         if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2659                                 break;
2660                         } else if (ret < 0) {
2661                                 gnutls_assert();
2662                                 goto fail;
2663                         }
2664
2665                         if (serial_size == cert_serial_size) {
2666                                 if (memcmp
2667                                     (serial, cert_serial,
2668                                      serial_size) == 0) {
2669                                         /* serials match */
2670                                         if (func)
2671                                                 func(cert, NULL,
2672                                                      crl_list[j],
2673                                                      GNUTLS_CERT_REVOKED |
2674                                                      GNUTLS_CERT_INVALID);
2675                                         ret = 1;        /* revoked! */
2676                                         goto fail;
2677                                 }
2678                         }
2679                 } while(1);
2680
2681                 gnutls_x509_crl_iter_deinit(iter);
2682                 iter = NULL;
2683
2684                 if (func)
2685                         func(cert, NULL, crl_list[j], 0);
2686
2687         }
2688         return 0;               /* not revoked. */
2689
2690  fail:
2691         gnutls_x509_crl_iter_deinit(iter);
2692         return ret;
2693 }
2694
2695
2696 /**
2697  * gnutls_x509_crt_check_revocation:
2698  * @cert: should contain a #gnutls_x509_crt_t structure
2699  * @crl_list: should contain a list of gnutls_x509_crl_t structures
2700  * @crl_list_length: the length of the crl_list
2701  *
2702  * This function will return check if the given certificate is
2703  * revoked.  It is assumed that the CRLs have been verified before.
2704  *
2705  * Returns: 0 if the certificate is NOT revoked, and 1 if it is.  A
2706  * negative error code is returned on error.
2707  **/
2708 int
2709 gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
2710                                  const gnutls_x509_crl_t * crl_list,
2711                                  int crl_list_length)
2712 {
2713         return _gnutls_x509_crt_check_revocation(cert, crl_list,
2714                                                  crl_list_length, NULL);
2715 }
2716
2717 /**
2718  * gnutls_x509_crt_get_verify_algorithm:
2719  * @crt: Holds the certificate
2720  * @signature: contains the signature
2721  * @hash: The result of the call with the hash algorithm used for signature
2722  *
2723  * This function will read the certifcate and the signed data to
2724  * determine the hash algorithm used to generate the signature.
2725  *
2726  * Deprecated: Use gnutls_pubkey_get_verify_algorithm() instead.
2727  *
2728  * Returns: the 0 if the hash algorithm is found. A negative error code is
2729  * returned on error.
2730  *
2731  * Since: 2.8.0
2732  **/
2733 int
2734 gnutls_x509_crt_get_verify_algorithm(gnutls_x509_crt_t crt,
2735                                      const gnutls_datum_t * signature,
2736                                      gnutls_digest_algorithm_t * hash)
2737 {
2738         gnutls_pk_params_st issuer_params;
2739         int ret;
2740
2741         if (crt == NULL) {
2742                 gnutls_assert();
2743                 return GNUTLS_E_INVALID_REQUEST;
2744         }
2745
2746         ret = _gnutls_x509_crt_get_mpis(crt, &issuer_params);
2747         if (ret < 0) {
2748                 gnutls_assert();
2749                 return ret;
2750         }
2751
2752         ret = _gnutls_x509_verify_algorithm(hash,
2753                                             signature,
2754                                             gnutls_x509_crt_get_pk_algorithm
2755                                             (crt, NULL), &issuer_params);
2756
2757         /* release allocated mpis */
2758         gnutls_pk_params_release(&issuer_params);
2759
2760         return ret;
2761 }
2762
2763
2764
2765 /**
2766  * gnutls_x509_crt_get_preferred_hash_algorithm:
2767  * @crt: Holds the certificate
2768  * @hash: The result of the call with the hash algorithm used for signature
2769  * @mand: If non-zero it means that the algorithm MUST use this hash. May be NULL.
2770  *
2771  * This function will read the certifcate and return the appropriate digest
2772  * algorithm to use for signing with this certificate. Some certificates (i.e.
2773  * DSA might not be able to sign without the preferred algorithm).
2774  *
2775  * Deprecated: Please use gnutls_pubkey_get_preferred_hash_algorithm().
2776  *
2777  * Returns: the 0 if the hash algorithm is found. A negative error code is
2778  * returned on error.
2779  *
2780  * Since: 2.12.0
2781  **/
2782 int
2783 gnutls_x509_crt_get_preferred_hash_algorithm(gnutls_x509_crt_t crt,
2784                                              gnutls_digest_algorithm_t *
2785                                              hash, unsigned int *mand)
2786 {
2787         gnutls_pk_params_st issuer_params;
2788         int ret;
2789
2790         if (crt == NULL) {
2791                 gnutls_assert();
2792                 return GNUTLS_E_INVALID_REQUEST;
2793         }
2794
2795         ret = _gnutls_x509_crt_get_mpis(crt, &issuer_params);
2796         if (ret < 0) {
2797                 gnutls_assert();
2798                 return ret;
2799         }
2800
2801         ret =
2802             _gnutls_pk_get_hash_algorithm(gnutls_x509_crt_get_pk_algorithm
2803                                           (crt, NULL), &issuer_params,
2804                                           hash, mand);
2805
2806         /* release allocated mpis */
2807         gnutls_pk_params_release(&issuer_params);
2808
2809         return ret;
2810 }
2811
2812 /**
2813  * gnutls_x509_crt_get_crl_dist_points:
2814  * @cert: should contain a #gnutls_x509_crt_t structure
2815  * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2816  * @san: is the place where the distribution point will be copied to
2817  * @san_size: holds the size of ret.
2818  * @reason_flags: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2819  * @critical: will be non-zero if the extension is marked as critical (may be null)
2820  *
2821  * This function retrieves the CRL distribution points (2.5.29.31),
2822  * contained in the given certificate in the X509v3 Certificate
2823  * Extensions.
2824  *
2825  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER and updates @ret_size if
2826  *   @ret_size is not enough to hold the distribution point, or the
2827  *   type of the distribution point if everything was ok. The type is
2828  *   one of the enumerated %gnutls_x509_subject_alt_name_t.  If the
2829  *   certificate does not have an Alternative name with the specified
2830  *   sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2831  *   returned.
2832  **/
2833 int
2834 gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
2835                                     unsigned int seq, void *san,
2836                                     size_t * san_size,
2837                                     unsigned int *reason_flags,
2838                                     unsigned int *critical)
2839 {
2840         int ret;
2841         gnutls_datum_t dist_points = { NULL, 0 };
2842         unsigned type;
2843         gnutls_x509_crl_dist_points_t cdp = NULL;
2844         gnutls_datum_t t_san;
2845
2846         if (cert == NULL) {
2847                 gnutls_assert();
2848                 return GNUTLS_E_INVALID_REQUEST;
2849         }
2850
2851         ret = gnutls_x509_crl_dist_points_init(&cdp);
2852         if (ret < 0)
2853                 return gnutls_assert_val(ret);
2854
2855         if (reason_flags)
2856                 *reason_flags = 0;
2857
2858         ret =
2859             _gnutls_x509_crt_get_extension(cert, "2.5.29.31", 0,
2860                                            &dist_points, critical);
2861         if (ret < 0) {
2862                 gnutls_assert();
2863                 goto cleanup;
2864         }
2865
2866         if (dist_points.size == 0 || dist_points.data == NULL) {
2867                 gnutls_assert();
2868                 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2869                 goto cleanup;
2870         }
2871
2872         ret = gnutls_x509_ext_import_crl_dist_points(&dist_points, cdp, 0);
2873         if (ret < 0) {
2874                 gnutls_assert();
2875                 goto cleanup;
2876         }
2877
2878         ret = gnutls_x509_crl_dist_points_get(cdp, seq, &type, &t_san, reason_flags);
2879         if (ret < 0) {
2880                 gnutls_assert();
2881                 goto cleanup;
2882         }
2883
2884         ret = _gnutls_copy_string(&t_san, san, san_size);
2885         if (ret < 0) {
2886                 gnutls_assert();
2887                 goto cleanup;
2888         }
2889
2890         ret = type;
2891
2892  cleanup:
2893         _gnutls_free_datum(&dist_points);
2894         if (cdp != NULL)
2895                 gnutls_x509_crl_dist_points_deinit(cdp);
2896
2897         return ret;
2898 }
2899
2900 /**
2901  * gnutls_x509_crt_get_key_purpose_oid:
2902  * @cert: should contain a #gnutls_x509_crt_t structure
2903  * @indx: This specifies which OID to return. Use (0) to get the first one.
2904  * @oid: a pointer to a buffer to hold the OID (may be null)
2905  * @oid_size: initially holds the size of @oid
2906  * @critical: output flag to indicate criticality of extension
2907  *
2908  * This function will extract the key purpose OIDs of the Certificate
2909  * specified by the given index.  These are stored in the Extended Key
2910  * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2911  * human readable names.
2912  *
2913  * If @oid is null then only the size will be filled. The @oid
2914  * returned will be null terminated, although @oid_size will not
2915  * account for the trailing null.
2916  *
2917  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2918  *   not long enough, and in that case the *oid_size will be updated
2919  *   with the required size.  On success 0 is returned.
2920  **/
2921 int
2922 gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert,
2923                                     int indx, void *oid, size_t * oid_size,
2924                                     unsigned int *critical)
2925 {
2926         int ret;
2927         gnutls_datum_t ext;
2928         gnutls_x509_key_purposes_t p = NULL;
2929         gnutls_datum_t out;
2930
2931         if (cert == NULL) {
2932                 gnutls_assert();
2933                 return GNUTLS_E_INVALID_REQUEST;
2934         }
2935
2936         if (oid)
2937                 memset(oid, 0, *oid_size);
2938         else
2939                 *oid_size = 0;