migrated public key IDs to identification_t

This commit is contained in:
Andreas Steffen
2009-10-08 11:25:43 +02:00
parent 4b1cd5a367
commit 0354d5703d
20 changed files with 462 additions and 465 deletions
+4 -7
View File
@@ -78,7 +78,7 @@ void free_acerts(void)
/** /**
* Get a X.509 attribute certificate for a given holder * 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 *x509ac = x509acerts;
x509acert_t *prev_ac = NULL; 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; ac_t *ac = (ac_t*)x509ac->ac;
identification_t *holderIssuer = ac->get_holderIssuer(ac); identification_t *holderIssuer = ac->get_holderIssuer(ac);
chunk_t holderIssuer_dn = holderIssuer->get_encoding(holderIssuer);
chunk_t holderSerial = ac->get_holderSerial(ac); chunk_t holderSerial = ac->get_holderSerial(ac);
if (same_dn(issuer, holderIssuer_dn) && if (issuer->equals(issuer, holderIssuer) &&
chunk_equals(serial, holderSerial)) chunk_equals(serial, holderSerial))
{ {
if (x509ac!= x509acerts) if (x509ac!= x509acerts)
@@ -116,11 +115,10 @@ static void add_acert(x509acert_t *x509ac)
certificate_t *cert_ac = x509ac->ac; certificate_t *cert_ac = x509ac->ac;
ac_t *ac = (ac_t*)cert_ac; ac_t *ac = (ac_t*)cert_ac;
identification_t *holderIssuer = ac->get_holderIssuer(ac); identification_t *holderIssuer = ac->get_holderIssuer(ac);
chunk_t holderIssuer_dn = holderIssuer->get_encoding(holderIssuer);
chunk_t holderSerial = ac->get_serial(ac); chunk_t holderSerial = ac->get_serial(ac);
x509acert_t *old_ac; x509acert_t *old_ac;
old_ac = get_x509acert(holderIssuer_dn, holderSerial); old_ac = get_x509acert(holderIssuer, holderSerial);
if (old_ac != NULL) if (old_ac != NULL)
{ {
if (cert_ac->is_newer(cert_ac, old_ac->ac)) 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; ac_t *ac = (ac_t*)cert_ac;
identification_t *subject = cert_ac->get_subject(cert_ac); identification_t *subject = cert_ac->get_subject(cert_ac);
identification_t *issuer = cert_ac->get_issuer(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); chunk_t authKeyID = ac->get_authKeyIdentifier(ac);
x509cert_t *aacert; x509cert_t *aacert;
time_t notBefore, valid_until; time_t notBefore, valid_until;
@@ -177,7 +174,7 @@ bool verify_x509acert(x509acert_t *x509ac, bool strict)
) )
lock_authcert_list("verify_x509acert"); 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"); unlock_authcert_list("verify_x509acert");
if (aacert == NULL) if (aacert == NULL)
+2 -1
View File
@@ -18,6 +18,7 @@
#ifndef _AC_H #ifndef _AC_H
#define _AC_H #define _AC_H
#include <utils/identification.h>
#include <credentials/certificates/certificate.h> #include <credentials/certificates/certificate.h>
#include <credentials/ietf_attributes/ietf_attributes.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 verify_x509acert(x509acert_t *ac, bool strict);
extern bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn, extern bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn,
ietf_attributes_t *conn_attributes); 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 load_acerts(void);
extern void free_acert(x509acert_t *ac); extern void free_acert(x509acert_t *ac);
extern void free_acerts(void); extern void free_acerts(void);
+35 -51
View File
@@ -45,19 +45,19 @@ static ca_info_t *ca_infos = NULL;
/* /*
* Checks if CA a is trusted by CA b * 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; bool match = FALSE;
/* no CA b specified -> any CA a is accepted */ /* 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; return TRUE;
} }
/* no CA a specified -> trust cannot be established */ /* no CA a specified -> trust cannot be established */
if (a.ptr == NULL) if (a == NULL)
{ {
*pathlen = MAX_CA_PATH_LEN; *pathlen = MAX_CA_PATH_LEN;
return FALSE; return FALSE;
@@ -66,7 +66,7 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen)
*pathlen = 0; *pathlen = 0;
/* CA a equals CA b -> we have a match */ /* CA a equals CA b -> we have a match */
if (same_dn(a, b)) if (a->equals(a, b))
{ {
return TRUE; return TRUE;
} }
@@ -78,7 +78,6 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen)
{ {
certificate_t *certificate; certificate_t *certificate;
identification_t *issuer; identification_t *issuer;
chunk_t issuer_dn;
x509cert_t *cacert; x509cert_t *cacert;
cacert = get_authcert(a, chunk_empty, X509_CA); 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? */ /* does the issuer of CA a match CA b? */
issuer = certificate->get_issuer(certificate); issuer = certificate->get_issuer(certificate);
issuer_dn = issuer->get_encoding(issuer); match = b->equals(b, issuer);
match = same_dn(issuer_dn, b);
/* we have a match and exit the loop */ /* we have a match and exit the loop */
if (match) if (match)
@@ -109,7 +107,7 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen)
break; break;
} }
/* go one level up in the CA chain */ /* go one level up in the CA chain */
a = issuer_dn; a = issuer;
} }
unlock_authcert_list("trusted_ca"); 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? * 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) int *our_pathlen)
{ {
identification_t *ca;
enumerator_t *enumerator;
/* if no ca is requested than any ca will match */ /* 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; *our_pathlen = 0;
return TRUE; 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; *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; int pathlen;
if (trusted_ca(our_ca, requested_ca->name, &pathlen) if (trusted_ca(our_ca, ca, &pathlen) && pathlen < *our_pathlen)
&& pathlen < *our_pathlen)
{ {
*our_pathlen = pathlen; *our_pathlen = pathlen;
} }
requested_ca = requested_ca->next;
} }
enumerator->destroy(enumerator);
if (*our_pathlen > MAX_CA_PATH_LEN) 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 * 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; 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; certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate; x509_t *x509 = (x509_t*)certificate;
identification_t *cert_subject;
chunk_t cert_subject_dn;
/* skip non-matching types of authority certificates */ /* skip non-matching types of authority certificates */
if (!(x509->get_flags(x509) & auth_flags)) 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 */ /* compare the subjectDistinguishedNames */
cert_subject = certificate->get_subject(certificate); if (!certificate->has_subject(certificate, subject))
cert_subject_dn = cert_subject->get_encoding(cert_subject);
if (!same_dn(subject, cert_subject_dn))
{ {
continue; continue;
} }
@@ -243,16 +241,14 @@ x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
{ {
certificate_t *certificate = cert->cert; certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate; 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; x509cert_t *old_cert;
lock_authcert_list("add_authcert"); lock_authcert_list("add_authcert");
old_cert = get_authcert(cert_subject_dn, old_cert = get_authcert(certificate->get_subject(certificate),
x509->get_subjectKeyIdentifier(x509), x509->get_subjectKeyIdentifier(x509),
auth_flags); auth_flags);
if (old_cert != NULL) if (old_cert)
{ {
if (certificate->equals(certificate, old_cert->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 * 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) const x509cert_t *cert)
{ {
if (cert == NULL) if (cert == NULL)
{ {
return NULL; return NULL;
} }
for (; cert != NULL; cert = cert->next) for (; cert != NULL; cert = cert->next)
{ {
certificate_t *certificate = cert->cert; certificate_t *certificate = cert->cert;
identification_t *cert_subject;
chunk_t cert_subject_dn;
/* compare the keyid with the certificate's subjectKeyIdentifier */ /* compare the keyid with the certificate's subjectKeyIdentifier */
if (keyid.ptr) if (keyid.ptr)
@@ -369,9 +362,7 @@ static const x509cert_t* get_alt_cacert(chunk_t subject, chunk_t keyid,
} }
/* compare the subjectDistinguishedNames */ /* compare the subjectDistinguishedNames */
cert_subject = certificate->get_subject(certificate); if (!certificate->has_subject(certificate, subject))
cert_subject_dn = cert_subject->get_encoding(cert_subject);
if (!same_dn(subject, cert_subject_dn))
{ {
continue; continue;
} }
@@ -397,7 +388,6 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
x509_t *x509 = (x509_t*)certificate; x509_t *x509 = (x509_t*)certificate;
identification_t *subject = certificate->get_subject(certificate); identification_t *subject = certificate->get_subject(certificate);
identification_t *issuer = certificate->get_issuer(certificate); identification_t *issuer = certificate->get_issuer(certificate);
chunk_t issuer_dn = issuer->get_encoding(issuer);
chunk_t authKeyID = x509->get_authKeyIdentifier(x509); chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
const x509cert_t *authcert = NULL; 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 */ /* 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) if (authcert != NULL)
{ {
@@ -422,7 +412,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
else else
{ {
/* search in trusted chain */ /* search in trusted chain */
authcert = get_authcert(issuer_dn, authKeyID, X509_CA); authcert = get_authcert(issuer, authKeyID, X509_CA);
if (authcert != NULL) 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 * 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; ca_info_t *ca= ca_infos;
while (ca!= NULL) while (ca != NULL)
{ {
if ((keyid.ptr != NULL) ? same_keyid(keyid, ca->authKeyID) if ((keyid.ptr) ? same_keyid(keyid, ca->authKeyID)
: same_dn(authname, ca->authName)) : name->equals(name, ca->authName))
{ {
return ca; return ca;
} }
@@ -497,11 +487,11 @@ free_ca_info(ca_info_t* ca_info)
return; return;
} }
ca_info->crluris->destroy_function(ca_info->crluris, free); ca_info->crluris->destroy_function(ca_info->crluris, free);
DESTROY_IF(ca_info->authName);
free(ca_info->name); free(ca_info->name);
free(ca_info->ldaphost); free(ca_info->ldaphost);
free(ca_info->ldapbase); free(ca_info->ldapbase);
free(ca_info->ocspuri); free(ca_info->ocspuri);
free(ca_info->authName.ptr);
free(ca_info->authKeyID.ptr); free(ca_info->authKeyID.ptr);
free(ca_info); free(ca_info);
} }
@@ -595,12 +585,11 @@ void add_ca_info(const whack_message_t *msg)
certificate_t *certificate = cacert->cert; certificate_t *certificate = cacert->cert;
x509_t *x509 = (x509_t*)certificate; x509_t *x509 = (x509_t*)certificate;
identification_t *subject = certificate->get_subject(certificate); identification_t *subject = certificate->get_subject(certificate);
chunk_t subject_dn = subject->get_encoding(subject);
chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509); chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509);
ca_info_t *ca = NULL; ca_info_t *ca = NULL;
/* does the authname already exist? */ /* does the authname already exist? */
ca = get_ca_info(subject_dn, subjectKeyID); ca = get_ca_info(subject, subjectKeyID);
if (ca != NULL) if (ca != NULL)
{ {
@@ -620,7 +609,7 @@ void add_ca_info(const whack_message_t *msg)
ca->name = clone_str(msg->name); ca->name = clone_str(msg->name);
/* authName */ /* authName */
ca->authName = chunk_clone(subject_dn); ca->authName = subject->clone(subject);
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
DBG_log("authname: '%Y'", subject) DBG_log("authname: '%Y'", subject)
) )
@@ -693,8 +682,6 @@ void list_ca_infos(bool utc)
while (ca != NULL) while (ca != NULL)
{ {
u_char buf[BUF_LEN];
/* strictpolicy per CA not supported yet /* strictpolicy per CA not supported yet
* *
whack_log(RC_COMMENT, "%T, \"%s\", strictcrlpolicy: %s" whack_log(RC_COMMENT, "%T, \"%s\", strictcrlpolicy: %s"
@@ -702,8 +689,7 @@ void list_ca_infos(bool utc)
, ca->strictcrlpolicy? "yes":"no"); , ca->strictcrlpolicy? "yes":"no");
*/ */
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
dntoa(buf, BUF_LEN, ca->authName); whack_log(RC_COMMENT, " authname: \"%Y\"", ca->authName);
whack_log(RC_COMMENT, " authname: \"%s\"", buf);
if (ca->ldaphost) if (ca->ldaphost)
{ {
whack_log(RC_COMMENT, " ldaphost: '%s'", 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); list_distribution_points(ca->crluris);
if (ca->authKeyID.ptr != NULL) if (ca->authKeyID.ptr)
{ {
datatot(ca->authKeyID.ptr, ca->authKeyID.len, ':' whack_log(RC_COMMENT, " authkey: %#B", &ca->authKeyID);
, buf, BUF_LEN);
whack_log(RC_COMMENT, " authkey: %s", buf);
} }
ca = ca->next; ca = ca->next;
} }
+15 -14
View File
@@ -16,6 +16,7 @@
#define _CA_H #define _CA_H
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/identification.h>
#include "x509.h" #include "x509.h"
#include "whack.h" #include "whack.h"
@@ -27,21 +28,21 @@
typedef struct ca_info ca_info_t; typedef struct ca_info ca_info_t;
struct ca_info { struct ca_info {
ca_info_t *next; ca_info_t *next;
char *name; char *name;
chunk_t authName; identification_t *authName;
chunk_t authKeyID; chunk_t authKeyID;
char *ldaphost; char *ldaphost;
char *ldapbase; char *ldapbase;
char *ocspuri; char *ocspuri;
linked_list_t *crluris; linked_list_t *crluris;
bool strictcrlpolicy; bool strictcrlpolicy;
}; };
extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen); extern bool trusted_ca(identification_t *a, identification_t *b, int *pathlen);
extern bool match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, extern bool match_requested_ca(linked_list_t *requested_ca,
int *our_pathlen); identification_t *our_ca, int *our_pathlen);
extern x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, extern x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
x509_flag_t auth_flags); x509_flag_t auth_flags);
extern void load_authcerts(const char *type, const char *path, extern void load_authcerts(const char *type, const char *path,
x509_flag_t auth_flags); 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 void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc);
extern bool trust_authcert_candidate(const x509cert_t *cert, extern bool trust_authcert_candidate(const x509cert_t *cert,
const x509cert_t *alt_chain); 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 bool find_ca_info_by_name(const char *name, bool delete);
extern void add_ca_info(const whack_message_t *msg); extern void add_ca_info(const whack_message_t *msg);
extern void delete_ca_info(const char *name); extern void delete_ca_info(const char *name);
+55 -39
View File
@@ -336,13 +336,17 @@ void delete_connection(connection_t *c, bool relations)
free(c->name); free(c->name);
free_id_content(&c->spd.this.id); free_id_content(&c->spd.this.id);
free(c->spd.this.updown); free(c->spd.this.updown);
free(c->spd.this.ca.ptr); DESTROY_IF(c->spd.this.ca);
DESTROY_IF(c->spd.this.groups); DESTROY_IF(c->spd.this.groups);
free_id_content(&c->spd.that.id); free_id_content(&c->spd.that.id);
free(c->spd.that.updown); free(c->spd.that.updown);
free(c->spd.that.ca.ptr); DESTROY_IF(c->spd.that.ca);
DESTROY_IF(c->spd.that.groups); 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); gw_delref(&c->gw_info);
lock_certs_and_keys("delete_connection"); 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); c->spd.this.updown = clone_str(c->spd.this.updown);
scx_share(c->spd.this.sc); scx_share(c->spd.this.sc);
share_cert(c->spd.this.cert); 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); unshare_id_content(&c->spd.that.id);
c->spd.that.updown = clone_str(c->spd.that.updown); c->spd.that.updown = clone_str(c->spd.that.updown);
scx_share(c->spd.that.sc); scx_share(c->spd.that.sc);
share_cert(c->spd.that.cert); 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 */ /* increment references to algo's */
alg_info_addref((struct alg_info *)c->alg_info_esp); 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 no CA is defined, use issuer as default */
if (dst->ca.ptr == NULL) if (dst->ca)
{ {
certificate_t *certificate = dst->cert.u.x509->cert; certificate_t *certificate = dst->cert.u.x509->cert;
identification_t *issuer = certificate->get_issuer(certificate); identification_t *issuer = certificate->get_issuer(certificate);
dst->ca = issuer->get_encoding(issuer); dst->ca = issuer->clone(issuer);
} }
break; break;
default: 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 */ /* decode CA distinguished name, if any */
if (src->ca) if (src->ca)
{ {
if streq(src->ca, "%same") if streq(src->ca, "%same")
{
same_ca = TRUE; same_ca = TRUE;
}
else if (!streq(src->ca, "%any")) else if (!streq(src->ca, "%any"))
{ {
err_t ugh; dst->ca = identification_create_from_string(src->ca);
if (dst->ca->get_type(dst->ca) != ID_DER_ASN1_DN)
dst->ca.ptr = temporary_cyclic_buffer();
ugh = atodn(src->ca, &dst->ca);
if (ugh != NULL)
{ {
plog("bad CA string '%s': %s (ignored)", src->ca, ugh); plog("bad CA string '%s', ignored", src->ca);
dst->ca = chunk_empty; 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, connection_t *refine_host_connection(const struct state *st,
const struct id *peer_id, const struct id *peer_id,
chunk_t peer_ca) identification_t *peer_ca)
{ {
connection_t *c = st->st_connection; connection_t *c = st->st_connection;
connection_t *d; 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_int16_t our_port,
const u_int8_t peer_protocol, const u_int8_t peer_protocol,
const u_int16_t peer_port, const u_int16_t peer_port,
chunk_t peer_ca, identification_t *peer_ca,
ietf_attributes_t *peer_attributes) ietf_attributes_t *peer_attributes)
{ {
connection_t *d; 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_int16_t our_port,
const u_int8_t peer_protocol, const u_int8_t peer_protocol,
const u_int16_t peer_port, const u_int16_t peer_port,
chunk_t peer_ca, identification_t *peer_ca,
ietf_attributes_t *peer_attributes) ietf_attributes_t *peer_attributes)
{ {
connection_t *d; 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 * 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; *peer_attributes = NULL;
if (p1st != NULL p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
&& p1st->st_peer_pubkey != NULL if (p1st && p1st->st_peer_pubkey && p1st->st_peer_pubkey->issuer)
&& p1st->st_peer_pubkey->issuer.ptr != NULL)
{ {
x509acert_t *x509ac = get_x509acert(p1st->st_peer_pubkey->issuer, x509acert_t *x509ac;
p1st->st_peer_pubkey->serial);
x509ac = get_x509acert(p1st->st_peer_pubkey->issuer,
p1st->st_peer_pubkey->serial);
if (x509ac && verify_x509acert(x509ac, strict_crl_policy)) if (x509ac && verify_x509acert(x509ac, strict_crl_policy))
{ {
ac_t * ac = (ac_t*)x509ac->ac; 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") 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, connection_t *find_client_connection(connection_t *c,
@@ -3806,7 +3817,9 @@ connection_t *find_client_connection(connection_t *c,
connection_t *d; connection_t *d;
struct spd_route *sr; struct spd_route *sr;
ietf_attributes_t *peer_attributes = NULL; 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 #ifdef DEBUG
if (DBGP(DBG_CONTROLMORE)) if (DBGP(DBG_CONTROLMORE))
@@ -4034,18 +4047,21 @@ void show_connections_status(bool all, const char *name)
if (all) if (all)
{ {
/* show CAs if defined */ /* 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]; 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);
dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any"); }
dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any"); else if (c->spd.that.ca)
{
whack_log(RC_COMMENT, "\"%s\"%s: CAs: '%s'...'%s'" whack_log(RC_COMMENT, "\"%s\"%s: CAs: %%any...\"%Y\"",
, c->name c->name, instance, c->spd.that.ca);
, instance
, this_ca
, that_ca);
} }
/* show group attributes if defined */ /* show group attributes if defined */
+28 -27
View File
@@ -17,6 +17,9 @@
#include <sys/queue.h> #include <sys/queue.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
#include "id.h" #include "id.h"
#include "certs.h" #include "certs.h"
#include "ac.h" #include "ac.h"
@@ -145,7 +148,7 @@ struct end {
u_int16_t port; /* host order */ u_int16_t port; /* host order */
u_int8_t protocol; u_int8_t protocol;
cert_t cert; /* end certificate */ cert_t cert; /* end certificate */
chunk_t ca; /* CA distinguished name */ identification_t *ca; /* CA distinguished name */
ietf_attributes_t *groups; /* access control groups */ ietf_attributes_t *groups; /* access control groups */
smartcard_t *sc; /* smartcard reader and key info */ smartcard_t *sc; /* smartcard reader and key info */
struct virtual_t *virt; struct virtual_t *virt;
@@ -214,16 +217,13 @@ struct connection {
connection_t *policy_next; /* if multiple policies, connection_t *policy_next; /* if multiple policies,
next one to apply */ next one to apply */
struct gw_info *gw_info; struct gw_info *gw_info;
struct alg_info_esp *alg_info_esp; struct alg_info_esp *alg_info_esp;
struct alg_info_ike *alg_info_ike; struct alg_info_ike *alg_info_ike;
struct host_pair *host_pair; struct host_pair *host_pair;
connection_t *hp_next; /* host pair list link */ connection_t *hp_next; /* host pair list link */
connection_t *ac_next; /* all connections list link */ connection_t *ac_next; /* all connections list link */
linked_list_t *requested_ca; /* collected certificate requests */
generalName_t *requested_ca; /* collected certificate requests */
bool got_certrequest; 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)) sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE))
struct state; /* forward declaration of tag (defined in state.h) */ 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 * extern connection_t* con_by_name(const char *nm, bool strict);
find_connection_for_clients(struct spd_route **srp extern connection_t* find_host_connection(const ip_address *me,
, const ip_address *our_client u_int16_t my_port,
, const ip_address *peer_client const ip_address *him,
, int transport_proto); u_int16_t his_port, lset_t policy);
extern connection_t* refine_host_connection(const struct state *st,
extern chunk_t get_peer_ca_and_groups(connection_t *c, const struct id *id,
ietf_attributes_t **peer_attributes); 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 /* instantiating routines
* Note: connection_discard() is in state.h because all its work * Note: connection_discard() is in state.h because all its work
+10 -14
View File
@@ -44,7 +44,7 @@ static x509crl_t *x509crls = NULL;
/** /**
* Get the X.509 CRL with a given issuer * 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 *x509crl = x509crls;
x509crl_t *prev_crl = NULL; 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; certificate_t *cert_crl = x509crl->crl;
crl_t *crl = (crl_t*)cert_crl; crl_t *crl = (crl_t*)cert_crl;
identification_t *crl_issuer = cert_crl->get_issuer(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); chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
if ((keyid.ptr && authKeyID.ptr)? same_keyid(keyid, authKeyID) : if ((keyid.ptr && authKeyID.ptr)? same_keyid(keyid, authKeyID) :
same_dn(crl_issuer_dn, issuer)) issuer->equals(issuer, crl_issuer))
{ {
if (x509crl != x509crls) 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; certificate_t *cert_crl = x509crl->crl;
crl_t *crl = (crl_t*)cert_crl; crl_t *crl = (crl_t*)cert_crl;
identification_t *issuer = cert_crl->get_issuer(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); chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
x509cert_t *issuer_cert; x509cert_t *issuer_cert;
x509crl_t *oldcrl; x509crl_t *oldcrl;
@@ -126,7 +124,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
lock_authcert_list("insert_crl"); lock_authcert_list("insert_crl");
/* get the issuer cacert */ /* 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) if (issuer_cert == NULL)
{ {
plog("crl issuer cacert not found"); plog("crl issuer cacert not found");
@@ -155,7 +153,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
time(&now); time(&now);
lock_crl_list("insert_crl"); lock_crl_list("insert_crl");
oldcrl = get_x509crl(issuer_dn, authKeyID); oldcrl = get_x509crl(issuer, authKeyID);
if (oldcrl != NULL) if (oldcrl != NULL)
{ {
@@ -315,7 +313,6 @@ void check_crls(void)
certificate_t *cert_crl = x509crl->crl; certificate_t *cert_crl = x509crl->crl;
crl_t *crl = (crl_t*)cert_crl; crl_t *crl = (crl_t*)cert_crl;
identification_t *issuer = cert_crl->get_issuer(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); chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate); cert_crl->get_validity(cert_crl, &now, NULL, &nextUpdate);
@@ -331,7 +328,7 @@ void check_crls(void)
) )
if (time_left < 2*crl_check_interval) 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); x509crl->distributionPoints);
add_crl_fetch_request(req); 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; certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate; x509_t *x509 = (x509_t*)certificate;
identification_t *issuer = certificate->get_issuer(certificate); identification_t *issuer = certificate->get_issuer(certificate);
chunk_t issuer_dn = issuer->get_encoding(issuer);
chunk_t authKeyID = x509->get_authKeyIdentifier(x509); chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
x509crl_t *x509crl; x509crl_t *x509crl;
ca_info_t *ca; ca_info_t *ca;
enumerator_t *enumerator; enumerator_t *enumerator;
char *point; char *point;
ca = get_ca_info(issuer_dn, authKeyID); ca = get_ca_info(issuer, authKeyID);
*revocationDate = UNDEFINED_TIME; *revocationDate = UNDEFINED_TIME;
*revocationReason = CRL_REASON_UNSPECIFIED; *revocationReason = CRL_REASON_UNSPECIFIED;
lock_crl_list("verify_by_crl"); lock_crl_list("verify_by_crl");
x509crl = get_x509crl(issuer_dn, authKeyID); x509crl = get_x509crl(issuer, authKeyID);
if (x509crl == NULL) if (x509crl == NULL)
{ {
@@ -389,7 +385,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
{ {
fetch_req_t *req; 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); crluris->destroy_function(crluris, free);
add_crl_fetch_request(req); add_crl_fetch_request(req);
wake_fetch_thread("verify_by_crl"); 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"); 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); trusted = cert_crl->issued_by(cert_crl, issuer_cert->cert);
unlock_authcert_list("verify_by_crl"); 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 */ /* try to fetch a crl update */
req = build_crl_fetch_request(issuer_dn, authKeyID, req = build_crl_fetch_request(issuer, authKeyID,
x509crl->distributionPoints); x509crl->distributionPoints);
unlock_crl_list("verify_by_crl"); unlock_crl_list("verify_by_crl");
+1 -1
View File
@@ -26,7 +26,7 @@ struct x509crl {
certificate_t *crl; certificate_t *crl;
x509crl_t *next; x509crl_t *next;
linked_list_t *distributionPoints; linked_list_t *distributionPoints;
chunk_t signature; chunk_t signature;
}; };
/* apply a strict CRL policy /* apply a strict CRL policy
+10 -14
View File
@@ -45,7 +45,7 @@
fetch_req_t empty_fetch_req = { fetch_req_t empty_fetch_req = {
NULL , /* next */ NULL , /* next */
0 , /* trials */ 0 , /* trials */
{ NULL, 0}, /* issuer */ NULL , /* issuer */
{ NULL, 0}, /* authKeyID */ { NULL, 0}, /* authKeyID */
NULL /* distributionPoints */ NULL /* distributionPoints */
}; };
@@ -250,7 +250,7 @@ void wake_fetch_thread(const char *who)
static void free_fetch_request(fetch_req_t *req) static void free_fetch_request(fetch_req_t *req)
{ {
req->distributionPoints->destroy_function(req->distributionPoints, free); req->distributionPoints->destroy_function(req->distributionPoints, free);
free(req->issuer.ptr); DESTROY_IF(req->issuer);
free(req->authKeyID.ptr); free(req->authKeyID.ptr);
free(req); free(req);
} }
@@ -598,7 +598,8 @@ void add_distribution_points(linked_list_t *points, linked_list_t *new_points)
enumerator->destroy(enumerator); 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) linked_list_t *distributionPoints)
{ {
char *point; char *point;
@@ -609,7 +610,7 @@ fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeyID,
req->distributionPoints = linked_list_create(); req->distributionPoints = linked_list_create();
/* clone fields */ /* clone fields */
req->issuer = chunk_clone(issuer); req->issuer = issuer->clone(issuer);
req->authKeyID = chunk_clone(authKeyID); req->authKeyID = chunk_clone(authKeyID);
/* copy distribution points */ /* copy distribution points */
@@ -637,7 +638,7 @@ void add_crl_fetch_request(fetch_req_t *req)
while (r != NULL) while (r != NULL)
{ {
if (req->authKeyID.ptr ? same_keyid(req->authKeyID, r->authKeyID) : 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 */ /* there is already a fetch request */
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
@@ -712,21 +713,16 @@ void list_crl_fetch_requests(bool utc)
{ {
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of CRL Fetch Requests:"); whack_log(RC_COMMENT, "List of CRL Fetch Requests:");
whack_log(RC_COMMENT, " ");
} }
while (req != NULL) while (req != NULL)
{ {
u_char buf[BUF_LEN]; whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, " trials: %d", req->trials); whack_log(RC_COMMENT, " trials: %d", req->trials);
dntoa(buf, BUF_LEN, req->issuer); whack_log(RC_COMMENT, " issuer: \"%Y\"", req->issuer);
whack_log(RC_COMMENT, " issuer: \"%s\"", buf); if (req->authKeyID.ptr)
if (req->authKeyID.ptr != NULL)
{ {
datatot(req->authKeyID.ptr, req->authKeyID.len, ':' whack_log(RC_COMMENT, " authkey: %#B", &req->authKeyID);
, buf, BUF_LEN);
whack_log(RC_COMMENT, " authkey: %s", buf);
} }
list_distribution_points(req->distributionPoints); list_distribution_points(req->distributionPoints);
req = req->next; req = req->next;
+8 -6
View File
@@ -14,6 +14,7 @@
*/ */
#include <utils/linked_list.h> #include <utils/linked_list.h>
#include <utils/identification.h>
#include "x509.h" #include "x509.h"
@@ -29,11 +30,11 @@ typedef enum {
typedef struct fetch_req fetch_req_t; typedef struct fetch_req fetch_req_t;
struct fetch_req { struct fetch_req {
fetch_req_t *next; fetch_req_t *next;
int trials; int trials;
chunk_t issuer; identification_t *issuer;
chunk_t authKeyID; chunk_t authKeyID;
linked_list_t *distributionPoints; linked_list_t *distributionPoints;
}; };
#ifdef THREADS #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_point(linked_list_t *points, char* new_point);
extern void add_distribution_points(linked_list_t *points, extern void add_distribution_points(linked_list_t *points,
linked_list_t *new_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); linked_list_t *distributionPoints);
extern void add_crl_fetch_request(fetch_req_t *req); extern void add_crl_fetch_request(fetch_req_t *req);
extern void add_ocsp_fetch_request(struct ocsp_location *location, extern void add_ocsp_fetch_request(struct ocsp_location *location,
+139 -91
View File
@@ -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); 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 linked_list_t *list = linked_list_create();
, pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY); 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) for (; d != NULL; d = d->hp_next)
{ {
/* must be a road warrior connection */ /* must be a road warrior connection */
if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO) if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO) &&
&& d->spd.that.ca.ptr != NULL) d->spd.that.ca)
{ {
generalName_t *gn; enumerator_t *enumerator;
identification_t *ca;
bool new_entry = TRUE; 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; new_entry = FALSE;
break; break;
} }
} }
enumerator->destroy(enumerator);
if (new_entry) if (new_entry)
{ {
gn = malloc_thing(generalName_t); list->insert_last(list, d->spd.that.ca->clone(d->spd.that.ca));
gn->kind = GN_DIRECTORY_NAME;
gn->name = d->spd.that.ca;
gn->next = *top;
*top = gn;
} }
} }
} }
return *top != NULL; return list;
} }
static bool build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, 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; pubkey_t *key = p->key;
key_type_t type = key->public_key->get_type(key->public_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); 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); *pp = free_public_keyentry(p);
continue; /* continue with next public key */ continue; /* continue with next public key */
} }
if (take_a_crack(&s, key)) if (take_a_crack(&s, key))
{ {
return STF_OK; return STF_OK;
@@ -2165,26 +2170,26 @@ static void decode_cert(struct msg_digest *md)
blob.len = pbs_left(&p->pbs); blob.len = pbs_left(&p->pbs);
if (cert->isacert_type == CERT_X509_SIGNATURE) 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, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, blob, BUILD_BLOB_ASN1_DER, blob,
BUILD_END); 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(DBG_PARSING,
DBG_log("Public key validated") DBG_log("Public key validated")
) )
add_x509_public_key(&cert, valid_until, DAL_SIGNED); add_x509_public_key(&x509cert, valid_until, DAL_SIGNED);
} }
else else
{ {
plog("X.509 certificate rejected"); plog("X.509 certificate rejected");
} }
DESTROY_IF(cert.cert); x509cert.cert->destroy(x509cert.cert);
} }
else else
{ {
@@ -2193,11 +2198,11 @@ static void decode_cert(struct msg_digest *md)
} }
else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509) 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 else
{ {
@@ -2232,29 +2237,31 @@ static void decode_cr(struct msg_digest *md, connection_t *c)
if (cr->isacr_type == CERT_X509_SIGNATURE) if (cr->isacr_type == CERT_X509_SIGNATURE)
{ {
char buf[BUF_LEN];
if (ca_name.len > 0) if (ca_name.len > 0)
{ {
generalName_t *gn; identification_t *ca;
if (!is_asn1(ca_name)) if (!is_asn1(ca_name))
{ {
continue; continue;
} }
gn = malloc_thing(generalName_t); if (c->requested_ca == NULL)
ca_name = chunk_clone(ca_name); {
gn->kind = GN_DIRECTORY_NAME; c->requested_ca = linked_list_create();
gn->name = ca_name; }
gn->next = c->requested_ca; ca = identification_create_from_encoding(ID_DER_ASN1_DN, ca_name);
c->requested_ca = gn; 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; 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 else
{ {
@@ -2388,16 +2395,21 @@ static bool switch_connection(struct msg_digest *md, struct id *peer,
{ {
struct state *const st = md->st; struct state *const st = md->st;
connection_t *c = st->st_connection; connection_t *c = st->st_connection;
identification_t *peer_ca;
chunk_t peer_ca = (st->st_peer_pubkey != NULL) peer_ca = st->st_peer_pubkey ? st->st_peer_pubkey->issuer : NULL;
? st->st_peer_pubkey->issuer : chunk_empty; if (peer_ca)
{
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
char buf[BUF_LEN]; DBG_log("peer CA: \"%Y\"", peer_ca)
)
dntoa_or_null(buf, BUF_LEN, peer_ca, "%none"); }
DBG_log("peer CA: '%s'", buf); else
) {
DBG(DBG_CONTROL,
DBG_log("peer CA: %%none")
)
}
if (initiator) if (initiator)
{ {
@@ -2416,12 +2428,18 @@ static bool switch_connection(struct msg_digest *md, struct id *peer,
return FALSE; return FALSE;
} }
DBG(DBG_CONTROL, if (c->spd.that.ca)
char buf[BUF_LEN]; {
DBG(DBG_CONTROL,
dntoa_or_null(buf, BUF_LEN, c->spd.that.ca, "%none"); DBG_log("required CA: \"%s\"", c->spd.that.ca);
DBG_log("required CA: '%s'", buf); )
) }
else
{
DBG(DBG_CONTROL,
DBG_log("required CA: %%none");
)
}
if (!trusted_ca(peer_ca, c->spd.that.ca, &pathlen)) 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); r = refine_host_connection(st, peer, peer_ca);
/* delete the collected certificate requests */ /* delete the collected certificate requests */
free_generalNames(c->requested_ca, TRUE); if (c->requested_ca)
c->requested_ca = NULL; {
c->requested_ca->destroy_offset(c->requested_ca,
offsetof(identification_t, destroy));
c->requested_ca = NULL;
}
if (r == NULL) if (r == NULL)
{ {
@@ -2452,12 +2474,18 @@ static bool switch_connection(struct msg_digest *md, struct id *peer,
return FALSE; return FALSE;
} }
DBG(DBG_CONTROL, if (r->spd.this.ca)
char buf[BUF_LEN]; {
DBG(DBG_CONTROL,
dntoa_or_null(buf, BUF_LEN, r->spd.this.ca, "%none"); DBG_log("offered CA: \"%s\"", r->spd.this.ca)
DBG_log("offered CA: '%s'", buf); )
) }
else
{
DBG(DBG_CONTROL,
DBG_log("offered CA: %%none")
)
}
if (r != c) if (r != c)
{ {
@@ -2708,8 +2736,10 @@ static bool has_preloaded_public_key(struct state *st)
{ {
pubkey_t *key = p->key; pubkey_t *key = p->key;
key_type_t type = key->public_key->get_type(key->public_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) key->until_time == UNDEFINED_TIME)
{ {
/* found a preloaded public key */ /* 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 (st->st_connection->kind == CK_PERMANENT)
{ {
if (!build_and_ship_CR(CERT_X509_SIGNATURE identification_t *ca = st->st_connection->spd.that.ca;
, st->st_connection->spd.that.ca chunk_t cr = (ca) ? ca->get_encoding(ca) : chunk_empty;
, &md->rbody, np))
if (!build_and_ship_CR(CERT_X509_SIGNATURE, cr, &md->rbody, np))
{ {
return STF_INTERNAL_ERROR; return STF_INTERNAL_ERROR;
} }
} }
else 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 if (!build_and_ship_CR(CERT_X509_SIGNATURE,
, &md->rbody ca->get_encoding(ca), &md->rbody,
, gn->next == NULL ? np : ISAKMP_NEXT_CR)) --count ? ISAKMP_NEXT_CR : np))
{ {
return STF_INTERNAL_ERROR; error = TRUE;
break;
} }
} }
free_generalNames(ca, FALSE); enumerator->destroy(enumerator);
} }
else else
{ {
if (!build_and_ship_CR(CERT_X509_SIGNATURE, chunk_empty if (!build_and_ship_CR(CERT_X509_SIGNATURE, chunk_empty,
, &md->rbody, np)) &md->rbody, np))
{ {
return STF_INTERNAL_ERROR; error = TRUE;
} }
} }
list->destroy_offset(list, offsetof(identification_t, destroy));
if (error)
{
return STF_INTERNAL_ERROR;
}
} }
} }
@@ -3479,8 +3520,9 @@ stf_status main_inR2_outI3(struct msg_digest *md)
pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs; pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
pb_stream id_pbs; /* ID Payload; also used for hash calculation */ pb_stream id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy = st->st_connection->spd.this.sendcert; connection_t *c = st->st_connection;
cert_t mycert = st->st_connection->spd.this.cert; certpolicy_t cert_policy = c->spd.this.sendcert;
cert_t mycert = c->spd.this.cert;
bool requested, send_cert, send_cr; bool requested, send_cert, send_cr;
bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth); 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")); RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
/* decode certificate requests */ /* decode certificate requests */
st->st_connection->got_certrequest = FALSE; c->got_certrequest = FALSE;
decode_cr(md, st->st_connection); decode_cr(md, c);
/* free collected certificate requests since as initiator /* free collected certificate requests since as initiator
* we don't heed them anyway * we don't heed them anyway
*/ */
free_generalNames(st->st_connection->requested_ca, TRUE); if (c->requested_ca)
st->st_connection->requested_ca = NULL; {
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 /* send certificate if auth is RSA, we have one and we want
* or are requested to send it * or are requested to send it
*/ */
requested = cert_policy == CERT_SEND_IF_ASKED requested = cert_policy == CERT_SEND_IF_ASKED && c->got_certrequest;
&& st->st_connection->got_certrequest;
send_cert = pubkey_auth && mycert.type != CERT_NONE send_cert = pubkey_auth && mycert.type != CERT_NONE
&& (cert_policy == CERT_ALWAYS_SEND || requested); && (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; struct isakmp_ipsec_id id_hd;
chunk_t id_b; 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; id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs) if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs)
|| !out_chunk(id_b, &id_pbs, "my identity")) || !out_chunk(id_b, &id_pbs, "my identity"))
@@ -3601,8 +3646,10 @@ stf_status main_inR2_outI3(struct msg_digest *md)
/* CR out */ /* CR out */
if (send_cr) if (send_cr)
{ {
if (!build_and_ship_CR(mycert.type, st->st_connection->spd.that.ca identification_t *ca = st->st_connection->spd.that.ca;
, &md->rbody, ISAKMP_NEXT_SIG)) 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; 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); 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) if (sig_len == 0)
{ {
loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature"); 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 */ /* check the peer's group attributes */
{ {
identification_t *peer_ca = NULL;
ietf_attributes_t *peer_attributes = NULL; ietf_attributes_t *peer_attributes = NULL;
bool match; 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, match = match_group_membership(peer_attributes,
st->st_connection->name, st->st_connection->name,
st->st_connection->spd.that.groups); st->st_connection->spd.that.groups);
+13 -3
View File
@@ -492,13 +492,23 @@ static bool do_command(connection_t *c, struct spd_route *sr,
{ {
pubkey_t *key = p->key; pubkey_t *key = p->key;
key_type_t type = key->public_key->get_type(key->public_key); key_type_t type = key->public_key->get_type(key->public_key);
struct id key_id;
int pathlen; 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)) trusted_ca(key->issuer, sr->that.ca, &pathlen))
{ {
dntoa_or_null(peerca_str, BUF_LEN, key->issuer, ""); if (key->issuer)
escape_metachar(peerca_str, secure_peerca_str, sizeof(secure_peerca_str)); {
snprintf(peerca_str, BUF_LEN, "%Y", key->issuer);
escape_metachar(peerca_str, secure_peerca_str, BUF_LEN);
}
else
{
secure_peerca_str[0] = '\0';
}
break; break;
} }
} }
+34 -51
View File
@@ -84,9 +84,9 @@ struct secret {
*/ */
static void free_public_key(pubkey_t *pk) static void free_public_key(pubkey_t *pk)
{ {
DESTROY_IF(pk->id);
DESTROY_IF(pk->public_key); DESTROY_IF(pk->public_key);
free_id_content(&pk->id); DESTROY_IF(pk->issuer);
free(pk->issuer.ptr);
free(pk->serial.ptr); free(pk->serial.ptr);
free(pk); free(pk);
} }
@@ -1118,8 +1118,8 @@ pubkey_t* public_key_from_rsa(public_key_t *key)
pubkey_t *p = malloc_thing(pubkey_t); pubkey_t *p = malloc_thing(pubkey_t);
zero(p); zero(p);
p->id = empty_id; /* don't know, doesn't matter */ p->id = identification_create_from_string("%any"); /* don't know, doesn't matter */
p->issuer = chunk_empty; p->issuer = NULL;
p->serial = chunk_empty; p->serial = chunk_empty;
p->public_key = key; p->public_key = key;
@@ -1127,7 +1127,6 @@ pubkey_t* public_key_from_rsa(public_key_t *key)
* invariant: recount > 0. * invariant: recount > 0.
*/ */
p->refcnt = 1; p->refcnt = 1;
time(&p->installed_time);
return p; 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); 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 */ /* install new key at front */
p->key = reference_key(pk); p->key = reference_key(pk);
p->next = *head; p->next = *head;
*head = p; *head = p;
} }
void delete_public_keys(const struct id *id, key_type_t type, void delete_public_keys(identification_t *id, key_type_t type,
chunk_t issuer, chunk_t serial) identification_t *issuer, chunk_t serial)
{ {
pubkey_list_t **pp, *p; pubkey_list_t **pp, *p;
pubkey_t *pk; pubkey_t *pk;
@@ -1235,9 +1223,9 @@ void delete_public_keys(const struct id *id, key_type_t type,
pk = p->key; pk = p->key;
pk_type = pk->public_key->get_type(pk->public_key); pk_type = pk->public_key->get_type(pk->public_key);
if (same_id(id, &pk->id) && pk_type == type if (id->equals(id, pk->id) && pk_type == type
&& (issuer.ptr == NULL || pk->issuer.ptr == NULL && (issuer == NULL || pk->issuer == NULL
|| same_dn(issuer, pk->issuer)) || issuer->equals(issuer, pk->issuer))
&& (serial.ptr == NULL || chunk_equals(serial, pk->serial))) && (serial.ptr == NULL || chunk_equals(serial, pk->serial)))
{ {
*pp = free_public_keyentry(p); *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) 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++; pk->refcnt++;
return pk; return pk;
} }
void void unreference_key(pubkey_t **pkp)
unreference_key(pubkey_t **pkp)
{ {
pubkey_t *pk = *pkp; pubkey_t *pk = *pkp;
char b[BUF_LEN];
if (pk == NULL) if (pk == NULL)
{ {
return; return;
} }
/* print stuff */
DBG(DBG_CONTROLMORE, DBG(DBG_CONTROLMORE,
idtoa(&pk->id, b, sizeof(b)); DBG_log("unref key: %p %p cnt %d '%Y'",
DBG_log("unreference key: %p %s cnt %d--", pk, b, pk->refcnt) pk, pk->public_key, pk->refcnt, pk->id)
) )
/* cancel out the pointer */ /* 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, enum pubkey_alg alg, chunk_t rfc3110_key,
pubkey_list_t **head) 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); pk = malloc_thing(pubkey_t);
zero(pk); zero(pk);
pk->public_key = key; pk->public_key = key;
pk->id = *id; pk->id = id->clone(id);
pk->dns_auth_level = dns_auth_level; pk->dns_auth_level = dns_auth_level;
pk->until_time = UNDEFINED_TIME; pk->until_time = UNDEFINED_TIME;
pk->issuer = chunk_empty; pk->issuer = NULL;
pk->serial = chunk_empty; pk->serial = chunk_empty;
install_public_key(pk, head); install_public_key(pk, head);
return TRUE; 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 *subject = certificate->get_subject(certificate);
identification_t *issuer = certificate->get_issuer(certificate); identification_t *issuer = certificate->get_issuer(certificate);
identification_t *id; identification_t *id;
chunk_t issuer_dn = issuer->get_encoding(issuer);
chunk_t serialNumber = x509->get_serial(x509); chunk_t serialNumber = x509->get_serial(x509);
pubkey_t *pk; pubkey_t *pk;
key_type_t pk_type; 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) */ /* ID type: ID_DER_ASN1_DN (X.509 subject field) */
pk = malloc_thing(pubkey_t); pk = malloc_thing(pubkey_t);
zero(pk); zero(pk);
pk->public_key = cert->cert->get_public_key(cert->cert); pk->public_key = certificate->get_public_key(certificate);
pk->id.kind = ID_DER_ASN1_DN; pk->id = subject->clone(subject);
pk->id.name = subject->get_encoding(subject);
pk->dns_auth_level = dns_auth_level; pk->dns_auth_level = dns_auth_level;
pk->until_time = until; pk->until_time = until;
pk->issuer = issuer_dn; pk->issuer = issuer->clone(issuer);
pk->serial = serialNumber; pk->serial = chunk_clone(serialNumber);
pk_type = pk->public_key->get_type(pk->public_key); 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); install_public_key(pk, &pubkeys);
/* insert all subjectAltNames */ /* insert all subjectAltNames */
@@ -1357,13 +1344,13 @@ void add_x509_public_key(x509cert_t *cert , time_t until,
{ {
pk = malloc_thing(pubkey_t); pk = malloc_thing(pubkey_t);
zero(pk); zero(pk);
id_from_identification(&pk->id, id); pk->id = id->clone(id);
pk->public_key = cert->cert->get_public_key(cert->cert); pk->public_key = certificate->get_public_key(certificate);
pk->dns_auth_level = dns_auth_level; pk->dns_auth_level = dns_auth_level;
pk->until_time = until; pk->until_time = until;
pk->issuer = issuer_dn; pk->issuer = issuer->clone(issuer);
pk->serial = serialNumber; pk->serial = chunk_clone(serialNumber);
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); 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); pk = malloc_thing(pubkey_t);
zero(pk); zero(pk);
pk->public_key = cert->public_key->get_ref(cert->public_key); pk->public_key = cert->public_key->get_ref(cert->public_key);
pk->id.kind = ID_KEY_ID; pk->id = cert->fingerprint->clone(cert->fingerprint);
pk->id.name = cert->fingerprint->get_encoding(cert->fingerprint);
pk->dns_auth_level = dns_auth_level; pk->dns_auth_level = dns_auth_level;
pk->until_time = until; pk->until_time = until;
pk_type = pk->public_key->get_type(pk->public_key); 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); install_public_key(pk, &pubkeys);
} }
@@ -1437,11 +1423,9 @@ void list_public_keys(bool utc)
pubkey_t *key = p->key; pubkey_t *key = p->key;
public_key_t *public = key->public_key; public_key_t *public = key->public_key;
chunk_t keyid; chunk_t keyid;
char buf[BUF_LEN];
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
idtoa(&key->id, buf, BUF_LEN); whack_log(RC_COMMENT, " identity: '%Y'", key->id);
whack_log(RC_COMMENT, " identity: '%s'", buf);
whack_log(RC_COMMENT, " pubkey: %N %4d bits, until %T %s", whack_log(RC_COMMENT, " pubkey: %N %4d bits, until %T %s",
key_type_names, public->get_type(public), key_type_names, public->get_type(public),
public->get_keysize(public) * BITS_PER_BYTE, public->get_keysize(public) * BITS_PER_BYTE,
@@ -1451,10 +1435,9 @@ void list_public_keys(bool utc)
{ {
whack_log(RC_COMMENT," keyid: %#B", &keyid); 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: \"%Y\"", key->issuer);
whack_log(RC_COMMENT," issuer: \"%s\"", buf);
} }
if (key->serial.len) if (key->serial.len)
{ {
+7 -11
View File
@@ -16,6 +16,7 @@
#ifndef _KEYS_H #ifndef _KEYS_H
#define _KEYS_H #define _KEYS_H
#include <utils/identification.h>
#include <credentials/keys/private_key.h> #include <credentials/keys/private_key.h>
#include <credentials/keys/public_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; typedef struct pubkey pubkey_t;
struct pubkey { struct pubkey {
struct id id; identification_t *id;
unsigned refcnt; /* reference counted! */ unsigned refcnt; /* reference counted! */
enum dns_auth_level dns_auth_level; enum dns_auth_level dns_auth_level;
char *dns_sig; char *dns_sig;
time_t installed_time time_t last_tried_time, last_worked_time, until_time;
, last_tried_time identification_t *issuer;
, last_worked_time
, until_time;
chunk_t issuer;
chunk_t serial; chunk_t serial;
public_key_t *public_key; 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 pubkey_list_t *free_public_keyentry(pubkey_list_t *p);
extern void free_public_keys(pubkey_list_t **keys); extern void free_public_keys(pubkey_list_t **keys);
extern void free_remembered_public_keys(void); extern void free_remembered_public_keys(void);
extern void delete_public_keys(const struct id *id, key_type_t type, extern void delete_public_keys(identification_t *id, key_type_t type,
chunk_t issuer, chunk_t serial); identification_t *issuer, chunk_t serial);
extern pubkey_t *reference_key(pubkey_t *pk); extern pubkey_t *reference_key(pubkey_t *pk);
extern void unreference_key(pubkey_t **pkp); extern void unreference_key(pubkey_t **pkp);
extern bool add_public_key(identification_t *id,
extern bool add_public_key(const struct id *id,
enum dns_auth_level dns_auth_level, enum dns_auth_level dns_auth_level,
enum pubkey_alg alg, enum pubkey_alg alg,
chunk_t rfc3110_key, chunk_t rfc3110_key,
pubkey_list_t **head); pubkey_list_t **head);
extern bool has_private_key(cert_t cert); extern bool has_private_key(cert_t cert);
extern void add_x509_public_key(x509cert_t *cert, time_t until extern void add_x509_public_key(x509cert_t *cert, time_t until
, enum dns_auth_level dns_auth_level); , enum dns_auth_level dns_auth_level);
+54 -67
View File
@@ -67,19 +67,19 @@ static const char *const response_status_names[] = {
typedef struct response response_t; typedef struct response response_t;
struct response { struct response {
chunk_t tbs; chunk_t tbs;
chunk_t responder_id_name; identification_t *responder_id_name;
chunk_t responder_id_key; chunk_t responder_id_key;
time_t produced_at; time_t produced_at;
chunk_t responses; chunk_t responses;
chunk_t nonce; chunk_t nonce;
int algorithm; int algorithm;
chunk_t signature; chunk_t signature;
}; };
const response_t empty_response = { const response_t empty_response = {
{ NULL, 0 } , /* tbs */ { NULL, 0 } , /* tbs */
{ NULL, 0 } , /* responder_id_name */ NULL , /* responder_id_name */
{ NULL, 0 } , /* responder_id_key */ { NULL, 0 } , /* responder_id_key */
UNDEFINED_TIME, /* produced_at */ UNDEFINED_TIME, /* produced_at */
{ NULL, 0 } , /* single_response */ { 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) if (location->uri == NULL)
{ {
ca_info_t *ca = get_ca_info(issuer_dn, authKeyID); ca_info_t *ca = get_ca_info(issuer, authKeyID);
if (ca != NULL && ca->ocspuri != NULL) if (ca && ca->ocspuri)
{ {
location->uri = 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); hasher->destroy(hasher);
location->next = NULL; location->next = NULL;
location->issuer = issuer_dn; location->issuer = issuer;
location->authKeyID = authKeyID; location->authKeyID = authKeyID;
if (authKeyID.ptr == NULL) 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; 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) 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_keyid(a->authKeyID, b->authKeyID)
: same_dn(a->issuer, b->issuer)) : a->issuer->equals(a->issuer, b->issuer))
&& streq(a->uri, b->uri); && 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) 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)) if (same_ocsp_location(loc, chain))
return chain; return chain;
@@ -393,7 +393,7 @@ static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
certinfop = &location->certinfo; certinfop = &location->certinfo;
certinfo = *certinfop; certinfo = *certinfop;
while (certinfo != NULL) while (certinfo)
{ {
cmp = chunk_compare(serialNumber, certinfo->serialNumber); cmp = chunk_compare(serialNumber, certinfo->serialNumber);
if (cmp <= 0) if (cmp <= 0)
@@ -462,13 +462,13 @@ void check_ocsp(void)
lock_ocsp_cache("check_ocsp"); lock_ocsp_cache("check_ocsp");
location = ocsp_cache; location = ocsp_cache;
while (location != NULL) while (location)
{ {
char buf[BUF_LEN]; char buf[BUF_LEN];
bool first = TRUE; bool first = TRUE;
ocsp_certinfo_t *certinfo = location->certinfo; ocsp_certinfo_t *certinfo = location->certinfo;
while (certinfo != NULL) while (certinfo)
{ {
if (!certinfo->once) if (!certinfo->once)
{ {
@@ -477,9 +477,8 @@ void check_ocsp(void)
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
if (first) if (first)
{ {
dntoa(buf, BUF_LEN, location->issuer); DBG_log("issuer: \"%Y\"", location->issuer);
DBG_log("issuer: '%s'", buf); if (location->authKeyID.ptr)
if (location->authKeyID.ptr != NULL)
{ {
datatot(location->authKeyID.ptr, location->authKeyID.len datatot(location->authKeyID.ptr, location->authKeyID.len
, ':', buf, BUF_LEN); , ':', buf, BUF_LEN);
@@ -518,7 +517,7 @@ static void free_certinfos(ocsp_certinfo_t *chain)
{ {
ocsp_certinfo_t *certinfo; ocsp_certinfo_t *certinfo;
while (chain != NULL) while (chain)
{ {
certinfo = chain; certinfo = chain;
chain = chain->next; chain = chain->next;
@@ -531,7 +530,7 @@ static void free_certinfos(ocsp_certinfo_t *chain)
*/ */
static void free_ocsp_location(ocsp_location_t* location) static void free_ocsp_location(ocsp_location_t* location)
{ {
free(location->issuer.ptr); DESTROY_IF(location->issuer);
free(location->authNameID.ptr); free(location->authNameID.ptr);
free(location->authKeyID.ptr); free(location->authKeyID.ptr);
free(location->uri); free(location->uri);
@@ -544,7 +543,7 @@ static void free_ocsp_location(ocsp_location_t* location)
*/ */
void free_ocsp_locations(ocsp_location_t **chain) void free_ocsp_locations(ocsp_location_t **chain)
{ {
while (*chain != NULL) while (*chain)
{ {
ocsp_location_t *location = *chain; ocsp_location_t *location = *chain;
*chain = location->next; *chain = location->next;
@@ -579,57 +578,50 @@ void list_ocsp_locations(ocsp_location_t *location, bool requests,
{ {
bool first = TRUE; bool first = TRUE;
while (location != NULL) while (location)
{ {
ocsp_certinfo_t *certinfo = location->certinfo; ocsp_certinfo_t *certinfo = location->certinfo;
if (certinfo != NULL) if (certinfo)
{ {
u_char buf[BUF_LEN];
if (first) if (first)
{ {
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, "List of OCSP %s:", requests? whack_log(RC_COMMENT, "List of OCSP %s:", requests ?
"fetch requests":"responses"); "Fetch Requests" : "Responses");
first = FALSE; first = FALSE;
} }
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
if (location->issuer.ptr) if (location->issuer)
{ {
dntoa(buf, BUF_LEN, location->issuer); whack_log(RC_COMMENT, " issuer: \"%Y\"", location->issuer);
whack_log(RC_COMMENT, " issuer: \"%s\"", buf);
} }
whack_log(RC_COMMENT, " uri: '%s'", location->uri); whack_log(RC_COMMENT, " uri: '%s'", location->uri);
if (location->authNameID.ptr) if (location->authNameID.ptr)
{ {
datatot(location->authNameID.ptr, location->authNameID.len, ':' whack_log(RC_COMMENT, " authname: %#B", &location->authNameID);
, buf, BUF_LEN);
whack_log(RC_COMMENT, " authname: %s", buf);
} }
if (location->authKeyID.ptr) if (location->authKeyID.ptr)
{ {
datatot(location->authKeyID.ptr, location->authKeyID.len, ':' whack_log(RC_COMMENT, " authkey: %#B", &location->authKeyID);
, buf, BUF_LEN);
whack_log(RC_COMMENT, " authkey: %s", buf);
} }
while (certinfo) while (certinfo)
{ {
if (requests) if (requests)
{ {
whack_log(RC_COMMENT, " serial: %#B, %d trials", whack_log(RC_COMMENT, " serial: %#B, %d trials",
&certinfo->serialNumber, certinfo->trials); &certinfo->serialNumber, certinfo->trials);
} }
else if (certinfo->once) else if (certinfo->once)
{ {
whack_log(RC_COMMENT, " serial: %#B, %s, once%s", whack_log(RC_COMMENT, " serial: %#B, %s, once%s",
&certinfo->serialNumber, &certinfo->serialNumber,
cert_status_names[certinfo->status], cert_status_names[certinfo->status],
(certinfo->nextUpdate < time(NULL))? " (expired)": ""); (certinfo->nextUpdate < time(NULL))? " (expired)": "");
} }
else else
{ {
whack_log(RC_COMMENT, " serial: %#B, %s, until %T %s", whack_log(RC_COMMENT, " serial: %#B, %s, until %T %s",
&certinfo->serialNumber, &certinfo->serialNumber,
cert_status_names[certinfo->status], cert_status_names[certinfo->status],
&certinfo->nextUpdate, utc, &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 */ /* look for a matching private key on a smartcard */
smartcard_t *sc = scx_get(cert); smartcard_t *sc = scx_get(cert);
if (sc != NULL) if (sc)
{ {
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
DBG_log("matching smartcard found") 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 */ /* look for a matching private key in the chained list */
private_key_t *private = get_x509_private_key(cert); private_key_t *private = get_x509_private_key(cert);
if (private != NULL) if (private)
{ {
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
DBG_log("matching private key found") DBG_log("matching private key found")
@@ -777,7 +769,7 @@ static chunk_t build_signature(chunk_t tbsRequest)
{ {
chunk_t sigdata, cert, certs; chunk_t sigdata, cert, certs;
if (ocsp_requestor_sc != NULL) if (ocsp_requestor_sc)
{ {
/* RSA signature is done on smartcard */ /* RSA signature is done on smartcard */
sigdata = sc_build_sha1_signature(tbsRequest, ocsp_requestor_sc); 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; size_t datalen = 0;
/* build content */ /* build content */
while (certinfo != NULL) while (certinfo)
{ {
/* build request for every certificate in list /* build request for every certificate in list
* and store them in a chained 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); pos = asn1_build_object(&requestList, ASN1_SEQUENCE, datalen);
/* copy all in chained list, free list afterwards */ /* copy all in chained list, free list afterwards */
while (reqs != NULL) while (reqs)
{ {
request_list_t *req = reqs; request_list_t *req = reqs;
@@ -936,17 +928,13 @@ chunk_t build_ocsp_request(ocsp_location_t *location)
{ {
bool has_requestor_cert; bool has_requestor_cert;
chunk_t tbsRequest, signature; chunk_t tbsRequest, signature;
char buf[BUF_LEN];
DBG(DBG_CONTROL, DBG(DBG_CONTROL,
DBG_log("assembling ocsp request"); DBG_log("assembling ocsp request");
dntoa(buf, BUF_LEN, location->issuer); DBG_log("issuer: \"%Y\"", location->issuer);
DBG_log("issuer: '%s'", buf); if (location->authKeyID.ptr)
if (location->authKeyID.ptr != NULL)
{ {
datatot(location->authKeyID.ptr, location->authKeyID.len, ':' DBG_log("authkey: %#B", &location->authKeyID);
, buf, BUF_LEN);
DBG_log("authkey: %s", buf);
} }
) )
lock_certs_and_keys("build_ocsp_request"); lock_certs_and_keys("build_ocsp_request");
@@ -1029,7 +1017,7 @@ static bool valid_ocsp_response(response_t *res)
DBG_log("certificate is valid") 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) if (authcert == NULL)
{ {
plog("issuer cacert not found"); 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; asn1_parser_t *parser;
chunk_t object; chunk_t object;
u_int version; u_int version;
u_char buf[BUF_LEN];
int objectID; int objectID;
int extn_oid = OID_UNKNOWN; int extn_oid = OID_UNKNOWN;
bool success = FALSE; bool success = FALSE;
@@ -1098,10 +1085,10 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
} }
break; break;
case BASIC_RESPONSE_ID_BY_NAME: 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, DBG(DBG_PARSING,
dntoa(buf, BUF_LEN, object); DBG_log(" '%Y'", res->responder_id_name)
DBG_log(" '%s'",buf)
) )
break; break;
case BASIC_RESPONSE_ID_BY_KEY: 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); ocsp_location_t *location = malloc_thing(ocsp_location_t);
/* unshare location fields */ /* unshare location fields */
location->issuer = chunk_clone(loc->issuer); location->issuer = loc->issuer->clone(loc->issuer);
location->authNameID = chunk_clone(loc->authNameID); location->authNameID = chunk_clone(loc->authNameID);
location->authKeyID = chunk_clone(loc->authKeyID); location->authKeyID = chunk_clone(loc->authKeyID);
location->uri = strdup(loc->uri); location->uri = strdup(loc->uri);
@@ -1362,7 +1349,7 @@ void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info,
certinfop = &location->certinfo; certinfop = &location->certinfo;
certinfo = *certinfop; certinfo = *certinfop;
while (certinfo != NULL) while (certinfo)
{ {
cmp = chunk_compare(info->serialNumber, certinfo->serialNumber); cmp = chunk_compare(info->serialNumber, certinfo->serialNumber);
if (cmp <= 0) if (cmp <= 0)
@@ -1445,7 +1432,7 @@ static void process_single_response(ocsp_location_t *location,
certinfop = &location->certinfo; certinfop = &location->certinfo;
certinfo = *certinfop; certinfo = *certinfop;
while (certinfo != NULL) while (certinfo)
{ {
cmp = chunk_compare(sres->serialNumber, certinfo->serialNumber); cmp = chunk_compare(sres->serialNumber, certinfo->serialNumber);
if (cmp <= 0) if (cmp <= 0)
@@ -1495,12 +1482,12 @@ void parse_ocsp(ocsp_location_t *location, chunk_t blob)
return; return;
} }
/* check if there was a nonce in the request */ /* 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"); plog("ocsp response contains no nonce, replay attack possible");
} }
/* check if the nonce is identical */ /* 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"); plog("invalid nonce in ocsp response");
return; return;
+4 -4
View File
@@ -54,10 +54,10 @@ typedef struct ocsp_location ocsp_location_t;
struct ocsp_location { struct ocsp_location {
ocsp_location_t *next; ocsp_location_t *next;
chunk_t issuer; identification_t *issuer;
chunk_t authNameID; chunk_t authNameID;
chunk_t authKeyID; chunk_t authKeyID;
chunk_t nonce; chunk_t nonce;
char *uri; char *uri;
ocsp_certinfo_t *certinfo; ocsp_certinfo_t *certinfo;
}; };
+5 -5
View File
@@ -490,17 +490,17 @@ void list_pgp_end_certs(bool utc)
c.u.pgp = cert; c.u.pgp = cert;
whack_log(RC_COMMENT, " "); whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, " digest: %Y", cert->fingerprint); whack_log(RC_COMMENT, " digest: %Y", cert->fingerprint);
whack_log(RC_COMMENT, " created: %T", &cert->created, utc); whack_log(RC_COMMENT, " created: %T", &cert->created, utc);
whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc, whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc,
check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE)); 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_type_names, key->get_type(key),
key->get_keysize(key) * BITS_PER_BYTE, key->get_keysize(key) * BITS_PER_BYTE,
has_private_key(c)? ", has private key" : ""); has_private_key(c)? ", has private key" : "");
if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid)) 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; cert = cert->next;
} }
+14 -16
View File
@@ -63,8 +63,7 @@
static char *next_str static char *next_str
, *str_roof; , *str_roof;
static bool static bool unpack_str(char **p)
unpack_str(char **p)
{ {
char *end = memchr(next_str, '\0', str_roof - next_str); char *end = memchr(next_str, '\0', str_roof - next_str);
@@ -103,8 +102,7 @@ struct key_add_continuation {
enum key_add_attempt lookingfor; enum key_add_attempt lookingfor;
}; };
static void static void key_add_ugh(const struct id *keyid, err_t ugh)
key_add_ugh(const struct id *keyid, err_t ugh)
{ {
char name[BUF_LEN]; /* longer IDs will be truncated in message */ 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 */ /* last one out: turn out the lights */
static void static void key_add_merge(struct key_add_common *oc, const struct id *keyid)
key_add_merge(struct key_add_common *oc, const struct id *keyid)
{ {
if (oc->refCount == 0) if (oc->refCount == 0)
{ {
@@ -135,8 +132,7 @@ key_add_merge(struct key_add_common *oc, const struct id *keyid)
} }
} }
static void static void key_add_continue(struct adns_continuation *ac, err_t ugh)
key_add_continue(struct adns_continuation *ac, err_t ugh)
{ {
struct key_add_continuation *kc = (void *) ac; struct key_add_continuation *kc = (void *) ac;
struct key_add_common *oc = kc->common; 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; whack_log_fd = NULL_FD;
} }
static void static void key_add_request(const whack_message_t *msg)
key_add_request(const whack_message_t *msg)
{ {
identification_t *key_id;
struct id keyid; struct id keyid;
err_t ugh = atoid(msg->keyid, &keyid, FALSE); err_t ugh = atoid(msg->keyid, &keyid, FALSE);
@@ -175,10 +171,12 @@ key_add_request(const whack_message_t *msg)
} }
else else
{ {
if (!msg->whack_addkey) key_id = identification_create_from_string(msg->keyid);
delete_public_keys(&keyid, msg->pubkey_alg
, chunk_empty, chunk_empty);
if (!msg->whack_addkey)
{
delete_public_keys(key_id, msg->pubkey_alg, NULL, chunk_empty);
}
if (msg->keyval.len == 0) if (msg->keyval.len == 0)
{ {
struct key_add_common *oc = malloc_thing(struct key_add_common); struct key_add_common *oc = malloc_thing(struct key_add_common);
@@ -234,20 +232,20 @@ key_add_request(const whack_message_t *msg)
} }
else 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)) &pubkeys))
{ {
loglog(RC_LOG_SERIOUS, "failed to add public key"); loglog(RC_LOG_SERIOUS, "failed to add public key");
} }
} }
key_id->destroy(key_id);
} }
} }
/* Handle a kernel request. Supposedly, there's a message in /* Handle a kernel request. Supposedly, there's a message in
* the kernelsock socket. * the kernelsock socket.
*/ */
void void whack_handle(int whackctlfd)
whack_handle(int whackctlfd)
{ {
whack_message_t msg; whack_message_t msg;
struct sockaddr_un whackaddr; struct sockaddr_un whackaddr;
+19 -38
View File
@@ -337,7 +337,7 @@ static err_t dn_parse(chunk_t dn, chunk_t *str)
err_t ugh = init_rdn(dn, &rdn, &attribute, &next); 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; 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); 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; return ugh;
} }
@@ -391,7 +391,7 @@ int dn_count_wildcards(chunk_t dn)
err_t ugh = init_rdn(dn, &rdn, &attribute, &next); 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; return -1;
} }
@@ -400,7 +400,7 @@ int dn_count_wildcards(chunk_t dn)
{ {
ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next); 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; return -1;
} }
@@ -436,7 +436,7 @@ int dntoa(char *dst, size_t dstlen, chunk_t dn)
str.len = dstlen; str.len = dstlen;
ugh = dn_parse(dn, &str); 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(DBG_PARSING,
DBG_log("error in DN parsing: %s", ugh) DBG_log("error in DN parsing: %s", ugh)
@@ -448,22 +448,6 @@ int dntoa(char *dst, size_t dstlen, chunk_t dn)
return (int)(dstlen - str.len); return (int)(dstlen - str.len);
} }
/**
* 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 * Codes ASN.1 lengths up to a size of 16'777'215 bytes
*/ */
@@ -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 * 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; certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate; 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); chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
if ((keyid.ptr != NULL) ? same_keyid(keyid, authKeyID) if (keyid.ptr ? same_keyid(keyid, authKeyID) :
: same_dn(issuer, cert_issuer_dn)) certificate->has_issuer(certificate, issuer))
{ {
return cert; 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) void free_generalNames(generalName_t* gn, bool free_name)
{ {
while (gn != NULL) while (gn)
{ {
generalName_t *gn_top = gn; generalName_t *gn_top = gn;
if (free_name) if (free_name)
@@ -957,7 +939,7 @@ void free_generalNames(generalName_t* gn, bool free_name)
*/ */
void free_x509cert(x509cert_t *cert) void free_x509cert(x509cert_t *cert)
{ {
if (cert != NULL) if (cert)
{ {
certificate_t *certificate = cert->cert; certificate_t *certificate = cert->cert;
@@ -976,7 +958,7 @@ void free_x509cert(x509cert_t *cert)
*/ */
void release_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; x509cert_t **pp = &x509certs;
while (*pp != cert) while (*pp != cert)
@@ -998,7 +980,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict)
/* first extract CA certs, discarding root CA certs */ /* first extract CA certs, discarding root CA certs */
while (*pp != NULL) while (*pp)
{ {
x509cert_t *cert = *pp; x509cert_t *cert = *pp;
certificate_t *certificate = cert->cert; certificate_t *certificate = cert->cert;
@@ -1030,7 +1012,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict)
/* now verify the candidate CA certs */ /* now verify the candidate CA certs */
while (cacerts != NULL) while (cacerts)
{ {
x509cert_t *cert = cacerts; x509cert_t *cert = cacerts;
@@ -1051,7 +1033,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict)
pp = firstcert; pp = firstcert;
while (*pp != NULL) while (*pp)
{ {
time_t valid_until; time_t valid_until;
x509cert_t *cert = *pp; x509cert_t *cert = *pp;
@@ -1269,7 +1251,7 @@ chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
chunk_t name = chunk_empty; chunk_t name = chunk_empty;
generalName_t * gn = parse_generalNames(blob, level, implicit); 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; name= gn->name;
} }
@@ -1362,8 +1344,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
) )
lock_authcert_list("verify_x509cert"); lock_authcert_list("verify_x509cert");
issuer_cert = get_authcert(issuer->get_encoding(issuer), issuer_cert = get_authcert(issuer, authKeyID, X509_CA);
authKeyID, X509_CA);
if (issuer_cert == NULL) if (issuer_cert == NULL)
{ {
plog("issuer cacert not found"); plog("issuer cacert not found");
@@ -1473,7 +1454,7 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
/* determine the current time */ /* determine the current time */
time(&now); time(&now);
while (cert != NULL) while (cert)
{ {
certificate_t *certificate = cert->cert; certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate; x509_t *x509 = (x509_t*)certificate;
+3 -3
View File
@@ -18,9 +18,11 @@
#ifndef _X509_H #ifndef _X509_H
#define _X509_H #define _X509_H
#include <utils/identification.h>
#include <credentials/keys/public_key.h> #include <credentials/keys/public_key.h>
#include <credentials/keys/private_key.h> #include <credentials/keys/private_key.h>
#include <credentials/certificates/x509.h> #include <credentials/certificates/x509.h>
#include "constants.h" #include "constants.h"
#include "id.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 void hex_str(chunk_t bin, chunk_t *str);
extern int dn_count_wildcards(chunk_t dn); extern int dn_count_wildcards(chunk_t dn);
extern int dntoa(char *dst, size_t dstlen, 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 err_t atodn(char *src, chunk_t *dn);
extern void select_x509cert_id(x509cert_t *cert, struct id *end_id); extern void select_x509cert_id(x509cert_t *cert, struct id *end_id);
extern void parse_authorityKeyIdentifier(chunk_t blob, int level0, 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); private_key_t *key, bool bit_string);
extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until); extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until);
extern x509cert_t* add_x509cert(x509cert_t *cert); 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 share_x509cert(x509cert_t *cert);
extern void release_x509cert(x509cert_t *cert); extern void release_x509cert(x509cert_t *cert);
extern void free_x509cert(x509cert_t *cert); extern void free_x509cert(x509cert_t *cert);