2 * Copyright (C) 2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include <gnutls_int.h>
22 #include "gnutls_auth_int.h"
23 #include "gnutls_errors.h"
24 #include <gnutls_cert.h>
25 #include <auth_cert.h>
26 #include "gnutls_dh.h"
27 #include "gnutls_num.h"
28 #include "x509_asn1.h"
30 #include "gnutls_datum.h"
31 #include <gnutls_random.h>
32 #include <gnutls_pk.h>
33 #include <gnutls_algorithms.h>
34 #include <gnutls_global.h>
35 #include <gnutls_record.h>
36 #include <x509_verify.h>
37 #include <gnutls_sig.h>
38 #include <x509_extensions.h>
39 #include <gnutls_state.h>
40 #include <gnutls_pk.h>
41 #include <gnutls_str.h>
44 #include <gnutls_privkey.h>
45 #include <gnutls_x509.h>
48 * some x509 certificate parsing functions.
51 int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum
* pkcs7_struct
, int indx
, char* certificate
, int* certificate_size
);
52 int gnutls_x509_pkcs7_extract_certificate_count(const gnutls_datum
* pkcs7_struct
);
55 #define _READ(a, aa, b, c, d, e, res, f) \
56 result = _IREAD(a, aa, sizeof(aa), b, c, d, e, res, sizeof(res)-1, f); \
57 if (result<0) return result; \
58 if (result==1) continue
61 static int _IREAD(node_asn
* rasn
, char *name3
, int name3_size
, char *rstr
, char *OID
,
62 char *ANAME
, char *TYPE
, char *res
, int res_size
, int CHOICE
)
69 if (strcmp(rstr
, OID
) == 0) {
71 _gnutls_str_cpy(str
, sizeof(str
), "PKIX1.");
72 _gnutls_str_cat(str
, sizeof(str
), ANAME
);
73 _gnutls_str_cpy(name2
, sizeof(name2
), "temp-structure-");
74 _gnutls_str_cat(name2
, sizeof(name2
), TYPE
);
77 asn1_create_structure(_gnutls_get_pkix(), str
,
78 &tmpasn
, name2
)) != ASN_OK
) {
80 return _gnutls_asn2err(result
);
85 asn1_read_value(rasn
, name3
, str
, &len
)) != ASN_OK
) {
86 asn1_delete_structure(tmpasn
);
90 if ((result
= asn1_get_der(tmpasn
, str
, len
)) != ASN_OK
) {
91 asn1_delete_structure(tmpasn
);
94 _gnutls_str_cpy(name3
, name3_size
, name2
);
96 len
= sizeof(str
) - 1;
97 if ((result
= asn1_read_value(tmpasn
, name3
, str
, &len
)) != ASN_OK
) { /* CHOICE */
98 asn1_delete_structure(tmpasn
);
104 /* strlen(str) < res_size, checked above */
105 _gnutls_str_cpy(res
, res_size
, str
);
107 } else { /* CHOICE */
109 _gnutls_str_cat(name3
, name3_size
, ".");
110 _gnutls_str_cat(name3
, name3_size
, str
);
111 len
= sizeof(str
) - 1;
114 asn1_read_value(tmpasn
, name3
, str
,
116 asn1_delete_structure(tmpasn
);
121 _gnutls_str_cpy(res
, res_size
, str
);
123 asn1_delete_structure(tmpasn
);
129 /* this function will convert up to 3 digit
130 * numbers to characters. Use a character string of MAX_INT_DIGITS, in
131 * order to have enough space for it.
133 void _gnutls_int2str(unsigned int k
, char *data
)
136 sprintf(data
, "%d", 999);
138 sprintf(data
, "%d", k
);
141 /* This function will attempt to read a Name
142 * ASN.1 structure. (Taken from Fabio's samples!)
144 * FIXME: These functions need carefull auditing
145 * (they're complex enough)
148 int _gnutls_x509_get_name_type(node_asn
* rasn
, char *root
, gnutls_DN
* dn
)
150 int k
, k2
, result
, len
;
151 char name
[128], str
[1024], name2
[128], counter
[MAX_INT_DIGITS
],
158 _gnutls_str_cpy(name
, sizeof(name
), root
);
159 _gnutls_str_cat(name
, sizeof(name
), ".rdnSequence.?");
160 _gnutls_int2str(k
, counter
);
161 _gnutls_str_cat(name
, sizeof(name
), counter
);
163 len
= sizeof(str
) - 1;
165 result
= asn1_read_value(rasn
, name
, str
, &len
);
169 if (result
== ASN_ELEMENT_NOT_FOUND
)
171 if (result
!= ASN_VALUE_NOT_FOUND
) {
173 return _gnutls_asn2err(result
);
180 _gnutls_str_cpy(name2
, sizeof(name2
), name
);
181 _gnutls_str_cat(name2
, sizeof(name2
), ".?");
182 _gnutls_int2str(k2
, counter
);
183 _gnutls_str_cat(name2
, sizeof(name2
), counter
);
185 len
= sizeof(str
) - 1;
186 result
= asn1_read_value(rasn
, name2
, str
, &len
);
188 if (result
== ASN_ELEMENT_NOT_FOUND
)
190 if (result
!= ASN_VALUE_NOT_FOUND
) {
192 return _gnutls_asn2err(result
);
195 _gnutls_str_cpy(name3
, sizeof(name3
), name2
);
196 _gnutls_str_cat(name3
, sizeof(name3
), ".type");
198 len
= sizeof(str
) - 1;
199 result
= asn1_read_value(rasn
, name3
, str
, &len
);
201 if (result
== ASN_ELEMENT_NOT_FOUND
)
203 else if (result
!= ASN_OK
) {
205 return _gnutls_asn2err(result
);
208 _gnutls_str_cpy(name3
, sizeof(name3
), name2
);
209 _gnutls_str_cat(name3
, sizeof(name3
), ".value");
211 if (result
== ASN_OK
) {
213 # warning " FIX COUNTRY HERE"
215 _READ(rasn
, name3
, str
, "2 5 4 6",
216 "X520OrganizationName",
217 "countryName", dn
->country
, 1);
218 _READ(rasn
, name3
, str
, "2 5 4 10",
219 "X520OrganizationName",
220 "OrganizationName", dn
->organization
,
222 _READ(rasn
, name3
, str
, "2 5 4 11",
223 "X520OrganizationalUnitName",
224 "OrganizationalUnitName",
225 dn
->organizational_unit_name
, 1);
226 _READ(rasn
, name3
, str
, "2 5 4 3",
227 "X520CommonName", "CommonName",
229 _READ(rasn
, name3
, str
, "2 5 4 7",
230 "X520LocalityName", "LocalityName",
231 dn
->locality_name
, 1);
232 _READ(rasn
, name3
, str
, "2 5 4 8",
233 "X520StateOrProvinceName",
234 "StateOrProvinceName",
235 dn
->state_or_province_name
, 1);
236 _READ(rasn
, name3
, str
,
237 "1 2 840 113549 1 9 1", "Pkcs9email",
238 "emailAddress", dn
->email
, 0);
243 if (result
== ASN_ELEMENT_NOT_FOUND
)
246 return _gnutls_asn2err(result
);
251 #define MAX_TIME 1024
252 time_t _gnutls_x509_get_time(node_asn
* c2
, char *root
, char *when
)
254 opaque ttime
[MAX_TIME
];
259 _gnutls_str_cpy(name
, sizeof(name
), root
);
260 _gnutls_str_cat(name
, sizeof(name
), ".tbsCertificate.validity.");
261 _gnutls_str_cat(name
, sizeof(name
), when
);
263 len
= sizeof(ttime
) - 1;
264 if ((result
= asn1_read_value(c2
, name
, ttime
, &len
)) < 0) {
266 return (time_t) (-1);
270 _gnutls_str_cpy(name
, sizeof(name
), root
);
272 if (strcmp(ttime
, "GeneralizedTime") == 0) {
274 _gnutls_str_cat(name
, sizeof(name
), ".tbsCertificate.validity.");
275 _gnutls_str_cat(name
, sizeof(name
), when
);
276 _gnutls_str_cat(name
, sizeof(name
), ".generalTime");
277 len
= sizeof(ttime
) - 1;
278 result
= asn1_read_value(c2
, name
, ttime
, &len
);
279 if (result
== ASN_OK
)
280 ctime
= _gnutls_x509_generalTime2gtime(ttime
);
281 } else { /* UTCTIME */
283 _gnutls_str_cat(name
, sizeof(name
), ".tbsCertificate.validity.");
284 _gnutls_str_cat(name
, sizeof(name
), when
);
285 _gnutls_str_cat(name
, sizeof(name
), ".utcTime");
286 len
= sizeof(ttime
) - 1;
287 result
= asn1_read_value(c2
, name
, ttime
, &len
);
288 if (result
== ASN_OK
)
289 ctime
= _gnutls_x509_utcTime2gtime(ttime
);
292 /* We cannot handle dates after 2031 in 32 bit machines.
293 * a time_t of 64bits has to be used.
296 if (result
!= ASN_OK
) {
298 return (time_t) (-1);
303 int _gnutls_x509_get_version(node_asn
* c2
, char *root
)
309 _gnutls_str_cpy(name
, sizeof(name
), root
);
310 _gnutls_str_cat(name
, sizeof(name
), ".tbsCertificate.version");
312 len
= sizeof(gversion
) - 1;
313 if ((result
= asn1_read_value(c2
, name
, gversion
, &len
)) < 0) {
317 return (int) gversion
[0] + 1;
325 * gnutls_x509_extract_dn - This function parses an RDN sequence
326 * @idn: should contain a DER encoded RDN sequence
327 * @rdn: a pointer to a structure to hold the name
329 * This function will return the name of the given RDN sequence.
330 * The name will be returned as a gnutls_x509_dn structure.
331 * Returns a negative error code in case of an error.
334 int gnutls_x509_extract_dn(const gnutls_datum
* idn
, gnutls_x509_dn
* rdn
)
340 asn1_create_structure(_gnutls_get_pkix(),
344 return _gnutls_asn2err(result
);
347 result
= asn1_get_der(dn
, idn
->data
, idn
->size
);
348 if (result
!= ASN_OK
) {
349 /* couldn't decode DER */
351 asn1_delete_structure(dn
);
352 return _gnutls_asn2err(result
);
355 result
= _gnutls_x509_get_name_type(dn
, "dn", rdn
);
356 asn1_delete_structure(dn
);
359 /* couldn't decode DER */
368 * gnutls_x509_extract_certificate_dn - This function returns the certificate's distinguished name
369 * @cert: should contain an X.509 DER encoded certificate
370 * @ret: a pointer to a structure to hold the peer's name
372 * This function will return the name of the certificate holder. The name is gnutls_x509_dn structure and
373 * is a obtained by the peer's certificate. If the certificate send by the
374 * peer is invalid, or in any other failure this function returns error.
375 * Returns a negative error code in case of an error.
378 int gnutls_x509_extract_certificate_dn(const gnutls_datum
* cert
,
379 gnutls_x509_dn
* ret
)
384 memset(ret
, 0, sizeof(gnutls_x509_dn
));
386 if ((result
=asn1_create_structure
387 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
391 return _gnutls_asn2err(result
);
395 result
= asn1_get_der(c2
, cert
->data
, cert
->size
);
396 if (result
!= ASN_OK
) {
397 /* couldn't decode DER */
399 _gnutls_log("X509_auth: Decoding error %d\n", result
);
402 asn1_delete_structure(c2
);
403 return _gnutls_asn2err(result
);
406 _gnutls_x509_get_name_type(c2
,
407 "certificate2.tbsCertificate.subject",
410 asn1_delete_structure(c2
);
414 asn1_delete_structure(c2
);
420 * gnutls_x509_extract_certificate_issuer_dn - This function returns the certificate's issuer distinguished name
421 * @cert: should contain an X.509 DER encoded certificate
422 * @ret: a pointer to a structure to hold the issuer's name
424 * This function will return the name of the issuer stated in the certificate. The name is a gnutls_x509_dn structure and
425 * is a obtained by the peer's certificate. If the certificate send by the
426 * peer is invalid, or in any other failure this function returns error.
427 * Returns a negative error code in case of an error.
430 int gnutls_x509_extract_certificate_issuer_dn(const gnutls_datum
* cert
,
431 gnutls_x509_dn
* ret
)
436 memset(ret
, 0, sizeof(gnutls_x509_dn
));
438 if ((result
=asn1_create_structure
439 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
443 return _gnutls_asn2err(result
);
446 result
= asn1_get_der(c2
, cert
->data
, cert
->size
);
447 if (result
!= ASN_OK
) {
448 /* couldn't decode DER */
450 _gnutls_log("X509_auth: Decoding error %d\n", result
);
453 asn1_delete_structure(c2
);
454 return _gnutls_asn2err(result
);
457 _gnutls_x509_get_name_type(c2
,
458 "certificate2.tbsCertificate.issuer",
461 asn1_delete_structure(c2
);
465 asn1_delete_structure(c2
);
470 static GNUTLS_X509_SUBJECT_ALT_NAME
_find_type( char* str_type
) {
471 if (strcmp( str_type
, "dNSName")==0) return GNUTLS_SAN_DNSNAME
;
472 if (strcmp( str_type
, "rfc822Name")==0) return GNUTLS_SAN_RFC822NAME
;
473 if (strcmp( str_type
, "uniformResourceIdentifier")==0) return GNUTLS_SAN_URI
;
474 if (strcmp( str_type
, "iPAddress")==0) return GNUTLS_SAN_IPADDRESS
;
479 * gnutls_x509_extract_certificate_subject_alt_name - This function returns the peer's alt name, if any
480 * @cert: should contain an X.509 DER encoded certificate
481 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
482 * @ret: is the place where the alternative name will be copied to
483 * @ret_size: holds the size of ret.
485 * This function will return the alternative names, contained in the
488 * This is specified in X509v3 Certificate Extensions.
489 * GNUTLS will return the Alternative name, or a negative
491 * Returns GNUTLS_E_INVALID_REQUEST if ret_size is not enough to hold the alternative name,
492 * or the type of alternative name if everything was ok. The type is one of the
493 * enumerated GNUTLS_X509_SUBJECT_ALT_NAME.
495 * If the certificate does not have an Alternative name with the specified sequence number
496 * then returns GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
499 int gnutls_x509_extract_certificate_subject_alt_name(const gnutls_datum
* cert
, int seq
, char *ret
, int *ret_size
)
502 gnutls_datum dnsname
;
507 char num
[MAX_INT_DIGITS
];
508 GNUTLS_X509_SUBJECT_ALT_NAME type
;
510 memset(ret
, 0, *ret_size
);
513 _gnutls_get_extension(cert
, "2 5 29 17", &dnsname
)) < 0) {
518 if (dnsname
.size
== 0 || dnsname
.data
==NULL
) {
520 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
523 if ((result
=asn1_create_structure
524 (_gnutls_get_pkix(), "PKIX1.SubjectAltName", &c2
, "san"))
527 gnutls_free_datum( &dnsname
);
528 return _gnutls_asn2err(result
);
531 result
= asn1_get_der(c2
, dnsname
.data
, dnsname
.size
);
532 gnutls_free_datum( &dnsname
);
534 if (result
!= ASN_OK
) {
535 /* couldn't decode DER */
537 _gnutls_log("X509_auth: Decoding error %d\n", result
);
539 asn1_delete_structure(c2
);
540 return _gnutls_asn2err(result
);
543 seq
++; /* 0->1, 1->2 etc */
544 _gnutls_int2str( seq
, num
);
545 _gnutls_str_cpy( nptr
, sizeof(nptr
), "san.?");
546 _gnutls_str_cat( nptr
, sizeof(nptr
), num
);
548 len
= sizeof(ext_data
);
550 asn1_read_value(c2
, nptr
, ext_data
, &len
);
552 if (result
== ASN_VALUE_NOT_FOUND
) {
553 asn1_delete_structure(c2
);
554 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
557 if (result
!= ASN_OK
) {
559 asn1_delete_structure(c2
);
560 return _gnutls_asn2err(result
);
564 type
= _find_type( ext_data
);
567 return GNUTLS_E_X509_UNKNOWN_SAN
;
570 _gnutls_str_cat( nptr
, sizeof(nptr
), ".");
571 _gnutls_str_cat( nptr
, sizeof(nptr
), ext_data
);
573 len
= sizeof(ext_data
);
576 asn1_read_value(c2
, nptr
, ret
, ret_size
);
577 asn1_delete_structure(c2
);
579 if (result
==ASN_MEM_ERROR
)
580 return GNUTLS_E_INVALID_REQUEST
;
582 if (result
!= ASN_OK
) {
584 return _gnutls_asn2err(result
);
591 * gnutls_x509_extract_certificate_activation_time - This function returns the peer's certificate activation time
592 * @cert: should contain an X.509 DER encoded certificate
594 * This function will return the certificate's activation time in UNIX time
595 * (ie seconds since 00:00:00 UTC January 1, 1970).
596 * Returns a (time_t) -1 in case of an error.
599 time_t gnutls_x509_extract_certificate_activation_time(const
607 if (asn1_create_structure
608 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
615 result
= asn1_get_der(c2
, cert
->data
, cert
->size
);
616 if (result
!= ASN_OK
) {
617 /* couldn't decode DER */
619 _gnutls_log("X509_auth: Decoding error %d\n", result
);
625 ret
= _gnutls_x509_get_time(c2
, "certificate2", "notBefore");
627 asn1_delete_structure(c2
);
633 * gnutls_x509_extract_certificate_expiration_time - This function returns the certificate's expiration time
634 * @cert: should contain an X.509 DER encoded certificate
636 * This function will return the certificate's expiration time in UNIX time
637 * (ie seconds since 00:00:00 UTC January 1, 1970).
638 * Returns a (time_t) -1 in case of an error.
641 time_t gnutls_x509_extract_certificate_expiration_time(const
649 if (asn1_create_structure
650 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
657 result
= asn1_get_der(c2
, cert
->data
, cert
->size
);
658 if (result
!= ASN_OK
) {
659 /* couldn't decode DER */
661 _gnutls_log("X509_auth: Decoding error %d\n", result
);
667 ret
= _gnutls_x509_get_time(c2
, "certificate2", "notAfter");
669 asn1_delete_structure(c2
);
675 * gnutls_x509_extract_certificate_version - This function returns the certificate's version
676 * @cert: is an X.509 DER encoded certificate
678 * This function will return the X.509 certificate's version (1, 2, 3). This is obtained by the X509 Certificate
679 * Version field. Returns a negative value in case of an error.
682 int gnutls_x509_extract_certificate_version(const gnutls_datum
* cert
)
687 if ((result
=asn1_create_structure
688 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
692 return _gnutls_asn2err(result
);
695 result
= asn1_get_der(c2
, cert
->data
, cert
->size
);
696 if (result
!= ASN_OK
) {
697 /* couldn't decode DER */
699 _gnutls_log("X509_auth: Decoding error %d\n", result
);
702 return _gnutls_asn2err(result
);
705 result
= _gnutls_x509_get_version(c2
, "certificate2");
707 asn1_delete_structure(c2
);
713 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(peer_certificate_list[x])
716 * _gnutls_x509_cert_verify_peers - This function returns the peer's certificate status
717 * @state: is a gnutls state
719 * This function will try to verify the peer's certificate and return it's status (TRUSTED, EXPIRED etc.).
720 * The return value (status) should be one of the CertificateStatus enumerated elements.
721 * However you must also check the peer's name in order to check if the verified certificate belongs to the
722 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
725 int _gnutls_x509_cert_verify_peers(GNUTLS_STATE state
)
727 CERTIFICATE_AUTH_INFO info
;
728 const GNUTLS_CERTIFICATE_CREDENTIALS cred
;
729 CertificateStatus verify
;
730 gnutls_cert
*peer_certificate_list
;
731 int peer_certificate_list_size
, i
, x
, ret
;
733 CHECK_AUTH(GNUTLS_CRD_CERTIFICATE
, GNUTLS_E_INVALID_REQUEST
);
735 info
= _gnutls_get_auth_info(state
);
738 return GNUTLS_E_INVALID_REQUEST
;
741 cred
= _gnutls_get_cred(state
->gnutls_key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
744 return GNUTLS_E_INSUFICIENT_CRED
;
747 if (info
->raw_certificate_list
== NULL
|| info
->ncerts
== 0)
748 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
750 /* generate a list of gnutls_certs based on the auth info
753 peer_certificate_list_size
= info
->ncerts
;
754 peer_certificate_list
=
756 peer_certificate_list_size
*
757 sizeof(gnutls_cert
));
758 if (peer_certificate_list
== NULL
) {
760 return GNUTLS_E_MEMORY_ERROR
;
763 for (i
= 0; i
< peer_certificate_list_size
; i
++) {
765 _gnutls_x509_cert2gnutls_cert(&peer_certificate_list
[i
],
767 raw_certificate_list
[i
])) <
771 gnutls_free(peer_certificate_list
);
776 /* Verify certificate
779 _gnutls_x509_verify_certificate(peer_certificate_list
,
780 peer_certificate_list_size
,
781 cred
->x509_ca_list
, cred
->x509_ncas
, NULL
, 0);
784 gnutls_free(peer_certificate_list
);
795 #define CLEAR_CERTS_CA for(x=0;x<peer_certificate_list_size;x++) _gnutls_free_cert(peer_certificate_list[x]); \
796 for(x=0;x<ca_certificate_list_size;x++) _gnutls_free_cert(ca_certificate_list[x])
798 * gnutls_x509_verify_certificate - This function verifies given certificate list
799 * @cert_list: is the certificate list to be verified
800 * @cert_list_length: holds the number of certificate in cert_list
801 * @CA_list: is the CA list which will be used in verification
802 * @CA_list_length: holds the number of CA certificate in CA_list
803 * @CRL_list: not used
804 * @CRL_list_length: not used
806 * This function will try to verify the given certificate list and return it's status (TRUSTED, EXPIRED etc.).
807 * The return value (status) should be one or more of the CertificateStatus
808 * enumerated elements bitwise or'd. Note that expiration and activation dates are not checked
809 * by this function, you should check them using the appropriate functions.
811 * However you must also check the peer's name in order to check if the verified certificate belongs to the
814 * The return value (status) should be one or more of the CertificateStatus
815 * enumerated elements bitwise or'd.
817 * GNUTLS_CERT_NOT_TRUSTED\: the peer's certificate is not trusted.
819 * GNUTLS_CERT_INVALID\: the certificate chain is broken.
821 * GNUTLS_CERT_REVOKED\: the certificate has been revoked
822 * (not implemented yet).
824 * GNUTLS_CERT_CORRUPTED\: the certificate is corrupted.
826 * A negative error code is returned in case of an error.
827 * GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that
828 * no certificate was sent by the peer.
832 int gnutls_x509_verify_certificate( const gnutls_datum
* cert_list
, int cert_list_length
, const gnutls_datum
* CA_list
, int CA_list_length
, const gnutls_datum
* CRL_list
, int CRL_list_length
)
834 CertificateStatus verify
;
835 gnutls_cert
*peer_certificate_list
;
836 gnutls_cert
*ca_certificate_list
;
837 int peer_certificate_list_size
, i
, x
, ret
, ca_certificate_list_size
;
839 if (cert_list
== NULL
|| cert_list_length
== 0)
840 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
842 /* generate a list of gnutls_certs based on the auth info
845 peer_certificate_list_size
= cert_list_length
;
846 peer_certificate_list
=
848 peer_certificate_list_size
*
849 sizeof(gnutls_cert
));
850 if (peer_certificate_list
== NULL
) {
852 return GNUTLS_E_MEMORY_ERROR
;
855 ca_certificate_list_size
= CA_list_length
;
856 ca_certificate_list
=
858 ca_certificate_list_size
*
859 sizeof(gnutls_cert
));
860 if (ca_certificate_list
== NULL
) {
862 gnutls_free( peer_certificate_list
);
863 return GNUTLS_E_MEMORY_ERROR
;
866 /* convert certA_list to gnutls_cert* list
868 for (i
= 0; i
< peer_certificate_list_size
; i
++) {
870 _gnutls_x509_cert2gnutls_cert(&peer_certificate_list
[i
],
871 cert_list
[i
])) < 0) {
874 gnutls_free( peer_certificate_list
);
875 gnutls_free( ca_certificate_list
);
880 /* convert CA_list to gnutls_cert* list
882 for (i
= 0; i
< ca_certificate_list_size
; i
++) {
884 _gnutls_x509_cert2gnutls_cert(&ca_certificate_list
[i
],
888 gnutls_free( peer_certificate_list
);
889 gnutls_free( ca_certificate_list
);
894 /* Verify certificate
897 _gnutls_x509_verify_certificate(peer_certificate_list
,
898 peer_certificate_list_size
,
899 ca_certificate_list
, ca_certificate_list_size
, NULL
, 0);
902 gnutls_free( peer_certificate_list
);
903 gnutls_free( ca_certificate_list
);
914 * gnutls_x509_extract_certificate_serial - This function returns the certificate's serial number
915 * @cert: is an X.509 DER encoded certificate
916 * @result: The place where the serial number will be copied
917 * @result_size: Holds the size of the result field.
919 * This function will return the X.509 certificate's serial number.
920 * This is obtained by the X509 Certificate serialNumber
921 * field. Serial is not always a 32 or 64bit number. Some CAs use
922 * large serial numbers, thus it may be wise to handle it as something
924 * Returns a negative value in case of an error.
927 int gnutls_x509_extract_certificate_serial(const gnutls_datum
* cert
, char* result
, int* result_size
)
932 if ((ret
=asn1_create_structure
933 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
940 ret
= asn1_get_der(c2
, cert
->data
, cert
->size
);
942 /* couldn't decode DER */
944 _gnutls_log("X509_auth: Decoding error %d\n", result
);
950 if ((ret
= asn1_read_value(c2
, "certificate2.tbsCertificate.serialNumber", result
, result_size
)) < 0) {
952 asn1_delete_structure(c2
);
956 asn1_delete_structure(c2
);
964 * Read certificates and private keys, from files, memory etc.
967 /* returns error if the certificate has different algorithm than
968 * the given key parameters.
970 static int _gnutls_check_key_cert_match( GNUTLS_CERTIFICATE_CREDENTIALS res
) {
972 if (res
->pkey
[res
->ncerts
-1].pk_algorithm
!= res
->cert_list
[res
->ncerts
-1][0].subject_pk_algorithm
) {
974 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH
;
979 #define MAX_FILE_SIZE 100*1024
980 #define CERT_SEP "-----BEGIN"
982 /* Reads a DER encoded certificate list from memory and stores it to
983 * a gnutls_cert structure. This is only called if PKCS7 read fails.
984 * returns the number of certificates parsed (1)
986 static int parse_der_cert_mem( gnutls_cert
** cert_list
, int* ncerts
,
987 const char *input_cert
, int input_cert_size
)
996 (gnutls_cert
*) gnutls_realloc( *cert_list
,
998 sizeof(gnutls_cert
));
1000 if ( *cert_list
== NULL
) {
1002 return GNUTLS_E_MEMORY_ERROR
;
1005 tmp
.data
= (opaque
*) input_cert
;
1006 tmp
.size
= input_cert_size
;
1009 _gnutls_x509_cert2gnutls_cert(
1010 &cert_list
[0][i
- 1],
1018 return 1; /* one certificate parsed */
1022 /* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
1023 * a gnutls_cert structure.
1024 * returns the number of certificate parsed
1026 static int parse_pkcs7_cert_mem( gnutls_cert
** cert_list
, int* ncerts
,
1027 const char *input_cert
, int input_cert_size
)
1030 gnutls_datum tmp
, tmp2
;
1032 opaque pcert
[MAX_X509_CERT_SIZE
];
1037 /* tmp now contains the decoded certificate list */
1038 tmp
.data
= (opaque
*)input_cert
;
1039 tmp
.size
= input_cert_size
;
1041 count
= gnutls_x509_pkcs7_extract_certificate_count( &tmp
);
1045 /* if we failed to read the count,
1046 * then just try to decode a plain DER
1049 return parse_der_cert_mem( cert_list
, ncerts
,
1050 input_cert
, input_cert_size
);
1056 pcert_size
= sizeof(pcert
);
1057 ret
= gnutls_x509_pkcs7_extract_certificate( &tmp
, j
, pcert
, &pcert_size
);
1060 /* if the current certificate is too long, just ignore
1062 if (ret
==GNUTLS_E_MEMORY_ERROR
) {
1069 (gnutls_cert
*) gnutls_realloc( *cert_list
,
1070 i
* sizeof(gnutls_cert
));
1072 if ( *cert_list
== NULL
) {
1074 return GNUTLS_E_MEMORY_ERROR
;
1078 tmp2
.size
= pcert_size
;
1081 _gnutls_x509_cert2gnutls_cert(
1082 &cert_list
[0][i
- 1],
1091 } while (ret
>= 0 && j
>= 0);
1099 /* Reads a base64 encoded certificate list from memory and stores it to
1100 * a gnutls_cert structure. Returns the number of certificate parsed.
1102 static int parse_pem_cert_mem( gnutls_cert
** cert_list
, int* ncerts
,
1103 const char *input_cert
, int input_cert_size
)
1111 if (strstr( input_cert
, "-----BEGIN PKCS7")!=NULL
) {
1112 siz2
= _gnutls_fbase64_decode(ptr
, siz
, &b64
);
1114 ret
= parse_pkcs7_cert_mem( cert_list
, ncerts
, b64
,
1124 siz
= input_cert_size
;
1129 siz2
= _gnutls_fbase64_decode(ptr
, siz
, &b64
);
1130 siz
-= siz2
; /* FIXME: this is not enough
1135 return GNUTLS_E_PARSING_ERROR
;
1140 (gnutls_cert
*) gnutls_realloc( *cert_list
,
1142 sizeof(gnutls_cert
));
1144 if ( *cert_list
== NULL
) {
1147 return GNUTLS_E_MEMORY_ERROR
;
1154 _gnutls_x509_cert2gnutls_cert(
1155 &cert_list
[0][i
- 1],
1163 /* now we move ptr after the pem header */
1164 ptr
= strstr(ptr
, CERT_SEP
);
1170 } while ((ptr
= strstr(ptr
, CERT_SEP
)) != NULL
);
1179 /* Reads a base64 encoded certificate from memory
1181 static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res
, const char *cert
, int cert_size
,
1182 GNUTLS_X509_CertificateFmt type
)
1186 /* allocate space for the certificate to add
1188 res
->cert_list
= gnutls_realloc( res
->cert_list
, (1+ res
->ncerts
)*sizeof(gnutls_cert
*));
1189 if ( res
->cert_list
==NULL
) {
1191 return GNUTLS_E_MEMORY_ERROR
;
1194 res
->cert_list_length
= gnutls_realloc( res
->cert_list_length
,
1195 (1+ res
->ncerts
)*sizeof(int));
1196 if (res
->cert_list_length
==NULL
) {
1198 return GNUTLS_E_MEMORY_ERROR
;
1201 res
->cert_list
[res
->ncerts
] = NULL
; /* for realloc */
1202 res
->cert_list_length
[res
->ncerts
] = 0;
1204 if (type
==GNUTLS_X509_FMT_DER
)
1205 ret
= parse_pkcs7_cert_mem( &res
->cert_list
[res
->ncerts
], &res
->cert_list_length
[res
->ncerts
],
1208 ret
= parse_pem_cert_mem( &res
->cert_list
[res
->ncerts
], &res
->cert_list_length
[res
->ncerts
],
1219 /* Reads a base64 encoded CA list from memory
1220 * This is to be called once.
1222 static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res
, const char *ca
, int ca_size
,
1223 GNUTLS_X509_CertificateFmt type
)
1226 if (type
==GNUTLS_X509_FMT_DER
)
1227 return parse_der_cert_mem( &res
->x509_ca_list
, &res
->x509_ncas
,
1230 return parse_pem_cert_mem( &res
->x509_ca_list
, &res
->x509_ncas
,
1236 /* This will check if the given DER key is a PKCS-1 RSA key.
1238 int _gnutls_der_check_if_rsa_key(const gnutls_datum
* key_struct
)
1244 /* Step 1. Parse content and content info */
1246 if (key_struct
->size
== 0 || key_struct
->data
== NULL
) {
1248 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1251 _gnutls_str_cpy( root2
, sizeof(root2
), "GNUTLS.RSAPrivateKey");
1252 if ((result
=asn1_create_structure
1253 (_gnutls_get_gnutls_asn(), root2
, &c2
, "rsakey")) != ASN_OK
) {
1255 return _gnutls_asn2err(result
);
1258 result
= asn1_get_der(c2
, key_struct
->data
, key_struct
->size
);
1259 asn1_delete_structure(c2
);
1261 if (result
!= ASN_OK
) {
1262 /* couldn't decode DER */
1265 return _gnutls_asn2err(result
);
1275 /* Reads a PEM encoded PKCS-1 RSA private key from memory
1276 * 2002-01-26: Added ability to read DSA keys.
1277 * type==0 then certificate is DER formatted, else -> DER
1279 static int read_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res
, const char *key
, int key_size
,
1280 GNUTLS_X509_CertificateFmt type
)
1287 /* allocate space for the pkey list
1289 res
->pkey
= gnutls_realloc( res
->pkey
, (res
->ncerts
+1)*sizeof(gnutls_private_key
));
1290 if (res
->pkey
==NULL
) {
1292 return GNUTLS_E_MEMORY_ERROR
;
1295 /* read PKCS-1 private key */
1297 if (type
==GNUTLS_X509_FMT_DER
) { /* DER */
1300 tmp
.data
= (opaque
*)key
;
1301 tmp
.size
= key_size
;
1303 /* The only way to distinguish the keys
1304 * is to count the sequence of integers.
1306 cv
= _gnutls_der_check_if_rsa_key( &tmp
);
1314 /* If we find the "DSA PRIVATE" string in the
1315 * pem encoded certificate then it's a DSA key.
1317 if (strstr( key
, "DSA PRIVATE")!=NULL
)
1322 ret
= _gnutls_fbase64_decode(key
, key_size
, &b64
);
1326 return GNUTLS_E_PARSING_ERROR
;
1333 switch (pk
) { /* decode the key */
1336 _gnutls_PKCS1key2gnutlsKey(&res
->pkey
[res
->ncerts
],
1345 _gnutls_DSAkey2gnutlsKey(&res
->pkey
[res
->ncerts
],
1354 /* this doesn't hurt in the DER case, since
1363 /* Reads a certificate file
1365 static int read_cert_file(GNUTLS_CERTIFICATE_CREDENTIALS res
, char *certfile
,
1366 GNUTLS_X509_CertificateFmt type
)
1369 char x
[MAX_FILE_SIZE
];
1372 fd1
= fopen(certfile
, "rb");
1374 return GNUTLS_E_FILE_ERROR
;
1376 siz
= fread(x
, 1, sizeof(x
)-1, fd1
);
1381 return read_cert_mem( res
, x
, siz
, type
);
1385 /* Reads a base64 encoded CA file (file contains multiple certificate
1386 * authorities). This is to be called once.
1388 static int read_ca_file(GNUTLS_CERTIFICATE_CREDENTIALS res
, char *cafile
,
1389 GNUTLS_X509_CertificateFmt type
)
1392 char x
[MAX_FILE_SIZE
];
1395 fd1
= fopen(cafile
, "rb");
1398 return GNUTLS_E_FILE_ERROR
;
1401 siz
= fread(x
, 1, sizeof(x
)-1, fd1
);
1406 return read_ca_mem( res
, x
, siz
, type
);
1410 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
1413 static int read_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res
, char *keyfile
,
1414 GNUTLS_X509_CertificateFmt type
)
1417 char x
[MAX_FILE_SIZE
];
1420 fd2
= fopen(keyfile
, "rb");
1422 return GNUTLS_E_FILE_ERROR
;
1424 siz
= fread(x
, 1, sizeof(x
)-1, fd2
);
1429 return read_key_mem( res
, x
, siz
, type
);
1434 * gnutls_certificate_set_x509_key_file - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure
1435 * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
1436 * @CERTFILE: is a file that containing the certificate list (path) for
1437 * the specified private key, in PKCS7 format, or a list of certificates
1438 * @KEYFILE: is a file that contains the private key
1439 * @type: is PEM or DER
1441 * This function sets a certificate/private key pair in the
1442 * GNUTLS_CERTIFICATE_CREDENTIALS structure. This function may be called
1443 * more than once (in case multiple keys/certificates exist for the
1446 * Currently only PKCS-1 encoded RSA and DSA private keys are accepted by
1450 int gnutls_certificate_set_x509_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res
, char *CERTFILE
,
1451 char *KEYFILE
, GNUTLS_X509_CertificateFmt type
)
1455 /* this should be first
1457 if ((ret
= read_key_file(res
, KEYFILE
, type
)) < 0)
1460 if ((ret
= read_cert_file(res
, CERTFILE
, type
)) < 0)
1465 if ((ret
=_gnutls_check_key_cert_match( res
)) < 0) {
1473 static int generate_rdn_seq( GNUTLS_CERTIFICATE_CREDENTIALS res
) {
1478 /* Generate the RDN sequence
1479 * This will be sent to clients when a certificate
1480 * request message is sent.
1483 /* FIXME: in case of a client it is not needed
1484 * to do that. This would save time and memory.
1485 * However we don't have that information available
1490 for (i
= 0; i
< res
->x509_ncas
; i
++) {
1491 if ((ret
= _gnutls_find_dn(&tmp
, &res
->x509_ca_list
[i
])) < 0) {
1495 size
+= (2 + tmp
.size
);
1498 if (res
->x509_rdn_sequence
.data
!= NULL
)
1499 gnutls_free( res
->x509_rdn_sequence
.data
);
1501 res
->x509_rdn_sequence
.data
= gnutls_malloc(size
);
1502 if (res
->x509_rdn_sequence
.data
== NULL
) {
1504 return GNUTLS_E_MEMORY_ERROR
;
1506 res
->x509_rdn_sequence
.size
= size
;
1508 pdata
= res
->x509_rdn_sequence
.data
;
1510 for (i
= 0; i
< res
->x509_ncas
; i
++) {
1511 if ((ret
= _gnutls_find_dn(&tmp
, &res
->x509_ca_list
[i
])) < 0) {
1512 gnutls_free(res
->x509_rdn_sequence
.data
);
1513 res
->x509_rdn_sequence
.size
= 0;
1514 res
->x509_rdn_sequence
.data
= NULL
;
1518 WRITEdatum16(pdata
, tmp
);
1519 pdata
+= (2 + tmp
.size
);
1526 * gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure
1527 * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
1528 * @CA: is a list of trusted CAs or a DER certificate
1529 * @type: is DER or PEM
1531 * This function adds the trusted CAs in order to verify client
1532 * certificates. This function may be called multiple times.
1535 int gnutls_certificate_set_x509_trust_mem(GNUTLS_CERTIFICATE_CREDENTIALS res
,
1536 const gnutls_datum
*CA
, GNUTLS_X509_CertificateFmt type
)
1540 if ((ret
= read_ca_mem(res
, CA
->data
, CA
->size
, type
)) < 0)
1543 if ((ret2
= generate_rdn_seq(res
)) < 0)
1550 * gnutls_certificate_set_x509_trust_file - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure
1551 * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
1552 * @CAFILE: is a file containing the list of trusted CAs (DER or PEM list)
1553 * @type: is PEM or DER
1555 * This function sets the trusted CAs in order to verify client
1556 * certificates. This function may be called multiple times.
1557 * Returns the number of certificate processed.
1560 int gnutls_certificate_set_x509_trust_file(GNUTLS_CERTIFICATE_CREDENTIALS res
,
1561 char *CAFILE
, GNUTLS_X509_CertificateFmt type
)
1565 if ((ret
= read_ca_file(res
, CAFILE
, type
)) < 0)
1568 if ((ret2
= generate_rdn_seq(res
)) < 0)
1576 * gnutls_certificate_set_x509_key_mem - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure
1577 * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
1578 * @CERT: contains a certificate list (path) for the specified private key
1579 * @KEY: is the private key
1580 * @type: is PEM or DER
1582 * This function sets a certificate/private key pair in the
1583 * GNUTLS_CERTIFICATE_CREDENTIALS structure. This function may be called
1584 * more than once (in case multiple keys/certificates exist for the
1587 * Currently are supported: RSA PKCS-1 encoded private keys,
1590 * DSA private keys are encoded the OpenSSL way, which is an ASN.1
1591 * DER sequence of 6 INTEGERs - version, p, q, g, pub, priv.
1594 int gnutls_certificate_set_x509_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res
, const gnutls_datum
* CERT
,
1595 const gnutls_datum
* KEY
, GNUTLS_X509_CertificateFmt type
)
1599 /* this should be first
1601 if ((ret
= read_key_mem( res
, KEY
->data
, KEY
->size
, type
)) < 0)
1604 if ((ret
= read_cert_mem( res
, CERT
->data
, CERT
->size
, type
)) < 0)
1607 if ((ret
=_gnutls_check_key_cert_match( res
)) < 0) {
1617 static int _read_rsa_params(opaque
* der
, int dersize
, MPI
* params
)
1619 opaque str
[MAX_PARAMETER_SIZE
];
1623 if ((result
=asn1_create_structure
1624 (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk
,
1625 "rsa_public_key")) != ASN_OK
) {
1627 return _gnutls_asn2err(result
);
1630 result
= asn1_get_der(spk
, der
, dersize
);
1632 if (result
!= ASN_OK
) {
1634 asn1_delete_structure(spk
);
1635 return _gnutls_asn2err(result
);
1639 if ( (result
=_gnutls_x509_read_int( spk
, "rsa_public_key.modulus",
1640 str
, sizeof(str
)-1, ¶ms
[0])) < 0) {
1642 asn1_delete_structure(spk
);
1643 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1646 if ( (result
=_gnutls_x509_read_int( spk
, "rsa_public_key.publicExponent",
1647 str
, sizeof(str
)-1, ¶ms
[1])) < 0) {
1649 _gnutls_mpi_release(¶ms
[0]);
1650 asn1_delete_structure(spk
);
1651 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1654 asn1_delete_structure(spk
);
1662 * from the certificate
1665 static int _read_dsa_params(opaque
* der
, int dersize
, MPI
* params
)
1667 opaque str
[MAX_PARAMETER_SIZE
];
1671 if ((result
=asn1_create_structure
1672 (_gnutls_get_pkix(), "PKIX1.Dss-Parms", &spk
,
1673 "dsa_parms")) != ASN_OK
) {
1675 return _gnutls_asn2err(result
);
1678 result
= asn1_get_der(spk
, der
, dersize
);
1680 if (result
!= ASN_OK
) {
1682 asn1_delete_structure(spk
);
1683 return _gnutls_asn2err(result
);
1686 /* FIXME: If the parameters are not included in the certificate
1687 * then the issuer's parameters should be used.
1692 if ( (result
=_gnutls_x509_read_int( spk
, "dsa_parms.p", str
, sizeof(str
)-1, ¶ms
[0])) < 0) {
1694 asn1_delete_structure(spk
);
1695 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1700 if ( (result
=_gnutls_x509_read_int( spk
, "dsa_parms.q", str
, sizeof(str
)-1, ¶ms
[1])) < 0) {
1702 asn1_delete_structure(spk
);
1703 _gnutls_mpi_release(¶ms
[0]);
1704 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1709 if ( (result
=_gnutls_x509_read_int( spk
, "dsa_parms.g", str
, sizeof(str
)-1, ¶ms
[2])) < 0) {
1711 asn1_delete_structure(spk
);
1712 _gnutls_mpi_release(¶ms
[0]);
1713 _gnutls_mpi_release(¶ms
[1]);
1714 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1717 asn1_delete_structure(spk
);
1724 * from the certificate
1727 static int _read_dsa_pubkey(opaque
* der
, int dersize
, MPI
* params
)
1729 opaque str
[MAX_PARAMETER_SIZE
];
1733 if ( (result
=asn1_create_structure
1734 (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk
,
1735 "dsa_public_key")) != ASN_OK
) {
1737 return _gnutls_asn2err(result
);
1740 result
= asn1_get_der(spk
, der
, dersize
);
1742 if (result
!= ASN_OK
) {
1744 asn1_delete_structure(spk
);
1745 return _gnutls_asn2err(result
);
1750 if ( (result
=_gnutls_x509_read_int( spk
, "dsa_public_key", str
, sizeof(str
)-1, ¶ms
[3])) < 0) {
1752 asn1_delete_structure(spk
);
1753 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1756 asn1_delete_structure(spk
);
1762 #define PKIX1_RSA_OID "1 2 840 113549 1 1 1"
1763 #define DSA_OID "1 2 840 10040 4 1"
1765 /* Extracts DSA and RSA parameters from a certificate.
1768 int _gnutls_extract_x509_cert_mpi_params( const char* ALGO_OID
, gnutls_cert
* gCert
,
1769 node_asn
* c2
, char* tmpstr
, int tmpstr_size
) {
1772 len
= tmpstr_size
- 1;
1775 (c2
, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
1778 if (result
!= ASN_OK
) {
1780 return _gnutls_asn2err(result
);
1783 if (strcmp( ALGO_OID
, PKIX1_RSA_OID
) == 0) { /* pkix-1 1 - RSA */
1784 /* params[0] is the modulus,
1785 * params[1] is the exponent
1787 gCert
->subject_pk_algorithm
= GNUTLS_PK_RSA
;
1789 if ((sizeof(gCert
->params
) / sizeof(MPI
)) < RSA_PUBLIC_PARAMS
) {
1791 /* internal error. Increase the MPIs in params */
1792 return GNUTLS_E_INTERNAL_ERROR
;
1796 _read_rsa_params(tmpstr
, len
/ 8, gCert
->params
)) < 0) {
1800 gCert
->params_size
= RSA_PUBLIC_PARAMS
;
1805 if (strcmp( ALGO_OID
, DSA_OID
) == 0) {
1811 gCert
->subject_pk_algorithm
= GNUTLS_PK_DSA
;
1813 if ((sizeof(gCert
->params
) / sizeof(MPI
)) < DSA_PUBLIC_PARAMS
) {
1815 /* internal error. Increase the MPIs in params */
1816 return GNUTLS_E_INTERNAL_ERROR
;
1820 _read_dsa_pubkey(tmpstr
, len
/ 8, gCert
->params
)) < 0) {
1825 /* Now read the parameters
1827 len
= tmpstr_size
- 1;
1830 (c2
, "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",
1833 if (result
!= ASN_OK
) {
1835 return _gnutls_asn2err(result
);
1839 _read_dsa_params(tmpstr
, len
, gCert
->params
)) < 0) {
1843 gCert
->params_size
= DSA_PUBLIC_PARAMS
;
1849 /* other types like DH
1850 * currently not supported
1854 _gnutls_log("CERT: ALGORITHM: %s\n", ALGO_OID
);
1856 gCert
->subject_pk_algorithm
= GNUTLS_PK_UNKNOWN
;
1858 return GNUTLS_E_INVALID_PARAMETERS
;
1863 #define X509_SIG_SIZE 1024
1865 /* This function will convert a der certificate, to a format
1866 * (structure) that gnutls can understand and use. Actually the
1867 * important thing on this function is that it extracts the
1868 * certificate's (public key) parameters.
1870 int _gnutls_x509_cert2gnutls_cert(gnutls_cert
* gCert
, gnutls_datum derCert
)
1874 opaque str
[MAX_X509_CERT_SIZE
];
1876 int len
= sizeof(str
);
1878 memset(gCert
, 0, sizeof(gnutls_cert
));
1881 gCert
->cert_type
= GNUTLS_CRT_X509
;
1883 if (gnutls_set_datum(&gCert
->raw
, derCert
.data
, derCert
.size
) < 0) {
1885 return GNUTLS_E_MEMORY_ERROR
;
1888 if ((result
=asn1_create_structure
1889 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
1893 gnutls_free_datum( &gCert
->raw
);
1894 return _gnutls_asn2err(result
);
1897 result
= asn1_get_der(c2
, derCert
.data
, derCert
.size
);
1898 if (result
!= ASN_OK
) {
1899 /* couldn't decode DER */
1901 _gnutls_log("CERT: Decoding error %d\n", result
);
1904 asn1_delete_structure(c2
);
1905 gnutls_free_datum( &gCert
->raw
);
1906 return _gnutls_asn2err(result
);
1909 len
= sizeof(oid
) - 1;
1913 "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
1916 if (result
!= ASN_OK
) {
1918 asn1_delete_structure(c2
);
1919 gnutls_free_datum( &gCert
->raw
);
1920 return _gnutls_asn2err(result
);
1923 if ( (result
=_gnutls_extract_x509_cert_mpi_params( oid
, gCert
, c2
, str
, sizeof(str
))) < 0) {
1925 asn1_delete_structure(c2
);
1926 gnutls_free_datum( &gCert
->raw
);
1930 len
= gCert
->signature
.size
= X509_SIG_SIZE
;
1931 gCert
->signature
.data
= gnutls_malloc( gCert
->signature
.size
);
1932 if (gCert
->signature
.data
==NULL
) {
1934 return GNUTLS_E_MEMORY_ERROR
;
1939 (c2
, "certificate2.signature", gCert
->signature
.data
, &len
);
1941 if ((len
% 8) != 0) {
1943 asn1_delete_structure(c2
);
1944 gnutls_free_datum( &gCert
->raw
);
1945 gnutls_free_datum( &gCert
->signature
);
1946 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
1949 len
/= 8; /* convert to bytes */
1950 gCert
->signature
.size
= len
; /* put the actual sig size */
1953 gCert
->expiration_time
=
1954 _gnutls_x509_get_time(c2
, "certificate2", "notAfter");
1955 gCert
->activation_time
=
1956 _gnutls_x509_get_time(c2
, "certificate2", "notBefore");
1958 gCert
->version
= _gnutls_x509_get_version(c2
, "certificate2");
1959 if (gCert
->version
< 0) {
1961 asn1_delete_structure(c2
);
1962 gnutls_free_datum( &gCert
->raw
);
1963 return GNUTLS_E_ASN1_GENERIC_ERROR
;
1967 _gnutls_get_ext_type(c2
,
1968 "certificate2.tbsCertificate.extensions",
1971 asn1_delete_structure(c2
);
1972 gnutls_free_datum( &gCert
->raw
);
1976 asn1_delete_structure(c2
);
1979 gCert
->valid
= 0; /* if we got until here
1980 * the certificate is valid.
1987 /* Returns 0 if it's ok to use the KXAlgorithm with this cert
1988 * (using KeyUsage field).
1990 int _gnutls_check_x509_key_usage(const gnutls_cert
* cert
,
1993 if (_gnutls_map_kx_get_cred(alg
) == GNUTLS_CRD_CERTIFICATE
) {
1996 if (cert
->keyUsage
!= 0) {
1999 keyUsage
& GNUTLS_X509KEY_KEY_ENCIPHERMENT
))
2001 GNUTLS_E_X509_KEY_USAGE_VIOLATION
;
2006 case GNUTLS_KX_DHE_RSA
:
2007 case GNUTLS_KX_DHE_DSS
:
2008 if (cert
->keyUsage
!= 0) {
2011 keyUsage
& GNUTLS_X509KEY_DIGITAL_SIGNATURE
))
2013 GNUTLS_E_X509_KEY_USAGE_VIOLATION
;
2020 return GNUTLS_E_X509_KEY_USAGE_VIOLATION
;
2028 /* Verifies a base64 encoded certificate list from memory
2030 int _gnutls_verify_x509_mem( const char *ca
, int ca_size
)
2037 gnutls_cert
* x509_ca_list
=NULL
;
2047 siz2
= _gnutls_fbase64_decode(ptr
, siz
, &b64
);
2048 siz
-= siz2
; /* FIXME: this is not enough
2053 return GNUTLS_E_PARSING_ERROR
;
2057 (gnutls_cert
*) gnutls_realloc( x509_ca_list
,
2059 sizeof(gnutls_cert
));
2060 if (x509_ca_list
== NULL
) {
2063 return GNUTLS_E_MEMORY_ERROR
;
2070 _gnutls_x509_cert2gnutls_cert(&x509_ca_list
[i
- 1],
2078 /* now we move ptr after the pem header */
2079 ptr
= strstr(ptr
, CERT_SEP
);
2084 } while ((ptr
= strstr(ptr
, CERT_SEP
)) != NULL
);
2088 siz
= _gnutls_x509_verify_certificate( x509_ca_list
, x509_ncas
-1,
2089 &x509_ca_list
[x509_ncas
-1], 1, NULL
, 0);
2096 /* Reads and verifies a base64 encoded certificate file
2098 int _gnutls_verify_x509_file( char *cafile
)
2101 char x
[MAX_FILE_SIZE
];
2104 fd1
= fopen(cafile
, "rb");
2107 return GNUTLS_E_FILE_ERROR
;
2110 siz
= fread(x
, 1, sizeof(x
)-1, fd1
);
2115 return _gnutls_verify_x509_mem( x
, siz
);
2123 * gnutls_x509_pkcs7_extract_certificate - This function returns a certificate in a PKCS7 certificate set
2124 * @pkcs7_struct: should contain a PKCS7 DER formatted structure
2125 * @indx: contains the index of the certificate to extract
2126 * @certificate: the contents of the certificate will be copied there
2127 * @certificate_size: should hold the size of the certificate
2129 * This function will return a certificate of the PKCS7 or RFC2630 certificate set.
2130 * Returns 0 on success. If the provided buffer is not long enough,
2131 * then GNUTLS_E_INVALID_REQUEST is returned.
2134 int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum
* pkcs7_struct
, int indx
, char* certificate
, int* certificate_size
)
2141 char counter
[MAX_INT_DIGITS
];
2142 opaque
* pkcs7_str
= pkcs7_struct
->data
;
2143 int pkcs7_str_size
= pkcs7_struct
->size
;
2148 /* Step 1. Parse content and content info */
2150 if (pkcs7_str_size
== 0 || pkcs7_str
== NULL
) {
2152 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2155 _gnutls_str_cpy( root1
, sizeof(root1
), "PKIX1.ContentInfo");
2156 if ((result
=asn1_create_structure
2157 (_gnutls_get_pkix(), root1
, &c1
, "c1")) != ASN_OK
) {
2159 return _gnutls_asn2err(result
);
2162 result
= asn1_get_der(c1
, pkcs7_str
, pkcs7_str_size
);
2163 if (result
!= ASN_OK
) {
2164 /* couldn't decode DER */
2167 asn1_delete_structure(c1
);
2168 return _gnutls_asn2err(result
);
2171 len
= sizeof(oid
) - 1;
2173 /* root2 is used as a temp storage area
2175 _gnutls_str_cpy( root2
, sizeof(root2
), "c1.contentType");
2176 result
= asn1_read_value(c1
, root2
, oid
, &len
);
2177 if (result
!= ASN_OK
) {
2179 asn1_delete_structure(c1
);
2180 return _gnutls_asn2err(result
);
2183 if ( strcmp( oid
, "1 2 840 113549 1 7 2") != 0) {
2185 asn1_delete_structure(c1
);
2186 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2189 pcert_size
= *certificate_size
- 1;
2190 pcert
= certificate
;
2192 _gnutls_str_cpy( root2
, sizeof(root2
), "c1.content");
2193 result
= asn1_read_value(c1
, root2
, pcert
, &pcert_size
);
2195 asn1_delete_structure(c1
);
2197 if (result
!= ASN_OK
) {
2199 return _gnutls_asn2err(result
);
2202 /* pcert, pcert_size hold the data and the size of the CertificateSet structure
2203 * actually the ANY stuff.
2207 /* Step 1.5. In case of a signed structure extract certificate set.
2209 _gnutls_str_cpy( root2
, sizeof(root2
), "PKIX1.SignedData");
2210 if ((result
=asn1_create_structure
2211 (_gnutls_get_pkix(), root2
, &c2
, "c2")) != ASN_OK
) {
2213 return _gnutls_asn2err(result
);
2216 result
= asn1_get_der(c2
, pcert
, pcert_size
);
2217 if (result
!= ASN_OK
) {
2218 /* couldn't decode DER */
2221 asn1_delete_structure(c2
);
2222 return _gnutls_asn2err(result
);
2226 /* Step 2. Parse CertificateSet */
2229 _gnutls_str_cpy( root2
, sizeof(root2
), "c2.certificates.?");
2230 _gnutls_int2str( indx
+1, counter
);
2231 _gnutls_str_cat( root2
, sizeof(root2
), counter
);
2233 len
= sizeof(oid
) - 1;
2235 result
= asn1_read_value(c2
, root2
, oid
, &len
);
2237 if (result
== ASN_VALUE_NOT_FOUND
) {
2238 asn1_delete_structure(c2
);
2239 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2242 if (result
!= ASN_OK
) {
2244 asn1_delete_structure(c2
);
2245 return _gnutls_asn2err(result
);
2248 /* if 'Certificate' is the choice found: */
2249 if (strcmp( oid
, "certificate") == 0) {
2252 /* _gnutls_str_cat( root2, sizeof(root2), ".certificate"); */
2254 result
= asn1_get_start_end_der(c2
, pcert
, pcert_size
,
2255 root2
, &start
, &end
);
2257 if (result
!= ASN_OK
) {
2259 asn1_delete_structure(c2
);
2260 return _gnutls_asn2err(result
);
2265 if (certificate
!=NULL
&& end
<= *certificate_size
)
2266 memcpy( certificate
, &pcert
[start
], end
);
2268 *certificate_size
= end
;
2269 return GNUTLS_E_INVALID_REQUEST
;
2272 *certificate_size
= end
;
2275 asn1_delete_structure(c2
);
2276 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
2279 asn1_delete_structure(c2
);
2286 * gnutls_x509_extract_certificate_pk_algorithm - This function returns the certificate's PublicKey algorithm
2287 * @cert: is a DER encoded X.509 certificate
2288 * @bits: if bits is non null it will hold the size of the parameters' in bits
2290 * This function will return the public key algorithm of an X.509
2293 * If bits is non null, it should have enough size to hold the parameters
2294 * size in bits. For RSA the bits returned is the modulus.
2295 * For DSA the bits returned are of the public
2298 * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
2299 * or a negative value on error.
2302 int gnutls_x509_extract_certificate_pk_algorithm( const gnutls_datum
* cert
, int* bits
)
2306 opaque str
[MAX_X509_CERT_SIZE
];
2308 int len
= sizeof(str
);
2309 MPI params
[MAX_PARAMS_SIZE
];
2311 if ((result
=asn1_create_structure
2312 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2
,
2316 return _gnutls_asn2err(result
);
2319 result
= asn1_get_der(c2
, cert
->data
, cert
->size
);
2320 if (result
!= ASN_OK
) {
2321 /* couldn't decode DER */
2323 _gnutls_log("CERT: Decoding error %d\n", result
);
2326 asn1_delete_structure(c2
);
2327 return _gnutls_asn2err(result
);
2330 len
= sizeof(str
) - 1;
2334 "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
2338 if (result
!= ASN_OK
) {
2340 asn1_delete_structure(c2
);
2341 return _gnutls_asn2err(result
);
2344 algo
= GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
2346 if ( strcmp( str
, PKIX1_RSA_OID
)==0)
2347 algo
= GNUTLS_PK_RSA
;
2349 if ( strcmp( str
, DSA_OID
)==0)
2350 algo
= GNUTLS_PK_DSA
;
2353 asn1_delete_structure(c2
);
2357 /* Now read the parameters' bits */
2359 len
= sizeof(str
) - 1;
2362 (c2
, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
2365 if (result
!= ASN_OK
) {
2367 return _gnutls_asn2err(result
);
2371 if (algo
==GNUTLS_PK_RSA
) {
2372 if ((result
=_read_rsa_params( str
, len
/8, params
)) < 0) {
2374 asn1_delete_structure(c2
);
2378 bits
[0] = gcry_mpi_get_nbits( params
[0]);
2380 _gnutls_mpi_release( ¶ms
[0]);
2381 _gnutls_mpi_release( ¶ms
[1]);
2384 if (algo
==GNUTLS_PK_DSA
) {
2387 _read_dsa_pubkey(str
, len
/ 8, params
)) < 0) {
2389 asn1_delete_structure(c2
);
2393 bits
[0] = gcry_mpi_get_nbits( params
[3]);
2395 _gnutls_mpi_release( ¶ms
[3]);
2398 asn1_delete_structure(c2
);
2403 * gnutls_x509_pkcs7_extract_certificate_count - This function returns the number of certificates in a PKCS7 certificate set
2404 * @pkcs7_struct: should contain a PKCS7 DER formatted structure
2406 * This function will return the certificate number of the PKCS7 or RFC2630 certificate set.
2407 * Returns a negative value on failure.
2410 int gnutls_x509_pkcs7_extract_certificate_count(const gnutls_datum
* pkcs7_struct
)
2413 int result
, len
, count
;
2416 char tmp
[MAX_X509_CERT_SIZE
];
2418 opaque
* pkcs7_str
= pkcs7_struct
->data
;
2419 int pkcs7_str_size
= pkcs7_struct
->size
;
2424 /* Step 1. Parse content and content info */
2426 if (pkcs7_str_size
== 0 || pkcs7_str
== NULL
) {
2428 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2431 _gnutls_str_cpy( root1
, sizeof(root1
), "PKIX1.ContentInfo");
2432 if ((result
=asn1_create_structure
2433 (_gnutls_get_pkix(), root1
, &c1
, "c1")) != ASN_OK
) {
2435 return _gnutls_asn2err(result
);
2438 result
= asn1_get_der(c1
, pkcs7_str
, pkcs7_str_size
);
2439 if (result
!= ASN_OK
) {
2440 /* couldn't decode DER */
2443 asn1_delete_structure(c1
);
2444 return _gnutls_asn2err(result
);
2447 len
= sizeof(oid
) - 1;
2449 /* root2 is used as a temp storage area
2451 _gnutls_str_cpy( root2
, sizeof(root2
), "c1.contentType");
2452 result
= asn1_read_value(c1
, root2
, oid
, &len
);
2453 if (result
!= ASN_OK
) {
2455 asn1_delete_structure(c1
);
2456 return _gnutls_asn2err(result
);
2459 if ( strcmp( oid
, "1 2 840 113549 1 7 2") != 0) {
2461 asn1_delete_structure(c1
);
2462 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2465 pcert_size
= sizeof(tmp
) - 1;
2468 _gnutls_str_cpy( root2
, sizeof(root2
), "c1.content");
2469 result
= asn1_read_value(c1
, root2
, pcert
, &pcert_size
);
2471 asn1_delete_structure(c1
);
2473 if (result
!= ASN_OK
) {
2475 return _gnutls_asn2err(result
);
2478 /* pcert, pcert_size hold the data and the size of the CertificateSet structure
2479 * actually the ANY stuff.
2483 /* Step 1.5. In case of a signed structure count the certificate set.
2485 _gnutls_str_cpy( root2
, sizeof(root2
), "PKIX1.SignedData");
2486 if ((result
=asn1_create_structure
2487 (_gnutls_get_pkix(), root2
, &c2
, "c2")) != ASN_OK
) {
2489 return _gnutls_asn2err(result
);
2492 result
= asn1_get_der(c2
, pcert
, pcert_size
);
2493 if (result
!= ASN_OK
) {
2494 /* couldn't decode DER */
2497 asn1_delete_structure(c2
);
2498 return _gnutls_asn2err(result
);
2501 /* Step 2. Count the CertificateSet */
2504 _gnutls_str_cpy( root2
, sizeof(root2
), "c2.certificates");
2505 result
= asn1_number_of_elements( c2
, root2
, &count
);
2507 asn1_delete_structure(c2
);
2509 if (result
!= ASN_OK
) {
2511 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2518 * Convertions between generalized or UTC time to time_t
2522 /* This is an emulations of the struct tm.
2523 * Since we do not use libc's functions, we don't need to
2524 * depend on the libc structure.
2526 typedef struct fake_tm
{
2528 int tm_year
; /* FULL year - ie 1971 */
2535 /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
2536 * who placed it under public domain:
2539 /* The number of days in each month.
2541 static const int MONTHDAYS
[] = {
2542 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
2545 /* Whether a given year is a leap year. */
2546 #define ISLEAP(year) \
2547 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
2550 ** Given a struct tm representing a calendar time in UTC, convert it to
2551 ** seconds since epoch. Returns (time_t) -1 if the time is not
2552 ** convertable. Note that this function does not canonicalize the provided
2553 ** struct tm, nor does it allow out of range values or years before 1970.
2555 static time_t mktime_utc(const struct fake_tm
*tm
)
2560 /* We do allow some ill-formed dates, but we don't do anything special
2561 * with them and our callers really shouldn't pass them to us. Do
2562 * explicitly disallow the ones that would cause invalid array accesses
2563 * or other algorithm problems.
2565 if (tm
->tm_mon
< 0 || tm
->tm_mon
> 11 || tm
->tm_year
< 1970)
2566 return (time_t) - 1;
2568 /* Convert to a time_t.
2570 for (i
= 1970; i
< tm
->tm_year
; i
++)
2571 result
+= 365 + ISLEAP(i
);
2572 for (i
= 0; i
< tm
->tm_mon
; i
++)
2573 result
+= MONTHDAYS
[i
];
2574 if (tm
->tm_mon
> 1 && ISLEAP(tm
->tm_year
))
2576 result
= 24 * (result
+ tm
->tm_mday
- 1) + tm
->tm_hour
;
2577 result
= 60 * result
+ tm
->tm_min
;
2578 result
= 60 * result
+ tm
->tm_sec
;
2583 /* this one will parse dates of the form:
2584 * month|day|hour|minute (2 chars each)
2585 * and year is given. Returns a time_t date.
2587 static time_t _gnutls_x509_time2gtime(char *ttime
, int year
)
2590 struct fake_tm etime
;
2593 if (strlen( ttime
) < 8) {
2598 etime
.tm_year
= year
;
2600 /* In order to work with 32 bit
2603 if (sizeof (time_t) <= 4 && etime
.tm_year
>= 2038)
2604 return (time_t)2145914603; /* 2037-12-31 23:23:23 */
2610 memcpy(xx
, ttime
, 2); /* month */
2611 etime
.tm_mon
= atoi(xx
) - 1;
2616 memcpy(xx
, ttime
, 2); /* day */
2617 etime
.tm_mday
= atoi(xx
);
2622 memcpy(xx
, ttime
, 2); /* hour */
2623 etime
.tm_hour
= atoi(xx
);
2628 memcpy(xx
, ttime
, 2); /* minutes */
2629 etime
.tm_min
= atoi(xx
);
2634 ret
= mktime_utc(&etime
);
2639 /* returns a time_t value that contains the given time.
2640 * The given time is expressed as:
2641 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)
2643 time_t _gnutls_x509_utcTime2gtime(char *ttime
)
2648 if (strlen( ttime
) < 10) {
2655 memcpy(xx
, ttime
, 2); /* year */
2664 return _gnutls_x509_time2gtime( ttime
, year
);
2667 /* returns a time_t value that contains the given time.
2668 * The given time is expressed as:
2669 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)
2671 time_t _gnutls_x509_generalTime2gtime(char *ttime
)
2676 if (strlen( ttime
) < 12) {
2681 if (strchr(ttime
, 'Z') == 0) {
2683 /* sorry we don't support it yet
2691 memcpy(xx
, ttime
, 4); /* year */
2695 return _gnutls_x509_time2gtime( ttime
, year
);