diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-10-08 11:25:33 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2009-10-08 11:25:43 +0200 |
commit | 0354d5703d87da94f08865fed8bb95a23893775f (patch) | |
tree | dc9741a51f0729314145f426655a6dd61482dba0 /src | |
parent | 4b1cd5a367058f2fe09d5e0e49a4c79eb5cd0193 (diff) | |
download | strongswan-0354d5703d87da94f08865fed8bb95a23893775f.tar.bz2 strongswan-0354d5703d87da94f08865fed8bb95a23893775f.tar.xz |
migrated public key IDs to identification_t
Diffstat (limited to 'src')
-rw-r--r-- | src/pluto/ac.c | 11 | ||||
-rw-r--r-- | src/pluto/ac.h | 3 | ||||
-rw-r--r-- | src/pluto/ca.c | 86 | ||||
-rw-r--r-- | src/pluto/ca.h | 29 | ||||
-rw-r--r-- | src/pluto/connections.c | 94 | ||||
-rw-r--r-- | src/pluto/connections.h | 57 | ||||
-rw-r--r-- | src/pluto/crl.c | 24 | ||||
-rw-r--r-- | src/pluto/crl.h | 2 | ||||
-rw-r--r-- | src/pluto/fetch.c | 24 | ||||
-rw-r--r-- | src/pluto/fetch.h | 14 | ||||
-rw-r--r-- | src/pluto/ipsec_doi.c | 234 | ||||
-rw-r--r-- | src/pluto/kernel.c | 16 | ||||
-rw-r--r-- | src/pluto/keys.c | 85 | ||||
-rw-r--r-- | src/pluto/keys.h | 18 | ||||
-rw-r--r-- | src/pluto/ocsp.c | 121 | ||||
-rw-r--r-- | src/pluto/ocsp.h | 8 | ||||
-rw-r--r-- | src/pluto/pgpcert.c | 10 | ||||
-rw-r--r-- | src/pluto/rcv_whack.c | 30 | ||||
-rw-r--r-- | src/pluto/x509.c | 57 | ||||
-rw-r--r-- | src/pluto/x509.h | 6 |
20 files changed, 463 insertions, 466 deletions
diff --git a/src/pluto/ac.c b/src/pluto/ac.c index 270efa85f..ce0c26f89 100644 --- a/src/pluto/ac.c +++ b/src/pluto/ac.c @@ -78,7 +78,7 @@ void free_acerts(void) /** * Get a X.509 attribute certificate for a given holder */ -x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial) +x509acert_t* get_x509acert(identification_t *issuer, chunk_t serial) { x509acert_t *x509ac = x509acerts; x509acert_t *prev_ac = NULL; @@ -87,10 +87,9 @@ x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial) { ac_t *ac = (ac_t*)x509ac->ac; identification_t *holderIssuer = ac->get_holderIssuer(ac); - chunk_t holderIssuer_dn = holderIssuer->get_encoding(holderIssuer); chunk_t holderSerial = ac->get_holderSerial(ac); - if (same_dn(issuer, holderIssuer_dn) && + if (issuer->equals(issuer, holderIssuer) && chunk_equals(serial, holderSerial)) { if (x509ac!= x509acerts) @@ -116,11 +115,10 @@ static void add_acert(x509acert_t *x509ac) certificate_t *cert_ac = x509ac->ac; ac_t *ac = (ac_t*)cert_ac; identification_t *holderIssuer = ac->get_holderIssuer(ac); - chunk_t holderIssuer_dn = holderIssuer->get_encoding(holderIssuer); chunk_t holderSerial = ac->get_serial(ac); x509acert_t *old_ac; - old_ac = get_x509acert(holderIssuer_dn, holderSerial); + old_ac = get_x509acert(holderIssuer, holderSerial); if (old_ac != NULL) { if (cert_ac->is_newer(cert_ac, old_ac->ac)) @@ -156,7 +154,6 @@ bool verify_x509acert(x509acert_t *x509ac, bool strict) ac_t *ac = (ac_t*)cert_ac; identification_t *subject = cert_ac->get_subject(cert_ac); identification_t *issuer = cert_ac->get_issuer(cert_ac); - chunk_t issuer_dn = issuer->get_encoding(issuer); chunk_t authKeyID = ac->get_authKeyIdentifier(ac); x509cert_t *aacert; time_t notBefore, valid_until; @@ -177,7 +174,7 @@ bool verify_x509acert(x509acert_t *x509ac, bool strict) ) lock_authcert_list("verify_x509acert"); - aacert = get_authcert(issuer_dn, authKeyID, X509_AA); + aacert = get_authcert(issuer, authKeyID, X509_AA); unlock_authcert_list("verify_x509acert"); if (aacert == NULL) diff --git a/src/pluto/ac.h b/src/pluto/ac.h index b7c02469d..46902429e 100644 --- a/src/pluto/ac.h +++ b/src/pluto/ac.h @@ -18,6 +18,7 @@ #ifndef _AC_H #define _AC_H +#include <utils/identification.h> #include <credentials/certificates/certificate.h> #include <credentials/ietf_attributes/ietf_attributes.h> @@ -33,7 +34,7 @@ struct x509acert { extern bool verify_x509acert(x509acert_t *ac, bool strict); extern bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn, ietf_attributes_t *conn_attributes); -extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial); +extern x509acert_t* get_x509acert(identification_t *issuer, chunk_t serial); extern void load_acerts(void); extern void free_acert(x509acert_t *ac); extern void free_acerts(void); diff --git a/src/pluto/ca.c b/src/pluto/ca.c index 5bee66443..5ee3ce14a 100644 --- a/src/pluto/ca.c +++ b/src/pluto/ca.c @@ -45,19 +45,19 @@ static ca_info_t *ca_infos = NULL; /* * Checks if CA a is trusted by CA b */ -bool trusted_ca(chunk_t a, chunk_t b, int *pathlen) +bool trusted_ca(identification_t *a, identification_t *b, int *pathlen) { bool match = FALSE; /* no CA b specified -> any CA a is accepted */ - if (b.ptr == NULL) + if (b == NULL) { - *pathlen = (a.ptr == NULL)? 0 : MAX_CA_PATH_LEN; + *pathlen = (a == NULL) ? 0 : MAX_CA_PATH_LEN; return TRUE; } /* no CA a specified -> trust cannot be established */ - if (a.ptr == NULL) + if (a == NULL) { *pathlen = MAX_CA_PATH_LEN; return FALSE; @@ -66,7 +66,7 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen) *pathlen = 0; /* CA a equals CA b -> we have a match */ - if (same_dn(a, b)) + if (a->equals(a, b)) { return TRUE; } @@ -78,7 +78,6 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen) { certificate_t *certificate; identification_t *issuer; - chunk_t issuer_dn; x509cert_t *cacert; cacert = get_authcert(a, chunk_empty, X509_CA); @@ -100,8 +99,7 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen) /* does the issuer of CA a match CA b? */ issuer = certificate->get_issuer(certificate); - issuer_dn = issuer->get_encoding(issuer); - match = same_dn(issuer_dn, b); + match = b->equals(b, issuer); /* we have a match and exit the loop */ if (match) @@ -109,7 +107,7 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen) break; } /* go one level up in the CA chain */ - a = issuer_dn; + a = issuer; } unlock_authcert_list("trusted_ca"); @@ -119,11 +117,14 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen) /* * does our CA match one of the requested CAs? */ -bool match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, +bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca, int *our_pathlen) { + identification_t *ca; + enumerator_t *enumerator; + /* if no ca is requested than any ca will match */ - if (requested_ca == NULL) + if (requested_ca == NULL || requested_ca->get_count(requested_ca) == 0) { *our_pathlen = 0; return TRUE; @@ -131,17 +132,17 @@ bool match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, *our_pathlen = MAX_CA_PATH_LEN + 1; - while (requested_ca != NULL) + enumerator = requested_ca->create_enumerator(requested_ca); + while (enumerator->enumerate(enumerator, &ca)) { int pathlen; - if (trusted_ca(our_ca, requested_ca->name, &pathlen) - && pathlen < *our_pathlen) + if (trusted_ca(our_ca, ca, &pathlen) && pathlen < *our_pathlen) { *our_pathlen = pathlen; } - requested_ca = requested_ca->next; } + enumerator->destroy(enumerator); if (*our_pathlen > MAX_CA_PATH_LEN) { @@ -180,7 +181,8 @@ void free_authcerts(void) /* * get a X.509 authority certificate with a given subject or keyid */ -x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, x509_flag_t auth_flags) +x509cert_t* get_authcert(identification_t *subject, chunk_t keyid, + x509_flag_t auth_flags) { x509cert_t *cert, *prev_cert = NULL; @@ -194,8 +196,6 @@ x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, x509_flag_t auth_flags) { certificate_t *certificate = cert->cert; x509_t *x509 = (x509_t*)certificate; - identification_t *cert_subject; - chunk_t cert_subject_dn; /* skip non-matching types of authority certificates */ if (!(x509->get_flags(x509) & auth_flags)) @@ -216,9 +216,7 @@ x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, x509_flag_t auth_flags) } /* compare the subjectDistinguishedNames */ - cert_subject = certificate->get_subject(certificate); - cert_subject_dn = cert_subject->get_encoding(cert_subject); - if (!same_dn(subject, cert_subject_dn)) + if (!certificate->has_subject(certificate, subject)) { continue; } @@ -243,16 +241,14 @@ x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags) { certificate_t *certificate = cert->cert; x509_t *x509 = (x509_t*)certificate; - identification_t *cert_subject = certificate->get_subject(certificate); - chunk_t cert_subject_dn = cert_subject->get_encoding(cert_subject); x509cert_t *old_cert; lock_authcert_list("add_authcert"); - old_cert = get_authcert(cert_subject_dn, + old_cert = get_authcert(certificate->get_subject(certificate), x509->get_subjectKeyIdentifier(x509), auth_flags); - if (old_cert != NULL) + if (old_cert) { if (certificate->equals(certificate, old_cert->cert)) { @@ -341,19 +337,16 @@ void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc) /* * get a cacert with a given subject or keyid from an alternative list */ -static const x509cert_t* get_alt_cacert(chunk_t subject, chunk_t keyid, +static const x509cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid, const x509cert_t *cert) { if (cert == NULL) { return NULL; } - for (; cert != NULL; cert = cert->next) { certificate_t *certificate = cert->cert; - identification_t *cert_subject; - chunk_t cert_subject_dn; /* compare the keyid with the certificate's subjectKeyIdentifier */ if (keyid.ptr) @@ -369,9 +362,7 @@ static const x509cert_t* get_alt_cacert(chunk_t subject, chunk_t keyid, } /* compare the subjectDistinguishedNames */ - cert_subject = certificate->get_subject(certificate); - cert_subject_dn = cert_subject->get_encoding(cert_subject); - if (!same_dn(subject, cert_subject_dn)) + if (!certificate->has_subject(certificate, subject)) { continue; } @@ -397,7 +388,6 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai x509_t *x509 = (x509_t*)certificate; identification_t *subject = certificate->get_subject(certificate); identification_t *issuer = certificate->get_issuer(certificate); - chunk_t issuer_dn = issuer->get_encoding(issuer); chunk_t authKeyID = x509->get_authKeyIdentifier(x509); const x509cert_t *authcert = NULL; @@ -411,7 +401,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai ) /* search in alternative chain first */ - authcert = get_alt_cacert(issuer_dn, authKeyID, alt_chain); + authcert = get_alt_cacert(issuer, authKeyID, alt_chain); if (authcert != NULL) { @@ -422,7 +412,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai else { /* search in trusted chain */ - authcert = get_authcert(issuer_dn, authKeyID, X509_CA); + authcert = get_authcert(issuer, authKeyID, X509_CA); if (authcert != NULL) { @@ -469,14 +459,14 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai /* * get a CA info record with a given authName or authKeyID */ -ca_info_t* get_ca_info(chunk_t authname, chunk_t keyid) +ca_info_t* get_ca_info(identification_t *name, chunk_t keyid) { ca_info_t *ca= ca_infos; - while (ca!= NULL) + while (ca != NULL) { - if ((keyid.ptr != NULL) ? same_keyid(keyid, ca->authKeyID) - : same_dn(authname, ca->authName)) + if ((keyid.ptr) ? same_keyid(keyid, ca->authKeyID) + : name->equals(name, ca->authName)) { return ca; } @@ -497,11 +487,11 @@ free_ca_info(ca_info_t* ca_info) return; } ca_info->crluris->destroy_function(ca_info->crluris, free); + DESTROY_IF(ca_info->authName); free(ca_info->name); free(ca_info->ldaphost); free(ca_info->ldapbase); free(ca_info->ocspuri); - free(ca_info->authName.ptr); free(ca_info->authKeyID.ptr); free(ca_info); } @@ -595,12 +585,11 @@ void add_ca_info(const whack_message_t *msg) certificate_t *certificate = cacert->cert; x509_t *x509 = (x509_t*)certificate; identification_t *subject = certificate->get_subject(certificate); - chunk_t subject_dn = subject->get_encoding(subject); chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509); ca_info_t *ca = NULL; /* does the authname already exist? */ - ca = get_ca_info(subject_dn, subjectKeyID); + ca = get_ca_info(subject, subjectKeyID); if (ca != NULL) { @@ -620,7 +609,7 @@ void add_ca_info(const whack_message_t *msg) ca->name = clone_str(msg->name); /* authName */ - ca->authName = chunk_clone(subject_dn); + ca->authName = subject->clone(subject); DBG(DBG_CONTROL, DBG_log("authname: '%Y'", subject) ) @@ -693,8 +682,6 @@ void list_ca_infos(bool utc) while (ca != NULL) { - u_char buf[BUF_LEN]; - /* strictpolicy per CA not supported yet * whack_log(RC_COMMENT, "%T, \"%s\", strictcrlpolicy: %s" @@ -702,8 +689,7 @@ void list_ca_infos(bool utc) , ca->strictcrlpolicy? "yes":"no"); */ whack_log(RC_COMMENT, " "); - dntoa(buf, BUF_LEN, ca->authName); - whack_log(RC_COMMENT, " authname: \"%s\"", buf); + whack_log(RC_COMMENT, " authname: \"%Y\"", ca->authName); if (ca->ldaphost) { whack_log(RC_COMMENT, " ldaphost: '%s'", ca->ldaphost); @@ -719,11 +705,9 @@ void list_ca_infos(bool utc) list_distribution_points(ca->crluris); - if (ca->authKeyID.ptr != NULL) + if (ca->authKeyID.ptr) { - datatot(ca->authKeyID.ptr, ca->authKeyID.len, ':' - , buf, BUF_LEN); - whack_log(RC_COMMENT, " authkey: %s", buf); + whack_log(RC_COMMENT, " authkey: %#B", &ca->authKeyID); } ca = ca->next; } diff --git a/src/pluto/ca.h b/src/pluto/ca.h index 9e2efb148..ca211587b 100644 --- a/src/pluto/ca.h +++ b/src/pluto/ca.h @@ -16,6 +16,7 @@ #define _CA_H #include <utils/linked_list.h> +#include <utils/identification.h> #include "x509.h" #include "whack.h" @@ -27,21 +28,21 @@ typedef struct ca_info ca_info_t; struct ca_info { - ca_info_t *next; - char *name; - chunk_t authName; - chunk_t authKeyID; - char *ldaphost; - char *ldapbase; - char *ocspuri; - linked_list_t *crluris; - bool strictcrlpolicy; + ca_info_t *next; + char *name; + identification_t *authName; + chunk_t authKeyID; + char *ldaphost; + char *ldapbase; + char *ocspuri; + linked_list_t *crluris; + bool strictcrlpolicy; }; -extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen); -extern bool match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, - int *our_pathlen); -extern x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, +extern bool trusted_ca(identification_t *a, identification_t *b, int *pathlen); +extern bool match_requested_ca(linked_list_t *requested_ca, + identification_t *our_ca, int *our_pathlen); +extern x509cert_t* get_authcert(identification_t *subject, chunk_t keyid, x509_flag_t auth_flags); extern void load_authcerts(const char *type, const char *path, x509_flag_t auth_flags); @@ -50,7 +51,7 @@ extern void free_authcerts(void); extern void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc); extern bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain); -extern ca_info_t* get_ca_info(chunk_t name, chunk_t keyid); +extern ca_info_t* get_ca_info(identification_t *name, chunk_t keyid); extern bool find_ca_info_by_name(const char *name, bool delete); extern void add_ca_info(const whack_message_t *msg); extern void delete_ca_info(const char *name); diff --git a/src/pluto/connections.c b/src/pluto/connections.c index 6c2872609..01a80a100 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -336,13 +336,17 @@ void delete_connection(connection_t *c, bool relations) free(c->name); free_id_content(&c->spd.this.id); free(c->spd.this.updown); - free(c->spd.this.ca.ptr); + DESTROY_IF(c->spd.this.ca); DESTROY_IF(c->spd.this.groups); free_id_content(&c->spd.that.id); free(c->spd.that.updown); - free(c->spd.that.ca.ptr); + DESTROY_IF(c->spd.that.ca); DESTROY_IF(c->spd.that.groups); - free_generalNames(c->requested_ca, TRUE); + if (c->requested_ca) + { + c->requested_ca->destroy_offset(c->requested_ca, + offsetof(identification_t, destroy)); + } gw_delref(&c->gw_info); lock_certs_and_keys("delete_connection"); @@ -674,13 +678,18 @@ static void unshare_connection_strings(connection_t *c) c->spd.this.updown = clone_str(c->spd.this.updown); scx_share(c->spd.this.sc); share_cert(c->spd.this.cert); - c->spd.this.ca = chunk_clone(c->spd.this.ca); - + if (c->spd.this.ca) + { + c->spd.this.ca = c->spd.this.ca->clone(c->spd.this.ca); + } unshare_id_content(&c->spd.that.id); c->spd.that.updown = clone_str(c->spd.that.updown); scx_share(c->spd.that.sc); share_cert(c->spd.that.cert); - c->spd.that.ca = chunk_clone(c->spd.that.ca); + if (c->spd.that.ca) + { + c->spd.that.ca = c->spd.that.ca->clone(c->spd.that.ca); + } /* increment references to algo's */ alg_info_addref((struct alg_info *)c->alg_info_esp); @@ -757,12 +766,12 @@ static void load_end_certificate(char *filename, struct end *dst) } /* if no CA is defined, use issuer as default */ - if (dst->ca.ptr == NULL) + if (dst->ca) { certificate_t *certificate = dst->cert.u.x509->cert; identification_t *issuer = certificate->get_issuer(certificate); - dst->ca = issuer->get_encoding(issuer); + dst->ca = issuer->clone(issuer); } break; default: @@ -806,23 +815,23 @@ static bool extract_end(struct end *dst, const whack_end_t *src, } } - dst->ca = chunk_empty; + dst->ca = NULL; /* decode CA distinguished name, if any */ if (src->ca) { if streq(src->ca, "%same") + { same_ca = TRUE; + } else if (!streq(src->ca, "%any")) { - err_t ugh; - - dst->ca.ptr = temporary_cyclic_buffer(); - ugh = atodn(src->ca, &dst->ca); - if (ugh != NULL) + dst->ca = identification_create_from_string(src->ca); + if (dst->ca->get_type(dst->ca) != ID_DER_ASN1_DN) { - plog("bad CA string '%s': %s (ignored)", src->ca, ugh); - dst->ca = chunk_empty; + plog("bad CA string '%s', ignored", src->ca); + dst->ca->destroy(dst->ca); + dst->ca = NULL; } } } @@ -3249,7 +3258,7 @@ connection_t *find_host_connection(const ip_address *me, u_int16_t my_port, connection_t *refine_host_connection(const struct state *st, const struct id *peer_id, - chunk_t peer_ca) + identification_t *peer_ca) { connection_t *c = st->st_connection; connection_t *d; @@ -3520,7 +3529,7 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp, const u_int16_t our_port, const u_int8_t peer_protocol, const u_int16_t peer_port, - chunk_t peer_ca, + identification_t *peer_ca, ietf_attributes_t *peer_attributes) { connection_t *d; @@ -3663,7 +3672,7 @@ static connection_t *fc_try_oppo(const connection_t *c, const u_int16_t our_port, const u_int8_t peer_protocol, const u_int16_t peer_port, - chunk_t peer_ca, + identification_t *peer_ca, ietf_attributes_t *peer_attributes) { connection_t *d; @@ -3765,19 +3774,22 @@ static connection_t *fc_try_oppo(const connection_t *c, /* * get the peer's CA and group attributes */ -chunk_t get_peer_ca_and_groups(connection_t *c, ietf_attributes_t **peer_attributes) +void get_peer_ca_and_groups(connection_t *c, + identification_t **peer_ca, + ietf_attributes_t **peer_attributes) { - struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES); + struct state *p1st; + *peer_ca = NULL; *peer_attributes = NULL; - if (p1st != NULL - && p1st->st_peer_pubkey != NULL - && p1st->st_peer_pubkey->issuer.ptr != NULL) + p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES); + if (p1st && p1st->st_peer_pubkey && p1st->st_peer_pubkey->issuer) { - x509acert_t *x509ac = get_x509acert(p1st->st_peer_pubkey->issuer, - p1st->st_peer_pubkey->serial); + x509acert_t *x509ac; + x509ac = get_x509acert(p1st->st_peer_pubkey->issuer, + p1st->st_peer_pubkey->serial); if (x509ac && verify_x509acert(x509ac, strict_crl_policy)) { ac_t * ac = (ac_t*)x509ac->ac; @@ -3790,9 +3802,8 @@ chunk_t get_peer_ca_and_groups(connection_t *c, ietf_attributes_t **peer_attribu DBG_log("no valid attribute cert found") ) } - return p1st->st_peer_pubkey->issuer; + *peer_ca = p1st->st_peer_pubkey->issuer; } - return chunk_empty; } connection_t *find_client_connection(connection_t *c, @@ -3806,7 +3817,9 @@ connection_t *find_client_connection(connection_t *c, connection_t *d; struct spd_route *sr; ietf_attributes_t *peer_attributes = NULL; - chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_attributes); + identification_t *peer_ca; + + get_peer_ca_and_groups(c, &peer_ca, &peer_attributes); #ifdef DEBUG if (DBGP(DBG_CONTROLMORE)) @@ -4034,18 +4047,21 @@ void show_connections_status(bool all, const char *name) if (all) { /* show CAs if defined */ - if (c->spd.this.ca.ptr != NULL || c->spd.that.ca.ptr != NULL) + if (c->spd.this.ca && c->spd.that.ca) { - char this_ca[BUF_LEN], that_ca[BUF_LEN]; - - dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any"); - dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any"); + whack_log(RC_COMMENT, "\"%s\"%s: CAs: \"%Y\"...\"%Y\"", + c->name, instance, c->spd.this.ca, c->spd.that.ca); + } + else if (c->spd.this.ca) + { + whack_log(RC_COMMENT, "\"%s\"%s: CAs: \"%Y\"...%%any", + c->name, instance, c->spd.this.ca); - whack_log(RC_COMMENT, "\"%s\"%s: CAs: '%s'...'%s'" - , c->name - , instance - , this_ca - , that_ca); + } + else if (c->spd.that.ca) + { + whack_log(RC_COMMENT, "\"%s\"%s: CAs: %%any...\"%Y\"", + c->name, instance, c->spd.that.ca); } /* show group attributes if defined */ diff --git a/src/pluto/connections.h b/src/pluto/connections.h index 5bef59b66..216ab5475 100644 --- a/src/pluto/connections.h +++ b/src/pluto/connections.h @@ -17,6 +17,9 @@ #include <sys/queue.h> +#include <utils/linked_list.h> +#include <utils/identification.h> + #include "id.h" #include "certs.h" #include "ac.h" @@ -145,7 +148,7 @@ struct end { u_int16_t port; /* host order */ u_int8_t protocol; cert_t cert; /* end certificate */ - chunk_t ca; /* CA distinguished name */ + identification_t *ca; /* CA distinguished name */ ietf_attributes_t *groups; /* access control groups */ smartcard_t *sc; /* smartcard reader and key info */ struct virtual_t *virt; @@ -214,16 +217,13 @@ struct connection { connection_t *policy_next; /* if multiple policies, next one to apply */ - struct gw_info *gw_info; struct alg_info_esp *alg_info_esp; struct alg_info_ike *alg_info_ike; - struct host_pair *host_pair; connection_t *hp_next; /* host pair list link */ connection_t *ac_next; /* all connections list link */ - - generalName_t *requested_ca; /* collected certificate requests */ + linked_list_t *requested_ca; /* collected certificate requests */ bool got_certrequest; }; @@ -267,29 +267,30 @@ extern void ISAKMP_SA_established(connection_t *c, so_serial_t serial); sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE)) struct state; /* forward declaration of tag (defined in state.h) */ -extern connection_t - *con_by_name(const char *nm, bool strict), - *find_host_connection(const ip_address *me, u_int16_t my_port - , const ip_address *him, u_int16_t his_port, lset_t policy), - *refine_host_connection(const struct state *st, const struct id *id - , chunk_t peer_ca), - *find_client_connection(connection_t *c - , const ip_subnet *our_net - , const ip_subnet *peer_net - , const u_int8_t our_protocol - , const u_int16_t out_port - , const u_int8_t peer_protocol - , const u_int16_t peer_port), - *find_connection_by_reqid(uint32_t reqid); - -extern connection_t * -find_connection_for_clients(struct spd_route **srp - , const ip_address *our_client - , const ip_address *peer_client - , int transport_proto); - -extern chunk_t get_peer_ca_and_groups(connection_t *c, - ietf_attributes_t **peer_attributes); + +extern connection_t* con_by_name(const char *nm, bool strict); +extern connection_t* find_host_connection(const ip_address *me, + u_int16_t my_port, + const ip_address *him, + u_int16_t his_port, lset_t policy); +extern connection_t* refine_host_connection(const struct state *st, + const struct id *id, + identification_t *peer_ca); +extern connection_t* find_client_connection(connection_t *c, + const ip_subnet *our_net, + const ip_subnet *peer_net, + const u_int8_t our_protocol, + const u_int16_t out_port, + const u_int8_t peer_protocol, + const u_int16_t peer_port); +extern connection_t* find_connection_by_reqid(uint32_t reqid); +extern connection_t* find_connection_for_clients(struct spd_route **srp, + const ip_address *our_client, + const ip_address *peer_client, + int transport_proto); +extern void get_peer_ca_and_groups(connection_t *c, + identification_t **peer_ca, + ietf_attributes_t **peer_attributes); /* instantiating routines * Note: connection_discard() is in state.h because all its work diff --git a/src/pluto/crl.c b/src/pluto/crl.c index 7f71c0f94..f80c7955b 100644 --- a/src/pluto/crl.c +++ b/src/pluto/crl.c @@ -44,7 +44,7 @@ static x509crl_t *x509crls = NULL; /** * Get the X.509 CRL with a given issuer */ -static x509crl_t* get_x509crl(chunk_t issuer, chunk_t keyid) +static x509crl_t* get_x509crl(identification_t *issuer, chunk_t keyid) { x509crl_t *x509crl = x509crls; x509crl_t *prev_crl = NULL; @@ -54,11 +54,10 @@ static x509crl_t* get_x509crl(chunk_t issuer, chunk_t keyid) certificate_t *cert_crl = x509crl->crl; crl_t *crl = (crl_t*)cert_crl; identification_t *crl_issuer = cert_crl->get_issuer(cert_crl); - chunk_t crl_issuer_dn = crl_issuer->get_encoding(crl_issuer); chunk_t authKeyID = crl->get_authKeyIdentifier(crl); if ((keyid.ptr && authKeyID.ptr)? same_keyid(keyid, authKeyID) : - same_dn(crl_issuer_dn, issuer)) + issuer->equals(issuer, crl_issuer)) { if (x509crl != x509crls) { @@ -113,7 +112,6 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl) certificate_t *cert_crl = x509crl->crl; crl_t *crl = (crl_t*)cert_crl; identification_t *issuer = cert_crl->get_issuer(cert_crl); - chunk_t issuer_dn = issuer->get_encoding(issuer); chunk_t authKeyID = crl->get_authKeyIdentifier(crl); x509cert_t *issuer_cert; x509crl_t *oldcrl; @@ -126,7 +124,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl) lock_authcert_list("insert_crl"); /* get the issuer cacert */ - issuer_cert = get_authcert(issuer_dn, authKeyID, X509_CA); + issuer_cert = get_authcert(issuer, authKeyID, X509_CA); if (issuer_cert == NULL) { plog("crl issuer cacert not found"); @@ -155,7 +153,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl) time(&now); lock_crl_list("insert_crl"); - oldcrl = get_x509crl(issuer_dn, authKeyID); + oldcrl = get_x509crl(issuer, authKeyID); if (oldcrl != NULL) { @@ -315,7 +313,6 @@ void check_crls(void) certificate_t *cert_crl = x509crl->crl; crl_t *crl = (crl_t*)cert_crl; identification_t *issuer = cert_crl->get_issuer(cert_crl); - chunk_t issuer_dn = issuer->get_encoding(issuer); chunk_t authKeyID = crl->get_authKeyIdentifier(crl); cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate); @@ -331,7 +328,7 @@ void check_crls(void) ) if (time_left < 2*crl_check_interval) { - fetch_req_t *req = build_crl_fetch_request(issuer_dn, authKeyID, + fetch_req_t *req = build_crl_fetch_request(issuer, authKeyID, x509crl->distributionPoints); add_crl_fetch_request(req); } @@ -350,20 +347,19 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until, certificate_t *certificate = cert->cert; x509_t *x509 = (x509_t*)certificate; identification_t *issuer = certificate->get_issuer(certificate); - chunk_t issuer_dn = issuer->get_encoding(issuer); chunk_t authKeyID = x509->get_authKeyIdentifier(x509); x509crl_t *x509crl; ca_info_t *ca; enumerator_t *enumerator; char *point; - ca = get_ca_info(issuer_dn, authKeyID); + ca = get_ca_info(issuer, authKeyID); *revocationDate = UNDEFINED_TIME; *revocationReason = CRL_REASON_UNSPECIFIED; lock_crl_list("verify_by_crl"); - x509crl = get_x509crl(issuer_dn, authKeyID); + x509crl = get_x509crl(issuer, authKeyID); if (x509crl == NULL) { @@ -389,7 +385,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until, { fetch_req_t *req; - req = build_crl_fetch_request(issuer_dn, authKeyID, crluris); + req = build_crl_fetch_request(issuer, authKeyID, crluris); crluris->destroy_function(crluris, free); add_crl_fetch_request(req); wake_fetch_thread("verify_by_crl"); @@ -427,7 +423,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until, lock_authcert_list("verify_by_crl"); - issuer_cert = get_authcert(issuer_dn, authKeyID, X509_CA); + issuer_cert = get_authcert(issuer, authKeyID, X509_CA); trusted = cert_crl->issued_by(cert_crl, issuer_cert->cert); unlock_authcert_list("verify_by_crl"); @@ -463,7 +459,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until, ) /* try to fetch a crl update */ - req = build_crl_fetch_request(issuer_dn, authKeyID, + req = build_crl_fetch_request(issuer, authKeyID, x509crl->distributionPoints); unlock_crl_list("verify_by_crl"); diff --git a/src/pluto/crl.h b/src/pluto/crl.h index cf8aa54b7..bac0717a0 100644 --- a/src/pluto/crl.h +++ b/src/pluto/crl.h @@ -26,7 +26,7 @@ struct x509crl { certificate_t *crl; x509crl_t *next; linked_list_t *distributionPoints; - chunk_t signature; + chunk_t signature; }; /* apply a strict CRL policy diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c index 9e630e081..d2a6c0d76 100644 --- a/src/pluto/fetch.c +++ b/src/pluto/fetch.c @@ -45,7 +45,7 @@ fetch_req_t empty_fetch_req = { NULL , /* next */ 0 , /* trials */ - { NULL, 0}, /* issuer */ + NULL , /* issuer */ { NULL, 0}, /* authKeyID */ NULL /* distributionPoints */ }; @@ -250,7 +250,7 @@ void wake_fetch_thread(const char *who) static void free_fetch_request(fetch_req_t *req) { req->distributionPoints->destroy_function(req->distributionPoints, free); - free(req->issuer.ptr); + DESTROY_IF(req->issuer); free(req->authKeyID.ptr); free(req); } @@ -598,7 +598,8 @@ void add_distribution_points(linked_list_t *points, linked_list_t *new_points) enumerator->destroy(enumerator); } -fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeyID, +fetch_req_t* build_crl_fetch_request(identification_t *issuer, + chunk_t authKeyID, linked_list_t *distributionPoints) { char *point; @@ -609,7 +610,7 @@ fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeyID, req->distributionPoints = linked_list_create(); /* clone fields */ - req->issuer = chunk_clone(issuer); + req->issuer = issuer->clone(issuer); req->authKeyID = chunk_clone(authKeyID); /* copy distribution points */ @@ -637,7 +638,7 @@ void add_crl_fetch_request(fetch_req_t *req) while (r != NULL) { if (req->authKeyID.ptr ? same_keyid(req->authKeyID, r->authKeyID) : - same_dn(req->issuer, r->issuer)) + req->issuer->equals(req->issuer, r->issuer)) { /* there is already a fetch request */ DBG(DBG_CONTROL, @@ -712,21 +713,16 @@ void list_crl_fetch_requests(bool utc) { whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, "List of CRL Fetch Requests:"); - whack_log(RC_COMMENT, " "); } while (req != NULL) { - u_char buf[BUF_LEN]; - + whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " trials: %d", req->trials); - dntoa(buf, BUF_LEN, req->issuer); - whack_log(RC_COMMENT, " issuer: \"%s\"", buf); - if (req->authKeyID.ptr != NULL) + whack_log(RC_COMMENT, " issuer: \"%Y\"", req->issuer); + if (req->authKeyID.ptr) { - datatot(req->authKeyID.ptr, req->authKeyID.len, ':' - , buf, BUF_LEN); - whack_log(RC_COMMENT, " authkey: %s", buf); + whack_log(RC_COMMENT, " authkey: %#B", &req->authKeyID); } list_distribution_points(req->distributionPoints); req = req->next; diff --git a/src/pluto/fetch.h b/src/pluto/fetch.h index bb504665c..a0e52a8f8 100644 --- a/src/pluto/fetch.h +++ b/src/pluto/fetch.h @@ -14,6 +14,7 @@ */ #include <utils/linked_list.h> +#include <utils/identification.h> #include "x509.h" @@ -29,11 +30,11 @@ typedef enum { typedef struct fetch_req fetch_req_t; struct fetch_req { - fetch_req_t *next; - int trials; - chunk_t issuer; - chunk_t authKeyID; - linked_list_t *distributionPoints; + fetch_req_t *next; + int trials; + identification_t *issuer; + chunk_t authKeyID; + linked_list_t *distributionPoints; }; #ifdef THREADS @@ -67,7 +68,8 @@ extern void free_ocsp_fetch(void); extern void add_distribution_point(linked_list_t *points, char* new_point); extern void add_distribution_points(linked_list_t *points, linked_list_t *new_points); -extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeyID, +extern fetch_req_t* build_crl_fetch_request(identification_t *issuer, + chunk_t authKeyID, linked_list_t *distributionPoints); extern void add_crl_fetch_request(fetch_req_t *req); extern void add_ocsp_fetch_request(struct ocsp_location *location, diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c index e4560bc90..9d5b1cfc9 100644 --- a/src/pluto/ipsec_doi.c +++ b/src/pluto/ipsec_doi.c @@ -233,39 +233,42 @@ static bool build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np, return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name); } -static bool collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top) +static linked_list_t* collect_rw_ca_candidates(struct msg_digest *md) { - connection_t *d = find_host_connection(&md->iface->addr - , pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY); + linked_list_t *list = linked_list_create(); + connection_t *d; + + d = find_host_connection(&md->iface->addr, pluto_port, (ip_address*)NULL, + md->sender_port, LEMPTY); for (; d != NULL; d = d->hp_next) { /* must be a road warrior connection */ - if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO) - && d->spd.that.ca.ptr != NULL) + if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO) && + d->spd.that.ca) { - generalName_t *gn; + enumerator_t *enumerator; + identification_t *ca; bool new_entry = TRUE; - for (gn = *top; gn != NULL; gn = gn->next) + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &ca)) { - if (same_dn(gn->name, d->spd.that.ca)) + if (ca->equals(ca, d->spd.that.ca)) { new_entry = FALSE; break; - } + } } + enumerator->destroy(enumerator); + if (new_entry) { - gn = malloc_thing(generalName_t); - gn->kind = GN_DIRECTORY_NAME; - gn->name = d->spd.that.ca; - gn->next = *top; - *top = gn; + list->insert_last(list, d->spd.that.ca->clone(d->spd.that.ca)); } } } - return *top != NULL; + return list; } static bool build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, @@ -1608,8 +1611,11 @@ static stf_status check_signature(key_type_t key_type, const struct id* peer, { pubkey_t *key = p->key; key_type_t type = key->public_key->get_type(key->public_key); + struct id key_id; - if (type == key_type && same_id(peer, &key->id)) + id_from_identification(&key_id, key->id); + + if (type == key_type && same_id(peer, &key_id)) { time_t now = time(NULL); @@ -1621,7 +1627,6 @@ static stf_status check_signature(key_type_t key_type, const struct id* peer, *pp = free_public_keyentry(p); continue; /* continue with next public key */ } - if (take_a_crack(&s, key)) { return STF_OK; @@ -2165,26 +2170,26 @@ static void decode_cert(struct msg_digest *md) blob.len = pbs_left(&p->pbs); if (cert->isacert_type == CERT_X509_SIGNATURE) { - x509cert_t cert = empty_x509cert; + x509cert_t x509cert = empty_x509cert; - cert.cert = lib->creds->create(lib->creds, + x509cert.cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, BUILD_BLOB_ASN1_DER, blob, BUILD_END); - if (cert.cert) + if (x509cert.cert) { - if (verify_x509cert(&cert, strict_crl_policy, &valid_until)) + if (verify_x509cert(&x509cert, strict_crl_policy, &valid_until)) { DBG(DBG_PARSING, DBG_log("Public key validated") ) - add_x509_public_key(&cert, valid_until, DAL_SIGNED); + add_x509_public_key(&x509cert, valid_until, DAL_SIGNED); } else { plog("X.509 certificate rejected"); } - DESTROY_IF(cert.cert); + x509cert.cert->destroy(x509cert.cert); } else { @@ -2193,11 +2198,11 @@ static void decode_cert(struct msg_digest *md) } else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509) { - x509cert_t *cert = NULL; + x509cert_t *x509cert = NULL; - if (pkcs7_parse_signedData(blob, NULL, &cert, NULL, NULL)) + if (pkcs7_parse_signedData(blob, NULL, &x509cert, NULL, NULL)) { - store_x509certs(&cert, strict_crl_policy); + store_x509certs(&x509cert, strict_crl_policy); } else { @@ -2232,29 +2237,31 @@ static void decode_cr(struct msg_digest *md, connection_t *c) if (cr->isacr_type == CERT_X509_SIGNATURE) { - char buf[BUF_LEN]; - if (ca_name.len > 0) { - generalName_t *gn; + identification_t *ca; if (!is_asn1(ca_name)) { continue; } - gn = malloc_thing(generalName_t); - ca_name = chunk_clone(ca_name); - gn->kind = GN_DIRECTORY_NAME; - gn->name = ca_name; - gn->next = c->requested_ca; - c->requested_ca = gn; + if (c->requested_ca == NULL) + { + c->requested_ca = linked_list_create(); + } + ca = identification_create_from_encoding(ID_DER_ASN1_DN, ca_name); + c->requested_ca->insert_last(c->requested_ca, ca); + DBG(DBG_PARSING | DBG_CONTROL, + DBG_log("requested CA: \"%Y\"", ca) + ) + } + else + { + DBG(DBG_PARSING | DBG_CONTROL, + DBG_log("requested CA: %%any") + ) } c->got_certrequest = TRUE; - - DBG(DBG_PARSING | DBG_CONTROL, - dntoa_or_null(buf, BUF_LEN, ca_name, "%any"); - DBG_log("requested CA: '%s'", buf); - ) } else { @@ -2388,16 +2395,21 @@ static bool switch_connection(struct msg_digest *md, struct id *peer, { struct state *const st = md->st; connection_t *c = st->st_connection; + identification_t *peer_ca; - chunk_t peer_ca = (st->st_peer_pubkey != NULL) - ? st->st_peer_pubkey->issuer : chunk_empty; - - DBG(DBG_CONTROL, - char buf[BUF_LEN]; - - dntoa_or_null(buf, BUF_LEN, peer_ca, "%none"); - DBG_log("peer CA: '%s'", buf); - ) + peer_ca = st->st_peer_pubkey ? st->st_peer_pubkey->issuer : NULL; + if (peer_ca) + { + DBG(DBG_CONTROL, + DBG_log("peer CA: \"%Y\"", peer_ca) + ) + } + else + { + DBG(DBG_CONTROL, + DBG_log("peer CA: %%none") + ) + } if (initiator) { @@ -2416,12 +2428,18 @@ static bool switch_connection(struct msg_digest *md, struct id *peer, return FALSE; } - DBG(DBG_CONTROL, - char buf[BUF_LEN]; - - dntoa_or_null(buf, BUF_LEN, c->spd.that.ca, "%none"); - DBG_log("required CA: '%s'", buf); - ) + if (c->spd.that.ca) + { + DBG(DBG_CONTROL, + DBG_log("required CA: \"%s\"", c->spd.that.ca); + ) + } + else + { + DBG(DBG_CONTROL, + DBG_log("required CA: %%none"); + ) + } if (!trusted_ca(peer_ca, c->spd.that.ca, &pathlen)) { @@ -2440,8 +2458,12 @@ static bool switch_connection(struct msg_digest *md, struct id *peer, r = refine_host_connection(st, peer, peer_ca); /* delete the collected certificate requests */ - free_generalNames(c->requested_ca, TRUE); - c->requested_ca = NULL; + if (c->requested_ca) + { + c->requested_ca->destroy_offset(c->requested_ca, + offsetof(identification_t, destroy)); + c->requested_ca = NULL; + } if (r == NULL) { @@ -2452,12 +2474,18 @@ static bool switch_connection(struct msg_digest *md, struct id *peer, return FALSE; } - DBG(DBG_CONTROL, - char buf[BUF_LEN]; - - dntoa_or_null(buf, BUF_LEN, r->spd.this.ca, "%none"); - DBG_log("offered CA: '%s'", buf); - ) + if (r->spd.this.ca) + { + DBG(DBG_CONTROL, + DBG_log("offered CA: \"%s\"", r->spd.this.ca) + ) + } + else + { + DBG(DBG_CONTROL, + DBG_log("offered CA: %%none") + ) + } if (r != c) { @@ -2708,8 +2736,10 @@ static bool has_preloaded_public_key(struct state *st) { pubkey_t *key = p->key; key_type_t type = key->public_key->get_type(key->public_key); + struct id key_id; - if (type == KEY_RSA && same_id(&c->spd.that.id, &key->id) && + id_from_identification(&key_id, key->id); + if (type == KEY_RSA && same_id(&c->spd.that.id, &key_id) && key->until_time == UNDEFINED_TIME) { /* found a preloaded public key */ @@ -3402,40 +3432,51 @@ stf_status main_inI2_outR2(struct msg_digest *md) { if (st->st_connection->kind == CK_PERMANENT) { - if (!build_and_ship_CR(CERT_X509_SIGNATURE - , st->st_connection->spd.that.ca - , &md->rbody, np)) + identification_t *ca = st->st_connection->spd.that.ca; + chunk_t cr = (ca) ? ca->get_encoding(ca) : chunk_empty; + + if (!build_and_ship_CR(CERT_X509_SIGNATURE, cr, &md->rbody, np)) { return STF_INTERNAL_ERROR; } } else { - generalName_t *ca = NULL; + linked_list_t *list = collect_rw_ca_candidates(md); + int count = list->get_count(list); + bool error = FALSE; - if (collect_rw_ca_candidates(md, &ca)) + if (count) { - generalName_t *gn; + enumerator_t *enumerator; + identification_t *ca; - for (gn = ca; gn != NULL; gn = gn->next) + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &ca)) { - if (!build_and_ship_CR(CERT_X509_SIGNATURE, gn->name - , &md->rbody - , gn->next == NULL ? np : ISAKMP_NEXT_CR)) + if (!build_and_ship_CR(CERT_X509_SIGNATURE, + ca->get_encoding(ca), &md->rbody, + --count ? ISAKMP_NEXT_CR : np)) { - return STF_INTERNAL_ERROR; + error = TRUE; + break; } } - free_generalNames(ca, FALSE); + enumerator->destroy(enumerator); } else { - if (!build_and_ship_CR(CERT_X509_SIGNATURE, chunk_empty - , &md->rbody, np)) + if (!build_and_ship_CR(CERT_X509_SIGNATURE, chunk_empty, + &md->rbody, np)) { - return STF_INTERNAL_ERROR; + error = TRUE; } } + list->destroy_offset(list, offsetof(identification_t, destroy)); + if (error) + { + return STF_INTERNAL_ERROR; + } } } @@ -3478,9 +3519,10 @@ stf_status main_inR2_outI3(struct msg_digest *md) struct state *const st = md->st; pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; pb_stream id_pbs; /* ID Payload; also used for hash calculation */ - - certpolicy_t cert_policy = st->st_connection->spd.this.sendcert; - cert_t mycert = st->st_connection->spd.this.cert; + + connection_t *c = st->st_connection; + certpolicy_t cert_policy = c->spd.this.sendcert; + cert_t mycert = c->spd.this.cert; bool requested, send_cert, send_cr; bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth); @@ -3493,20 +3535,23 @@ stf_status main_inR2_outI3(struct msg_digest *md) RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr")); /* decode certificate requests */ - st->st_connection->got_certrequest = FALSE; - decode_cr(md, st->st_connection); + c->got_certrequest = FALSE; + decode_cr(md, c); /* free collected certificate requests since as initiator * we don't heed them anyway */ - free_generalNames(st->st_connection->requested_ca, TRUE); - st->st_connection->requested_ca = NULL; + if (c->requested_ca) + { + c->requested_ca->destroy_offset(c->requested_ca, + offsetof(identification_t, destroy)); + c->requested_ca = NULL; + } /* send certificate if auth is RSA, we have one and we want * or are requested to send it */ - requested = cert_policy == CERT_SEND_IF_ASKED - && st->st_connection->got_certrequest; + requested = cert_policy == CERT_SEND_IF_ASKED && c->got_certrequest; send_cert = pubkey_auth && mycert.type != CERT_NONE && (cert_policy == CERT_ALWAYS_SEND || requested); @@ -3542,7 +3587,7 @@ stf_status main_inR2_outI3(struct msg_digest *md) struct isakmp_ipsec_id id_hd; chunk_t id_b; - build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this); + build_id_payload(&id_hd, &id_b, &c->spd.this); id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload; if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs) || !out_chunk(id_b, &id_pbs, "my identity")) @@ -3601,8 +3646,10 @@ stf_status main_inR2_outI3(struct msg_digest *md) /* CR out */ if (send_cr) { - if (!build_and_ship_CR(mycert.type, st->st_connection->spd.that.ca - , &md->rbody, ISAKMP_NEXT_SIG)) + identification_t *ca = st->st_connection->spd.that.ca; + chunk_t cr = (ca) ? ca->get_encoding(ca) : chunk_empty; + + if (!build_and_ship_CR(mycert.type, cr, &md->rbody, ISAKMP_NEXT_SIG)) { return STF_INTERNAL_ERROR; } @@ -3632,7 +3679,7 @@ stf_status main_inR2_outI3(struct msg_digest *md) scheme = oakley_to_signature_scheme(st->st_oakley.auth); - sig_len = sign_hash(scheme, st->st_connection, sig_val, hash); + sig_len = sign_hash(scheme, c, sig_val, hash); if (sig_len == 0) { loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature"); @@ -5182,10 +5229,11 @@ stf_status quick_inR1_outI2(struct msg_digest *md) /* check the peer's group attributes */ { + identification_t *peer_ca = NULL; ietf_attributes_t *peer_attributes = NULL; bool match; - get_peer_ca_and_groups(st->st_connection, &peer_attributes); + get_peer_ca_and_groups(st->st_connection, &peer_ca, &peer_attributes); match = match_group_membership(peer_attributes, st->st_connection->name, st->st_connection->spd.that.groups); diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c index 608645974..27f25bc83 100644 --- a/src/pluto/kernel.c +++ b/src/pluto/kernel.c @@ -492,13 +492,23 @@ static bool do_command(connection_t *c, struct spd_route *sr, { pubkey_t *key = p->key; key_type_t type = key->public_key->get_type(key->public_key); + struct id key_id; int pathlen; - if (type == KEY_RSA && same_id(&sr->that.id, &key->id) && + id_from_identification(&key_id, key->id); + + if (type == KEY_RSA && same_id(&sr->that.id, &key_id) && trusted_ca(key->issuer, sr->that.ca, &pathlen)) { - dntoa_or_null(peerca_str, BUF_LEN, key->issuer, ""); - escape_metachar(peerca_str, secure_peerca_str, sizeof(secure_peerca_str)); + if (key->issuer) + { + snprintf(peerca_str, BUF_LEN, "%Y", key->issuer); + escape_metachar(peerca_str, secure_peerca_str, BUF_LEN); + } + else + { + secure_peerca_str[0] = '\0'; + } break; } } diff --git a/src/pluto/keys.c b/src/pluto/keys.c index 292406563..828e45d2e 100644 --- a/src/pluto/keys.c +++ b/src/pluto/keys.c @@ -84,9 +84,9 @@ struct secret { */ static void free_public_key(pubkey_t *pk) { + DESTROY_IF(pk->id); DESTROY_IF(pk->public_key); - free_id_content(&pk->id); - free(pk->issuer.ptr); + DESTROY_IF(pk->issuer); free(pk->serial.ptr); free(pk); } @@ -1118,8 +1118,8 @@ pubkey_t* public_key_from_rsa(public_key_t *key) pubkey_t *p = malloc_thing(pubkey_t); zero(p); - p->id = empty_id; /* don't know, doesn't matter */ - p->issuer = chunk_empty; + p->id = identification_create_from_string("%any"); /* don't know, doesn't matter */ + p->issuer = NULL; p->serial = chunk_empty; p->public_key = key; @@ -1127,7 +1127,6 @@ pubkey_t* public_key_from_rsa(public_key_t *key) * invariant: recount > 0. */ p->refcnt = 1; - time(&p->installed_time); return p; } @@ -1206,25 +1205,14 @@ static void install_public_key(pubkey_t *pk, pubkey_list_t **head) { pubkey_list_t *p = malloc_thing(pubkey_list_t); - unshare_id_content(&pk->id); - - /* copy issuer dn */ - pk->issuer = chunk_clone(pk->issuer); - - /* copy serial number */ - pk->serial = chunk_clone(pk->serial); - - /* store the time the public key was installed */ - time(&pk->installed_time); - /* install new key at front */ p->key = reference_key(pk); p->next = *head; *head = p; } -void delete_public_keys(const struct id *id, key_type_t type, - chunk_t issuer, chunk_t serial) +void delete_public_keys(identification_t *id, key_type_t type, + identification_t *issuer, chunk_t serial) { pubkey_list_t **pp, *p; pubkey_t *pk; @@ -1235,9 +1223,9 @@ void delete_public_keys(const struct id *id, key_type_t type, pk = p->key; pk_type = pk->public_key->get_type(pk->public_key); - if (same_id(id, &pk->id) && pk_type == type - && (issuer.ptr == NULL || pk->issuer.ptr == NULL - || same_dn(issuer, pk->issuer)) + if (id->equals(id, pk->id) && pk_type == type + && (issuer == NULL || pk->issuer == NULL + || issuer->equals(issuer, pk->issuer)) && (serial.ptr == NULL || chunk_equals(serial, pk->serial))) { *pp = free_public_keyentry(p); @@ -1251,25 +1239,26 @@ void delete_public_keys(const struct id *id, key_type_t type, pubkey_t* reference_key(pubkey_t *pk) { + DBG(DBG_CONTROLMORE, + DBG_log(" ref key: %p %p cnt %d '%Y'", + pk, pk->public_key, pk->refcnt, pk->id) + ) pk->refcnt++; return pk; } -void -unreference_key(pubkey_t **pkp) +void unreference_key(pubkey_t **pkp) { pubkey_t *pk = *pkp; - char b[BUF_LEN]; if (pk == NULL) { return; } - /* print stuff */ DBG(DBG_CONTROLMORE, - idtoa(&pk->id, b, sizeof(b)); - DBG_log("unreference key: %p %s cnt %d--", pk, b, pk->refcnt) + DBG_log("unref key: %p %p cnt %d '%Y'", + pk, pk->public_key, pk->refcnt, pk->id) ) /* cancel out the pointer */ @@ -1283,7 +1272,7 @@ unreference_key(pubkey_t **pkp) } } -bool add_public_key(const struct id *id, enum dns_auth_level dns_auth_level, +bool add_public_key(identification_t *id, enum dns_auth_level dns_auth_level, enum pubkey_alg alg, chunk_t rfc3110_key, pubkey_list_t **head) { @@ -1309,10 +1298,10 @@ bool add_public_key(const struct id *id, enum dns_auth_level dns_auth_level, pk = malloc_thing(pubkey_t); zero(pk); pk->public_key = key; - pk->id = *id; + pk->id = id->clone(id); pk->dns_auth_level = dns_auth_level; pk->until_time = UNDEFINED_TIME; - pk->issuer = chunk_empty; + pk->issuer = NULL; pk->serial = chunk_empty; install_public_key(pk, head); return TRUE; @@ -1329,7 +1318,6 @@ void add_x509_public_key(x509cert_t *cert , time_t until, identification_t *subject = certificate->get_subject(certificate); identification_t *issuer = certificate->get_issuer(certificate); identification_t *id; - chunk_t issuer_dn = issuer->get_encoding(issuer); chunk_t serialNumber = x509->get_serial(x509); pubkey_t *pk; key_type_t pk_type; @@ -1338,15 +1326,14 @@ void add_x509_public_key(x509cert_t *cert , time_t until, /* ID type: ID_DER_ASN1_DN (X.509 subject field) */ pk = malloc_thing(pubkey_t); zero(pk); - pk->public_key = cert->cert->get_public_key(cert->cert); - pk->id.kind = ID_DER_ASN1_DN; - pk->id.name = subject->get_encoding(subject); + pk->public_key = certificate->get_public_key(certificate); + pk->id = subject->clone(subject); pk->dns_auth_level = dns_auth_level; pk->until_time = until; - pk->issuer = issuer_dn; - pk->serial = serialNumber; + pk->issuer = issuer->clone(issuer); + pk->serial = chunk_clone(serialNumber); pk_type = pk->public_key->get_type(pk->public_key); - delete_public_keys(&pk->id, pk_type, pk->issuer, pk->serial); + delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial); install_public_key(pk, &pubkeys); /* insert all subjectAltNames */ @@ -1357,13 +1344,13 @@ void add_x509_public_key(x509cert_t *cert , time_t until, { pk = malloc_thing(pubkey_t); zero(pk); - id_from_identification(&pk->id, id); - pk->public_key = cert->cert->get_public_key(cert->cert); + pk->id = id->clone(id); + pk->public_key = certificate->get_public_key(certificate); pk->dns_auth_level = dns_auth_level; pk->until_time = until; - pk->issuer = issuer_dn; - pk->serial = serialNumber; - delete_public_keys(&pk->id, pk_type, pk->issuer, pk->serial); + pk->issuer = issuer->clone(issuer); + pk->serial = chunk_clone(serialNumber); + delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial); install_public_key(pk, &pubkeys); } } @@ -1382,12 +1369,11 @@ void add_pgp_public_key(pgpcert_t *cert , time_t until, pk = malloc_thing(pubkey_t); zero(pk); pk->public_key = cert->public_key->get_ref(cert->public_key); - pk->id.kind = ID_KEY_ID; - pk->id.name = cert->fingerprint->get_encoding(cert->fingerprint); + pk->id = cert->fingerprint->clone(cert->fingerprint); pk->dns_auth_level = dns_auth_level; pk->until_time = until; pk_type = pk->public_key->get_type(pk->public_key); - delete_public_keys(&pk->id, pk_type, chunk_empty, chunk_empty); + delete_public_keys(pk->id, pk_type, NULL, chunk_empty); install_public_key(pk, &pubkeys); } @@ -1437,11 +1423,9 @@ void list_public_keys(bool utc) pubkey_t *key = p->key; public_key_t *public = key->public_key; chunk_t keyid; - char buf[BUF_LEN]; whack_log(RC_COMMENT, " "); - idtoa(&key->id, buf, BUF_LEN); - whack_log(RC_COMMENT, " identity: '%s'", buf); + whack_log(RC_COMMENT, " identity: '%Y'", key->id); whack_log(RC_COMMENT, " pubkey: %N %4d bits, until %T %s", key_type_names, public->get_type(public), public->get_keysize(public) * BITS_PER_BYTE, @@ -1451,10 +1435,9 @@ void list_public_keys(bool utc) { whack_log(RC_COMMENT," keyid: %#B", &keyid); } - if (key->issuer.len) + if (key->issuer) { - dntoa(buf, BUF_LEN, key->issuer); - whack_log(RC_COMMENT," issuer: \"%s\"", buf); + whack_log(RC_COMMENT," issuer: \"%Y\"", key->issuer); } if (key->serial.len) { diff --git a/src/pluto/keys.h b/src/pluto/keys.h index 8bc94d839..558a44f1b 100644 --- a/src/pluto/keys.h +++ b/src/pluto/keys.h @@ -16,6 +16,7 @@ #ifndef _KEYS_H #define _KEYS_H +#include <utils/identification.h> #include <credentials/keys/private_key.h> #include <credentials/keys/public_key.h> @@ -51,15 +52,12 @@ extern private_key_t *get_x509_private_key(const x509cert_t *cert); typedef struct pubkey pubkey_t; struct pubkey { - struct id id; + identification_t *id; unsigned refcnt; /* reference counted! */ enum dns_auth_level dns_auth_level; char *dns_sig; - time_t installed_time - , last_tried_time - , last_worked_time - , until_time; - chunk_t issuer; + time_t last_tried_time, last_worked_time, until_time; + identification_t *issuer; chunk_t serial; public_key_t *public_key; }; @@ -77,17 +75,15 @@ extern pubkey_t *public_key_from_rsa(public_key_t *key); extern pubkey_list_t *free_public_keyentry(pubkey_list_t *p); extern void free_public_keys(pubkey_list_t **keys); extern void free_remembered_public_keys(void); -extern void delete_public_keys(const struct id *id, key_type_t type, - chunk_t issuer, chunk_t serial); +extern void delete_public_keys(identification_t *id, key_type_t type, + identification_t *issuer, chunk_t serial); extern pubkey_t *reference_key(pubkey_t *pk); extern void unreference_key(pubkey_t **pkp); - -extern bool add_public_key(const struct id *id, +extern bool add_public_key(identification_t *id, enum dns_auth_level dns_auth_level, enum pubkey_alg alg, chunk_t rfc3110_key, pubkey_list_t **head); - extern bool has_private_key(cert_t cert); extern void add_x509_public_key(x509cert_t *cert, time_t until , enum dns_auth_level dns_auth_level); diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c index 642cf770a..226f16c50 100644 --- a/src/pluto/ocsp.c +++ b/src/pluto/ocsp.c @@ -67,19 +67,19 @@ static const char *const response_status_names[] = { typedef struct response response_t; struct response { - chunk_t tbs; - chunk_t responder_id_name; - chunk_t responder_id_key; - time_t produced_at; - chunk_t responses; - chunk_t nonce; - int algorithm; - chunk_t signature; + chunk_t tbs; + identification_t *responder_id_name; + chunk_t responder_id_key; + time_t produced_at; + chunk_t responses; + chunk_t nonce; + int algorithm; + chunk_t signature; }; const response_t empty_response = { { NULL, 0 } , /* tbs */ - { NULL, 0 } , /* responder_id_name */ + NULL , /* responder_id_name */ { NULL, 0 } , /* responder_id_key */ UNDEFINED_TIME, /* produced_at */ { NULL, 0 } , /* single_response */ @@ -302,8 +302,8 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio if (location->uri == NULL) { - ca_info_t *ca = get_ca_info(issuer_dn, authKeyID); - if (ca != NULL && ca->ocspuri != NULL) + ca_info_t *ca = get_ca_info(issuer, authKeyID); + if (ca && ca->ocspuri) { location->uri = ca->ocspuri; } @@ -324,14 +324,14 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio hasher->destroy(hasher); location->next = NULL; - location->issuer = issuer_dn; + location->issuer = issuer; location->authKeyID = authKeyID; if (authKeyID.ptr == NULL) { - x509cert_t *authcert = get_authcert(issuer_dn, authKeyID, X509_CA); + x509cert_t *authcert = get_authcert(issuer, authKeyID, X509_CA); - if (authcert != NULL) + if (authcert) { x509_t *x509 = (x509_t*)authcert->cert; @@ -350,9 +350,9 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio */ static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b) { - return ((a->authKeyID.ptr != NULL) + return ((a->authKeyID.ptr) ? same_keyid(a->authKeyID, b->authKeyID) - : same_dn(a->issuer, b->issuer)) + : a->issuer->equals(a->issuer, b->issuer)) && streq(a->uri, b->uri); } @@ -362,7 +362,7 @@ static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t * ocsp_location_t* get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain) { - while (chain != NULL) + while (chain) { if (same_ocsp_location(loc, chain)) return chain; @@ -393,7 +393,7 @@ static cert_status_t get_ocsp_status(const ocsp_location_t *loc, certinfop = &location->certinfo; certinfo = *certinfop; - while (certinfo != NULL) + while (certinfo) { cmp = chunk_compare(serialNumber, certinfo->serialNumber); if (cmp <= 0) @@ -462,13 +462,13 @@ void check_ocsp(void) lock_ocsp_cache("check_ocsp"); location = ocsp_cache; - while (location != NULL) + while (location) { char buf[BUF_LEN]; bool first = TRUE; ocsp_certinfo_t *certinfo = location->certinfo; - while (certinfo != NULL) + while (certinfo) { if (!certinfo->once) { @@ -477,9 +477,8 @@ void check_ocsp(void) DBG(DBG_CONTROL, if (first) { - dntoa(buf, BUF_LEN, location->issuer); - DBG_log("issuer: '%s'", buf); - if (location->authKeyID.ptr != NULL) + DBG_log("issuer: \"%Y\"", location->issuer); + if (location->authKeyID.ptr) { datatot(location->authKeyID.ptr, location->authKeyID.len , ':', buf, BUF_LEN); @@ -518,7 +517,7 @@ static void free_certinfos(ocsp_certinfo_t *chain) { ocsp_certinfo_t *certinfo; - while (chain != NULL) + while (chain) { certinfo = chain; chain = chain->next; @@ -531,7 +530,7 @@ static void free_certinfos(ocsp_certinfo_t *chain) */ static void free_ocsp_location(ocsp_location_t* location) { - free(location->issuer.ptr); + DESTROY_IF(location->issuer); free(location->authNameID.ptr); free(location->authKeyID.ptr); free(location->uri); @@ -544,7 +543,7 @@ static void free_ocsp_location(ocsp_location_t* location) */ void free_ocsp_locations(ocsp_location_t **chain) { - while (*chain != NULL) + while (*chain) { ocsp_location_t *location = *chain; *chain = location->next; @@ -579,57 +578,50 @@ void list_ocsp_locations(ocsp_location_t *location, bool requests, { bool first = TRUE; - while (location != NULL) + while (location) { ocsp_certinfo_t *certinfo = location->certinfo; - if (certinfo != NULL) + if (certinfo) { - u_char buf[BUF_LEN]; - if (first) { whack_log(RC_COMMENT, " "); - whack_log(RC_COMMENT, "List of OCSP %s:", requests? - "fetch requests":"responses"); + whack_log(RC_COMMENT, "List of OCSP %s:", requests ? + "Fetch Requests" : "Responses"); first = FALSE; } whack_log(RC_COMMENT, " "); - if (location->issuer.ptr) + if (location->issuer) { - dntoa(buf, BUF_LEN, location->issuer); - whack_log(RC_COMMENT, " issuer: \"%s\"", buf); + whack_log(RC_COMMENT, " issuer: \"%Y\"", location->issuer); } - whack_log(RC_COMMENT, " uri: '%s'", location->uri); + whack_log(RC_COMMENT, " uri: '%s'", location->uri); if (location->authNameID.ptr) { - datatot(location->authNameID.ptr, location->authNameID.len, ':' - , buf, BUF_LEN); - whack_log(RC_COMMENT, " authname: %s", buf); + whack_log(RC_COMMENT, " authname: %#B", &location->authNameID); } if (location->authKeyID.ptr) { - datatot(location->authKeyID.ptr, location->authKeyID.len, ':' - , buf, BUF_LEN); - whack_log(RC_COMMENT, " authkey: %s", buf); + whack_log(RC_COMMENT, " authkey: %#B", &location->authKeyID); } while (certinfo) { if (requests) { - whack_log(RC_COMMENT, " serial: %#B, %d trials", + whack_log(RC_COMMENT, " serial: %#B, %d trials", &certinfo->serialNumber, certinfo->trials); } else if (certinfo->once) { - whack_log(RC_COMMENT, " serial: %#B, %s, once%s", + whack_log(RC_COMMENT, " serial: %#B, %s, once%s", &certinfo->serialNumber, cert_status_names[certinfo->status], (certinfo->nextUpdate < time(NULL))? " (expired)": ""); } else { - whack_log(RC_COMMENT, " serial: %#B, %s, until %T %s", + whack_log(RC_COMMENT, " serial: %#B, %s, until %T %s", &certinfo->serialNumber, cert_status_names[certinfo->status], &certinfo->nextUpdate, utc, @@ -681,7 +673,7 @@ static bool get_ocsp_requestor_cert(ocsp_location_t *location) /* look for a matching private key on a smartcard */ smartcard_t *sc = scx_get(cert); - if (sc != NULL) + if (sc) { DBG(DBG_CONTROL, DBG_log("matching smartcard found") @@ -700,7 +692,7 @@ static bool get_ocsp_requestor_cert(ocsp_location_t *location) /* look for a matching private key in the chained list */ private_key_t *private = get_x509_private_key(cert); - if (private != NULL) + if (private) { DBG(DBG_CONTROL, DBG_log("matching private key found") @@ -777,7 +769,7 @@ static chunk_t build_signature(chunk_t tbsRequest) { chunk_t sigdata, cert, certs; - if (ocsp_requestor_sc != NULL) + if (ocsp_requestor_sc) { /* RSA signature is done on smartcard */ sigdata = sc_build_sha1_signature(tbsRequest, ocsp_requestor_sc); @@ -836,7 +828,7 @@ static chunk_t build_request_list(ocsp_location_t *location) size_t datalen = 0; /* build content */ - while (certinfo != NULL) + while (certinfo) { /* build request for every certificate in list * and store them in a chained list @@ -854,7 +846,7 @@ static chunk_t build_request_list(ocsp_location_t *location) pos = asn1_build_object(&requestList, ASN1_SEQUENCE, datalen); /* copy all in chained list, free list afterwards */ - while (reqs != NULL) + while (reqs) { request_list_t *req = reqs; @@ -936,17 +928,13 @@ chunk_t build_ocsp_request(ocsp_location_t *location) { bool has_requestor_cert; chunk_t tbsRequest, signature; - char buf[BUF_LEN]; DBG(DBG_CONTROL, DBG_log("assembling ocsp request"); - dntoa(buf, BUF_LEN, location->issuer); - DBG_log("issuer: '%s'", buf); - if (location->authKeyID.ptr != NULL) + DBG_log("issuer: \"%Y\"", location->issuer); + if (location->authKeyID.ptr) { - datatot(location->authKeyID.ptr, location->authKeyID.len, ':' - , buf, BUF_LEN); - DBG_log("authkey: %s", buf); + DBG_log("authkey: %#B", &location->authKeyID); } ) lock_certs_and_keys("build_ocsp_request"); @@ -1029,7 +1017,7 @@ static bool valid_ocsp_response(response_t *res) DBG_log("certificate is valid") ) - authcert = get_authcert(issuer->get_encoding(issuer), authKeyID, X509_CA); + authcert = get_authcert(issuer, authKeyID, X509_CA); if (authcert == NULL) { plog("issuer cacert not found"); @@ -1073,7 +1061,6 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res) asn1_parser_t *parser; chunk_t object; u_int version; - u_char buf[BUF_LEN]; int objectID; int extn_oid = OID_UNKNOWN; bool success = FALSE; @@ -1098,10 +1085,10 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res) } break; case BASIC_RESPONSE_ID_BY_NAME: - res->responder_id_name = object; + res->responder_id_name = identification_create_from_encoding( + ID_DER_ASN1_DN, object); DBG(DBG_PARSING, - dntoa(buf, BUF_LEN, object); - DBG_log(" '%s'",buf) + DBG_log(" '%Y'", res->responder_id_name) ) break; case BASIC_RESPONSE_ID_BY_KEY: @@ -1323,7 +1310,7 @@ ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t *location = malloc_thing(ocsp_location_t); /* unshare location fields */ - location->issuer = chunk_clone(loc->issuer); + location->issuer = loc->issuer->clone(loc->issuer); location->authNameID = chunk_clone(loc->authNameID); location->authKeyID = chunk_clone(loc->authKeyID); location->uri = strdup(loc->uri); @@ -1362,7 +1349,7 @@ void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, certinfop = &location->certinfo; certinfo = *certinfop; - while (certinfo != NULL) + while (certinfo) { cmp = chunk_compare(info->serialNumber, certinfo->serialNumber); if (cmp <= 0) @@ -1445,7 +1432,7 @@ static void process_single_response(ocsp_location_t *location, certinfop = &location->certinfo; certinfo = *certinfop; - while (certinfo != NULL) + while (certinfo) { cmp = chunk_compare(sres->serialNumber, certinfo->serialNumber); if (cmp <= 0) @@ -1495,12 +1482,12 @@ void parse_ocsp(ocsp_location_t *location, chunk_t blob) return; } /* check if there was a nonce in the request */ - if (location->nonce.ptr != NULL && res.nonce.ptr == NULL) + if (location->nonce.ptr && res.nonce.ptr == NULL) { plog("ocsp response contains no nonce, replay attack possible"); } /* check if the nonce is identical */ - if (res.nonce.ptr != NULL && !chunk_equals(res.nonce, location->nonce)) + if (res.nonce.ptr && !chunk_equals(res.nonce, location->nonce)) { plog("invalid nonce in ocsp response"); return; diff --git a/src/pluto/ocsp.h b/src/pluto/ocsp.h index dd3854fbf..a3ba6c0a3 100644 --- a/src/pluto/ocsp.h +++ b/src/pluto/ocsp.h @@ -54,10 +54,10 @@ typedef struct ocsp_location ocsp_location_t; struct ocsp_location { ocsp_location_t *next; - chunk_t issuer; - chunk_t authNameID; - chunk_t authKeyID; - chunk_t nonce; + identification_t *issuer; + chunk_t authNameID; + chunk_t authKeyID; + chunk_t nonce; char *uri; ocsp_certinfo_t *certinfo; }; diff --git a/src/pluto/pgpcert.c b/src/pluto/pgpcert.c index 4faa7c6f1..49d31390e 100644 --- a/src/pluto/pgpcert.c +++ b/src/pluto/pgpcert.c @@ -490,17 +490,17 @@ void list_pgp_end_certs(bool utc) c.u.pgp = cert; whack_log(RC_COMMENT, " "); - whack_log(RC_COMMENT, " digest: %Y", cert->fingerprint); - whack_log(RC_COMMENT, " created: %T", &cert->created, utc); - whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc, + whack_log(RC_COMMENT, " digest: %Y", cert->fingerprint); + whack_log(RC_COMMENT, " created: %T", &cert->created, utc); + whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc, check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE)); - whack_log(RC_COMMENT, " pubkey: %N %4d bits%s", + whack_log(RC_COMMENT, " pubkey: %N %4d bits%s", key_type_names, key->get_type(key), key->get_keysize(key) * BITS_PER_BYTE, has_private_key(c)? ", has private key" : ""); if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid)) { - whack_log(RC_COMMENT, " keyid: %#B", &keyid); + whack_log(RC_COMMENT, " keyid: %#B", &keyid); } cert = cert->next; } diff --git a/src/pluto/rcv_whack.c b/src/pluto/rcv_whack.c index d84a9f5f1..fbc8e7e2c 100644 --- a/src/pluto/rcv_whack.c +++ b/src/pluto/rcv_whack.c @@ -63,8 +63,7 @@ static char *next_str , *str_roof; -static bool -unpack_str(char **p) +static bool unpack_str(char **p) { char *end = memchr(next_str, '\0', str_roof - next_str); @@ -103,8 +102,7 @@ struct key_add_continuation { enum key_add_attempt lookingfor; }; -static void -key_add_ugh(const struct id *keyid, err_t ugh) +static void key_add_ugh(const struct id *keyid, err_t ugh) { char name[BUF_LEN]; /* longer IDs will be truncated in message */ @@ -114,8 +112,7 @@ key_add_ugh(const struct id *keyid, err_t ugh) } /* last one out: turn out the lights */ -static void -key_add_merge(struct key_add_common *oc, const struct id *keyid) +static void key_add_merge(struct key_add_common *oc, const struct id *keyid) { if (oc->refCount == 0) { @@ -135,8 +132,7 @@ key_add_merge(struct key_add_common *oc, const struct id *keyid) } } -static void -key_add_continue(struct adns_continuation *ac, err_t ugh) +static void key_add_continue(struct adns_continuation *ac, err_t ugh) { struct key_add_continuation *kc = (void *) ac; struct key_add_common *oc = kc->common; @@ -163,9 +159,9 @@ key_add_continue(struct adns_continuation *ac, err_t ugh) whack_log_fd = NULL_FD; } -static void -key_add_request(const whack_message_t *msg) +static void key_add_request(const whack_message_t *msg) { + identification_t *key_id; struct id keyid; err_t ugh = atoid(msg->keyid, &keyid, FALSE); @@ -175,10 +171,12 @@ key_add_request(const whack_message_t *msg) } else { - if (!msg->whack_addkey) - delete_public_keys(&keyid, msg->pubkey_alg - , chunk_empty, chunk_empty); + key_id = identification_create_from_string(msg->keyid); + if (!msg->whack_addkey) + { + delete_public_keys(key_id, msg->pubkey_alg, NULL, chunk_empty); + } if (msg->keyval.len == 0) { struct key_add_common *oc = malloc_thing(struct key_add_common); @@ -234,20 +232,20 @@ key_add_request(const whack_message_t *msg) } else { - if (!add_public_key(&keyid, DAL_LOCAL, msg->pubkey_alg, msg->keyval, + if (!add_public_key(key_id, DAL_LOCAL, msg->pubkey_alg, msg->keyval, &pubkeys)) { loglog(RC_LOG_SERIOUS, "failed to add public key"); } } + key_id->destroy(key_id); } } /* Handle a kernel request. Supposedly, there's a message in * the kernelsock socket. */ -void -whack_handle(int whackctlfd) +void whack_handle(int whackctlfd) { whack_message_t msg; struct sockaddr_un whackaddr; diff --git a/src/pluto/x509.c b/src/pluto/x509.c index 172baa1cf..fe94d3800 100644 --- a/src/pluto/x509.c +++ b/src/pluto/x509.c @@ -337,7 +337,7 @@ static err_t dn_parse(chunk_t dn, chunk_t *str) err_t ugh = init_rdn(dn, &rdn, &attribute, &next); - if (ugh != NULL) /* a parsing error has occured */ + if (ugh) /* a parsing error has occured */ { return ugh; } @@ -346,7 +346,7 @@ static err_t dn_parse(chunk_t dn, chunk_t *str) { ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next); - if (ugh != NULL) /* a parsing error has occured */ + if (ugh) /* a parsing error has occured */ { return ugh; } @@ -391,7 +391,7 @@ int dn_count_wildcards(chunk_t dn) err_t ugh = init_rdn(dn, &rdn, &attribute, &next); - if (ugh != NULL) /* a parsing error has occured */ + if (ugh) /* a parsing error has occured */ { return -1; } @@ -400,7 +400,7 @@ int dn_count_wildcards(chunk_t dn) { ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next); - if (ugh != NULL) /* a parsing error has occured */ + if (ugh) /* a parsing error has occured */ { return -1; } @@ -436,7 +436,7 @@ int dntoa(char *dst, size_t dstlen, chunk_t dn) str.len = dstlen; ugh = dn_parse(dn, &str); - if (ugh != NULL) /* error, print DN as hex string */ + if (ugh) /* error, print DN as hex string */ { DBG(DBG_PARSING, DBG_log("error in DN parsing: %s", ugh) @@ -449,22 +449,6 @@ int dntoa(char *dst, size_t dstlen, chunk_t dn) } /** - * Same as dntoa but prints a special string for a null dn - */ -int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn) -{ - if (dn.ptr == NULL) - { - return snprintf(dst, dstlen, "%s", null_dn); - } - else - { - return dntoa(dst, dstlen, dn); - } -} - - -/** * Codes ASN.1 lengths up to a size of 16'777'215 bytes */ static void code_asn1_length(size_t length, chunk_t *code) @@ -913,20 +897,18 @@ bool same_keyid(chunk_t a, chunk_t b) /** * Get a X.509 certificate with a given issuer found at a certain position */ -x509cert_t* get_x509cert(chunk_t issuer, chunk_t keyid, x509cert_t *chain) +x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t *chain) { - x509cert_t *cert = (chain != NULL)? chain->next : x509certs; + x509cert_t *cert = chain ? chain->next : x509certs; - while (cert != NULL) + while (cert) { certificate_t *certificate = cert->cert; x509_t *x509 = (x509_t*)certificate; - identification_t *cert_issuer = certificate->get_issuer(certificate); - chunk_t cert_issuer_dn = cert_issuer->get_encoding(cert_issuer); chunk_t authKeyID = x509->get_authKeyIdentifier(x509); - if ((keyid.ptr != NULL) ? same_keyid(keyid, authKeyID) - : same_dn(issuer, cert_issuer_dn)) + if (keyid.ptr ? same_keyid(keyid, authKeyID) : + certificate->has_issuer(certificate, issuer)) { return cert; } @@ -940,7 +922,7 @@ x509cert_t* get_x509cert(chunk_t issuer, chunk_t keyid, x509cert_t *chain) */ void free_generalNames(generalName_t* gn, bool free_name) { - while (gn != NULL) + while (gn) { generalName_t *gn_top = gn; if (free_name) @@ -957,7 +939,7 @@ void free_generalNames(generalName_t* gn, bool free_name) */ void free_x509cert(x509cert_t *cert) { - if (cert != NULL) + if (cert) { certificate_t *certificate = cert->cert; @@ -976,7 +958,7 @@ void free_x509cert(x509cert_t *cert) */ void release_x509cert(x509cert_t *cert) { - if (cert != NULL && --cert->count == 0) + if (cert && --cert->count == 0) { x509cert_t **pp = &x509certs; while (*pp != cert) @@ -998,7 +980,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict) /* first extract CA certs, discarding root CA certs */ - while (*pp != NULL) + while (*pp) { x509cert_t *cert = *pp; certificate_t *certificate = cert->cert; @@ -1030,7 +1012,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict) /* now verify the candidate CA certs */ - while (cacerts != NULL) + while (cacerts) { x509cert_t *cert = cacerts; @@ -1051,7 +1033,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict) pp = firstcert; - while (*pp != NULL) + while (*pp) { time_t valid_until; x509cert_t *cert = *pp; @@ -1269,7 +1251,7 @@ chunk_t get_directoryName(chunk_t blob, int level, bool implicit) chunk_t name = chunk_empty; generalName_t * gn = parse_generalNames(blob, level, implicit); - if (gn != NULL && gn->kind == GN_DIRECTORY_NAME) + if (gn && gn->kind == GN_DIRECTORY_NAME) { name= gn->name; } @@ -1362,8 +1344,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until) ) lock_authcert_list("verify_x509cert"); - issuer_cert = get_authcert(issuer->get_encoding(issuer), - authKeyID, X509_CA); + issuer_cert = get_authcert(issuer, authKeyID, X509_CA); if (issuer_cert == NULL) { plog("issuer cacert not found"); @@ -1473,7 +1454,7 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert, /* determine the current time */ time(&now); - while (cert != NULL) + while (cert) { certificate_t *certificate = cert->cert; x509_t *x509 = (x509_t*)certificate; diff --git a/src/pluto/x509.h b/src/pluto/x509.h index 4b9abf3e6..d6809ba38 100644 --- a/src/pluto/x509.h +++ b/src/pluto/x509.h @@ -18,9 +18,11 @@ #ifndef _X509_H #define _X509_H +#include <utils/identification.h> #include <credentials/keys/public_key.h> #include <credentials/keys/private_key.h> #include <credentials/certificates/x509.h> + #include "constants.h" #include "id.h" @@ -68,8 +70,6 @@ extern bool match_dn(chunk_t a, chunk_t b, int *wildcards); extern void hex_str(chunk_t bin, chunk_t *str); extern int dn_count_wildcards(chunk_t dn); extern int dntoa(char *dst, size_t dstlen, chunk_t dn); -extern int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, - const char* null_dn); extern err_t atodn(char *src, chunk_t *dn); extern void select_x509cert_id(x509cert_t *cert, struct id *end_id); extern void parse_authorityKeyIdentifier(chunk_t blob, int level0, @@ -82,7 +82,7 @@ extern chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key, bool bit_string); extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until); extern x509cert_t* add_x509cert(x509cert_t *cert); -extern x509cert_t* get_x509cert(chunk_t issuer, chunk_t keyid, x509cert_t* chain); +extern x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t* chain); extern void share_x509cert(x509cert_t *cert); extern void release_x509cert(x509cert_t *cert); extern void free_x509cert(x509cert_t *cert); |