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