aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-12-17 16:53:00 +0100
committerMartin Willi <martin@revosec.ch>2011-01-05 16:46:03 +0100
commit55e4d8982fd728a60a2cabfda1b2eac240a19ce7 (patch)
treeb02334d97f6737bf1f00fe36dcd6964e42e71760 /src
parent1019cad161ecfc975c69dd0e1a753fdc78f1dcf7 (diff)
downloadstrongswan-55e4d8982fd728a60a2cabfda1b2eac240a19ce7.tar.bz2
strongswan-55e4d8982fd728a60a2cabfda1b2eac240a19ce7.tar.xz
Added support for delta CRLs to x509 plugin
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/credentials/builder.c1
-rw-r--r--src/libstrongswan/credentials/builder.h2
-rw-r--r--src/libstrongswan/credentials/certificates/crl.h15
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crl.c2
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c117
5 files changed, 130 insertions, 7 deletions
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index 3651e4b44..768b9da3d 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -51,6 +51,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_POLICY_CONSTRAINT_INHIBIT",
"BUILD_X509_FLAG",
"BUILD_REVOKED_ENUMERATOR",
+ "BUILD_BASE_CRL",
"BUILD_CHALLENGE_PWD",
"BUILD_PKCS11_MODULE",
"BUILD_PKCS11_SLOT",
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index 956b1ac34..5db37775a 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -109,6 +109,8 @@ enum builder_part_t {
BUILD_X509_FLAG,
/** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */
BUILD_REVOKED_ENUMERATOR,
+ /** Base CRL serial for a delta CRL, chunk_t, */
+ BUILD_BASE_CRL,
/** PKCS#10 challenge password */
BUILD_CHALLENGE_PWD,
/** friendly name of a PKCS#11 module, null terminated char* */
diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h
index 9425311fb..2f3497474 100644
--- a/src/libstrongswan/credentials/certificates/crl.h
+++ b/src/libstrongswan/credentials/certificates/crl.h
@@ -72,6 +72,21 @@ struct crl_t {
chunk_t (*get_authKeyIdentifier)(crl_t *this);
/**
+ * Is this CRL a delta CRL?
+ *
+ * @param base_crl gets to baseCrlNumber, if this is a delta CRL
+ * @return TRUE if delta CRL
+ */
+ bool (*is_delta_crl)(crl_t *this, chunk_t *base_crl);
+
+ /**
+ * Create an enumerator over Freshest CRL distribution points and issuers.
+ *
+ * @return enumerator over x509_cdp_t
+ */
+ enumerator_t* (*create_delta_crl_uri_enumerator)(crl_t *this);
+
+ /**
* Create an enumerator over all revoked certificates.
*
* The enumerator takes 3 pointer arguments:
diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c
index 793899d33..7786b7fbb 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crl.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crl.c
@@ -382,6 +382,8 @@ static private_openssl_crl_t *create_empty()
},
.get_serial = _get_serial,
.get_authKeyIdentifier = _get_authKeyIdentifier,
+ .is_delta_crl = (void*)return_false,
+ .create_delta_crl_uri_enumerator = (void*)enumerator_create_empty,
.create_enumerator = _create_enumerator,
},
},
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index 979e0afd4..06936c8a6 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -100,6 +100,11 @@ struct private_x509_crl_t {
linked_list_t *revoked;
/**
+ * List of Freshest CRL distribution points
+ */
+ linked_list_t *crl_uris;
+
+ /**
* Authority Key Identifier
*/
chunk_t authKeyIdentifier;
@@ -110,6 +115,11 @@ struct private_x509_crl_t {
chunk_t authKeySerialNumber;
/**
+ * Number of BaseCRL, if a delta CRL
+ */
+ chunk_t baseCrlNumber;
+
+ /**
* Signature algorithm
*/
int algorithm;
@@ -133,9 +143,19 @@ struct private_x509_crl_t {
/**
* from x509_cert
*/
-extern chunk_t x509_parse_authorityKeyIdentifier(
- chunk_t blob, int level0,
- chunk_t *authKeySerialNumber);
+extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
+ chunk_t *authKeySerialNumber);
+
+/**
+ * from x509_cert
+ */
+extern void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
+ linked_list_t *list);
+
+/**
+ * from x509_cert
+ */
+extern chunk_t x509_build_crlDistributionPoints(linked_list_t *list, int extn);
/**
* ASN.1 definition of an X.509 certificate revocation list
@@ -288,6 +308,18 @@ static bool parse(private_x509_crl_t *this)
}
this->crlNumber = object;
break;
+ case OID_FRESHEST_CRL:
+ x509_parse_crlDistributionPoints(object, level,
+ this->crl_uris);
+ break;
+ case OID_DELTA_CRL_INDICATOR:
+ if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+ level, "deltaCrlIndicator"))
+ {
+ goto end;
+ }
+ this->baseCrlNumber = object;
+ break;
default:
if (critical && lib->settings->get_bool(lib->settings,
"libstrongswan.plugins.x509.enforce_critical", FALSE))
@@ -358,6 +390,26 @@ METHOD(crl_t, get_authKeyIdentifier, chunk_t,
return this->authKeyIdentifier;
}
+METHOD(crl_t, is_delta_crl, bool,
+ private_x509_crl_t *this, chunk_t *base_crl)
+{
+ if (this->baseCrlNumber.len)
+ {
+ if (base_crl)
+ {
+ *base_crl = this->baseCrlNumber;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(crl_t, create_delta_crl_uri_enumerator, enumerator_t*,
+ private_x509_crl_t *this)
+{
+ return this->crl_uris->create_enumerator(this->crl_uris);
+}
+
METHOD(crl_t, create_enumerator, enumerator_t*,
private_x509_crl_t *this)
{
@@ -515,18 +567,30 @@ static void revoked_destroy(revoked_t *revoked)
free(revoked);
}
+/**
+ * Destroy a CDP entry
+ */
+static void cdp_destroy(x509_cdp_t *this)
+{
+ free(this->uri);
+ DESTROY_IF(this->issuer);
+ free(this);
+}
+
METHOD(certificate_t, destroy, void,
private_x509_crl_t *this)
{
if (ref_put(&this->ref))
{
this->revoked->destroy_function(this->revoked, (void*)revoked_destroy);
+ this->crl_uris->destroy_function(this->crl_uris, (void*)cdp_destroy);
DESTROY_IF(this->issuer);
free(this->authKeyIdentifier.ptr);
free(this->encoding.ptr);
if (this->generated)
{
free(this->crlNumber.ptr);
+ free(this->baseCrlNumber.ptr);
free(this->signature.ptr);
free(this->tbsCertList.ptr);
}
@@ -560,10 +624,13 @@ static private_x509_crl_t* create_empty(void)
},
.get_serial = _get_serial,
.get_authKeyIdentifier = _get_authKeyIdentifier,
+ .is_delta_crl = _is_delta_crl,
+ .create_delta_crl_uri_enumerator = _create_delta_crl_uri_enumerator,
.create_enumerator = _create_enumerator,
},
},
.revoked = linked_list_create(),
+ .crl_uris = linked_list_create(),
.ref = 1,
);
return this;
@@ -632,6 +699,7 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
private_key_t *key, hash_algorithm_t digest_alg)
{
chunk_t extensions = chunk_empty, certList = chunk_empty, serial;
+ chunk_t crlDistributionPoints = chunk_empty, baseCrlNumber = chunk_empty;
enumerator_t *enumerator;
crl_reason_t reason;
time_t date;
@@ -674,8 +742,21 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
}
enumerator->destroy(enumerator);
+ crlDistributionPoints = x509_build_crlDistributionPoints(this->crl_uris,
+ OID_FRESHEST_CRL);
+
+ if (this->baseCrlNumber.len)
+ {
+ baseCrlNumber = asn1_wrap(ASN1_SEQUENCE, "mmm",
+ asn1_build_known_oid(OID_DELTA_CRL_INDICATOR),
+ asn1_wrap(ASN1_BOOLEAN, "c",
+ chunk_from_chars(0xFF)),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_integer("c", this->baseCrlNumber)));
+ }
+
extensions = asn1_wrap(ASN1_CONTEXT_C_0, "m",
- asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_SEQUENCE, "mmmm",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
asn1_wrap(ASN1_OCTET_STRING, "m",
@@ -685,9 +766,8 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_CRL_NUMBER),
asn1_wrap(ASN1_OCTET_STRING, "m",
- asn1_integer("c", this->crlNumber))
- )
- ));
+ asn1_integer("c", this->crlNumber))),
+ crlDistributionPoints, baseCrlNumber));
this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cmcmmmm",
ASN1_INTEGER_1,
@@ -750,6 +830,29 @@ x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args)
case BUILD_REVOKED_ENUMERATOR:
read_revoked(crl, va_arg(args, enumerator_t*));
continue;
+ case BUILD_BASE_CRL:
+ crl->baseCrlNumber = va_arg(args, chunk_t);
+ crl->baseCrlNumber = chunk_clone(crl->baseCrlNumber);
+ break;
+ case BUILD_CRL_DISTRIBUTION_POINTS:
+ {
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ x509_cdp_t *in, *cdp;
+
+ list = va_arg(args, linked_list_t*);
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &in))
+ {
+ INIT(cdp,
+ .uri = strdup(in->uri),
+ .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL,
+ );
+ crl->crl_uris->insert_last(crl->crl_uris, cdp);
+ }
+ enumerator->destroy(enumerator);
+ continue;
+ }
case BUILD_END:
break;
default: