summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2003-02-08 20:25:03 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2003-02-08 20:25:03 +0000
commit3f08429200ccfcab06ef151d5ebd5c57431cf284 (patch)
tree30f2677f698a1fe972db39fb834b6bdc40d3b7d8 /lib
parent00aef08f3f6446d82dcf0a884ab56e2146b36e82 (diff)
downloadgnutls-3f08429200ccfcab06ef151d5ebd5c57431cf284.tar.gz
Certificate revocation support is almost complete.
Diffstat (limited to 'lib')
-rw-r--r--lib/x509/Makefile.am2
-rw-r--r--lib/x509/common.c4
-rw-r--r--lib/x509/crl.c182
-rw-r--r--lib/x509/crl.h19
-rw-r--r--lib/x509/dn.c23
-rw-r--r--lib/x509/dn.h5
-rw-r--r--lib/x509/pkcs7.c13
-rw-r--r--lib/x509/verify.c63
-rw-r--r--lib/x509/x509.c105
-rw-r--r--lib/x509/x509.h23
10 files changed, 299 insertions, 140 deletions
diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am
index 357dbf8a89..cedcc7fcb8 100644
--- a/lib/x509/Makefile.am
+++ b/lib/x509/Makefile.am
@@ -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
diff --git a/lib/x509/common.c b/lib/x509/common.c
index bdc7c22d53..3b9fcb32a6 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -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);
diff --git a/lib/x509/crl.c b/lib/x509/crl.c
index c13aa7caec..1b4aad67ff 100644
--- a/lib/x509/crl.c
+++ b/lib/x509/crl.c
@@ -26,7 +26,7 @@
#include <gnutls_errors.h>
#include <common.h>
#include <x509_b64.h>
-#include <crl.h>
+#include <x509.h>
#include <dn.h>
/**
@@ -41,9 +41,12 @@
**/
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
index afb7c57d1d..0000000000
--- a/lib/x509/crl.h
+++ /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
diff --git a/lib/x509/dn.c b/lib/x509/dn.c
index 67df0def11..72f213d21b 100644
--- a/lib/x509/dn.c
+++ b/lib/x509/dn.c
@@ -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 */
+}
diff --git a/lib/x509/dn.h b/lib/x509/dn.h
index 65483375ed..d6b0fff4d0 100644
--- a/lib/x509/dn.h
+++ b/lib/x509/dn.h
@@ -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
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index df84ca84c2..36583c83ed 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -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);
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 42547029df..2c105f2425 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -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);
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 30b26d821a..fc45dd872d 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -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. */
+}
diff --git a/lib/x509/x509.h b/lib/x509/x509.h
index f1a3aa16cb..31f06e4918 100644
--- a/lib/x509/x509.h
+++ b/lib/x509/x509.h
@@ -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