*** empty log message ***
[gnutls.git] / lib / gnutls_x509.c
blob35aa118a9554285f2fef7c6202697fb072312d1b
1 /*
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"
29 #include "x509_der.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>
42 #include <debug.h>
43 #include <x509_b64.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)
64 char name2[256];
65 int result, len;
66 char str[1024];
67 node_asn *tmpasn;
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);
76 if ((result =
77 asn1_create_structure(_gnutls_get_pkix(), str,
78 &tmpasn, name2)) != ASN_OK) {
79 gnutls_assert();
80 return _gnutls_asn2err(result);
83 len = sizeof(str) -1;
84 if ((result =
85 asn1_read_value(rasn, name3, str, &len)) != ASN_OK) {
86 asn1_delete_structure(tmpasn);
87 return 1;
90 if ((result = asn1_get_der(tmpasn, str, len)) != ASN_OK) {
91 asn1_delete_structure(tmpasn);
92 return 1;
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);
99 return 1;
102 if (CHOICE == 0) {
103 str[len] = 0;
104 /* strlen(str) < res_size, checked above */
105 _gnutls_str_cpy(res, res_size, str);
107 } else { /* CHOICE */
108 str[len] = 0;
109 _gnutls_str_cat(name3, name3_size, ".");
110 _gnutls_str_cat(name3, name3_size, str);
111 len = sizeof(str) - 1;
113 if ((result =
114 asn1_read_value(tmpasn, name3, str,
115 &len)) != ASN_OK) {
116 asn1_delete_structure(tmpasn);
117 return 1;
119 str[len] = 0;
120 if ( len < res_size)
121 _gnutls_str_cpy(res, res_size, str);
123 asn1_delete_structure(tmpasn);
126 return 0;
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)
135 if (k > 999)
136 sprintf(data, "%d", 999);
137 else
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)
146 * --nmav
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],
152 name3[128];
154 k = 0;
155 do {
156 k++;
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);
167 /* move to next
169 if (result == ASN_ELEMENT_NOT_FOUND)
170 break;
171 if (result != ASN_VALUE_NOT_FOUND) {
172 gnutls_assert();
173 return _gnutls_asn2err(result);
176 k2 = 0;
177 do {
178 k2++;
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)
189 break;
190 if (result != ASN_VALUE_NOT_FOUND) {
191 gnutls_assert();
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)
202 break;
203 else if (result != ASN_OK) {
204 gnutls_assert();
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) {
212 #ifdef DEBUG
213 # warning " FIX COUNTRY HERE"
214 #endif
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",
228 dn->common_name, 1);
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);
240 } while (1);
241 } while (1);
243 if (result == ASN_ELEMENT_NOT_FOUND)
244 return 0;
245 else
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];
255 char name[1024];
256 time_t ctime;
257 int len, result;
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) {
265 gnutls_assert();
266 return (time_t) (-1);
269 /* CHOICE */
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) {
297 gnutls_assert();
298 return (time_t) (-1);
300 return ctime;
303 int _gnutls_x509_get_version(node_asn * c2, char *root)
305 opaque gversion[5];
306 char name[1024];
307 int len, result;
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) {
314 gnutls_assert();
315 return result;
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)
336 node_asn *dn;
337 int result;
339 if ((result =
340 asn1_create_structure(_gnutls_get_pkix(),
341 "PKIX1.Name", &dn,
342 "dn")) != ASN_OK) {
343 gnutls_assert();
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 */
350 gnutls_assert();
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);
358 if (result < 0) {
359 /* couldn't decode DER */
360 gnutls_assert();
361 return result;
364 return 0;
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)
381 node_asn *c2;
382 int result;
384 memset(ret, 0, sizeof(gnutls_x509_dn));
386 if ((result=asn1_create_structure
387 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
388 "certificate2"))
389 != ASN_OK) {
390 gnutls_assert();
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);
401 gnutls_assert();
402 asn1_delete_structure(c2);
403 return _gnutls_asn2err(result);
405 if ((result =
406 _gnutls_x509_get_name_type(c2,
407 "certificate2.tbsCertificate.subject",
408 ret)) < 0) {
409 gnutls_assert();
410 asn1_delete_structure(c2);
411 return result;
414 asn1_delete_structure(c2);
416 return 0;
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)
433 node_asn *c2;
434 int result;
436 memset(ret, 0, sizeof(gnutls_x509_dn));
438 if ((result=asn1_create_structure
439 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
440 "certificate2"))
441 != ASN_OK) {
442 gnutls_assert();
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);
452 gnutls_assert();
453 asn1_delete_structure(c2);
454 return _gnutls_asn2err(result);
456 if ((result =
457 _gnutls_x509_get_name_type(c2,
458 "certificate2.tbsCertificate.issuer",
459 ret)) < 0) {
460 gnutls_assert();
461 asn1_delete_structure(c2);
462 return result;
465 asn1_delete_structure(c2);
467 return 0;
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;
475 return -1;
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
486 * given certificate.
488 * This is specified in X509v3 Certificate Extensions.
489 * GNUTLS will return the Alternative name, or a negative
490 * error code.
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)
501 int result;
502 gnutls_datum dnsname;
503 node_asn *c2;
504 char nptr[128];
505 char ext_data[256];
506 int len;
507 char num[MAX_INT_DIGITS];
508 GNUTLS_X509_SUBJECT_ALT_NAME type;
510 memset(ret, 0, *ret_size);
512 if ((result =
513 _gnutls_get_extension(cert, "2 5 29 17", &dnsname)) < 0) {
514 gnutls_assert();
515 return result;
518 if (dnsname.size == 0 || dnsname.data==NULL) {
519 gnutls_assert();
520 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
523 if ((result=asn1_create_structure
524 (_gnutls_get_pkix(), "PKIX1.SubjectAltName", &c2, "san"))
525 != ASN_OK) {
526 gnutls_assert();
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);
538 gnutls_assert();
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);
549 result =
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) {
558 gnutls_assert();
559 asn1_delete_structure(c2);
560 return _gnutls_asn2err(result);
564 type = _find_type( ext_data);
565 if (type == -1) {
566 gnutls_assert();
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);
575 result =
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) {
583 gnutls_assert();
584 return _gnutls_asn2err(result);
587 return type;
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
600 gnutls_datum *
601 cert)
603 node_asn *c2;
604 int result;
605 time_t ret;
607 if (asn1_create_structure
608 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
609 "certificate2")
610 != ASN_OK) {
611 gnutls_assert();
612 return (time_t)-1;
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);
621 gnutls_assert();
622 return (time_t)-1;
625 ret = _gnutls_x509_get_time(c2, "certificate2", "notBefore");
627 asn1_delete_structure(c2);
629 return ret;
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
642 gnutls_datum *
643 cert)
645 node_asn *c2;
646 int result;
647 time_t ret;
649 if (asn1_create_structure
650 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
651 "certificate2")
652 != ASN_OK) {
653 gnutls_assert();
654 return (time_t)-1;
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);
663 gnutls_assert();
664 return (time_t)-1;
667 ret = _gnutls_x509_get_time(c2, "certificate2", "notAfter");
669 asn1_delete_structure(c2);
671 return ret;
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)
684 node_asn *c2;
685 int result;
687 if ((result=asn1_create_structure
688 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
689 "certificate2"))
690 != ASN_OK) {
691 gnutls_assert();
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);
701 gnutls_assert();
702 return _gnutls_asn2err(result);
705 result = _gnutls_x509_get_version(c2, "certificate2");
707 asn1_delete_structure(c2);
709 return result;
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);
736 if (info == NULL) {
737 gnutls_assert();
738 return GNUTLS_E_INVALID_REQUEST;
741 cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_CERTIFICATE, NULL);
742 if (cred == NULL) {
743 gnutls_assert();
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
751 * raw certs.
753 peer_certificate_list_size = info->ncerts;
754 peer_certificate_list =
755 gnutls_calloc(1,
756 peer_certificate_list_size *
757 sizeof(gnutls_cert));
758 if (peer_certificate_list == NULL) {
759 gnutls_assert();
760 return GNUTLS_E_MEMORY_ERROR;
763 for (i = 0; i < peer_certificate_list_size; i++) {
764 if ((ret =
765 _gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i],
766 info->
767 raw_certificate_list[i])) <
768 0) {
769 gnutls_assert();
770 CLEAR_CERTS;
771 gnutls_free(peer_certificate_list);
772 return ret;
776 /* Verify certificate
778 verify =
779 _gnutls_x509_verify_certificate(peer_certificate_list,
780 peer_certificate_list_size,
781 cred->x509_ca_list, cred->x509_ncas, NULL, 0);
783 CLEAR_CERTS;
784 gnutls_free(peer_certificate_list);
786 if (verify < 0) {
787 gnutls_assert();
788 return verify;
792 return verify;
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
812 * actual peer.
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
843 * raw certs.
845 peer_certificate_list_size = cert_list_length;
846 peer_certificate_list =
847 gnutls_calloc(1,
848 peer_certificate_list_size *
849 sizeof(gnutls_cert));
850 if (peer_certificate_list == NULL) {
851 gnutls_assert();
852 return GNUTLS_E_MEMORY_ERROR;
855 ca_certificate_list_size = CA_list_length;
856 ca_certificate_list =
857 gnutls_calloc(1,
858 ca_certificate_list_size *
859 sizeof(gnutls_cert));
860 if (ca_certificate_list == NULL) {
861 gnutls_assert();
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++) {
869 if ((ret =
870 _gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i],
871 cert_list[i])) < 0) {
872 gnutls_assert();
873 CLEAR_CERTS_CA;
874 gnutls_free( peer_certificate_list);
875 gnutls_free( ca_certificate_list);
876 return ret;
880 /* convert CA_list to gnutls_cert* list
882 for (i = 0; i < ca_certificate_list_size; i++) {
883 if ((ret =
884 _gnutls_x509_cert2gnutls_cert(&ca_certificate_list[i],
885 CA_list[i])) < 0) {
886 gnutls_assert();
887 CLEAR_CERTS_CA;
888 gnutls_free( peer_certificate_list);
889 gnutls_free( ca_certificate_list);
890 return ret;
894 /* Verify certificate
896 verify =
897 _gnutls_x509_verify_certificate(peer_certificate_list,
898 peer_certificate_list_size,
899 ca_certificate_list, ca_certificate_list_size, NULL, 0);
901 CLEAR_CERTS_CA;
902 gnutls_free( peer_certificate_list);
903 gnutls_free( ca_certificate_list);
905 if (verify < 0) {
906 gnutls_assert();
907 return verify;
910 return verify;
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
923 * opaque.
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)
929 node_asn *c2;
930 int ret;
932 if ((ret=asn1_create_structure
933 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
934 "certificate2"))
935 != ASN_OK) {
936 gnutls_assert();
937 return ret;
940 ret = asn1_get_der(c2, cert->data, cert->size);
941 if (ret != ASN_OK) {
942 /* couldn't decode DER */
944 _gnutls_log("X509_auth: Decoding error %d\n", result);
946 gnutls_assert();
947 return ret;
950 if ((ret = asn1_read_value(c2, "certificate2.tbsCertificate.serialNumber", result, result_size)) < 0) {
951 gnutls_assert();
952 asn1_delete_structure(c2);
953 return ret;
956 asn1_delete_structure(c2);
958 return 0;
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) {
973 gnutls_assert();
974 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
976 return 0;
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)
989 int i;
990 gnutls_datum tmp;
991 int ret;
993 i = *ncerts + 1;
995 *cert_list =
996 (gnutls_cert *) gnutls_realloc( *cert_list,
998 sizeof(gnutls_cert));
1000 if ( *cert_list == NULL) {
1001 gnutls_assert();
1002 return GNUTLS_E_MEMORY_ERROR;
1005 tmp.data = (opaque*) input_cert;
1006 tmp.size = input_cert_size;
1008 if ((ret =
1009 _gnutls_x509_cert2gnutls_cert(
1010 &cert_list[0][i - 1],
1011 tmp)) < 0) {
1012 gnutls_assert();
1013 return ret;
1016 *ncerts = i;
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)
1029 int i, j, count;
1030 gnutls_datum tmp, tmp2;
1031 int ret;
1032 opaque pcert[MAX_X509_CERT_SIZE];
1033 int pcert_size;
1035 i = *ncerts + 1;
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);
1043 if (count < 0) {
1044 gnutls_assert();
1045 /* if we failed to read the count,
1046 * then just try to decode a plain DER
1047 * certificate.
1049 return parse_der_cert_mem( cert_list, ncerts,
1050 input_cert, input_cert_size);
1054 j = count - 1;
1055 do {
1056 pcert_size = sizeof(pcert);
1057 ret = gnutls_x509_pkcs7_extract_certificate( &tmp, j, pcert, &pcert_size);
1058 j--;
1060 /* if the current certificate is too long, just ignore
1061 * it. */
1062 if (ret==GNUTLS_E_MEMORY_ERROR) {
1063 count--;
1064 continue;
1067 if (ret >= 0) {
1068 *cert_list =
1069 (gnutls_cert *) gnutls_realloc( *cert_list,
1070 i * sizeof(gnutls_cert));
1072 if ( *cert_list == NULL) {
1073 gnutls_assert();
1074 return GNUTLS_E_MEMORY_ERROR;
1077 tmp2.data = pcert;
1078 tmp2.size = pcert_size;
1080 if ((ret =
1081 _gnutls_x509_cert2gnutls_cert(
1082 &cert_list[0][i - 1],
1083 tmp2)) < 0) {
1084 gnutls_assert();
1085 return ret;
1088 i++;
1091 } while (ret >= 0 && j >= 0);
1093 *ncerts = i - 1;
1095 return count;
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)
1105 int siz, i, siz2;
1106 opaque *b64;
1107 const char *ptr;
1108 gnutls_datum tmp;
1109 int ret, count;
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,
1115 siz2);
1117 gnutls_free(b64);
1119 return ret;
1123 ptr = input_cert;
1124 siz = input_cert_size;
1125 i = *ncerts + 1;
1126 count = 0;
1128 do {
1129 siz2 = _gnutls_fbase64_decode(ptr, siz, &b64);
1130 siz -= siz2; /* FIXME: this is not enough
1133 if (siz2 < 0) {
1134 gnutls_assert();
1135 return GNUTLS_E_PARSING_ERROR;
1139 *cert_list =
1140 (gnutls_cert *) gnutls_realloc( *cert_list,
1142 sizeof(gnutls_cert));
1144 if ( *cert_list == NULL) {
1145 gnutls_assert();
1146 gnutls_free(b64);
1147 return GNUTLS_E_MEMORY_ERROR;
1150 tmp.data = b64;
1151 tmp.size = siz2;
1153 if ((ret =
1154 _gnutls_x509_cert2gnutls_cert(
1155 &cert_list[0][i - 1],
1156 tmp)) < 0) {
1157 gnutls_free(b64);
1158 gnutls_assert();
1159 return ret;
1161 gnutls_free(b64);
1163 /* now we move ptr after the pem header */
1164 ptr = strstr(ptr, CERT_SEP);
1165 if (ptr!=NULL)
1166 ptr++;
1168 i++;
1169 count++;
1170 } while ((ptr = strstr(ptr, CERT_SEP)) != NULL);
1172 *ncerts = i - 1;
1174 return count;
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)
1184 int ret;
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) {
1190 gnutls_assert();
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) {
1197 gnutls_assert();
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],
1206 cert, cert_size);
1207 else
1208 ret = parse_pem_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts],
1209 cert, cert_size);
1211 if (ret < 0) {
1212 gnutls_assert();
1213 return ret;
1216 return ret;
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,
1228 ca, ca_size);
1229 else
1230 return parse_pem_cert_mem( &res->x509_ca_list, &res->x509_ncas,
1231 ca, ca_size);
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)
1240 node_asn *c2;
1241 int result;
1242 char root2[128];
1244 /* Step 1. Parse content and content info */
1246 if (key_struct->size == 0 || key_struct->data == NULL) {
1247 gnutls_assert();
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) {
1254 gnutls_assert();
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 */
1264 gnutls_assert();
1265 return _gnutls_asn2err(result);
1268 return 0;
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)
1282 int ret;
1283 opaque *b64 = NULL;
1284 gnutls_datum tmp;
1285 PKAlgorithm pk;
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) {
1291 gnutls_assert();
1292 return GNUTLS_E_MEMORY_ERROR;
1295 /* read PKCS-1 private key */
1297 if (type==GNUTLS_X509_FMT_DER) { /* DER */
1298 int cv;
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);
1307 if (cv==0)
1308 pk = GNUTLS_PK_RSA;
1309 else
1310 pk = GNUTLS_PK_DSA;
1312 } else { /* PEM */
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)
1318 pk = GNUTLS_PK_DSA;
1319 else
1320 pk = GNUTLS_PK_RSA;
1322 ret = _gnutls_fbase64_decode(key, key_size, &b64);
1324 if (ret < 0) {
1325 gnutls_assert();
1326 return GNUTLS_E_PARSING_ERROR;
1329 tmp.data = b64;
1330 tmp.size = ret;
1333 switch (pk) { /* decode the key */
1334 case GNUTLS_PK_RSA:
1335 if ((ret =
1336 _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts],
1337 tmp)) < 0) {
1338 gnutls_assert();
1339 gnutls_free(b64);
1340 return ret;
1342 break;
1343 case GNUTLS_PK_DSA:
1344 if ((ret =
1345 _gnutls_DSAkey2gnutlsKey(&res->pkey[res->ncerts],
1346 tmp)) < 0) {
1347 gnutls_assert();
1348 gnutls_free(b64);
1349 return ret;
1351 break;
1354 /* this doesn't hurt in the DER case, since
1355 * b64 is NULL
1357 gnutls_free(b64);
1359 return 0;
1363 /* Reads a certificate file
1365 static int read_cert_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *certfile,
1366 GNUTLS_X509_CertificateFmt type)
1368 int siz;
1369 char x[MAX_FILE_SIZE];
1370 FILE *fd1;
1372 fd1 = fopen(certfile, "rb");
1373 if (fd1 == NULL)
1374 return GNUTLS_E_FILE_ERROR;
1376 siz = fread(x, 1, sizeof(x)-1, fd1);
1377 fclose(fd1);
1379 x[siz] = 0;
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)
1391 int siz;
1392 char x[MAX_FILE_SIZE];
1393 FILE *fd1;
1395 fd1 = fopen(cafile, "rb");
1396 if (fd1 == NULL) {
1397 gnutls_assert();
1398 return GNUTLS_E_FILE_ERROR;
1401 siz = fread(x, 1, sizeof(x)-1, fd1);
1402 fclose(fd1);
1404 x[siz] = 0;
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
1411 * stores it).
1413 static int read_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *keyfile,
1414 GNUTLS_X509_CertificateFmt type)
1416 int siz;
1417 char x[MAX_FILE_SIZE];
1418 FILE *fd2;
1420 fd2 = fopen(keyfile, "rb");
1421 if (fd2 == NULL)
1422 return GNUTLS_E_FILE_ERROR;
1424 siz = fread(x, 1, sizeof(x)-1, fd2);
1425 fclose(fd2);
1427 x[siz] = 0;
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
1444 * server).
1446 * Currently only PKCS-1 encoded RSA and DSA private keys are accepted by
1447 * this function.
1450 int gnutls_certificate_set_x509_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE,
1451 char *KEYFILE, GNUTLS_X509_CertificateFmt type)
1453 int ret;
1455 /* this should be first
1457 if ((ret = read_key_file(res, KEYFILE, type)) < 0)
1458 return ret;
1460 if ((ret = read_cert_file(res, CERTFILE, type)) < 0)
1461 return ret;
1463 res->ncerts++;
1465 if ((ret=_gnutls_check_key_cert_match( res)) < 0) {
1466 gnutls_assert();
1467 return ret;
1470 return 0;
1473 static int generate_rdn_seq( GNUTLS_CERTIFICATE_CREDENTIALS res) {
1474 gnutls_datum tmp;
1475 int ret, size, i;
1476 opaque *pdata;
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
1486 * here.
1489 size = 0;
1490 for (i = 0; i < res->x509_ncas; i++) {
1491 if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) {
1492 gnutls_assert();
1493 return ret;
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) {
1503 gnutls_assert();
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;
1515 gnutls_assert();
1516 return ret;
1518 WRITEdatum16(pdata, tmp);
1519 pdata += (2 + tmp.size);
1522 return 0;
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)
1538 int ret, ret2;
1540 if ((ret = read_ca_mem(res, CA->data, CA->size, type)) < 0)
1541 return ret;
1543 if ((ret2 = generate_rdn_seq(res)) < 0)
1544 return ret2;
1546 return ret;
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)
1563 int ret, ret2;
1565 if ((ret = read_ca_file(res, CAFILE, type)) < 0)
1566 return ret;
1568 if ((ret2 = generate_rdn_seq(res)) < 0)
1569 return ret2;
1571 return ret;
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
1585 * server).
1587 * Currently are supported: RSA PKCS-1 encoded private keys,
1588 * DSA 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)
1597 int ret;
1599 /* this should be first
1601 if ((ret = read_key_mem( res, KEY->data, KEY->size, type)) < 0)
1602 return ret;
1604 if ((ret = read_cert_mem( res, CERT->data, CERT->size, type)) < 0)
1605 return ret;
1607 if ((ret=_gnutls_check_key_cert_match( res)) < 0) {
1608 gnutls_assert();
1609 return ret;
1612 return 0;
1617 static int _read_rsa_params(opaque * der, int dersize, MPI * params)
1619 opaque str[MAX_PARAMETER_SIZE];
1620 int result;
1621 node_asn *spk;
1623 if ((result=asn1_create_structure
1624 (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk,
1625 "rsa_public_key")) != ASN_OK) {
1626 gnutls_assert();
1627 return _gnutls_asn2err(result);
1630 result = asn1_get_der(spk, der, dersize);
1632 if (result != ASN_OK) {
1633 gnutls_assert();
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, &params[0])) < 0) {
1641 gnutls_assert();
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, &params[1])) < 0) {
1648 gnutls_assert();
1649 _gnutls_mpi_release(&params[0]);
1650 asn1_delete_structure(spk);
1651 return GNUTLS_E_ASN1_GENERIC_ERROR;
1654 asn1_delete_structure(spk);
1656 return 0;
1661 /* reads p,q and g
1662 * from the certificate
1663 * params[0-2]
1665 static int _read_dsa_params(opaque * der, int dersize, MPI * params)
1667 opaque str[MAX_PARAMETER_SIZE];
1668 int result;
1669 node_asn *spk;
1671 if ((result=asn1_create_structure
1672 (_gnutls_get_pkix(), "PKIX1.Dss-Parms", &spk,
1673 "dsa_parms")) != ASN_OK) {
1674 gnutls_assert();
1675 return _gnutls_asn2err(result);
1678 result = asn1_get_der(spk, der, dersize);
1680 if (result != ASN_OK) {
1681 gnutls_assert();
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.
1690 /* Read p */
1692 if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.p", str, sizeof(str)-1, &params[0])) < 0) {
1693 gnutls_assert();
1694 asn1_delete_structure(spk);
1695 return GNUTLS_E_ASN1_GENERIC_ERROR;
1698 /* Read q */
1700 if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.q", str, sizeof(str)-1, &params[1])) < 0) {
1701 gnutls_assert();
1702 asn1_delete_structure(spk);
1703 _gnutls_mpi_release(&params[0]);
1704 return GNUTLS_E_ASN1_GENERIC_ERROR;
1707 /* Read g */
1709 if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.g", str, sizeof(str)-1, &params[2])) < 0) {
1710 gnutls_assert();
1711 asn1_delete_structure(spk);
1712 _gnutls_mpi_release(&params[0]);
1713 _gnutls_mpi_release(&params[1]);
1714 return GNUTLS_E_ASN1_GENERIC_ERROR;
1717 asn1_delete_structure(spk);
1719 return 0;
1723 /* reads DSA's Y
1724 * from the certificate
1725 * params[3]
1727 static int _read_dsa_pubkey(opaque * der, int dersize, MPI * params)
1729 opaque str[MAX_PARAMETER_SIZE];
1730 int result;
1731 node_asn *spk;
1733 if ( (result=asn1_create_structure
1734 (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk,
1735 "dsa_public_key")) != ASN_OK) {
1736 gnutls_assert();
1737 return _gnutls_asn2err(result);
1740 result = asn1_get_der(spk, der, dersize);
1742 if (result != ASN_OK) {
1743 gnutls_assert();
1744 asn1_delete_structure(spk);
1745 return _gnutls_asn2err(result);
1748 /* Read p */
1750 if ( (result=_gnutls_x509_read_int( spk, "dsa_public_key", str, sizeof(str)-1, &params[3])) < 0) {
1751 gnutls_assert();
1752 asn1_delete_structure(spk);
1753 return GNUTLS_E_ASN1_GENERIC_ERROR;
1756 asn1_delete_structure(spk);
1758 return 0;
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.
1767 static
1768 int _gnutls_extract_x509_cert_mpi_params( const char* ALGO_OID, gnutls_cert * gCert,
1769 node_asn* c2, char* tmpstr, int tmpstr_size) {
1770 int len, result;
1772 len = tmpstr_size - 1;
1773 result =
1774 asn1_read_value
1775 (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
1776 tmpstr, &len);
1778 if (result != ASN_OK) {
1779 gnutls_assert();
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) {
1790 gnutls_assert();
1791 /* internal error. Increase the MPIs in params */
1792 return GNUTLS_E_INTERNAL_ERROR;
1795 if ((result =
1796 _read_rsa_params(tmpstr, len / 8, gCert->params)) < 0) {
1797 gnutls_assert();
1798 return result;
1800 gCert->params_size = RSA_PUBLIC_PARAMS;
1802 return 0;
1805 if (strcmp( ALGO_OID, DSA_OID) == 0) {
1806 /* params[0] is p,
1807 * params[1] is q,
1808 * params[2] is q,
1809 * params[3] is pub.
1811 gCert->subject_pk_algorithm = GNUTLS_PK_DSA;
1813 if ((sizeof(gCert->params) / sizeof(MPI)) < DSA_PUBLIC_PARAMS) {
1814 gnutls_assert();
1815 /* internal error. Increase the MPIs in params */
1816 return GNUTLS_E_INTERNAL_ERROR;
1819 if ((result =
1820 _read_dsa_pubkey(tmpstr, len / 8, gCert->params)) < 0) {
1821 gnutls_assert();
1822 return result;
1825 /* Now read the parameters
1827 len = tmpstr_size - 1;
1828 result =
1829 asn1_read_value
1830 (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",
1831 tmpstr, &len);
1833 if (result != ASN_OK) {
1834 gnutls_assert();
1835 return _gnutls_asn2err(result);
1838 if ((result =
1839 _read_dsa_params(tmpstr, len, gCert->params)) < 0) {
1840 gnutls_assert();
1841 return result;
1843 gCert->params_size = DSA_PUBLIC_PARAMS;
1845 return 0;
1849 /* other types like DH
1850 * currently not supported
1852 gnutls_assert();
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)
1872 int result;
1873 node_asn *c2;
1874 opaque str[MAX_X509_CERT_SIZE];
1875 char oid[128];
1876 int len = sizeof(str);
1878 memset(gCert, 0, sizeof(gnutls_cert));
1880 gCert->valid = 1;
1881 gCert->cert_type = GNUTLS_CRT_X509;
1883 if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) {
1884 gnutls_assert();
1885 return GNUTLS_E_MEMORY_ERROR;
1888 if ((result=asn1_create_structure
1889 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
1890 "certificate2"))
1891 != ASN_OK) {
1892 gnutls_assert();
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);
1903 gnutls_assert();
1904 asn1_delete_structure(c2);
1905 gnutls_free_datum( &gCert->raw);
1906 return _gnutls_asn2err(result);
1909 len = sizeof(oid) - 1;
1910 result =
1911 asn1_read_value
1912 (c2,
1913 "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
1914 oid, &len);
1916 if (result != ASN_OK) {
1917 gnutls_assert();
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) {
1924 gnutls_assert();
1925 asn1_delete_structure(c2);
1926 gnutls_free_datum( &gCert->raw);
1927 return result;
1930 len = gCert->signature.size = X509_SIG_SIZE;
1931 gCert->signature.data = gnutls_malloc( gCert->signature.size);
1932 if (gCert->signature.data==NULL) {
1933 gnutls_assert();
1934 return GNUTLS_E_MEMORY_ERROR;
1937 result =
1938 asn1_read_value
1939 (c2, "certificate2.signature", gCert->signature.data, &len);
1941 if ((len % 8) != 0) {
1942 gnutls_assert();
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) {
1960 gnutls_assert();
1961 asn1_delete_structure(c2);
1962 gnutls_free_datum( &gCert->raw);
1963 return GNUTLS_E_ASN1_GENERIC_ERROR;
1966 if ((result =
1967 _gnutls_get_ext_type(c2,
1968 "certificate2.tbsCertificate.extensions",
1969 gCert)) < 0) {
1970 gnutls_assert();
1971 asn1_delete_structure(c2);
1972 gnutls_free_datum( &gCert->raw);
1973 return result;
1976 asn1_delete_structure(c2);
1979 gCert->valid = 0; /* if we got until here
1980 * the certificate is valid.
1983 return 0;
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,
1991 KXAlgorithm alg)
1993 if (_gnutls_map_kx_get_cred(alg) == GNUTLS_CRD_CERTIFICATE) {
1994 switch (alg) {
1995 case GNUTLS_KX_RSA:
1996 if (cert->keyUsage != 0) {
1997 if (!
1998 (cert->
1999 keyUsage & GNUTLS_X509KEY_KEY_ENCIPHERMENT))
2000 return
2001 GNUTLS_E_X509_KEY_USAGE_VIOLATION;
2002 else
2003 return 0;
2005 return 0;
2006 case GNUTLS_KX_DHE_RSA:
2007 case GNUTLS_KX_DHE_DSS:
2008 if (cert->keyUsage != 0) {
2009 if (!
2010 (cert->
2011 keyUsage & GNUTLS_X509KEY_DIGITAL_SIGNATURE))
2012 return
2013 GNUTLS_E_X509_KEY_USAGE_VIOLATION;
2014 else
2015 return 0;
2017 return 0;
2018 default:
2019 gnutls_assert();
2020 return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
2023 return 0;
2026 #ifdef DEBUG
2028 /* Verifies a base64 encoded certificate list from memory
2030 int _gnutls_verify_x509_mem( const char *ca, int ca_size)
2032 int siz, siz2, i;
2033 opaque *b64;
2034 const char *ptr;
2035 int ret;
2036 gnutls_datum tmp;
2037 gnutls_cert* x509_ca_list=NULL;
2038 int x509_ncas;
2040 siz = ca_size;
2042 ptr = ca;
2044 i = 1;
2046 do {
2047 siz2 = _gnutls_fbase64_decode(ptr, siz, &b64);
2048 siz -= siz2; /* FIXME: this is not enough
2051 if (siz2 < 0) {
2052 gnutls_assert();
2053 return GNUTLS_E_PARSING_ERROR;
2056 x509_ca_list =
2057 (gnutls_cert *) gnutls_realloc( x509_ca_list,
2059 sizeof(gnutls_cert));
2060 if (x509_ca_list == NULL) {
2061 gnutls_assert();
2062 gnutls_free(b64);
2063 return GNUTLS_E_MEMORY_ERROR;
2066 tmp.data = b64;
2067 tmp.size = siz2;
2069 if ((ret =
2070 _gnutls_x509_cert2gnutls_cert(&x509_ca_list[i - 1],
2071 tmp)) < 0) {
2072 gnutls_assert();
2073 gnutls_free(b64);
2074 return ret;
2076 gnutls_free(b64);
2078 /* now we move ptr after the pem header */
2079 ptr = strstr(ptr, CERT_SEP);
2080 if (ptr!=NULL)
2081 ptr++;
2083 i++;
2084 } while ((ptr = strstr(ptr, CERT_SEP)) != NULL);
2086 x509_ncas = i - 1;
2088 siz = _gnutls_x509_verify_certificate( x509_ca_list, x509_ncas-1,
2089 &x509_ca_list[x509_ncas-1], 1, NULL, 0);
2091 return siz;
2096 /* Reads and verifies a base64 encoded certificate file
2098 int _gnutls_verify_x509_file( char *cafile)
2100 int siz;
2101 char x[MAX_FILE_SIZE];
2102 FILE *fd1;
2104 fd1 = fopen(cafile, "rb");
2105 if (fd1 == NULL) {
2106 gnutls_assert();
2107 return GNUTLS_E_FILE_ERROR;
2110 siz = fread(x, 1, sizeof(x)-1, fd1);
2111 fclose(fd1);
2113 x[siz] = 0;
2115 return _gnutls_verify_x509_mem( x, siz);
2120 #endif
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)
2136 node_asn *c2, *c1;
2137 int result, len;
2138 char root1[128];
2139 char oid[128];
2140 char root2[128];
2141 char counter[MAX_INT_DIGITS];
2142 opaque* pkcs7_str = pkcs7_struct->data;
2143 int pkcs7_str_size = pkcs7_struct->size;
2145 opaque* pcert;
2146 int pcert_size;
2148 /* Step 1. Parse content and content info */
2150 if (pkcs7_str_size == 0 || pkcs7_str == NULL) {
2151 gnutls_assert();
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) {
2158 gnutls_assert();
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 */
2166 gnutls_assert();
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) {
2178 gnutls_assert();
2179 asn1_delete_structure(c1);
2180 return _gnutls_asn2err(result);
2183 if ( strcmp( oid, "1 2 840 113549 1 7 2") != 0) {
2184 gnutls_assert();
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) {
2198 gnutls_assert();
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) {
2212 gnutls_assert();
2213 return _gnutls_asn2err(result);
2216 result = asn1_get_der(c2, pcert, pcert_size);
2217 if (result != ASN_OK) {
2218 /* couldn't decode DER */
2220 gnutls_assert();
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) {
2243 gnutls_assert();
2244 asn1_delete_structure(c2);
2245 return _gnutls_asn2err(result);
2248 /* if 'Certificate' is the choice found: */
2249 if (strcmp( oid, "certificate") == 0) {
2250 int start, end;
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) {
2258 gnutls_assert();
2259 asn1_delete_structure(c2);
2260 return _gnutls_asn2err(result);
2263 end = end-start+1;
2265 if (certificate!=NULL && end <= *certificate_size)
2266 memcpy( certificate, &pcert[start], end);
2267 else {
2268 *certificate_size = end;
2269 return GNUTLS_E_INVALID_REQUEST;
2272 *certificate_size = end;
2274 } else {
2275 asn1_delete_structure(c2);
2276 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
2279 asn1_delete_structure(c2);
2281 return 0;
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
2291 * certificate.
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
2296 * exponent.
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)
2304 int result;
2305 node_asn *c2;
2306 opaque str[MAX_X509_CERT_SIZE];
2307 int algo;
2308 int len = sizeof(str);
2309 MPI params[MAX_PARAMS_SIZE];
2311 if ((result=asn1_create_structure
2312 (_gnutls_get_pkix(), "PKIX1.Certificate", &c2,
2313 "certificate2"))
2314 != ASN_OK) {
2315 gnutls_assert();
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);
2325 gnutls_assert();
2326 asn1_delete_structure(c2);
2327 return _gnutls_asn2err(result);
2330 len = sizeof(str) - 1;
2331 result =
2332 asn1_read_value
2333 (c2,
2334 "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
2335 str, &len);
2338 if (result != ASN_OK) {
2339 gnutls_assert();
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;
2352 if ( bits==NULL) {
2353 asn1_delete_structure(c2);
2354 return algo;
2357 /* Now read the parameters' bits */
2359 len = sizeof(str) - 1;
2360 result =
2361 asn1_read_value
2362 (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
2363 str, &len);
2365 if (result != ASN_OK) {
2366 gnutls_assert();
2367 return _gnutls_asn2err(result);
2371 if (algo==GNUTLS_PK_RSA) {
2372 if ((result=_read_rsa_params( str, len/8, params)) < 0) {
2373 gnutls_assert();
2374 asn1_delete_structure(c2);
2375 return result;
2378 bits[0] = gcry_mpi_get_nbits( params[0]);
2380 _gnutls_mpi_release( &params[0]);
2381 _gnutls_mpi_release( &params[1]);
2384 if (algo==GNUTLS_PK_DSA) {
2386 if ((result =
2387 _read_dsa_pubkey(str, len / 8, params)) < 0) {
2388 gnutls_assert();
2389 asn1_delete_structure(c2);
2390 return result;
2393 bits[0] = gcry_mpi_get_nbits( params[3]);
2395 _gnutls_mpi_release( &params[3]);
2398 asn1_delete_structure(c2);
2399 return algo;
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)
2412 node_asn *c2, *c1;
2413 int result, len, count;
2414 char root1[128];
2415 char oid[64];
2416 char tmp[MAX_X509_CERT_SIZE];
2417 char root2[128];
2418 opaque* pkcs7_str = pkcs7_struct->data;
2419 int pkcs7_str_size = pkcs7_struct->size;
2421 opaque* pcert;
2422 int pcert_size;
2424 /* Step 1. Parse content and content info */
2426 if (pkcs7_str_size == 0 || pkcs7_str == NULL) {
2427 gnutls_assert();
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) {
2434 gnutls_assert();
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 */
2442 gnutls_assert();
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) {
2454 gnutls_assert();
2455 asn1_delete_structure(c1);
2456 return _gnutls_asn2err(result);
2459 if ( strcmp( oid, "1 2 840 113549 1 7 2") != 0) {
2460 gnutls_assert();
2461 asn1_delete_structure(c1);
2462 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2465 pcert_size = sizeof(tmp) - 1;
2466 pcert = tmp;
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) {
2474 gnutls_assert();
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) {
2488 gnutls_assert();
2489 return _gnutls_asn2err(result);
2492 result = asn1_get_der(c2, pcert, pcert_size);
2493 if (result != ASN_OK) {
2494 /* couldn't decode DER */
2496 gnutls_assert();
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) {
2510 gnutls_assert();
2511 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2514 return count;
2517 /* TIME functions
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 {
2527 int tm_mon;
2528 int tm_year; /* FULL year - ie 1971 */
2529 int tm_mday;
2530 int tm_hour;
2531 int tm_min;
2532 int tm_sec;
2533 } fake_tm;
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)
2557 time_t result = 0;
2558 int i;
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))
2575 result++;
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;
2579 return result;
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)
2589 char xx[3];
2590 struct fake_tm etime;
2591 time_t ret;
2593 if (strlen( ttime) < 8) {
2594 gnutls_assert();
2595 return (time_t) -1;
2598 etime.tm_year = year;
2600 /* In order to work with 32 bit
2601 * time_t.
2603 if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
2604 return (time_t)2145914603; /* 2037-12-31 23:23:23 */
2606 xx[2] = 0;
2608 /* get the month
2610 memcpy(xx, ttime, 2); /* month */
2611 etime.tm_mon = atoi(xx) - 1;
2612 ttime += 2;
2614 /* get the day
2616 memcpy(xx, ttime, 2); /* day */
2617 etime.tm_mday = atoi(xx);
2618 ttime += 2;
2620 /* get the hour
2622 memcpy(xx, ttime, 2); /* hour */
2623 etime.tm_hour = atoi(xx);
2624 ttime += 2;
2626 /* get the minutes
2628 memcpy(xx, ttime, 2); /* minutes */
2629 etime.tm_min = atoi(xx);
2630 ttime += 2;
2632 etime.tm_sec = 0;
2634 ret = mktime_utc(&etime);
2636 return ret;
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)
2645 char xx[3];
2646 int year;
2648 if (strlen( ttime) < 10) {
2649 gnutls_assert();
2650 return (time_t) -1;
2652 xx[2] = 0;
2653 /* get the year
2655 memcpy(xx, ttime, 2); /* year */
2656 year = atoi(xx);
2657 ttime += 2;
2659 if (year > 49)
2660 year += 1900;
2661 else
2662 year += 2000;
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)
2673 char xx[5];
2674 int year;
2676 if (strlen( ttime) < 12) {
2677 gnutls_assert();
2678 return (time_t) -1;
2681 if (strchr(ttime, 'Z') == 0) {
2682 gnutls_assert();
2683 /* sorry we don't support it yet
2685 return (time_t)-1;
2687 xx[4] = 0;
2689 /* get the year
2691 memcpy(xx, ttime, 4); /* year */
2692 year = atoi(xx);
2693 ttime += 4;
2695 return _gnutls_x509_time2gtime( ttime, year);