migrated public key IDs to identification_t
This commit is contained in:
+4
-7
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user