diff options
Diffstat (limited to 'src/libstrongswan/plugins/x509')
-rw-r--r-- | src/libstrongswan/plugins/x509/Makefile.in | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ac.c | 42 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_cert.c | 56 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_crl.c | 366 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_crl.h | 9 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ocsp_request.c | 28 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ocsp_response.c | 42 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_pkcs10.c | 33 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_plugin.c | 4 |
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, |