2 * Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2010 Free Software
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS-EXTRA.
9 * GnuTLS-extra is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * GnuTLS-extra is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* This file includes all functions that were in the 0.5.x and 0.8.x
24 * gnutls API. They are now implemented over the new certificate parsing
28 #include "gnutls_int.h"
30 #include <gnutls_global.h>
31 #include <gnutls_errors.h>
32 #include <string.h> /* memset */
33 #include <x509/x509_int.h>
35 #include <gnutls/x509.h>
36 #include <openssl_compat.h>
39 * gnutls_x509_extract_dn:
40 * @idn: should contain a DER encoded RDN sequence
41 * @rdn: a pointer to a structure to hold the name
43 * This function will return the name of the given RDN sequence.
44 * The name will be returned as a gnutls_x509_dn structure.
45 * Returns a negative error code in case of an error.
49 gnutls_x509_extract_dn (const gnutls_datum_t * idn, gnutls_x509_dn * rdn)
51 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
56 asn1_create_element (_gnutls_get_pkix (),
57 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
59 return _gnutls_asn2err (result);
62 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
63 if (result != ASN1_SUCCESS)
65 /* couldn't decode DER */
66 asn1_delete_structure (&dn);
67 return _gnutls_asn2err (result);
70 memset (rdn, 0, sizeof (gnutls_x509_dn));
72 len = sizeof (rdn->country);
73 _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_COUNTRY_NAME, 0, 0,
76 len = sizeof (rdn->organization);
77 _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
78 0, rdn->organization, &len);
80 len = sizeof (rdn->organizational_unit_name);
81 _gnutls_x509_parse_dn_oid (dn, "",
82 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
83 0, rdn->organizational_unit_name, &len);
85 len = sizeof (rdn->common_name);
86 _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_COMMON_NAME, 0, 0,
87 rdn->common_name, &len);
89 len = sizeof (rdn->locality_name);
90 _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_X520_LOCALITY_NAME, 0, 0,
91 rdn->locality_name, &len);
93 len = sizeof (rdn->state_or_province_name);
94 _gnutls_x509_parse_dn_oid (dn, "",
95 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0,
96 rdn->state_or_province_name, &len);
98 len = sizeof (rdn->email);
99 _gnutls_x509_parse_dn_oid (dn, "", GNUTLS_OID_PKCS9_EMAIL, 0, 0,
102 asn1_delete_structure (&dn);
108 * gnutls_x509_extract_certificate_dn:
109 * @cert: should contain an X.509 DER encoded certificate
110 * @ret: a pointer to a structure to hold the peer's name
112 * This function will return the name of the certificate holder. The name is gnutls_x509_dn structure and
113 * is a obtained by the peer's certificate. If the certificate send by the
114 * peer is invalid, or in any other failure this function returns error.
115 * Returns a negative error code in case of an error.
118 gnutls_x509_extract_certificate_dn (const gnutls_datum_t * cert,
119 gnutls_x509_dn * ret)
121 gnutls_x509_crt_t xcert;
125 result = gnutls_x509_crt_init (&xcert);
129 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
132 gnutls_x509_crt_deinit (xcert);
136 len = sizeof (ret->country);
137 gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_COUNTRY_NAME, 0,
138 0, ret->country, &len);
140 len = sizeof (ret->organization);
141 gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_ORGANIZATION_NAME,
142 0, 0, ret->organization, &len);
144 len = sizeof (ret->organizational_unit_name);
145 gnutls_x509_crt_get_dn_by_oid (xcert,
146 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
147 0, 0, ret->organizational_unit_name, &len);
149 len = sizeof (ret->common_name);
150 gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_COMMON_NAME, 0, 0,
151 ret->common_name, &len);
153 len = sizeof (ret->locality_name);
154 gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_X520_LOCALITY_NAME, 0,
155 0, ret->locality_name, &len);
157 len = sizeof (ret->state_or_province_name);
158 gnutls_x509_crt_get_dn_by_oid (xcert,
159 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME,
160 0, 0, ret->state_or_province_name, &len);
162 len = sizeof (ret->email);
163 gnutls_x509_crt_get_dn_by_oid (xcert, GNUTLS_OID_PKCS9_EMAIL, 0, 0,
166 gnutls_x509_crt_deinit (xcert);
172 * gnutls_x509_extract_certificate_issuer_dn:
173 * @cert: should contain an X.509 DER encoded certificate
174 * @ret: a pointer to a structure to hold the issuer's name
176 * This function will return the name of the issuer stated in the certificate. The name is a gnutls_x509_dn structure and
177 * is a obtained by the peer's certificate. If the certificate send by the
178 * peer is invalid, or in any other failure this function returns error.
179 * Returns a negative error code in case of an error.
182 gnutls_x509_extract_certificate_issuer_dn (const gnutls_datum_t * cert,
183 gnutls_x509_dn * ret)
185 gnutls_x509_crt_t xcert;
189 result = gnutls_x509_crt_init (&xcert);
193 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
196 gnutls_x509_crt_deinit (xcert);
200 len = sizeof (ret->country);
201 gnutls_x509_crt_get_issuer_dn_by_oid (xcert,
202 GNUTLS_OID_X520_COUNTRY_NAME, 0,
203 0, ret->country, &len);
205 len = sizeof (ret->organization);
206 gnutls_x509_crt_get_issuer_dn_by_oid (xcert,
207 GNUTLS_OID_X520_ORGANIZATION_NAME,
208 0, 0, ret->organization, &len);
210 len = sizeof (ret->organizational_unit_name);
211 gnutls_x509_crt_get_issuer_dn_by_oid (xcert,
212 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
214 ret->organizational_unit_name, &len);
216 len = sizeof (ret->common_name);
217 gnutls_x509_crt_get_issuer_dn_by_oid (xcert,
218 GNUTLS_OID_X520_COMMON_NAME, 0, 0,
219 ret->common_name, &len);
221 len = sizeof (ret->locality_name);
222 gnutls_x509_crt_get_issuer_dn_by_oid (xcert,
223 GNUTLS_OID_X520_LOCALITY_NAME, 0,
224 0, ret->locality_name, &len);
226 len = sizeof (ret->state_or_province_name);
227 gnutls_x509_crt_get_issuer_dn_by_oid (xcert,
228 GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME,
229 0, 0, ret->state_or_province_name,
232 len = sizeof (ret->email);
233 gnutls_x509_crt_get_issuer_dn_by_oid (xcert, GNUTLS_OID_PKCS9_EMAIL, 0,
234 0, ret->email, &len);
236 gnutls_x509_crt_deinit (xcert);
243 * gnutls_x509_extract_certificate_subject_alt_name:
244 * @cert: should contain an X.509 DER encoded certificate
245 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
246 * @ret: is the place where the alternative name will be copied to
247 * @ret_size: holds the size of ret.
249 * This function will return the alternative names, contained in the
252 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if ret_size is not enough to hold the alternative
253 * name, or the type of alternative name if everything was ok. The type is
254 * one of the enumerated GNUTLS_X509_SUBJECT_ALT_NAME.
256 * If the certificate does not have an Alternative name with the specified
257 * sequence number then returns GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
260 gnutls_x509_extract_certificate_subject_alt_name (const gnutls_datum_t *
262 char *ret, int *ret_size)
264 gnutls_x509_crt_t xcert;
266 size_t size = *ret_size;
268 result = gnutls_x509_crt_init (&xcert);
272 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
275 gnutls_x509_crt_deinit (xcert);
280 gnutls_x509_crt_get_subject_alt_name (xcert, seq, ret, &size, NULL);
283 gnutls_x509_crt_deinit (xcert);
289 * gnutls_x509_extract_certificate_ca_status:
290 * @cert: should contain an X.509 DER encoded certificate
292 * This function will return certificates CA status, by reading the
293 * basicConstraints X.509 extension. If the certificate is a CA a positive
294 * value will be returned, or zero if the certificate does not have
297 * A negative value may be returned in case of parsing error.
298 * If the certificate does not contain the basicConstraints extension
299 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
302 gnutls_x509_extract_certificate_ca_status (const gnutls_datum_t * cert)
304 gnutls_x509_crt_t xcert;
307 result = gnutls_x509_crt_init (&xcert);
311 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
314 gnutls_x509_crt_deinit (xcert);
318 result = gnutls_x509_crt_get_ca_status (xcert, NULL);
320 gnutls_x509_crt_deinit (xcert);
326 * gnutls_x509_extract_certificate_activation_time:
327 * @cert: should contain an X.509 DER encoded certificate
329 * This function will return the certificate's activation time in UNIX time
330 * (ie seconds since 00:00:00 UTC January 1, 1970).
331 * Returns a (time_t) -1 in case of an error.
334 gnutls_x509_extract_certificate_activation_time (const gnutls_datum_t * cert)
336 gnutls_x509_crt_t xcert;
339 result = gnutls_x509_crt_init (&xcert);
343 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
346 gnutls_x509_crt_deinit (xcert);
350 result = gnutls_x509_crt_get_activation_time (xcert);
352 gnutls_x509_crt_deinit (xcert);
358 * gnutls_x509_extract_certificate_expiration_time:
359 * @cert: should contain an X.509 DER encoded certificate
361 * This function will return the certificate's expiration time in UNIX time
362 * (ie seconds since 00:00:00 UTC January 1, 1970).
363 * Returns a (time_t) -1 in case of an error.
366 gnutls_x509_extract_certificate_expiration_time (const gnutls_datum_t * cert)
368 gnutls_x509_crt_t xcert;
371 result = gnutls_x509_crt_init (&xcert);
375 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
378 gnutls_x509_crt_deinit (xcert);
382 result = gnutls_x509_crt_get_expiration_time (xcert);
384 gnutls_x509_crt_deinit (xcert);
390 * gnutls_x509_extract_certificate_version:
391 * @cert: is an X.509 DER encoded certificate
393 * This function will return the X.509 certificate's version (1, 2, 3). This is obtained by the X509 Certificate
394 * Version field. Returns a negative value in case of an error.
397 gnutls_x509_extract_certificate_version (const gnutls_datum_t * cert)
399 gnutls_x509_crt_t xcert;
402 result = gnutls_x509_crt_init (&xcert);
406 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
409 gnutls_x509_crt_deinit (xcert);
413 result = gnutls_x509_crt_get_version (xcert);
415 gnutls_x509_crt_deinit (xcert);
422 * gnutls_x509_extract_certificate_serial:
423 * @cert: is an X.509 DER encoded certificate
424 * @result: The place where the serial number will be copied
425 * @result_size: Holds the size of the result field.
427 * This function will return the X.509 certificate's serial number.
428 * This is obtained by the X509 Certificate serialNumber
429 * field. Serial is not always a 32 or 64bit number. Some CAs use
430 * large serial numbers, thus it may be wise to handle it as something
433 * Returns a negative value in case of an error.
436 gnutls_x509_extract_certificate_serial (const gnutls_datum_t * cert,
437 char *result, int *result_size)
439 gnutls_x509_crt_t xcert;
440 size_t size = *result_size;
443 ret = gnutls_x509_crt_init (&xcert);
447 ret = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
450 gnutls_x509_crt_deinit (xcert);
454 ret = gnutls_x509_crt_get_serial (xcert, result, &size);
457 gnutls_x509_crt_deinit (xcert);
464 * gnutls_x509_extract_certificate_pk_algorithm:
465 * @cert: is a DER encoded X.509 certificate
466 * @bits: if bits is non null it will hold the size of the parameters' in bits
468 * This function will return the public key algorithm of an X.509
471 * If bits is non null, it should have enough size to hold the parameters
472 * size in bits. For RSA the bits returned is the modulus.
473 * For DSA the bits returned are of the public
476 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
477 * or a negative value on error.
480 gnutls_x509_extract_certificate_pk_algorithm (const gnutls_datum_t *
483 gnutls_x509_crt_t xcert;
486 result = gnutls_x509_crt_init (&xcert);
490 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
493 gnutls_x509_crt_deinit (xcert);
497 result = gnutls_x509_crt_get_pk_algorithm (xcert, bits);
499 gnutls_x509_crt_deinit (xcert);
506 * gnutls_x509_extract_certificate_dn_string:
507 * @cert: should contain an X.509 DER encoded certificate
508 * @buf: a pointer to a structure to hold the peer's name
509 * @sizeof_buf: holds the size of 'buf'
510 * @issuer: if non zero, then extract the name of the issuer, instead of the holder
512 * This function will copy the name of the certificate holder in the
513 * provided buffer. The name will be in the form
514 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253.
516 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
517 * long enough, and 0 on success.
520 gnutls_x509_extract_certificate_dn_string (char *buf,
521 unsigned int sizeof_buf,
522 const gnutls_datum_t * cert,
525 gnutls_x509_crt_t xcert;
529 result = gnutls_x509_crt_init (&xcert);
533 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
536 gnutls_x509_crt_deinit (xcert);
542 result = gnutls_x509_crt_get_dn (xcert, buf, &size);
544 result = gnutls_x509_crt_get_issuer_dn (xcert, buf, &size);
546 gnutls_x509_crt_deinit (xcert);
552 * gnutls_x509_verify_certificate:
553 * @cert_list: is the certificate list to be verified
554 * @cert_list_length: holds the number of certificate in cert_list
555 * @CA_list: is the CA list which will be used in verification
556 * @CA_list_length: holds the number of CA certificate in CA_list
557 * @CRL_list: not used
558 * @CRL_list_length: not used
560 * This function will try to verify the given certificate list and
561 * return its status (TRUSTED, EXPIRED etc.). The return value
562 * (status) should be one or more of the gnutls_certificate_status_t
563 * enumerated elements bitwise or'd. Note that expiration and
564 * activation dates are not checked by this function, you should
565 * check them using the appropriate functions.
567 * This function understands the basicConstraints (2.5.29.19) PKIX
568 * extension. This means that only a certificate authority can sign
571 * However you must also check the peer's name in order to check if
572 * the verified certificate belongs to the actual peer.
574 * The return value (status) should be one or more of the
575 * gnutls_certificate_status_t enumerated elements bitwise or'd.
577 * GNUTLS_CERT_INVALID: the peer's certificate is not valid.
579 * GNUTLS_CERT_REVOKED: the certificate has been revoked.
581 * A negative error code is returned in case of an error.
582 * GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that
583 * no certificate was sent by the peer.
586 gnutls_x509_verify_certificate (const gnutls_datum_t * cert_list,
587 int cert_list_length,
588 const gnutls_datum_t * CA_list,
590 const gnutls_datum_t * CRL_list,
594 gnutls_x509_crt_t *peer_certificate_list = NULL;
595 gnutls_x509_crt_t *ca_certificate_list = NULL;
596 gnutls_x509_crl_t *crl_list = NULL;
597 int peer_certificate_list_size = 0, i, x, ret;
598 int ca_certificate_list_size = 0, crl_list_size = 0;
600 if (cert_list == NULL || cert_list_length == 0)
601 return GNUTLS_E_NO_CERTIFICATE_FOUND;
603 /* generate a list of gnutls_certs based on the auth info
606 peer_certificate_list_size = cert_list_length;
607 peer_certificate_list =
608 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
609 if (peer_certificate_list == NULL)
612 ret = GNUTLS_E_MEMORY_ERROR;
616 ca_certificate_list_size = CA_list_length;
617 ca_certificate_list =
618 gnutls_calloc (ca_certificate_list_size, sizeof (gnutls_x509_crt_t));
619 if (ca_certificate_list == NULL)
622 ret = GNUTLS_E_MEMORY_ERROR;
626 /* allocate memory for CRL
628 crl_list_size = CRL_list_length;
629 crl_list = gnutls_calloc (crl_list_size, sizeof (gnutls_x509_crl_t));
630 if (crl_list == NULL)
633 ret = GNUTLS_E_MEMORY_ERROR;
637 /* convert certA_list to gnutls_cert* list
639 for (i = 0; i < peer_certificate_list_size; i++)
641 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
649 gnutls_x509_crt_import (peer_certificate_list[i],
650 &cert_list[i], GNUTLS_X509_FMT_DER);
658 /* convert CA_list to gnutls_x509_cert* list
660 for (i = 0; i < ca_certificate_list_size; i++)
662 ret = gnutls_x509_crt_init (&ca_certificate_list[i]);
670 gnutls_x509_crt_import (ca_certificate_list[i],
671 &CA_list[i], GNUTLS_X509_FMT_DER);
680 /* convert CRL_list to gnutls_x509_crl* list
682 for (i = 0; i < crl_list_size; i++)
684 ret = gnutls_x509_crl_init (&crl_list[i]);
692 gnutls_x509_crl_import (crl_list[i],
693 &CRL_list[i], GNUTLS_X509_FMT_DER);
702 /* Verify certificate
705 gnutls_x509_crt_list_verify (peer_certificate_list,
706 peer_certificate_list_size,
708 ca_certificate_list_size, crl_list,
709 crl_list_size, 0, &verify);
721 if (peer_certificate_list != NULL)
722 for (x = 0; x < peer_certificate_list_size; x++)
724 if (peer_certificate_list[x] != NULL)
725 gnutls_x509_crt_deinit (peer_certificate_list[x]);
728 if (ca_certificate_list != NULL)
729 for (x = 0; x < ca_certificate_list_size; x++)
731 if (ca_certificate_list[x] != NULL)
732 gnutls_x509_crt_deinit (ca_certificate_list[x]);
735 if (crl_list != NULL)
736 for (x = 0; x < crl_list_size; x++)
738 if (crl_list[x] != NULL)
739 gnutls_x509_crl_deinit (crl_list[x]);
742 gnutls_free (crl_list);
745 gnutls_free (ca_certificate_list);
746 gnutls_free (peer_certificate_list);
752 * gnutls_x509_extract_key_pk_algorithm:
753 * @cert: is a DER encoded private key
755 * This function will return the public key algorithm of a DER encoded private
758 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
759 * or GNUTLS_E_UNKNOWN_PK_ALGORITHM on error.
762 gnutls_x509_extract_key_pk_algorithm (const gnutls_datum_t * key)
764 gnutls_x509_privkey_t pkey;
767 ret = gnutls_x509_privkey_init (&pkey);
774 ret = gnutls_x509_privkey_import (pkey, key, GNUTLS_X509_FMT_DER);
781 pk = gnutls_x509_privkey_get_pk_algorithm (pkey);
783 gnutls_x509_privkey_deinit (pkey);
790 * gnutls_x509_pkcs7_extract_certificate:
791 * @pkcs7_struct: should contain a PKCS7 DER formatted structure
792 * @indx: contains the index of the certificate to extract
793 * @certificate: the contents of the certificate will be copied there
794 * @certificate_size: should hold the size of the certificate
796 * This function will return a certificate of the PKCS7 or RFC2630
797 * certificate set. Returns 0 on success. If the provided buffer is
798 * not long enough, then GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
800 * After the last certificate has been read
801 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
804 gnutls_x509_pkcs7_extract_certificate (const gnutls_datum_t *
805 pkcs7_struct, int indx,
807 int *certificate_size)
809 gnutls_pkcs7_t pkcs7;
811 size_t size = *certificate_size;
813 result = gnutls_pkcs7_init (&pkcs7);
817 result = gnutls_pkcs7_import (pkcs7, pkcs7_struct, GNUTLS_X509_FMT_DER);
820 gnutls_pkcs7_deinit (pkcs7);
824 result = gnutls_pkcs7_get_crt_raw (pkcs7, indx, certificate, &size);
825 *certificate_size = size;
827 gnutls_pkcs7_deinit (pkcs7);