summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/x509
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/x509')
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c42
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c56
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c366
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.h9
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c28
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c42
-rw-r--r--src/libstrongswan/plugins/x509/x509_pkcs10.c33
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.c4
9 files changed, 361 insertions, 221 deletions
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 2bee453cd..f40427f3f 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index 95e72789e..ba0357cc4 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -568,7 +568,7 @@ static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
public = this->signerCert->get_public_key(this->signerCert);
if (public)
{
- if (public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &keyIdentifier))
+ if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyIdentifier))
{
this->authKeyIdentifier = chunk_clone(keyIdentifier);
}
@@ -749,7 +749,7 @@ static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
{
chunk_t fingerprint;
- if (!key->get_fingerprint(key, KEY_ID_PUBKEY_SHA1, &fingerprint) ||
+ if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
!chunk_equals(fingerprint, this->authKeyIdentifier))
{
return FALSE;
@@ -813,30 +813,18 @@ static bool get_validity(private_x509_ac_t *this, time_t *when,
}
/**
- * Implementation of certificate_t.is_newer.
- */
-static bool is_newer(private_x509_ac_t *this, ac_t *that)
-{
- certificate_t *this_cert = &this->public.interface.certificate;
- certificate_t *that_cert = &that->certificate;
- time_t this_update, that_update, now = time(NULL);
- bool new;
-
- this_cert->get_validity(this_cert, &now, &this_update, NULL);
- that_cert->get_validity(that_cert, &now, &that_update, NULL);
- new = this_update > that_update;
- DBG1(DBG_LIB, " attr cert from %T is %s - existing attr cert from %T %s",
- &this_update, FALSE, new ? "newer":"not newer",
- &that_update, FALSE, new ? "replaced":"retained");
- return new;
-}
-
-/**
* Implementation of certificate_t.get_encoding.
*/
-static chunk_t get_encoding(private_x509_ac_t *this)
+static bool get_encoding(private_x509_ac_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
- return chunk_clone(this->encoding);
+ if (type == CERT_ASN1_DER)
+ {
+ *encoding = chunk_clone(this->encoding);
+ return TRUE;
+ }
+ return lib->encoding->encode(lib->encoding, type, NULL, encoding,
+ CRED_PART_X509_AC_ASN1_DER, this->encoding, CRED_PART_END);
}
/**
@@ -855,7 +843,10 @@ static bool equals(private_x509_ac_t *this, certificate_t *other)
{ /* skip allocation if we have the same implementation */
return chunk_equals(this->encoding, ((private_x509_ac_t*)other)->encoding);
}
- encoding = other->get_encoding(other);
+ if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
equal = chunk_equals(this->encoding, encoding);
free(encoding.ptr);
return equal;
@@ -904,8 +895,7 @@ static private_x509_ac_t *create_empty(void)
this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
- this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.certificate.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index bdbaa8d4a..92b576aa5 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -366,7 +366,17 @@ static identification_t *parse_generalName(chunk_t blob, int level0)
id_type = ID_DER_ASN1_DN;
break;
case GN_OBJ_IP_ADDRESS:
- id_type = ID_IPV4_ADDR;
+ switch (object.len)
+ {
+ case 4:
+ id_type = ID_IPV4_ADDR;
+ break;
+ case 16:
+ id_type = ID_IPV6_ADDR;
+ break;
+ default:
+ break;
+ }
break;
case GN_OBJ_OTHER_NAME:
if (!parse_otherName(object, parser->get_level(parser)+1))
@@ -1209,28 +1219,18 @@ static bool get_validity(private_x509_cert_t *this, time_t *when,
}
/**
- * Implementation of certificate_t.is_newer.
- */
-static bool is_newer(certificate_t *this, certificate_t *that)
-{
- time_t this_update, that_update, now = time(NULL);
- bool new;
-
- this->get_validity(this, &now, &this_update, NULL);
- that->get_validity(that, &now, &that_update, NULL);
- new = this_update > that_update;
- DBG1(DBG_LIB, " certificate from %T is %s - existing certificate "
- "from %T %s", &this_update, FALSE, new ? "newer":"not newer",
- &that_update, FALSE, new ? "replaced":"retained");
- return new;
-}
-
-/**
* Implementation of certificate_t.get_encoding.
*/
-static chunk_t get_encoding(private_x509_cert_t *this)
+static bool get_encoding(private_x509_cert_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
- return chunk_clone(this->encoding);
+ if (type == CERT_ASN1_DER)
+ {
+ *encoding = chunk_clone(this->encoding);
+ return TRUE;
+ }
+ return lib->encoding->encode(lib->encoding, type, NULL, encoding,
+ CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
}
/**
@@ -1253,7 +1253,10 @@ static bool equals(private_x509_cert_t *this, certificate_t *other)
{ /* skip allocation if we have the same implementation */
return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding);
}
- encoding = other->get_encoding(other);
+ if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
equal = chunk_equals(this->encoding, encoding);
free(encoding.ptr);
return equal;
@@ -1281,7 +1284,7 @@ static chunk_t get_subjectKeyIdentifier(private_x509_cert_t *this)
chunk_t fingerprint;
if (this->public_key->get_fingerprint(this->public_key,
- KEY_ID_PUBKEY_SHA1, &fingerprint))
+ KEYID_PUBKEY_SHA1, &fingerprint))
{
return fingerprint;
}
@@ -1383,8 +1386,7 @@ static private_x509_cert_t* create_empty(void)
this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
- this->public.interface.interface.is_newer = (bool (*) (certificate_t*,certificate_t*))is_newer;
- this->public.interface.interface.get_encoding = (chunk_t (*) (certificate_t*))get_encoding;
+ this->public.interface.interface.get_encoding = (bool (*) (certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
@@ -1536,7 +1538,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
scheme = signature_scheme_from_oid(cert->algorithm);
if (!cert->public_key->get_encoding(cert->public_key,
- KEY_PUB_SPKI_ASN1_DER, &key_info))
+ PUBKEY_SPKI_ASN1_DER, &key_info))
{
return FALSE;
}
@@ -1650,7 +1652,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
chunk_t keyid;
if (cert->public_key->get_fingerprint(cert->public_key,
- KEY_ID_PUBKEY_SHA1, &keyid))
+ KEYID_PUBKEY_SHA1, &keyid))
{
subjectKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_SUBJECT_KEY_ID),
@@ -1664,7 +1666,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
{
chunk_t keyid;
- if (sign_key->get_fingerprint(sign_key, KEY_ID_PUBKEY_SHA1, &keyid))
+ if (sign_key->get_fingerprint(sign_key, KEYID_PUBKEY_SHA1, &keyid))
{
authKeyIdentifier = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index c755d7f63..4bd0470d3 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -26,6 +26,7 @@ typedef struct revoked_t revoked_t;
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <credentials/certificates/x509.h>
+#include <credentials/keys/private_key.h>
#include <utils/linked_list.h>
/**
@@ -119,6 +120,11 @@ struct private_x509_crl_t {
chunk_t signature;
/**
+ * has this CRL been generated
+ */
+ bool generated;
+
+ /**
* reference counter
*/
refcount_t ref;
@@ -236,7 +242,7 @@ static bool parse(private_x509_crl_t *this)
break;
case CRL_OBJ_REVOCATION_DATE:
revoked = malloc_thing(revoked_t);
- revoked->serial = userCertificate;
+ revoked->serial = chunk_clone(userCertificate);
revoked->date = asn1_parse_time(object, level);
revoked->reason = CRL_REASON_UNSPECIFIED;
this->revoked->insert_last(this->revoked, (void *)revoked);
@@ -267,7 +273,6 @@ static bool parse(private_x509_crl_t *this)
}
else if (extn_oid == OID_AUTHORITY_KEY_ID)
{
-
this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
level, &this->authKeySerialNumber);
}
@@ -327,52 +332,40 @@ static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2,
return TRUE;
}
-/**
- * Implementation of crl_t.get_serial.
- */
-static chunk_t get_serial(private_x509_crl_t *this)
+METHOD(crl_t, get_serial, chunk_t,
+ private_x509_crl_t *this)
{
return this->crlNumber;
}
-/**
- * Implementation of crl_t.get_authKeyIdentifier.
- */
-static chunk_t get_authKeyIdentifier(private_x509_crl_t *this)
+METHOD(crl_t, get_authKeyIdentifier, chunk_t,
+ private_x509_crl_t *this)
{
return this->authKeyIdentifier;
}
-/**
- * Implementation of crl_t.create_enumerator.
- */
-static enumerator_t* create_enumerator(private_x509_crl_t *this)
+METHOD(crl_t, create_enumerator, enumerator_t*,
+ private_x509_crl_t *this)
{
return enumerator_create_filter(
this->revoked->create_enumerator(this->revoked),
(void*)filter, NULL, NULL);
}
-/**
- * Implementation of certificate_t.get_type
- */
-static certificate_type_t get_type(private_x509_crl_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_x509_crl_t *this)
{
return CERT_X509_CRL;
}
-/**
- * Implementation of certificate_t.get_issuer and get_subject
- */
-static identification_t* get_issuer(private_x509_crl_t *this)
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_x509_crl_t *this)
{
return this->issuer;
}
-/**
- * Implementation of certificate_t.has_subject and has_issuer.
- */
-static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_x509_crl_t *this, identification_t *issuer)
{
if (issuer->get_type(issuer) == ID_KEY_ID && this->authKeyIdentifier.ptr &&
chunk_equals(this->authKeyIdentifier, issuer->get_encoding(issuer)))
@@ -382,10 +375,8 @@ static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
return this->issuer->matches(this->issuer, issuer);
}
-/**
- * Implementation of certificate_t.issued_by
- */
-static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by, bool,
+ private_x509_crl_t *this, certificate_t *issuer)
{
public_key_t *key;
signature_scheme_t scheme;
@@ -410,7 +401,7 @@ static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
{
chunk_t fingerprint;
- if (!key->get_fingerprint(key, KEY_ID_PUBKEY_SHA1, &fingerprint) ||
+ if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
!chunk_equals(fingerprint, this->authKeyIdentifier))
{
return FALSE;
@@ -436,28 +427,22 @@ static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
return valid;
}
-/**
- * Implementation of certificate_t.get_public_key
- */
-static public_key_t* get_public_key(private_x509_crl_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_x509_crl_t *this)
{
return NULL;
}
-/**
- * Implementation of certificate_t.asdf
- */
-static private_x509_crl_t* get_ref(private_x509_crl_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_x509_crl_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.crl.certificate;
}
-/**
- * Implementation of certificate_t.get_validity.
- */
-static bool get_validity(private_x509_crl_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_x509_crl_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
{
time_t t = when ? *when : time(NULL);
@@ -472,51 +457,20 @@ static bool get_validity(private_x509_crl_t *this, time_t *when,
return (t <= this->nextUpdate);
}
-/**
- * Implementation of certificate_t.is_newer.
- */
-static bool is_newer(private_x509_crl_t *this, crl_t *that)
+METHOD(certificate_t, get_encoding, bool,
+ private_x509_crl_t *this, cred_encoding_type_t type, chunk_t *encoding)
{
- chunk_t that_crlNumber = that->get_serial(that);
- bool new;
-
- /* compare crlNumbers if available - otherwise use thisUpdate */
- if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL)
+ if (type == CERT_ASN1_DER)
{
- new = chunk_compare(this->crlNumber, that_crlNumber) > 0;
- DBG1(DBG_LIB, " crl #%#B is %s - existing crl #%#B %s",
- &this->crlNumber, new ? "newer":"not newer",
- &that_crlNumber, new ? "replaced":"retained");
- }
- else
- {
- certificate_t *this_cert = &this->public.crl.certificate;
- certificate_t *that_cert = &that->certificate;
-
- time_t this_update, that_update, now = time(NULL);
-
- this_cert->get_validity(this_cert, &now, &this_update, NULL);
- that_cert->get_validity(that_cert, &now, &that_update, NULL);
- new = this_update > that_update;
- DBG1(DBG_LIB, " crl from %T is %s - existing crl from %T %s",
- &this_update, FALSE, new ? "newer":"not newer",
- &that_update, FALSE, new ? "replaced":"retained");
+ *encoding = chunk_clone(this->encoding);
+ return TRUE;
}
- return new;
-}
-
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static chunk_t get_encoding(private_x509_crl_t *this)
-{
- return chunk_clone(this->encoding);
+ return lib->encoding->encode(lib->encoding, type, NULL, encoding,
+ CRED_PART_X509_CRL_ASN1_DER, this->encoding, CRED_PART_END);
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_x509_crl_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_x509_crl_t *this, certificate_t *other)
{
chunk_t encoding;
bool equal;
@@ -529,23 +483,39 @@ static bool equals(private_x509_crl_t *this, certificate_t *other)
{ /* skip allocation if we have the same implementation */
return chunk_equals(this->encoding, ((private_x509_crl_t*)other)->encoding);
}
- encoding = other->get_encoding(other);
+ if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
equal = chunk_equals(this->encoding, encoding);
free(encoding.ptr);
return equal;
}
/**
- * Implementation of certificate_t.destroy
+ * Destroy a revoked_t entry
*/
-static void destroy(private_x509_crl_t *this)
+static void revoked_destroy(revoked_t *revoked)
+{
+ free(revoked->serial.ptr);
+ free(revoked);
+}
+
+METHOD(certificate_t, destroy, void,
+ private_x509_crl_t *this)
{
if (ref_put(&this->ref))
{
- this->revoked->destroy_function(this->revoked, free);
+ this->revoked->destroy_function(this->revoked, (void*)revoked_destroy);
DESTROY_IF(this->issuer);
free(this->authKeyIdentifier.ptr);
free(this->encoding.ptr);
+ if (this->generated)
+ {
+ free(this->crlNumber.ptr);
+ free(this->signature.ptr);
+ free(this->tbsCertList.ptr);
+ }
free(this);
}
}
@@ -555,34 +525,33 @@ static void destroy(private_x509_crl_t *this)
*/
static private_x509_crl_t* create_empty(void)
{
- private_x509_crl_t *this = malloc_thing(private_x509_crl_t);
-
- this->public.crl.get_serial = (chunk_t (*)(crl_t*))get_serial;
- this->public.crl.get_authKeyIdentifier = (chunk_t (*)(crl_t*))get_authKeyIdentifier;
- this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator;
- this->public.crl.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
- this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.crl.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_issuer;
- this->public.crl.certificate.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
- this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
- this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
- this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.crl.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
- this->public.crl.certificate.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
- this->public.crl.certificate.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
- this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
- this->public.crl.certificate.destroy = (void (*)(certificate_t *this))destroy;
-
- this->encoding = chunk_empty;
- this->tbsCertList = chunk_empty;
- this->issuer = NULL;
- this->crlNumber = chunk_empty;
- this->revoked = linked_list_create();
- this->authKeyIdentifier = chunk_empty;
- this->authKeySerialNumber = chunk_empty;
- this->ref = 1;
-
+ private_x509_crl_t *this;
+
+ INIT(this,
+ .public = {
+ .crl = {
+ .certificate = {
+ .get_type = _get_type,
+ .get_subject = _get_issuer,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_issuer,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_serial = _get_serial,
+ .get_authKeyIdentifier = _get_authKeyIdentifier,
+ .create_enumerator = _create_enumerator,
+ },
+ },
+ .revoked = linked_list_create(),
+ .ref = 1,
+ );
return this;
}
@@ -621,3 +590,166 @@ x509_crl_t *x509_crl_load(certificate_type_t type, va_list args)
return NULL;
};
+/**
+ * Read certificate status from enumerator, copy to crl
+ */
+static void read_revoked(private_x509_crl_t *crl, enumerator_t *enumerator)
+{
+ revoked_t *revoked;
+ chunk_t serial;
+ time_t date;
+ crl_reason_t reason;
+
+ while (enumerator->enumerate(enumerator, &serial, &date, &reason))
+ {
+ INIT(revoked,
+ .serial = chunk_clone(serial),
+ .date = date,
+ .reason = reason,
+ );
+ crl->revoked->insert_last(crl->revoked, revoked);
+ }
+}
+
+/**
+ * Generate CRL encoding, sign CRL
+ */
+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;
+ enumerator_t *enumerator;
+ crl_reason_t reason;
+ time_t date;
+ x509_t *x509;
+
+ x509 = (x509_t*)cert;
+
+ this->issuer = cert->get_issuer(cert);
+ this->issuer = this->issuer->clone(this->issuer);
+
+ this->authKeyIdentifier = chunk_clone(x509->get_subjectKeyIdentifier(x509));
+
+ /* select signature scheme */
+ this->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
+ key->get_type(key));
+ if (this->algorithm == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+
+ enumerator = create_enumerator(this);
+ while (enumerator->enumerate(enumerator, &serial, &date, &reason))
+ {
+ chunk_t revoked, entry_ext = chunk_empty;
+
+ if (reason != CRL_REASON_UNSPECIFIED)
+ {
+ entry_ext = asn1_wrap(ASN1_SEQUENCE, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_CRL_REASON_CODE),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_ENUMERATED, "c",
+ chunk_from_chars(reason)))));
+ }
+ revoked = asn1_wrap(ASN1_SEQUENCE, "mmm",
+ asn1_integer("c", serial),
+ asn1_from_time(&date, ASN1_UTCTIME),
+ entry_ext);
+ certList = chunk_cat("mm", certList, revoked);
+ }
+ enumerator->destroy(enumerator);
+
+ extensions = asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_AUTHORITY_KEY_ID),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "m",
+ asn1_wrap(ASN1_CONTEXT_S_0, "c",
+ this->authKeyIdentifier)))),
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_CRL_NUMBER),
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_integer("c", this->crlNumber))
+ )
+ ));
+
+ this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cmcmmmm",
+ ASN1_INTEGER_1,
+ asn1_algorithmIdentifier(this->algorithm),
+ this->issuer->get_encoding(this->issuer),
+ asn1_from_time(&this->thisUpdate, ASN1_UTCTIME),
+ asn1_from_time(&this->nextUpdate, ASN1_UTCTIME),
+ asn1_wrap(ASN1_SEQUENCE, "m", certList),
+ extensions);
+
+ if (!key->sign(key, signature_scheme_from_oid(this->algorithm),
+ this->tbsCertList, &this->signature))
+ {
+ return FALSE;
+ }
+ this->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
+ this->tbsCertList,
+ asn1_algorithmIdentifier(this->algorithm),
+ asn1_bitstring("c", this->signature));
+ return TRUE;
+}
+
+/**
+ * See header.
+ */
+x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args)
+{
+ hash_algorithm_t digest_alg = HASH_SHA1;
+ private_x509_crl_t *crl;
+ certificate_t *cert = NULL;
+ private_key_t *key = NULL;
+
+ crl = create_empty();
+ crl->generated = TRUE;
+ while (TRUE)
+ {
+ builder_part_t part = va_arg(args, builder_part_t);
+
+ switch (part)
+ {
+ case BUILD_SIGNING_KEY:
+ key = va_arg(args, private_key_t*);
+ continue;
+ case BUILD_SIGNING_CERT:
+ cert = va_arg(args, certificate_t*);
+ continue;
+ case BUILD_NOT_BEFORE_TIME:
+ crl->thisUpdate = va_arg(args, time_t);
+ continue;
+ case BUILD_NOT_AFTER_TIME:
+ crl->nextUpdate = va_arg(args, time_t);
+ continue;
+ case BUILD_SERIAL:
+ crl->crlNumber = va_arg(args, chunk_t);
+ crl->crlNumber = chunk_clone(crl->crlNumber);
+ continue;
+ case BUILD_DIGEST_ALG:
+ digest_alg = va_arg(args, int);
+ continue;
+ case BUILD_REVOKED_ENUMERATOR:
+ read_revoked(crl, va_arg(args, enumerator_t*));
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ destroy(crl);
+ return NULL;
+ }
+ break;
+ }
+
+ if (key && cert && cert->get_type(cert) == CERT_X509 &&
+ generate(crl, cert, key, digest_alg))
+ {
+ return &crl->public;
+ }
+ destroy(crl);
+ return NULL;
+}
diff --git a/src/libstrongswan/plugins/x509/x509_crl.h b/src/libstrongswan/plugins/x509/x509_crl.h
index 890650162..e8fe74e81 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.h
+++ b/src/libstrongswan/plugins/x509/x509_crl.h
@@ -46,4 +46,13 @@ struct x509_crl_t {
*/
x509_crl_t *x509_crl_load(certificate_type_t type, va_list args);
+/**
+ * Generate a X.509 CRL.
+ *
+ * @param type certificate type, CERT_X509_CRL only
+ * @param args builder_part_t argument list
+ * @return X.509 CRL, NULL on failure
+ */
+x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args);
+
#endif /** X509_CRL_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index c835d5dc8..ea02cbab5 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -153,7 +153,7 @@ static chunk_t build_requestList(private_x509_ocsp_request_t *this)
hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (hasher)
{
- if (public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1,
+ if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1,
&issuerKeyHash))
{
enumerator_t *enumerator;
@@ -250,7 +250,7 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
{
int oid;
signature_scheme_t scheme;
- chunk_t certs, signature;
+ chunk_t certs, signature, encoding;
switch (this->key->get_type(this->key))
{
@@ -274,11 +274,11 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
DBG1(DBG_LIB, "creating OCSP signature failed, skipped");
return chunk_empty;
}
- if (this->cert)
+ if (this->cert &&
+ this->cert->get_encoding(this->cert, CERT_ASN1_DER, &encoding))
{
certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
- asn1_wrap(ASN1_SEQUENCE, "m",
- this->cert->get_encoding(this->cert)));
+ asn1_wrap(ASN1_SEQUENCE, "m", encoding));
}
return asn1_wrap(ASN1_CONTEXT_C_0, "m",
asn1_wrap(ASN1_SEQUENCE, "cmm",
@@ -413,9 +413,16 @@ static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
/**
* Implementation of certificate_t.get_encoding.
*/
-static chunk_t get_encoding(private_x509_ocsp_request_t *this)
+static bool get_encoding(private_x509_ocsp_request_t *this,
+ cred_encoding_type_t type, chunk_t *encoding)
{
- return chunk_clone(this->encoding);
+ if (type == CERT_ASN1_DER)
+ {
+ *encoding = chunk_clone(this->encoding);
+ return TRUE;
+ }
+ return lib->encoding->encode(lib->encoding, type, NULL, encoding,
+ CRED_PART_X509_OCSP_REQ_ASN1_DER, this->encoding, CRED_PART_END);
}
/**
@@ -438,7 +445,10 @@ static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
{ /* skip allocation if we have the same implementation */
return chunk_equals(this->encoding, ((private_x509_ocsp_request_t*)other)->encoding);
}
- encoding = other->get_encoding(other);
+ if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
equal = chunk_equals(this->encoding, encoding);
free(encoding.ptr);
return equal;
@@ -486,7 +496,7 @@ static private_x509_ocsp_request_t *create_empty()
this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.interface.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.interface.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
this->public.interface.interface.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index c70d461df..829f47f81 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -167,7 +167,7 @@ static cert_validation_t get_status(private_x509_ocsp_response_t *this,
{
hasher_t *hasher;
identification_t *id;
- key_encoding_type_t type;
+ cred_encoding_type_t type;
chunk_t hash, fingerprint;
/* check serial first, is cheaper */
@@ -188,7 +188,7 @@ static cert_validation_t get_status(private_x509_ocsp_response_t *this,
switch (response->hashAlgorithm)
{
case OID_SHA1:
- type = KEY_ID_PUBKEY_SHA1;
+ type = KEYID_PUBKEY_SHA1;
break;
default:
public->destroy(public);
@@ -698,7 +698,7 @@ static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
key = issuer->get_public_key(issuer);
if (!key ||
- !key->get_fingerprint(key, KEY_ID_PUBKEY_SHA1, &fingerprint) ||
+ !key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
!chunk_equals(fingerprint,
this->responderId->get_encoding(this->responderId)))
{
@@ -764,28 +764,18 @@ static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
}
/**
- * Implementation of certificate_t.is_newer.
- */
-static bool is_newer(certificate_t *this, certificate_t *that)
-{
- time_t this_update, that_update, now = time(NULL);
- bool new;
-
- this->get_validity(this, &now, &this_update, NULL);
- that->get_validity(that, &now, &that_update, NULL);
- new = this_update > that_update;
- DBG1(DBG_LIB, " ocsp response from %T is %s - existing ocsp response "
- "from %T %s", &this_update, FALSE, new ? "newer" : "not newer",
- &that_update, FALSE, new ? "replaced" : "retained");
- return new;
-}
-
-/**
* Implementation of certificate_t.get_encoding.
*/
-static chunk_t get_encoding(private_x509_ocsp_response_t *this)
+static bool get_encoding(private_x509_ocsp_response_t *this,
+ cred_encoding_type_t type, chunk_t *encoding)
{
- return chunk_clone(this->encoding);
+ if (type == CERT_ASN1_DER)
+ {
+ *encoding = chunk_clone(this->encoding);
+ return TRUE;
+ }
+ return lib->encoding->encode(lib->encoding, type, NULL, encoding,
+ CRED_PART_X509_OCSP_RES_ASN1_DER, this->encoding, CRED_PART_END);
}
/**
@@ -808,7 +798,10 @@ static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
{ /* skip allocation if we have the same implementation */
return chunk_equals(this->encoding, ((private_x509_ocsp_response_t*)other)->encoding);
}
- encoding = other->get_encoding(other);
+ if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
equal = chunk_equals(this->encoding, encoding);
free(encoding.ptr);
return equal;
@@ -855,8 +848,7 @@ static x509_ocsp_response_t *load(chunk_t blob)
this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
- this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.certificate.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index 1009ec931..bfb0ca621 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -189,19 +189,18 @@ static bool get_validity(private_x509_pkcs10_t *this, time_t *when,
}
/**
- * Implementation of certificate_t.is_newer.
- */
-static bool is_newer(certificate_t *this, certificate_t *that)
-{
- return FALSE;
-}
-
-/**
* Implementation of certificate_t.get_encoding.
*/
-static chunk_t get_encoding(private_x509_pkcs10_t *this)
+static bool get_encoding(private_x509_pkcs10_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
- return chunk_clone(this->encoding);
+ if (type == CERT_ASN1_DER)
+ {
+ *encoding = chunk_clone(this->encoding);
+ return TRUE;
+ }
+ return lib->encoding->encode(lib->encoding, type, NULL, encoding,
+ CRED_PART_PKCS10_ASN1_DER, this->encoding, CRED_PART_END);
}
/**
@@ -224,7 +223,10 @@ static bool equals(private_x509_pkcs10_t *this, certificate_t *other)
{ /* skip allocation if we have the same implementation */
return chunk_equals(this->encoding, ((private_x509_pkcs10_t*)other)->encoding);
}
- encoding = other->get_encoding(other);
+ if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
+ {
+ return FALSE;
+ }
equal = chunk_equals(this->encoding, encoding);
free(encoding.ptr);
return equal;
@@ -357,7 +359,7 @@ static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, i
*/
static const asn1Object_t certificationRequestObjects[] = {
{ 0, "certificationRequest", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "certificationRequestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 1, "certificationRequestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
{ 2, "version", ASN1_INTEGER, ASN1_BODY }, /* 2 */
{ 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 3 */
{ 2, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_RAW }, /* 4 */
@@ -369,7 +371,7 @@ static const asn1Object_t certificationRequestObjects[] = {
{ 4, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
{ 2, "end loop", ASN1_EOC, ASN1_END }, /* 11 */
{ 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
- { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 13 */
+ { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 13 */
{ 0, "exit", ASN1_EOC, ASN1_EXIT }
};
#define PKCS10_CERT_REQUEST_INFO 1
@@ -512,8 +514,7 @@ static private_x509_pkcs10_t* create_empty(void)
this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
- this->public.interface.interface.is_newer = (bool (*) (certificate_t*,certificate_t*))is_newer;
- this->public.interface.interface.get_encoding = (chunk_t (*) (certificate_t*))get_encoding;
+ this->public.interface.interface.get_encoding = (bool (*) (certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
@@ -559,7 +560,7 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
scheme = signature_scheme_from_oid(cert->algorithm);
if (!cert->public_key->get_encoding(cert->public_key,
- KEY_PUB_SPKI_ASN1_DER, &key_info))
+ PUBKEY_SPKI_ASN1_DER, &key_info))
{
return FALSE;
}
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c
index e71c55efc..8391781e2 100644
--- a/src/libstrongswan/plugins/x509/x509_plugin.c
+++ b/src/libstrongswan/plugins/x509/x509_plugin.c
@@ -52,6 +52,8 @@ static void destroy(private_x509_plugin_t *this)
lib->creds->remove_builder(lib->creds,
(builder_function_t)x509_crl_load);
lib->creds->remove_builder(lib->creds,
+ (builder_function_t)x509_crl_gen);
+ lib->creds->remove_builder(lib->creds,
(builder_function_t)x509_ocsp_request_gen);
lib->creds->remove_builder(lib->creds,
(builder_function_t)x509_ocsp_response_load);
@@ -81,6 +83,8 @@ plugin_t *x509_plugin_create()
(builder_function_t)x509_ac_load);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
(builder_function_t)x509_crl_load);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ (builder_function_t)x509_crl_gen);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
(builder_function_t)x509_ocsp_request_gen);
lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,