]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Certificate revocation support is almost complete.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 8 Feb 2003 20:25:03 +0000 (20:25 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 8 Feb 2003 20:25:03 +0000 (20:25 +0000)
14 files changed:
includes/gnutls/x509.h
lib/x509/Makefile.am
lib/x509/common.c
lib/x509/crl.c
lib/x509/crl.h [deleted file]
lib/x509/dn.c
lib/x509/dn.h
lib/x509/pkcs7.c
lib/x509/verify.c
lib/x509/x509.c
lib/x509/x509.h
tests/test20.pem [new file with mode: 0644]
tests/test21.pem [new file with mode: 0644]
tests/x509_test.c

index b9e94897c830888d7328cf38f82585b110ca08ca..64bad194501074af0047896d2c9342081fab78c6 100644 (file)
@@ -83,10 +83,10 @@ int gnutls_x509_certificate_get_key_usage( gnutls_x509_certificate cert, unsigne
  */
 #define GNUTLS_KEY_DIGITAL_SIGNATURE           256
 #define GNUTLS_KEY_NON_REPUDIATION             128
-#define GNUTLS_KEY_GNUTLS_KEY_ENCIPHERMENT     64
+#define GNUTLS_KEY_KEY_ENCIPHERMENT            64
 #define GNUTLS_KEY_DATA_ENCIPHERMENT           32
-#define GNUTLS_KEY_GNUTLS_KEY_AGREEMENT                16
-#define GNUTLS_KEY_GNUTLS_KEY_CERT_SIGN                8
+#define GNUTLS_KEY_KEY_AGREEMENT               16
+#define GNUTLS_KEY_KEY_CERT_SIGN               8
 #define GNUTLS_KEY_CRL_SIGN                    4
 #define GNUTLS_KEY_ENCIPHER_ONLY               2
 #define GNUTLS_KEY_DECIPHER_ONLY               1
@@ -137,6 +137,8 @@ int gnutls_x509_crl_get_certificate_count(gnutls_x509_crl crl);
 int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index, unsigned char* serial,
         int* serial_size, time_t* time);
 
+int gnutls_x509_crl_check_issuer( gnutls_x509_crl crl,
+       gnutls_x509_certificate issuer);
 
 /* PKCS7 structures handling 
  */
@@ -166,7 +168,7 @@ typedef enum gnutls_certificate_verify_flags {
                                         */
 } gnutls_certificate_verify_flags;
 
-int gnutls_x509_certificate_is_issuer( gnutls_x509_certificate cert,
+int gnutls_x509_certificate_check_issuer( gnutls_x509_certificate cert,
        gnutls_x509_certificate issuer);
 
 int gnutls_x509_certificate_list_verify( gnutls_x509_certificate* cert_list, int cert_list_length, 
@@ -181,6 +183,10 @@ int gnutls_x509_crl_verify( gnutls_x509_crl crl,
        gnutls_x509_certificate *CA_list, int CA_list_length,
        unsigned int flags, unsigned int *verify);
 
+int gnutls_x509_certificate_check_revocation(gnutls_x509_certificate cert,
+                                            gnutls_x509_crl * crl_list,
+                                            int crl_list_length);
+
 
 #ifdef __cplusplus
 }
index 357dbf8a8908f0a5e6b263be879710afbfc33d2b..cedcc7fcb8920747c449e97023f1fbbd5210fbc2 100644 (file)
@@ -1,5 +1,5 @@
 INCLUDES = -I../ -I../minitasn1/ -I../../includes/
-EXTRA_DIST = crl.h dn.h common.h x509.h extensions.h pkcs7.h \
+EXTRA_DIST = dn.h common.h x509.h extensions.h pkcs7.h \
        x509-api.tex compat.h verify.h mpi.h
 
 noinst_LTLIBRARIES = libx509.la
index bdc7c22d534af89e951cc3a8379d7d45280d3bde..3b9fcb32a68754245a27d1c2db0183a4824d3985 100644 (file)
@@ -122,7 +122,7 @@ int result;
 char str[1024], tmpname[1024];
 const char* ANAME = NULL;
 int CHOICE = -1, len = -1;
-ASN1_TYPE tmpasn;
+ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
 
        if (value==NULL || value_size <=0 || res_size == NULL) {
                gnutls_assert();
@@ -150,7 +150,7 @@ ASN1_TYPE tmpasn;
        _gnutls_str_cat( tmpname, sizeof(tmpname), ANAME);
 
        if ((result =
-            _gnutls_asn1_create_element(_gnutls_get_pkix(), str,
+            asn1_create_element(_gnutls_get_pkix(), str,
                                   &tmpasn, tmpname)) != ASN1_SUCCESS) {
                gnutls_assert();
                return _gnutls_asn2err(result);
index c13aa7caec01feb14ea4b821d8ff87fffd200191..1b4aad67ffaaf7d42448eec58c0cd9be9a0f060e 100644 (file)
@@ -26,7 +26,7 @@
 #include <gnutls_errors.h>
 #include <common.h>
 #include <x509_b64.h>
-#include <crl.h>
+#include <x509.h>
 #include <dn.h>
 
 /**
   **/
 int gnutls_x509_crl_init(gnutls_x509_crl * crl)
 {
-       *crl = gnutls_calloc( 1, sizeof(gnutls_x509_crl_int));
+       *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
 
-       if (*crl) return 0;             /* success */
+       if (*crl) {
+               (*crl)->crl = ASN1_TYPE_EMPTY;
+               return 0;       /* success */
+       }
        return GNUTLS_E_MEMORY_ERROR;
 }
 
@@ -80,7 +83,7 @@ void gnutls_x509_crl_deinit(gnutls_x509_crl crl)
   *
   **/
 int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
-       gnutls_x509_certificate_format format)
+                          gnutls_x509_certificate_format format)
 {
        int result = 0, need_free = 0;
        int start, end;
@@ -90,19 +93,21 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
         */
        if (format == GNUTLS_X509_FMT_PEM) {
                opaque *out;
-               
-               result = _gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
-                       &out);
+
+               result =
+                   _gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
+                                          &out);
 
                if (result <= 0) {
-                       if (result==0) result = GNUTLS_E_INTERNAL_ERROR;
+                       if (result == 0)
+                               result = GNUTLS_E_INTERNAL_ERROR;
                        gnutls_assert();
                        return result;
                }
-               
+
                _data.data = out;
                _data.size = result;
-               
+
                need_free = 1;
        }
 
@@ -116,7 +121,8 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
                return _gnutls_asn2err(result);
        }
 
-       result = asn1_der_decoding(&crl->crl, _data.data, _data.size, NULL);
+       result =
+           asn1_der_decoding(&crl->crl, _data.data, _data.size, NULL);
        if (result != ASN1_SUCCESS) {
                result = _gnutls_asn2err(result);
                gnutls_assert();
@@ -125,9 +131,9 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
 
        /* Get the signed data
         */
-       result = asn1_der_decoding_startEnd(crl->crl, _data.data, _data.size,
-                                           "crl2.tbsCertList", &start,
-                                           &end);
+       result =
+           asn1_der_decoding_startEnd(crl->crl, _data.data, _data.size,
+                                      "crl2.tbsCertList", &start, &end);
        if (result != ASN1_SUCCESS) {
                result = _gnutls_asn2err(result);
                gnutls_assert();
@@ -142,62 +148,70 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
                gnutls_assert();
                goto cleanup;
        }
-       
+
        /* Read the signature */
        {
                opaque signature[640];
                int len;
-               
+
                /* read the bit string of the signature
                 */
                len = sizeof(signature);
-               result = asn1_read_value( crl->crl, "crl2.signature", signature,
-                       &len);
-               
+               result =
+                   asn1_read_value(crl->crl, "crl2.signature", signature,
+                                   &len);
+
                if (result != ASN1_SUCCESS) {
                        result = _gnutls_asn2err(result);
                        gnutls_assert();
                        goto cleanup;
                }
-               
+
                if (len % 8 != 0) {
                        gnutls_assert();
                        result = GNUTLS_E_UNIMPLEMENTED_FEATURE;
                        goto cleanup;
                }
-               
-               if ((result=_gnutls_set_datum(&crl->signature, signature, len/8)) < 0) {
+
+               if ((result =
+                    _gnutls_set_datum(&crl->signature, signature,
+                                      len / 8)) < 0) {
                        gnutls_assert();
                        goto cleanup;
                }
-               
+
                /* Read the signature algorithm. Note that parameters are not
                 * read. They will be read from the issuer's certificate if needed.
                 */
-               
+
                len = sizeof(signature);
-               result = asn1_read_value( crl->crl, "crl2.signatureAlgorithm.algorithm",
-                       signature, &len);
-               
+               result =
+                   asn1_read_value(crl->crl,
+                                   "crl2.signatureAlgorithm.algorithm",
+                                   signature, &len);
+
                if (result != ASN1_SUCCESS) {
                        result = _gnutls_asn2err(result);
                        gnutls_assert();
                        goto cleanup;
                }
-               
-               crl->signature_algorithm = _gnutls_x509_oid2pk_algorithm( signature);
+
+               crl->signature_algorithm =
+                   _gnutls_x509_oid2pk_algorithm(signature);
        }
 
-       if (need_free) _gnutls_free_datum( &_data);
+       if (need_free)
+               _gnutls_free_datum(&_data);
 
        return 0;
 
       cleanup:
-       if (crl->crl)
+       if (crl->crl)
                asn1_delete_structure(&crl->crl);
        _gnutls_free_datum(&crl->signed_data);
        _gnutls_free_datum(&crl->signature);
-       if (need_free) _gnutls_free_datum( &_data);
+       if (need_free)
+               _gnutls_free_datum(&_data);
        return result;
 }
 
@@ -219,16 +233,17 @@ int gnutls_x509_crl_import(gnutls_x509_crl crl, const gnutls_datum * data,
   *
   **/
 int gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl crl, char *buf,
-                                        int *sizeof_buf)
+                                 int *sizeof_buf)
 {
        if (sizeof_buf == 0 || crl == NULL) {
                return GNUTLS_E_INVALID_REQUEST;
        }
-       
-       return _gnutls_x509_parse_dn( crl->crl, "crl2.tbsCertList.issuer.rdnSequence",
-               buf, sizeof_buf);
 
-               
+       return _gnutls_x509_parse_dn(crl->crl,
+                                    "crl2.tbsCertList.issuer.rdnSequence",
+                                    buf, sizeof_buf);
+
+
 }
 
 /**
@@ -251,17 +266,19 @@ int gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl crl, char *buf,
   * On success zero is returned.
   *
   **/
-int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl crl, const char* oid, 
-       int indx, char *buf, int *sizeof_buf)
+int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl crl,
+                                        const char *oid, int indx,
+                                        char *buf, int *sizeof_buf)
 {
        if (sizeof_buf == 0 || crl == NULL) {
                return GNUTLS_E_INVALID_REQUEST;
        }
-       
-       return _gnutls_x509_parse_dn_oid( crl->crl, "crl2.tbsCertList.issuer.rdnSequence", oid,
-               indx, buf, sizeof_buf);
 
-               
+       return _gnutls_x509_parse_dn_oid(crl->crl,
+                                        "crl2.tbsCertList.issuer.rdnSequence",
+                                        oid, indx, buf, sizeof_buf);
+
+
 }
 
 /**
@@ -275,7 +292,8 @@ int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl crl, const char* oid,
   * Returns 0 on success.
   *
   **/
-int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_const_datum *data)
+int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl,
+                                   gnutls_const_datum * data)
 {
        data->data = crl->signed_data.data;
        data->size = crl->signed_data.size;
@@ -294,7 +312,8 @@ int gnutls_x509_crl_get_signed_data(gnutls_x509_crl crl, gnutls_const_datum *dat
   * Returns 0 on success.
   *
   **/
-int gnutls_x509_crl_get_signature(gnutls_x509_crl crl, gnutls_const_datum *data)
+int gnutls_x509_crl_get_signature(gnutls_x509_crl crl,
+                                 gnutls_const_datum * data)
 {
        data->data = crl->signature.data;
        data->size = crl->signature.size;
@@ -332,10 +351,11 @@ int gnutls_x509_crl_get_version(gnutls_x509_crl crl)
 {
        opaque version[5];
        int len, result;
-       
+
        len = sizeof(version);
-       if ((result = asn1_read_value(crl->crl, "crl2.tbsCertList.version", version, &len)) !=
-               ASN1_SUCCESS) {
+       if ((result =
+            asn1_read_value(crl->crl, "crl2.tbsCertList.version", version,
+                            &len)) != ASN1_SUCCESS) {
                gnutls_assert();
                return _gnutls_asn2err(result);
        }
@@ -354,7 +374,8 @@ int gnutls_x509_crl_get_version(gnutls_x509_crl crl)
   **/
 time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl crl)
 {
-       return _gnutls_x509_get_time( crl->crl, "crl2.tbsCertList.thisUpdate");
+       return _gnutls_x509_get_time(crl->crl,
+                                    "crl2.tbsCertList.thisUpdate");
 }
 
 /**
@@ -370,7 +391,8 @@ time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl crl)
   **/
 time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl crl)
 {
-       return _gnutls_x509_get_time( crl->crl, "crl2.tbsCertList.nextUpdate");
+       return _gnutls_x509_get_time(crl->crl,
+                                    "crl2.tbsCertList.nextUpdate");
 }
 
 /**
@@ -387,12 +409,15 @@ int gnutls_x509_crl_get_certificate_count(gnutls_x509_crl crl)
 {
 
        int count, result;
-       
-       result = asn1_number_of_elements( crl->crl, "crl2.tbsCertList.revokedCertificates", &count);
+
+       result =
+           asn1_number_of_elements(crl->crl,
+                                   "crl2.tbsCertList.revokedCertificates",
+                                   &count);
 
        if (result != ASN1_SUCCESS) {
                gnutls_assert();
-               return 0; /* no certificates */
+               return 0;       /* no certificates */
        }
 
        return count;
@@ -412,37 +437,42 @@ int gnutls_x509_crl_get_certificate_count(gnutls_x509_crl crl)
   * Returns a negative value on failure.
   *
   **/
-int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index, unsigned char* serial,
-       int* serial_size, time_t* time)
+int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index,
+                                   unsigned char *serial,
+                                   int *serial_size, time_t * time)
 {
 
        int result;
        char str_index[MAX_INT_DIGITS];
        char serial_name[64];
        char date_name[64];
-       
-       _gnutls_int2str(index+1, str_index);
-       _gnutls_str_cpy( serial_name, sizeof(serial_name), "crl2.tbsCertList.revokedCertificates.?");
-       _gnutls_str_cat( serial_name, sizeof(serial_name), str_index);
-       _gnutls_str_cat( serial_name, sizeof(serial_name), ".userCertificate");
 
-       _gnutls_str_cpy( date_name, sizeof(date_name), "crl2.tbsCertList.revokedCertificates.?");
-       _gnutls_str_cat( date_name, sizeof(date_name), str_index);
-       _gnutls_str_cat( date_name, sizeof(date_name), ".revocationDate");
+       _gnutls_int2str(index + 1, str_index);
+       _gnutls_str_cpy(serial_name, sizeof(serial_name),
+                       "crl2.tbsCertList.revokedCertificates.?");
+       _gnutls_str_cat(serial_name, sizeof(serial_name), str_index);
+       _gnutls_str_cat(serial_name, sizeof(serial_name),
+                       ".userCertificate");
 
+       _gnutls_str_cpy(date_name, sizeof(date_name),
+                       "crl2.tbsCertList.revokedCertificates.?");
+       _gnutls_str_cat(date_name, sizeof(date_name), str_index);
+       _gnutls_str_cat(date_name, sizeof(date_name), ".revocationDate");
 
-       if ((result = asn1_read_value(crl->crl, serial_name, serial, serial_size)) != ASN1_SUCCESS)
-       {
+
+       if ((result =
+            asn1_read_value(crl->crl, serial_name, serial,
+                            serial_size)) != ASN1_SUCCESS) {
                gnutls_assert();
                if (result == ASN1_ELEMENT_NOT_FOUND)
                        return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
                return _gnutls_asn2err(result);
        }
-       
+
        if (time) {
-               *time = _gnutls_x509_get_time( crl->crl, date_name);
+               *time = _gnutls_x509_get_time(crl->crl, date_name);
        }
-       
+
        return 0;
 }
 
@@ -457,8 +487,8 @@ int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index, unsigned cha
   * Returns a negative value on error, and zero on success.
   *
   -*/
-int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
-       gnutls_const_datum* dn)
+int _gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl crl,
+                                      gnutls_const_datum * dn)
 {
        ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
        int result, len1;
@@ -468,12 +498,14 @@ int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
         */
        if ((result =
             asn1_create_element(_gnutls_get_pkix(), "PKIX1.TBSCertList",
-                                  &c2, "c2")) != ASN1_SUCCESS) {
+                                &c2, "c2")) != ASN1_SUCCESS) {
                gnutls_assert();
                return _gnutls_asn2err(result);
        }
 
-       result = asn1_der_decoding(&c2, crl->signed_data.data, crl->signed_data.size, NULL);
+       result =
+           asn1_der_decoding(&c2, crl->signed_data.data,
+                             crl->signed_data.size, NULL);
        if (result != ASN1_SUCCESS) {
                /* couldn't decode DER */
                gnutls_assert();
@@ -482,8 +514,9 @@ int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
        }
 
        result =
-           asn1_der_decoding_startEnd(c2, crl->signed_data.data, crl->signed_data.size,
-                  "c2.issuer", &start1, &end1);
+           asn1_der_decoding_startEnd(c2, crl->signed_data.data,
+                                      crl->signed_data.size, "c2.issuer",
+                                      &start1, &end1);
        asn1_delete_structure(&c2);
 
        if (result != ASN1_SUCCESS) {
@@ -499,3 +532,4 @@ int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
        return 0;
 
 }
+
diff --git a/lib/x509/crl.h b/lib/x509/crl.h
deleted file mode 100644 (file)
index afb7c57..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef CRL_H
-# define CRL_H
-
-#include "x509.h"
-
-typedef struct gnutls_x509_crl_int {
-       ASN1_TYPE crl;
-       gnutls_datum signed_data; /* Holds the signed data of the CRL.
-                                  */
-       gnutls_datum signature;
-       gnutls_pk_algorithm signature_algorithm;
-} gnutls_x509_crl_int;
-
-typedef struct gnutls_x509_crl_int *gnutls_x509_crl;
-
-int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
-       gnutls_const_datum* dn);
-
-#endif
index 67df0def118c3b040460a788187a537cefb40793..72f213d21b2802474e401e07c865e99a6572fcd0 100644 (file)
@@ -584,3 +584,26 @@ int gnutls_x509_rdn_get_by_oid(const gnutls_datum * idn, const char* oid, int in
        return result;
 
 }
+
+/*
+ * Compares the DER encoded part of a DN.
+ *
+ * FIXME: use a real DN comparison algorithm.
+ *
+ * Returns 1 if the DN's match and zero if they don't match. Otherwise
+ * a negative value is returned to indicate error.
+ */
+int _gnutls_x509_compare_raw_dn(const gnutls_const_datum * dn1,
+       const gnutls_const_datum * dn2) 
+{
+
+       if (dn1->size != dn2->size) {
+               gnutls_assert();
+               return 0;
+       }
+       if (memcmp(dn1->data, dn2->data, dn2->size) != 0) {
+               gnutls_assert();
+               return 0;
+       }
+       return 1; /* they match */
+}
index 65483375edb034c94935344250ca21a4b00894b3..d6b0fff4d018d7cef9d419cece5fc0fca625050b 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef DN_H
+# define DN_H
+
 /* Some OIDs usually found in Distinguished names
  */
 #define OID_X520_COUNTRY_NAME          "2 5 4 6"
@@ -17,3 +20,5 @@ int _gnutls_x509_parse_dn(ASN1_TYPE asn1_struct,
 int _gnutls_x509_parse_dn_oid(ASN1_TYPE asn1_struct, 
        const char* asn1_rdn_name, const char* oid, int indx, char *buf,
        int* sizeof_buf);
+
+#endif
index df84ca84c253a046e8abf563b1669cca2c1dabbc..36583c83eda06fa3f98bc1102bfcc311c141dcdf 100644 (file)
@@ -43,7 +43,10 @@ int gnutls_pkcs7_init(gnutls_pkcs7 * pkcs7)
 {
        *pkcs7 = gnutls_calloc( 1, sizeof(gnutls_pkcs7_int));
 
-       if (*pkcs7) return 0;           /* success */
+       if (*pkcs7) {
+               (*pkcs7)->pkcs7 = ASN1_TYPE_EMPTY;
+               return 0;               /* success */
+       }
        return GNUTLS_E_MEMORY_ERROR;
 }
 
@@ -150,7 +153,7 @@ int gnutls_pkcs7_import(gnutls_pkcs7 pkcs7, const gnutls_datum * data,
 int gnutls_pkcs7_get_certificate(gnutls_pkcs7 pkcs7, 
        int indx, char* certificate, int* certificate_size)
 {
-       ASN1_TYPE c2 = NULL;
+       ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
        int result, len;
        char oid[128];
        opaque *tmp = NULL;
@@ -205,7 +208,7 @@ int gnutls_pkcs7_get_certificate(gnutls_pkcs7 pkcs7,
 
        /* Step 1. In case of a signed structure extract certificate set.
         */
-       if ((result=_gnutls_asn1_create_element
+       if ((result=asn1_create_element
            (_gnutls_get_pkix(), "PKIX1.SignedData", &c2, "c2")) != ASN1_SUCCESS) {
                gnutls_assert();
                result = _gnutls_asn2err(result);
@@ -292,7 +295,7 @@ int gnutls_pkcs7_get_certificate(gnutls_pkcs7 pkcs7,
   **/
 int gnutls_pkcs7_get_certificate_count(gnutls_pkcs7 pkcs7)
 {
-       ASN1_TYPE c2;
+       ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
        int result, len, count;
        char oid[64];
        opaque *tmp = NULL;
@@ -344,7 +347,7 @@ int gnutls_pkcs7_get_certificate_count(gnutls_pkcs7 pkcs7)
 
        /* Step 1. In case of a signed structure count the certificate set.
         */
-       if ((result=_gnutls_asn1_create_element
+       if ((result=asn1_create_element
            (_gnutls_get_pkix(), "PKIX1.SignedData", &c2, "c2")) != ASN1_SUCCESS) {
                gnutls_assert();
                result = _gnutls_asn2err(result);
index 42547029df8b8b2c72d04838929199b3282c6069..2c105f242515f8c886625bdff414e245221ca036 100644 (file)
@@ -32,8 +32,8 @@
 #include <gnutls_sig.h>
 #include <gnutls_str.h>
 #include <gnutls_datum.h>
+#include <dn.h>
 #include <x509.h>
-#include <crl.h>
 #include <mpi.h>
 #include <verify.h>
 
@@ -83,8 +83,6 @@ static int check_if_ca(gnutls_x509_certificate cert,
  * This does a straight (DER) compare of the issuer/subject fields in
  * the given certificates.
  *
- * FIXME: use a real DN comparison algorithm.
- *
  * Returns 1 if the match and zero if they don't match. Otherwise
  * a negative value is returned to indicate error.
  */
@@ -106,17 +104,7 @@ int is_issuer(gnutls_x509_certificate cert, gnutls_x509_certificate issuer_cert)
                return ret;
        }
 
-       if (dn1.size != dn2.size) {
-               gnutls_assert();
-               return 0;
-       }
-       if (memcmp(dn1.data, dn2.data, dn2.size) != 0) {
-               gnutls_assert();
-               return 0;
-       }
-
-       /* they match */
-       return 1;
+       return _gnutls_x509_compare_raw_dn( &dn1, &dn2);
 
 }
 
@@ -140,17 +128,7 @@ int is_crl_issuer(gnutls_x509_crl crl, gnutls_x509_certificate issuer_cert)
                return ret;
        }
 
-       if (dn1.size != dn2.size) {
-               gnutls_assert();
-               return 0;
-       }
-       if (memcmp(dn1.data, dn2.data, dn2.size) != 0) {
-               gnutls_assert();
-               return 0;
-       }
-
-       /* they match */
-       return 1;
+       return _gnutls_x509_compare_raw_dn( &dn1, &dn2);
 
 }
 
@@ -224,7 +202,7 @@ static int _gnutls_verify_certificate2(gnutls_x509_certificate cert,
                return 0;
        }
 
-       if (flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) {
+       if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN)) {
                if (check_if_ca(cert, issuer)==0) {
                        gnutls_assert();
                        return 0;
@@ -271,7 +249,7 @@ static int _gnutls_verify_crl2(gnutls_x509_crl crl,
                return 0;
        }
 
-       if (flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) {
+       if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN)) {
                if (gnutls_x509_certificate_get_ca_status(issuer, NULL) != 1) 
                {
                        gnutls_assert();
@@ -313,7 +291,18 @@ unsigned int _gnutls_x509_verify_certificate(gnutls_x509_certificate * certifica
        int i = 0, ret;
        unsigned int status = 0;
 
-       /* Verify the certificate path */
+       /* Check for revoked certificates in the chain
+        */
+       for (i = 0; i < clist_size; i++) {
+               ret = gnutls_x509_certificate_check_revocation( certificate_list[i],
+                       CRLs, crls_size);
+               if (ret == 1) { /* revoked */
+                       status |= GNUTLS_CERT_REVOKED;
+               }
+       }
+
+       /* Verify the certificate path 
+        */
        for (i = 0; i < clist_size; i++) {
                if (i + 1 >= clist_size)
                        break;
@@ -326,10 +315,12 @@ unsigned int _gnutls_x509_verify_certificate(gnutls_x509_certificate * certifica
                }
        }
 
-       if (status != 0) { /* If there is any problem in the
-                          * certificate chain then mark as not trusted
-                          * and return immediately.
-                          */
+       if (status != 0) {
+                 /* If there is any problem in the
+                  * certificate chain then mark as not trusted
+                  * and return immediately.
+                  */
+               gnutls_assert();
                return (status | GNUTLS_CERT_NOT_TRUSTED);
        }
        
@@ -624,7 +615,7 @@ int gnutls_x509_certificate_verify( gnutls_x509_certificate cert,
 }
 
 /**
-  * gnutls_x509_certificate_is_issuer - This function checks if the certificate given has the given issuer
+  * gnutls_x509_certificate_check_issuer - This function checks if the certificate given has the given issuer
   * @cert: is the certificate to be checked
   * @issuer: is the certificate of a possible issuer
   *
@@ -635,14 +626,14 @@ int gnutls_x509_certificate_verify( gnutls_x509_certificate cert,
   * A negative value is returned in case of an error.
   *
   **/
-int gnutls_x509_certificate_is_issuer( gnutls_x509_certificate cert,
+int gnutls_x509_certificate_check_issuer( gnutls_x509_certificate cert,
        gnutls_x509_certificate issuer)
 {
        return is_issuer(cert, issuer);
 }
 
 /**
-  * gnutls_x509_crl_is_issuer - This function checks if the CRL given has the given issuer
+  * gnutls_x509_crl_check_issuer - This function checks if the CRL given has the given issuer
   * @crl: is the CRL to be checked
   * @issuer: is the certificate of a possible issuer
   *
@@ -653,7 +644,7 @@ int gnutls_x509_certificate_is_issuer( gnutls_x509_certificate cert,
   * A negative value is returned in case of an error.
   *
   **/
-int gnutls_x509_crl_is_issuer( gnutls_x509_crl cert,
+int gnutls_x509_crl_check_issuer( gnutls_x509_crl cert,
        gnutls_x509_certificate issuer)
 {
        return is_crl_issuer(cert, issuer);
index 30b26d821ad8c316349f8aa2654b47c732513698..fc45dd872d79cd6cc4eee78b01db3a7251629780 100644 (file)
@@ -44,7 +44,10 @@ int gnutls_x509_certificate_init(gnutls_x509_certificate * cert)
 {
        *cert = gnutls_calloc( 1, sizeof(gnutls_x509_certificate_int));
 
-       if (*cert) return 0;            /* success */
+       if (*cert) {
+               (*cert)->cert = ASN1_TYPE_EMPTY;
+               return 0;               /* success */
+       }
        return GNUTLS_E_MEMORY_ERROR;
 }
 
@@ -726,8 +729,8 @@ int gnutls_x509_certificate_get_ca_status(gnutls_x509_certificate cert, int* cri
   * This function will return certificate's key usage, by reading the 
   * keyUsage X.509 extension. The key usage value will ORed values of the:
   * GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_NON_REPUDIATION,
-  * GNUTLS_KEY_GNUTLS_KEY_ENCIPHERMENT, GNUTLS_KEY_DATA_ENCIPHERMENT,
-  * GNUTLS_KEY_GNUTLS_KEY_AGREEMENT, GNUTLS_KEY_GNUTLS_KEY_CERT_SIGN,
+  * GNUTLS_KEY_KEY_ENCIPHERMENT, GNUTLS_KEY_DATA_ENCIPHERMENT,
+  * GNUTLS_KEY_KEY_AGREEMENT, GNUTLS_KEY_KEY_CERT_SIGN,
   * GNUTLS_KEY_CRL_SIGN, GNUTLS_KEY_ENCIPHER_ONLY,
   * GNUTLS_KEY_DECIPHER_ONLY.
   *
@@ -896,3 +899,99 @@ int _gnutls_x509_certificate_get_raw_dn( gnutls_x509_certificate cert,
 {
        return _gnutls_x509_certificate_get_raw_dn2( cert, "c2.subject", start);
 }
+
+
+/**
+  * gnutls_x509_certificate_check_revocation - This function checks if the given certificate is revoked
+  * @cert: should contain a gnutls_x509_certificate structure
+  * @crl_list: should contain a list of gnutls_x509_crl structures
+  * @crl_list_length: the length of the crl_list
+  *
+  * This function will return check if the given certificate is revoked.
+  * It is assumed that the CRLs have been verified before.
+  *
+  * Returns 0 if the certificate is NOT revoked, and 1 if it is.
+  * A negative value is returned on error. 
+  *
+  **/
+int gnutls_x509_certificate_check_revocation(gnutls_x509_certificate cert,
+                                            gnutls_x509_crl * crl_list,
+                                            int crl_list_length)
+{
+       opaque serial[64];
+       opaque cert_serial[64];
+       int serial_size, cert_serial_size;
+       int ncerts, ret, i, j;
+       gnutls_const_datum dn1, dn2;
+
+       for (j = 0; j < crl_list_length; j++) { /* do for all the crls */
+
+               /* Step 1. check if issuer's DN match
+                */
+               ret = _gnutls_x509_crl_get_raw_issuer_dn(crl_list[j], &dn1);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+
+               ret =
+                   _gnutls_x509_certificate_get_raw_issuer_dn(cert, &dn2);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+
+               ret = _gnutls_x509_compare_raw_dn(&dn1, &dn2);
+               if (ret == 0) {
+                       /* issuers do not match so don't even
+                        * bother checking.
+                        */
+                       continue;
+               }
+
+               /* Step 2. Read the certificate's serial number
+                */
+               cert_serial_size = sizeof(cert_serial);
+               ret =
+                   gnutls_x509_certificate_get_serial(cert, cert_serial,
+                                                      &cert_serial_size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+
+               /* Step 3. cycle through the CRL serials and compare with
+                *   certificate serial we have.
+                */
+
+               ncerts = gnutls_x509_crl_get_certificate_count(crl_list[j]);
+               if (ncerts < 0) {
+                       gnutls_assert();
+                       return ncerts;
+               }
+
+               for (i = 0; i < ncerts; i++) {
+                       serial_size = sizeof(serial);
+                       ret =
+                           gnutls_x509_crl_get_certificate(crl_list[j], i, serial,
+                                                           &serial_size,
+                                                           NULL);
+
+                       if (ret < 0) {
+                               gnutls_assert();
+                               return ret;
+                       }
+
+                       if (serial_size == cert_serial_size) {
+                               if (memcmp
+                                   (serial, cert_serial,
+                                    serial_size) == 0) {
+                                       /* serials match */
+                                       return 1;       /* revoked! */
+                               }
+                       }
+               }
+
+       }
+       return 0;               /* not revoked. */
+}
index f1a3aa16cbb6d542208226989b8e566f3112c745..31f06e4918049024376bb45f6943e2d7e0c2a622 100644 (file)
@@ -1,6 +1,14 @@
 #ifndef X509_H
 # define X509_H
 
+typedef struct gnutls_x509_crl_int {
+       ASN1_TYPE crl;
+       gnutls_datum signed_data; /* Holds the signed data of the CRL.
+                                  */
+       gnutls_datum signature;
+       gnutls_pk_algorithm signature_algorithm;
+} gnutls_x509_crl_int;
+
 typedef struct gnutls_x509_certificate_int {
        ASN1_TYPE cert;
        gnutls_datum signed_data; /* Holds the signed data of the CRL.
@@ -10,6 +18,7 @@ typedef struct gnutls_x509_certificate_int {
 } gnutls_x509_certificate_int;
 
 typedef struct gnutls_x509_certificate_int *gnutls_x509_certificate;
+typedef struct gnutls_x509_crl_int *gnutls_x509_crl;
 
 int gnutls_x509_certificate_get_issuer_dn_by_oid(gnutls_x509_certificate cert, const char* oid, 
        int indx, char *buf, int *sizeof_buf);
@@ -25,5 +34,19 @@ int _gnutls_x509_certificate_get_raw_issuer_dn( gnutls_x509_certificate cert,
 int _gnutls_x509_certificate_get_raw_dn( gnutls_x509_certificate cert,
        gnutls_const_datum* start);
 
+int gnutls_x509_certificate_get_serial(gnutls_x509_certificate cert, char* result, int* result_size);
+
+int _gnutls_x509_compare_raw_dn(const gnutls_const_datum * dn1,
+       const gnutls_const_datum * dn2);
+
+int gnutls_x509_certificate_check_revocation(gnutls_x509_certificate cert, gnutls_x509_crl * crl_list, int crl_list_length);
+
+
+int _gnutls_x509_crl_get_raw_issuer_dn( gnutls_x509_crl crl,
+       gnutls_const_datum* dn);
+int gnutls_x509_crl_get_certificate_count(gnutls_x509_crl crl);
+int gnutls_x509_crl_get_certificate(gnutls_x509_crl crl, int index,
+                                   unsigned char *serial,
+                                   int *serial_size, time_t * time);
 
 #endif
diff --git a/tests/test20.pem b/tests/test20.pem
new file mode 100644 (file)
index 0000000..957832d
--- /dev/null
@@ -0,0 +1,192 @@
+[ The intermediate certificate has been revoked ]
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 40 (0x28)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=US, O=U.S. Government, OU=Dod, OU=Testing, CN=CA1-CP.06.01
+        Validity
+            Not Before: Jan  1 12:01:00 1998 GMT
+            Not After : Jan  1 12:01:00 2048 GMT
+        Subject: C=US, O=U.S. Government, OU=DoD, OU=Testing, CN=User1-CP.06.01
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:e8:7b:95:4c:0c:45:eb:7b:b7:f0:01:23:a9:a8:
+                    db:b0:ac:9d:1c:d0:eb:85:f1:ed:fd:5d:ab:1a:c9:
+                    36:eb:92:46:c9:55:4a:16:96:9f:08:86:1e:37:3e:
+                    e7:f4:d2:ed:4a:df:8f:d5:4e:d1:db:1e:04:2c:cf:
+                    b3:26:05:a0:85:f5:ab:b4:39:ce:50:2b:c3:2d:b8:
+                    aa:95:d3:18:c9:a5:a4:41:81:cb:38:bb:8e:45:ce:
+                    f3:0e:7e:c2:a8:77:fb:c4:45:ad:04:33:af:bd:73:
+                    2e:d0:15:57:fa:8f:53:29:5e:b8:5f:0c:f2:3c:e4:
+                    c1:f3:ef:6b:0b:a7:9b:07:4b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Key Usage: critical
+                Digital Signature, Non Repudiation, Key Encipherment
+            X509v3 Certificate Policies: 
+                Policy: 2.16.840.1.101.3.1.48.1
+
+            X509v3 Subject Key Identifier: 
+                6B:20:B4:3C:F5:3D:CF:2B
+            X509v3 Authority Key Identifier: 
+                keyid:08:80:26:97:3E:BE:09:CD
+
+    Signature Algorithm: sha1WithRSAEncryption
+        3f:3e:db:52:f6:84:57:b3:32:8e:17:bc:2c:93:bf:b2:88:fc:
+        e1:7e:f5:ae:f5:4f:b4:13:eb:85:88:d6:4c:9e:a9:eb:d1:82:
+        7c:94:72:86:8d:ef:01:42:2d:f1:11:5a:97:51:85:6f:bd:9c:
+        e3:90:d0:1a:47:15:cc:b2:c9:c3:c7:03:3f:76:a3:b5:66:9c:
+        e4:76:7d:74:d3:c9:91:6f:8a:87:5d:a5:f6:0a:a3:9f:4e:b5:
+        5c:08:d0:e1:79:db:6f:04:03:60:2b:97:86:0b:8f:13:db:f7:
+        93:30:db:8a:6c:15:c0:81:0e:07:fe:12:01:15:f7:ef:2e:d3:
+        51:69
+-----BEGIN CERTIFICATE-----
+MIIChjCCAe+gAwIBAgIBKDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsT
+B1Rlc3RpbmcxFTATBgNVBAMTDENBMS1DUC4wNi4wMTAeFw05ODAxMDExMjAxMDBa
+Fw00ODAxMDExMjAxMDBaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdv
+dmVybm1lbnQxDDAKBgNVBAsTA0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UE
+AxMOVXNlcjEtQ1AuMDYuMDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh7
+lUwMRet7t/ABI6mo27CsnRzQ64Xx7f1dqxrJNuuSRslVShaWnwiGHjc+5/TS7Urf
+j9VO0dseBCzPsyYFoIX1q7Q5zlArwy24qpXTGMmlpEGByzi7jkXO8w5+wqh3+8RF
+rQQzr71zLtAVV/qPUyleuF8M8jzkwfPvawunmwdLAgMBAAGjUjBQMA4GA1UdDwEB
+/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECgQIayC0PPU9
+zyswEwYDVR0jBAwwCoAICIAmlz6+Cc0wDQYJKoZIhvcNAQEFBQADgYEAPz7bUvaE
+V7Myjhe8LJO/soj84X71rvVPtBPrhYjWTJ6p69GCfJRyho3vAUIt8RFal1GFb72c
+45DQGkcVzLLJw8cDP3ajtWac5HZ9dNPJkW+Kh12l9gqjn061XAjQ4XnbbwQDYCuX
+hguPE9v3kzDbimwVwIEOB/4SARX37y7TUWk=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 39 (0x27)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=US, O=U.S. Government, OU=DoD, OU=Testing, CN=Trust Anchor
+        Validity
+            Not Before: Jan  1 12:01:00 1998 GMT
+            Not After : Jan  1 12:01:00 2048 GMT
+        Subject: C=US, O=U.S. Government, OU=Dod, OU=Testing, CN=CA1-CP.06.01
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:c8:e0:c5:d9:07:4f:01:7d:41:f1:a3:ff:f8:45:
+                    ee:c0:c7:4a:96:90:78:32:ea:76:fe:fd:76:8b:43:
+                    61:70:3d:bb:e9:6f:99:a4:84:b8:6a:0d:90:52:5f:
+                    72:90:2f:46:22:27:ca:7c:d6:d9:9d:bd:14:07:fc:
+                    b6:c5:cd:7f:f7:38:a0:53:51:f5:79:8a:66:32:f7:
+                    bf:40:d8:d1:1b:e2:8b:45:a7:a1:03:4a:c9:19:86:
+                    db:58:dd:dd:88:cd:42:02:a0:25:94:5e:13:9b:9e:
+                    69:07:27:68:c4:73:cd:5b:82:01:64:2b:92:e2:af:
+                    59:bf:b4:aa:b6:20:e3:c5:25
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Certificate Policies: 
+                Policy: 2.16.840.1.101.3.1.48.1
+
+            X509v3 Subject Key Identifier: 
+                08:80:26:97:3E:BE:09:CD
+            X509v3 Authority Key Identifier: 
+                keyid:AB:9A:EB:F9:C2:E7:54:8F
+
+    Signature Algorithm: sha1WithRSAEncryption
+        d1:9b:c8:1b:67:27:93:7d:a9:ea:ec:6a:1b:0f:01:bb:8d:0d:
+        ad:f1:ee:f6:03:64:24:be:4c:84:31:c9:5c:0e:8e:c5:4e:41:
+        5f:96:d6:66:92:e7:29:72:e8:1e:2a:92:76:d1:1d:9b:2e:5c:
+        2d:9c:37:92:08:31:9d:dc:63:b2:74:45:33:20:9a:c1:a6:2e:
+        a4:90:61:96:0a:ae:15:bb:af:06:d0:3c:ac:cb:64:73:91:f8:
+        ce:e7:4f:65:c3:9c:bd:7b:bb:5f:0e:7c:2b:ed:5c:69:21:94:
+        44:bf:80:ea:e5:c5:3e:73:14:05:dd:7e:93:e7:a3:6e:d3:bc:
+        3e:da
+-----BEGIN CERTIFICATE-----
+MIIClTCCAf6gAwIBAgIBJzANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsT
+B1Rlc3RpbmcxFTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBa
+Fw00ODAxMDExMjAxMDBaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdv
+dmVybm1lbnQxDDAKBgNVBAsTA0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UE
+AxMMQ0ExLUNQLjA2LjAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI4MXZ
+B08BfUHxo//4Re7Ax0qWkHgy6nb+/XaLQ2FwPbvpb5mkhLhqDZBSX3KQL0YiJ8p8
+1tmdvRQH/LbFzX/3OKBTUfV5imYy979A2NEb4otFp6EDSskZhttY3d2IzUICoCWU
+XhObnmkHJ2jEc81bggFkK5Lir1m/tKq2IOPFJQIDAQABo2MwYTAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATAR
+BgNVHQ4ECgQICIAmlz6+Cc0wEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN
+AQEFBQADgYEA0ZvIG2cnk32p6uxqGw8Bu40NrfHu9gNkJL5MhDHJXA6OxU5BX5bW
+ZpLnKXLoHiqSdtEdmy5cLZw3kggxndxjsnRFMyCawaYupJBhlgquFbuvBtA8rMtk
+c5H4zudPZcOcvXu7Xw58K+1caSGURL+A6uXFPnMUBd1+k+ejbtO8Pto=
+-----END CERTIFICATE-----
+Certificate Revocation List (CRL):
+        Version 2 (0x1)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: /C=US/O=U.S. Government/OU=Dod/OU=Testing/CN=CA1-CP.06.01
+        Last Update: Jan  1 12:01:00 1999 GMT
+        Next Update: Jan  1 12:01:00 2048 GMT
+        CRL extensions:
+            X509v3 CRL Number: 
+                1
+            X509v3 Authority Key Identifier: 
+                keyid:08:80:26:97:3E:BE:09:CD
+
+No Revoked Certificates.
+    Signature Algorithm: sha1WithRSAEncryption
+        6e:42:5e:8d:f7:35:af:3b:42:6e:d0:ba:c4:96:77:89:91:03:
+        0c:c5:b6:0b:11:6f:3a:f4:b0:86:60:a3:3e:a5:58:de:5a:c2:
+        3c:d4:90:cd:d8:e6:a9:ea:62:a0:29:ee:ee:89:e0:3f:e1:c0:
+        03:b8:4c:ed:b9:be:4a:83:7b:2b:35:ca:b9:f4:3b:0b:63:8d:
+        a0:0c:2f:a0:f6:60:9e:88:9d:83:b4:55:10:2c:54:07:20:fa:
+        00:9b:b4:e3:27:76:c0:22:d8:46:90:9f:4b:6b:43:b5:72:e1:
+        1c:40:e9:7b:e1:0b:c2:fd:f9:a5:b9:02:32:50:8e:da:ee:c9:
+        f9:37
+-----BEGIN X509 CRL-----
+MIIBSzCBtQIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UE
+ChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rp
+bmcxFTATBgNVBAMTDENBMS1DUC4wNi4wMRcNOTkwMTAxMTIwMTAwWhcNNDgwMTAx
+MTIwMTAwWqAjMCEwCgYDVR0UBAMCAQEwEwYDVR0jBAwwCoAICIAmlz6+Cc0wDQYJ
+KoZIhvcNAQEFBQADgYEAbkJejfc1rztCbtC6xJZ3iZEDDMW2CxFvOvSwhmCjPqVY
+3lrCPNSQzdjmqepioCnu7ongP+HAA7hM7bm+SoN7KzXKufQ7C2ONoAwvoPZgnoid
+g7RVECxUByD6AJu04yd2wCLYRpCfS2tDtXLhHEDpe+ELwv35pbkCMlCO2u7J+Tc=
+-----END X509 CRL-----
+
+Certificate Revocation List (CRL):
+        Version 2 (0x1)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: /C=US/O=U.S. Government/OU=DoD/OU=Testing/CN=Trust Anchor
+        Last Update: Jan  1 12:01:00 1999 GMT
+        Next Update: Jan  1 12:01:00 2048 GMT
+        CRL extensions:
+            X509v3 CRL Number: 
+                1
+            X509v3 Authority Key Identifier: 
+                keyid:AB:9A:EB:F9:C2:E7:54:8F
+
+Revoked Certificates:
+    Serial Number: 27
+        Revocation Date: Jan  1 12:00:00 1999 GMT
+            X509v3 CRL Reason Code: 
+                Key Compromise
+    Signature Algorithm: sha1WithRSAEncryption
+        0b:b9:6a:67:07:a3:25:15:bb:42:fc:c7:d7:5f:fb:71:87:0b:
+        de:b6:9c:80:cc:47:dc:f4:94:fe:e7:ef:c8:b9:3b:6a:14:7e:
+        f9:1b:47:6a:bc:bf:59:e0:af:45:dc:b3:9c:b8:88:38:0f:19:
+        06:28:2e:5a:d5:4f:aa:c3:72:b0:d9:fb:58:ba:1f:40:85:5a:
+        fb:f4:c3:dd:3f:a5:79:c7:b8:7b:53:70:19:0b:e3:e5:0f:9e:
+        db:04:6d:19:78:3e:80:2b:93:8d:32:94:15:f2:91:9d:6c:fb:
+        3b:b4:72:88:92:8a:8a:6d:23:b4:01:78:46:40:a9:2d:e6:cd:
+        0a:16
+-----BEGIN X509 CRL-----
+MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UE
+ChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsTB1Rlc3Rp
+bmcxFTATBgNVBAMTDFRydXN0IEFuY2hvchcNOTkwMTAxMTIwMTAwWhcNNDgwMTAx
+MTIwMTAwWjAiMCACAScXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEw
+CgYDVR0UBAMCAQEwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcNAQEFBQAD
+gYEAC7lqZwejJRW7QvzH11/7cYcL3racgMxH3PSU/ufvyLk7ahR++RtHary/WeCv
+RdyznLiIOA8ZBiguWtVPqsNysNn7WLofQIVa+/TD3T+lece4e1NwGQvj5Q+e2wRt
+GXg+gCuTjTKUFfKRnWz7O7RyiJKKim0jtAF4RkCpLebNChY=
+-----END X509 CRL-----
diff --git a/tests/test21.pem b/tests/test21.pem
new file mode 100644 (file)
index 0000000..2a3b253
--- /dev/null
@@ -0,0 +1,163 @@
+[ The end certificate has been revoked ]
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 42 (0x2a)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=US, O=U.S. Government, OU=Dod, OU=Testing, CN=CA1-CP.06.02
+        Validity
+            Not Before: Jan  1 12:01:00 1998 GMT
+            Not After : Jan  1 12:01:00 2048 GMT
+        Subject: C=US, O=U.S. Government, OU=DoD, OU=Testing, CN=User1-CP.06.02
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:ae:03:f4:7f:09:c5:e2:2b:16:e3:a6:c7:47:12:
+                    90:86:0d:4b:4a:7b:70:34:81:95:c7:39:ec:d6:b7:
+                    fb:59:3b:94:90:fb:98:4f:59:3f:af:f8:ed:8b:03:
+                    54:ad:9b:c1:ee:1a:4c:a0:93:5e:d3:e4:fe:41:90:
+                    e9:bb:0b:b3:02:57:6f:25:b8:93:8f:9f:e4:b7:80:
+                    62:85:e0:6e:66:57:8c:05:85:f8:12:88:97:cb:8a:
+                    7a:db:2a:0b:71:e4:09:ea:a1:05:a6:35:00:65:2a:
+                    79:fe:28:38:09:1a:90:43:fe:d6:36:05:ba:63:58:
+                    b4:c6:81:fb:dc:7f:d2:77:01
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Key Usage: critical
+                Digital Signature, Non Repudiation, Key Encipherment
+            X509v3 Certificate Policies: 
+                Policy: 2.16.840.1.101.3.1.48.1
+
+            X509v3 Subject Key Identifier: 
+                0B:D3:22:24:D2:3B:D5:13
+            X509v3 Authority Key Identifier: 
+                keyid:68:7C:56:39:D1:EC:2D:B5
+
+    Signature Algorithm: sha1WithRSAEncryption
+        a3:f8:9b:98:8c:6d:7a:2b:72:8d:99:6c:ce:30:9c:fe:ce:f2:
+        33:fd:2c:9c:be:fc:a5:8a:4c:39:9d:cf:d9:33:ca:91:88:76:
+        4e:1e:3e:07:0f:09:a9:7d:74:f8:cf:f3:c0:50:63:e4:1c:3b:
+        22:6c:c2:21:17:d2:dc:61:6e:2a:67:15:73:21:c1:e0:e6:4b:
+        31:c4:19:b5:75:80:f0:63:99:f7:86:2f:5a:ae:53:04:83:65:
+        56:d4:e1:42:db:ac:42:3d:79:28:1a:b6:4c:93:4d:15:4c:83:
+        a4:17:6f:ca:8d:39:02:71:2c:45:8d:07:6c:84:2e:e9:98:4d:
+        43:8d
+-----BEGIN CERTIFICATE-----
+MIIChjCCAe+gAwIBAgIBKjANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsT
+B1Rlc3RpbmcxFTATBgNVBAMTDENBMS1DUC4wNi4wMjAeFw05ODAxMDExMjAxMDBa
+Fw00ODAxMDExMjAxMDBaMGAxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdv
+dmVybm1lbnQxDDAKBgNVBAsTA0RvRDEQMA4GA1UECxMHVGVzdGluZzEXMBUGA1UE
+AxMOVXNlcjEtQ1AuMDYuMDIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK4D
+9H8JxeIrFuOmx0cSkIYNS0p7cDSBlcc57Na3+1k7lJD7mE9ZP6/47YsDVK2bwe4a
+TKCTXtPk/kGQ6bsLswJXbyW4k4+f5LeAYoXgbmZXjAWF+BKIl8uKetsqC3HkCeqh
+BaY1AGUqef4oOAkakEP+1jYFumNYtMaB+9x/0ncBAgMBAAGjUjBQMA4GA1UdDwEB
+/wQEAwIF4DAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATARBgNVHQ4ECgQIC9MiJNI7
+1RMwEwYDVR0jBAwwCoAIaHxWOdHsLbUwDQYJKoZIhvcNAQEFBQADgYEAo/ibmIxt
+eityjZlszjCc/s7yM/0snL78pYpMOZ3P2TPKkYh2Th4+Bw8JqX10+M/zwFBj5Bw7
+ImzCIRfS3GFuKmcVcyHB4OZLMcQZtXWA8GOZ94YvWq5TBINlVtThQtusQj15KBq2
+TJNNFUyDpBdvyo05AnEsRY0HbIQu6ZhNQ40=
+-----END CERTIFICATE-----
+
+
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 41 (0x29)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=US, O=U.S. Government, OU=DoD, OU=Testing, CN=Trust Anchor
+        Validity
+            Not Before: Jan  1 12:01:00 1998 GMT
+            Not After : Jan  1 12:01:00 2048 GMT
+        Subject: C=US, O=U.S. Government, OU=Dod, OU=Testing, CN=CA1-CP.06.02
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (1024 bit)
+                Modulus (1024 bit):
+                    00:bf:21:e8:d5:dc:39:9e:68:b5:bc:3b:03:1f:00:
+                    6c:ab:e7:ef:0d:3b:13:35:0b:e5:01:62:c9:5b:39:
+                    f5:a3:29:41:9d:86:55:fa:4f:11:5c:e4:03:89:54:
+                    90:69:4b:f4:23:78:0f:91:5a:85:02:c6:7c:4a:6f:
+                    d4:12:94:ea:c1:98:00:eb:72:71:b3:f3:35:74:fd:
+                    cd:09:0c:b6:94:de:84:a0:b1:51:16:64:4d:12:7b:
+                    10:55:5a:b2:9c:97:58:fb:c0:dd:11:bb:13:1e:02:
+                    9d:f8:db:f6:28:ca:f0:70:79:ad:d5:7a:a2:64:99:
+                    20:9c:ed:8d:93:8e:bb:96:11
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+            X509v3 Certificate Policies: 
+                Policy: 2.16.840.1.101.3.1.48.1
+
+            X509v3 Subject Key Identifier: 
+                68:7C:56:39:D1:EC:2D:B5
+            X509v3 Authority Key Identifier: 
+                keyid:AB:9A:EB:F9:C2:E7:54:8F
+
+    Signature Algorithm: sha1WithRSAEncryption
+        bb:37:aa:fe:5a:a9:d2:ab:3a:da:4a:ca:e8:40:3c:d5:28:a5:
+        87:2e:36:97:f2:a6:ca:71:37:99:5b:bd:18:f0:60:41:2d:01:
+        50:38:bb:fa:b4:10:fa:6d:14:c5:81:25:ce:3d:92:34:ee:09:
+        e5:a0:58:78:2f:7c:95:52:45:08:75:fb:40:4f:32:54:ea:0f:
+        05:07:79:ac:0f:ab:af:3e:07:0f:d4:28:3f:b8:25:c5:3a:8b:
+        53:a4:dc:f5:51:5d:fa:26:85:a6:ab:15:b5:28:76:6f:11:f6:
+        06:d5:01:d8:04:60:79:b4:e4:95:a3:65:e5:53:db:bb:4f:b2:
+        73:62
+-----BEGIN CERTIFICATE-----
+MIIClTCCAf6gAwIBAgIBKTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEY
+MBYGA1UEChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb0QxEDAOBgNVBAsT
+B1Rlc3RpbmcxFTATBgNVBAMTDFRydXN0IEFuY2hvcjAeFw05ODAxMDExMjAxMDBa
+Fw00ODAxMDExMjAxMDBaMF4xCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9VLlMuIEdv
+dmVybm1lbnQxDDAKBgNVBAsTA0RvZDEQMA4GA1UECxMHVGVzdGluZzEVMBMGA1UE
+AxMMQ0ExLUNQLjA2LjAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/IejV
+3DmeaLW8OwMfAGyr5+8NOxM1C+UBYslbOfWjKUGdhlX6TxFc5AOJVJBpS/QjeA+R
+WoUCxnxKb9QSlOrBmADrcnGz8zV0/c0JDLaU3oSgsVEWZE0SexBVWrKcl1j7wN0R
+uxMeAp342/YoyvBwea3VeqJkmSCc7Y2TjruWEQIDAQABo2MwYTAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAWBgNVHSAEDzANMAsGCWCGSAFlAwEwATAR
+BgNVHQ4ECgQIaHxWOdHsLbUwEwYDVR0jBAwwCoAIq5rr+cLnVI8wDQYJKoZIhvcN
+AQEFBQADgYEAuzeq/lqp0qs62krK6EA81Silhy42l/KmynE3mVu9GPBgQS0BUDi7
++rQQ+m0UxYElzj2SNO4J5aBYeC98lVJFCHX7QE8yVOoPBQd5rA+rrz4HD9QoP7gl
+xTqLU6Tc9VFd+iaFpqsVtSh2bxH2BtUB2ARgebTklaNl5VPbu0+yc2I=
+-----END CERTIFICATE-----
+
+Certificate Revocation List (CRL):
+        Version 2 (0x1)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: /C=US/O=U.S. Government/OU=Dod/OU=Testing/CN=CA1-CP.06.02
+        Last Update: Jan  1 12:01:00 1999 GMT
+        Next Update: Jan  1 12:01:00 2048 GMT
+        CRL extensions:
+            X509v3 CRL Number: 
+                1
+            X509v3 Authority Key Identifier: 
+                keyid:68:7C:56:39:D1:EC:2D:B5
+
+Revoked Certificates:
+    Serial Number: 2A
+        Revocation Date: Jan  1 12:00:00 1999 GMT
+            X509v3 CRL Reason Code: 
+                Key Compromise
+    Signature Algorithm: sha1WithRSAEncryption
+        60:66:80:cd:5a:14:76:54:99:de:e1:8a:89:13:df:1c:01:48:
+        a0:a4:fb:f6:13:4e:be:d3:b1:68:60:34:68:87:a4:f4:ec:a9:
+        0e:b0:ea:60:08:7f:b3:68:ec:5d:28:5e:2f:4a:6b:fe:ff:56:
+        44:81:ef:b4:2b:7b:ca:d5:c3:c5:5c:a7:e0:dc:63:a5:fb:fb:
+        06:40:0c:32:27:1c:75:4c:75:38:7d:55:12:54:d1:92:69:ad:
+        31:ee:d1:3b:35:1e:1d:41:b3:5c:93:4f:7b:1d:41:73:d0:6f:
+        48:28:47:d7:c6:d6:61:c9:32:39:97:58:24:18:dc:b4:22:89:
+        16:0c
+-----BEGIN X509 CRL-----
+MIIBbzCB2QIBATANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEYMBYGA1UE
+ChMPVS5TLiBHb3Zlcm5tZW50MQwwCgYDVQQLEwNEb2QxEDAOBgNVBAsTB1Rlc3Rp
+bmcxFTATBgNVBAMTDENBMS1DUC4wNi4wMhcNOTkwMTAxMTIwMTAwWhcNNDgwMTAx
+MTIwMTAwWjAiMCACASoXDTk5MDEwMTEyMDAwMFowDDAKBgNVHRUEAwoBAaAjMCEw
+CgYDVR0UBAMCAQEwEwYDVR0jBAwwCoAIaHxWOdHsLbUwDQYJKoZIhvcNAQEFBQAD
+gYEAYGaAzVoUdlSZ3uGKiRPfHAFIoKT79hNOvtOxaGA0aIek9OypDrDqYAh/s2js
+XSheL0pr/v9WRIHvtCt7ytXDxVyn4Nxjpfv7BkAMMiccdUx1OH1VElTRkmmtMe7R
+OzUeHUGzXJNPex1Bc9BvSChH18bWYckyOZdYJBjctCKJFgw=
+-----END X509 CRL-----
index 7df91202babf866627678eec318872977fe9c795..f09338724359a875d11105ec925c6138c66c665c 100644 (file)
@@ -3,8 +3,6 @@
 #include <string.h>
 #include <gnutls/x509.h>
 
-#include <dmalloc.h>
-
 #define MAX_FILE_SIZE 16*1024
 
 struct file_res {
@@ -18,6 +16,8 @@ static struct file_res test_files[] = {
        { "test3.pem", GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED },
        { "test10.pem", 0 },
        { "test13.pem", GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED },
+       { "test20.pem", GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED },
+       { "test21.pem", GNUTLS_CERT_REVOKED | GNUTLS_CERT_NOT_TRUSTED },
        { "test22.pem", GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED },
        { "test23.pem", GNUTLS_CERT_INVALID | GNUTLS_CERT_NOT_TRUSTED },
        { "test24.pem", 0 },
@@ -41,8 +41,13 @@ static void print_res( int x)
                printf("- certificate is NOT trusted\n");
        else
                printf("- certificate is trusted\n");
+
        if (x&GNUTLS_CERT_CORRUPTED)
                printf("- Found a corrupted certificate.\n");
+
+       if (x&GNUTLS_CERT_REVOKED)
+               printf("- certificate is revoked.\n");
+
        return;
 }
 
@@ -92,13 +97,13 @@ int i = 0, exp_result;
 
 }
 
-#define PEM_SEP "-----BEGIN CERT"
-#define PEM_SEP_SIZE (sizeof(PEM_SEP)-1)
+#define CERT_SEP "-----BEGIN CERT"
+#define CRL_SEP "-----BEGIN X509 CRL"
 
 /* Verifies a base64 encoded certificate list from memory 
  */
 int _verify_x509_mem( const char* cert, int cert_size,
-       const char *ca, int ca_size)
+       const char *ca, int ca_size, const char* crl, int crl_size)
 {
        int siz, i;
        const char *ptr;
@@ -107,7 +112,8 @@ int _verify_x509_mem( const char* cert, int cert_size,
        gnutls_datum tmp;
        gnutls_x509_certificate *x509_cert_list = NULL;
        gnutls_x509_certificate x509_ca;
-       int x509_ncerts;
+       gnutls_x509_crl *x509_crl_list = NULL;
+       int x509_ncerts, x509_ncrls;
 
        /* Decode the CA certificate
         */
@@ -127,6 +133,50 @@ int _verify_x509_mem( const char* cert, int cert_size,
                exit(1);
        }
 
+       /* Decode the CRL list
+        */
+       siz = crl_size;
+       ptr = crl;
+
+       i = 1;
+
+       if (strstr(ptr, CRL_SEP)!=NULL) /* if CRLs exist */
+       do {
+               x509_crl_list =
+                   (gnutls_x509_crl *) realloc( x509_crl_list,
+                                                  i *
+                                                  sizeof(gnutls_x509_crl));
+               if (x509_crl_list == NULL) {
+                       fprintf(stderr, "memory error\n");
+                       exit(1);
+               }
+
+               tmp.data = (char*)ptr;
+               tmp.size = siz;
+
+               ret = gnutls_x509_crl_init( &x509_crl_list[i-1]);
+               if (ret < 0) {
+                       fprintf(stderr, "Error parsing the CRL[%d]: %s\n", i, gnutls_strerror(ret));
+                       exit(1);
+               }
+       
+               ret = gnutls_x509_crl_import( x509_crl_list[i-1], &tmp, GNUTLS_X509_FMT_PEM);
+               if (ret < 0) {
+                       fprintf(stderr, "Error parsing the CRL[%d]: %s\n", i, gnutls_strerror(ret));
+                       exit(1);
+               }
+
+               /* now we move ptr after the pem header */
+               ptr = strstr(ptr, CRL_SEP);
+               if (ptr!=NULL)
+                       ptr++;
+
+               i++;
+       } while ((ptr = strstr(ptr, CRL_SEP)) != NULL);
+
+       x509_ncrls = i - 1;
+
+
        /* Decode the certificate chain. 
         */
        siz = cert_size;
@@ -160,23 +210,30 @@ int _verify_x509_mem( const char* cert, int cert_size,
                }
 
                /* now we move ptr after the pem header */
-               ptr = strstr(ptr, PEM_SEP);
+               ptr = strstr(ptr, CERT_SEP);
                if (ptr!=NULL)
                        ptr++;
 
                i++;
-       } while ((ptr = strstr(ptr, PEM_SEP)) != NULL);
+       } while ((ptr = strstr(ptr, CERT_SEP)) != NULL);
 
        x509_ncerts = i - 1;
 
        ret  = gnutls_x509_certificate_list_verify( x509_cert_list, x509_ncerts,
-               &x509_ca, 1, NULL, 0, &output);
+               &x509_ca, 1, x509_crl_list, x509_ncrls, 0, &output);
 
        gnutls_x509_certificate_deinit( x509_ca);
+
        for (i=0;i<x509_ncerts;i++) {
                gnutls_x509_certificate_deinit( x509_cert_list[i]);
        }
+
+       for (i=0;i<x509_ncrls;i++) {
+               gnutls_x509_crl_deinit( x509_crl_list[i]);
+       }
+
        free( x509_cert_list);
+       free( x509_crl_list);
 
        if ( ret < 0) {
                fprintf(stderr, "Error in verification: %s\n", gnutls_strerror(ret));
@@ -220,6 +277,6 @@ int _verify_x509_file( const char* certfile, const char *cafile)
        
        ca[ca_size] = 0;
 
-       return _verify_x509_mem( cert, cert_size, ca, ca_size);
+       return _verify_x509_mem( cert, cert_size, ca, ca_size, cert, cert_size);
 }