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