aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-11-10 23:54:04 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-11-10 23:54:04 +0100
commitf565d0c575f9d7e4a53e10ee447871fea21cb2e3 (patch)
tree950b57b988a21db56ded2da3892cfad4dea6b9d4
parentcc543182bcf79b306188262b5537bc55f89c0965 (diff)
downloadstrongswan-f565d0c575f9d7e4a53e10ee447871fea21cb2e3.tar.bz2
strongswan-f565d0c575f9d7e4a53e10ee447871fea21cb2e3.tar.xz
merged pluto's PGP certificate parsing with charon's
-rw-r--r--src/pluto/Makefile.am1
-rw-r--r--src/pluto/ac.c2
-rw-r--r--src/pluto/builder.c50
-rw-r--r--src/pluto/ca.c65
-rw-r--r--src/pluto/ca.h9
-rw-r--r--src/pluto/certs.c205
-rw-r--r--src/pluto/certs.h45
-rw-r--r--src/pluto/connections.c110
-rw-r--r--src/pluto/connections.h2
-rw-r--r--src/pluto/crl.c7
-rw-r--r--src/pluto/crl.h3
-rw-r--r--src/pluto/ike_alg.c5
-rw-r--r--src/pluto/ipsec_doi.c43
-rw-r--r--src/pluto/keys.c114
-rw-r--r--src/pluto/keys.h12
-rw-r--r--src/pluto/ocsp.c22
-rw-r--r--src/pluto/ocsp.h4
-rw-r--r--src/pluto/pgpcert.c472
-rw-r--r--src/pluto/pgpcert.h34
-rw-r--r--src/pluto/rcv_whack.c2
-rw-r--r--src/pluto/smartcard.c141
-rw-r--r--src/pluto/smartcard.h7
-rw-r--r--src/pluto/x509.c174
-rw-r--r--src/pluto/x509.h30
-rw-r--r--src/whack/whack.h1
25 files changed, 472 insertions, 1088 deletions
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index e966299c0..14a13a52b 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -36,7 +36,6 @@ modecfg.c modecfg.h \
nat_traversal.c nat_traversal.h \
ocsp.c ocsp.h \
packet.c packet.h \
-pgpcert.c pgpcert.h \
pkcs7.c pkcs7.h \
plutomain.c \
rcv_whack.c rcv_whack.h \
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
index f2d81a5b8..d8b16112f 100644
--- a/src/pluto/ac.c
+++ b/src/pluto/ac.c
@@ -85,7 +85,7 @@ bool ac_verify_cert(certificate_t *cert, bool strict)
identification_t *subject = cert->get_subject(cert);
identification_t *issuer = cert->get_issuer(cert);
chunk_t authKeyID = ac->get_authKeyIdentifier(ac);
- x509cert_t *aacert;
+ cert_t *aacert;
time_t notBefore, valid_until;
DBG1("holder: '%Y'", subject);
diff --git a/src/pluto/builder.c b/src/pluto/builder.c
index 6c7cde547..0cba32bcf 100644
--- a/src/pluto/builder.c
+++ b/src/pluto/builder.c
@@ -64,43 +64,31 @@ static cert_t *builder_load_cert(certificate_type_t type, va_list args)
}
if (blob.ptr)
{
+ cert_t *cert = malloc_thing(cert_t);
+
+ *cert = cert_empty;
+
if (pgp)
{
- pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
- *pgpcert = pgpcert_empty;
- if (parse_pgp(chunk_clone(blob), pgpcert))
- {
- cert_t *cert = malloc_thing(cert_t);
- *cert = cert_empty;
- cert->type = CERT_PGP;
- cert->u.pgp = pgpcert;
- return cert;
- }
- plog(" error in OpenPGP certificate");
- free_pgpcert(pgpcert);
+ cert->cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_GPG,
+ BUILD_BLOB_PGP, blob,
+ BUILD_END);
}
else
{
- x509cert_t *x509cert = malloc_thing(x509cert_t);
-
- *x509cert = empty_x509cert;
- x509cert->cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, blob,
- BUILD_X509_FLAG, flags,
- BUILD_END);
- if (x509cert->cert)
- {
- cert_t *cert = malloc_thing(cert_t);
-
- *cert = cert_empty;
- cert->type = CERT_X509_SIGNATURE;
- cert->u.x509 = x509cert;
- return cert;
- }
- plog(" error in X.509 certificate");
- free_x509cert(x509cert);
+ cert->cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, blob,
+ BUILD_X509_FLAG, flags,
+ BUILD_END);
+ }
+ if (cert->cert)
+ {
+ return cert;
}
+ plog(" error in X.509 certificate");
+ cert_free(cert);
}
return NULL;
}
diff --git a/src/pluto/ca.c b/src/pluto/ca.c
index 583ef8b90..e25e7f6f5 100644
--- a/src/pluto/ca.c
+++ b/src/pluto/ca.c
@@ -37,7 +37,7 @@
/* chained list of X.509 authority certificates (ca, aa, and ocsp) */
-static x509cert_t *x509authcerts = NULL;
+static cert_t *x509authcerts = NULL;
/* chained list of X.509 certification authority information records */
@@ -79,7 +79,7 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
{
certificate_t *certificate;
identification_t *issuer;
- x509cert_t *cacert;
+ cert_t *cacert;
cacert = get_authcert(a, chunk_empty, X509_CA);
if (cacert == NULL)
@@ -161,9 +161,10 @@ bool match_requested_ca(linked_list_t *requested_ca, identification_t *our_ca,
*/
static void free_first_authcert(void)
{
- x509cert_t *first = x509authcerts;
+ cert_t *first = x509authcerts;
+
x509authcerts = first->next;
- free_x509cert(first);
+ cert_free(first);
}
/*
@@ -174,18 +175,19 @@ void free_authcerts(void)
lock_authcert_list("free_authcerts");
while (x509authcerts != NULL)
+ {
free_first_authcert();
-
+ }
unlock_authcert_list("free_authcerts");
}
/*
* get a X.509 authority certificate with a given subject or keyid
*/
-x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
+cert_t* get_authcert(identification_t *subject, chunk_t keyid,
x509_flag_t auth_flags)
{
- x509cert_t *cert, *prev_cert = NULL;
+ cert_t *cert, *prev_cert = NULL;
/* the authority certificate list is empty */
if (x509authcerts == NULL)
@@ -238,11 +240,11 @@ x509cert_t* get_authcert(identification_t *subject, chunk_t keyid,
/*
* add an authority certificate to the chained list
*/
-x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
+cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags)
{
certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate;
- x509cert_t *old_cert;
+ cert_t *old_cert;
lock_authcert_list("add_authcert");
@@ -258,7 +260,7 @@ x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
)
unlock_authcert_list("add_authcert");
- free_x509cert(cert);
+ cert_free(cert);
return old_cert;
}
else
@@ -274,7 +276,7 @@ x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
/* add new authcert to chained list */
cert->next = x509authcerts;
x509authcerts = cert;
- share_x509cert(cert); /* set count to one */
+ cert_share(cert); /* set count to one */
DBG(DBG_CONTROL | DBG_PARSING,
DBG_log(" authcert inserted")
)
@@ -302,16 +304,17 @@ void load_authcerts(char *type, char *path, x509_flag_t auth_flags)
while (enumerator->enumerate(enumerator, NULL, &file, &st))
{
- cert_t cert;
+ cert_t *cert;
if (!S_ISREG(st.st_mode))
{
/* skip special file */
continue;
}
- if (load_cert(file, type, auth_flags, &cert))
+ cert = load_cert(file, type, auth_flags);
+ if (cert)
{
- add_authcert(cert.u.x509, auth_flags);
+ add_authcert(cert, auth_flags);
}
}
enumerator->destroy(enumerator);
@@ -330,8 +333,8 @@ 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(identification_t *subject, chunk_t keyid,
- const x509cert_t *cert)
+static const cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid,
+ const cert_t *cert)
{
if (cert == NULL)
{
@@ -369,7 +372,7 @@ static const x509cert_t* get_alt_cacert(identification_t *subject, chunk_t keyid
/* establish trust into a candidate authcert by going up the trust chain.
* validity and revocation status are not checked.
*/
-bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
+bool trust_authcert_candidate(const cert_t *cert, const cert_t *alt_chain)
{
int pathlen;
@@ -382,7 +385,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
identification_t *subject = certificate->get_subject(certificate);
identification_t *issuer = certificate->get_issuer(certificate);
chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
- const x509cert_t *authcert = NULL;
+ const cert_t *authcert = NULL;
DBG(DBG_CONTROL,
DBG_log("subject: '%Y'", subject);
@@ -551,8 +554,7 @@ ca_info_t* create_ca_info(void)
void add_ca_info(const whack_message_t *msg)
{
smartcard_t *sc = NULL;
- cert_t cert;
- bool valid_cert = FALSE;
+ cert_t *cert = NULL;
bool cached_cert = FALSE;
if (find_ca_info_by_name(msg->name, FALSE))
@@ -564,18 +566,17 @@ void add_ca_info(const whack_message_t *msg)
if (scx_on_smartcard(msg->cacert))
{
/* load CA cert from smartcard */
- valid_cert = scx_load_cert(msg->cacert, &sc, &cert, &cached_cert);
+ cert = scx_load_cert(msg->cacert, &sc, &cached_cert);
}
else
{
/* load CA cert from file */
- valid_cert = load_ca_cert(msg->cacert, &cert);
+ cert = load_ca_cert(msg->cacert);
}
- if (valid_cert)
+ if (cert)
{
- x509cert_t *cacert = cert.u.x509;
- certificate_t *certificate = cacert->cert;
+ certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate;
identification_t *subject = certificate->get_subject(certificate);
chunk_t subjectKeyID = x509->get_subjectKeyIdentifier(x509);
@@ -589,7 +590,7 @@ void add_ca_info(const whack_message_t *msg)
/* ca_info is already present */
loglog(RC_DUPNAME, " duplicate ca information in record \"%s\" found,"
"ignoring \"%s\"", ca->name, msg->name);
- free_x509cert(cacert);
+ cert_free(cert);
return;
}
@@ -647,13 +648,15 @@ void add_ca_info(const whack_message_t *msg)
unlock_ca_info_list("add_ca_info");
/* add cacert to list of authcerts */
- cacert = add_authcert(cacert, X509_CA);
+ cert = add_authcert(cert, X509_CA);
if (!cached_cert && sc != NULL)
{
- if (sc->last_cert.type == CERT_X509_SIGNATURE)
- sc->last_cert.u.x509->count--;
- sc->last_cert.u.x509 = cacert;
- share_cert(sc->last_cert);
+ if (sc->last_cert != NULL)
+ {
+ sc->last_cert->count--;
+ }
+ sc->last_cert = cert;
+ cert_share(sc->last_cert);
}
if (sc != NULL)
time(&sc->last_load);
diff --git a/src/pluto/ca.h b/src/pluto/ca.h
index 7b016f943..d964a694a 100644
--- a/src/pluto/ca.h
+++ b/src/pluto/ca.h
@@ -18,7 +18,7 @@
#include <utils/linked_list.h>
#include <utils/identification.h>
-#include "x509.h"
+#include "certs.h"
#include "whack.h"
/* CA info structures */
@@ -40,14 +40,13 @@ struct ca_info {
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,
+extern cert_t* get_authcert(identification_t *subject, chunk_t keyid,
x509_flag_t auth_flags);
extern void load_authcerts(char *type, char *path, x509_flag_t auth_flags);
-extern x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags);
+extern cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags);
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 bool trust_authcert_candidate(const cert_t *cert, const cert_t *alt_chain);
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);
diff --git a/src/pluto/certs.c b/src/pluto/certs.c
index 89e289b6c..644f65766 100644
--- a/src/pluto/certs.c
+++ b/src/pluto/certs.c
@@ -18,60 +18,83 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#include <time.h>
#include <freeswan.h>
-#include "library.h"
-#include "asn1/asn1.h"
-#include "credentials/certificates/certificate.h"
+#include <library.h>
+#include <asn1/asn1.h>
+#include <credentials/certificates/certificate.h>
+#include <credentials/certificates/pgp_certificate.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "certs.h"
#include "whack.h"
+#include "fetch.h"
+#include "keys.h"
#include "builder.h"
/**
- * used for initializatin of certs
+ * Initialization
*/
-const cert_t cert_empty = {CERT_NONE, {NULL}};
+const cert_t cert_empty = {
+ NULL , /* cert */
+ NULL , /* *next */
+ 0 , /* count */
+ FALSE /* smartcard */
+};
/**
- * extracts the certificate to be sent to the peer
+ * Chained lists of X.509 and PGP end entity certificates
*/
-chunk_t cert_get_encoding(cert_t cert)
+static cert_t *certs = NULL;
+
+/**
+ * Free a pluto certificate
+ */
+void cert_free(cert_t *cert)
{
- switch (cert.type)
+ if (cert)
{
- case CERT_PGP:
- return chunk_clone(cert.u.pgp->certificate);
- case CERT_X509_SIGNATURE:
- return cert.u.x509->cert->get_encoding(cert.u.x509->cert);
- default:
- return chunk_empty;
+ certificate_t *certificate = cert->cert;
+
+ if (certificate)
+ {
+ certificate->destroy(certificate);
+ }
+ free(cert);
}
}
-public_key_t* cert_get_public_key(const cert_t cert)
+/**
+ * Add a pluto end entity certificate to the chained list
+ */
+cert_t* cert_add(cert_t *cert)
{
- switch (cert.type)
- {
- case CERT_PGP:
- {
- public_key_t *public_key = cert.u.pgp->public_key;
+ certificate_t *certificate = cert->cert;
+ cert_t *c = certs;
- return public_key->get_ref(public_key);
- }
- case CERT_X509_SIGNATURE:
+ while (c != NULL)
+ {
+ if (certificate->equals(certificate, c->cert)) /* already in chain, free cert */
{
- certificate_t *certificate = cert.u.x509->cert;
-
- return certificate->get_public_key(certificate);
+ cert_free(cert);
+ return c;
}
- default:
- return NULL;
+ c = c->next;
}
+
+ /* insert new cert at the root of the chain */
+ lock_certs_and_keys("cert_add");
+ cert->next = certs;
+ certs = cert;
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" cert inserted")
+ )
+ unlock_certs_and_keys("cert_add");
+ return cert;
}
/**
@@ -161,7 +184,7 @@ private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
/**
* Loads a X.509 or OpenPGP certificate
*/
-bool load_cert(char *filename, const char *label, x509_flag_t flags, cert_t *out)
+cert_t* load_cert(char *filename, const char *label, x509_flag_t flags)
{
cert_t *cert;
@@ -171,83 +194,133 @@ bool load_cert(char *filename, const char *label, x509_flag_t flags, cert_t *out
BUILD_END);
if (cert)
{
- /* the API passes an empty cert_t, we move over and free the built one */
plog(" loaded %s certificate from '%s'", label, filename);
- *out = *cert;
- free(cert);
- return TRUE;
}
- return FALSE;
+ return cert;
}
/**
* Loads a host certificate
*/
-bool load_host_cert(char *filename, cert_t *cert)
+cert_t* load_host_cert(char *filename)
{
char *path = concatenate_paths(HOST_CERT_PATH, filename);
- return load_cert(path, "host", X509_NONE, cert);
+ return load_cert(path, "host", X509_NONE);
}
/**
* Loads a CA certificate
*/
-bool load_ca_cert(char *filename, cert_t *cert)
+cert_t* load_ca_cert(char *filename)
{
char *path = concatenate_paths(CA_CERT_PATH, filename);
- return load_cert(path, "CA", X509_NONE, cert);
+ return load_cert(path, "CA", X509_NONE);
}
/**
- * establish equality of two certificates
+ * for each link pointing to the certificate increase the count by one
*/
-bool same_cert(const cert_t *a, const cert_t *b)
+void cert_share(cert_t *cert)
{
- return a->type == b->type && a->u.x509 == b->u.x509;
+ if (cert != NULL)
+ {
+ cert->count++;
+ }
}
-/**
- * for each link pointing to the certificate increase the count by one
+/* release of a certificate decreases the count by one
+ * the certificate is freed when the counter reaches zero
*/
-void share_cert(cert_t cert)
+void cert_release(cert_t *cert)
{
- switch (cert.type)
+ if (cert && --cert->count == 0)
{
- case CERT_PGP:
- share_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- share_x509cert(cert.u.x509);
- break;
- default:
- break;
+ cert_t **pp = &certs;
+ while (*pp != cert)
+ {
+ pp = &(*pp)->next;
+ }
+ *pp = cert->next;
+ cert_free(cert);
}
}
-/* release of a certificate decreases the count by one
- * the certificate is freed when the counter reaches zero
+/**
+ * List all PGP end certificates in a chained list
*/
-void release_cert(cert_t cert)
+void list_pgp_end_certs(bool utc)
{
- switch (cert.type)
+ cert_t *cert = certs;
+ time_t now = time(NULL);
+ bool first = TRUE;
+
+
+ while (cert != NULL)
{
- case CERT_PGP:
- release_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- release_x509cert(cert.u.x509);
- break;
- default:
- break;
+ certificate_t *certificate = cert->cert;
+
+ if (certificate->get_type(certificate) == CERT_GPG)
+ {
+ time_t created, until;
+ public_key_t *key;
+ identification_t *userid = certificate->get_subject(certificate);
+ pgp_certificate_t *pgp_cert = (pgp_certificate_t*)certificate;
+ chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
+
+ if (first)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of PGP End Entity Certificates:");
+ first = false;
+ }
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, " userid: '%Y'", userid);
+ whack_log(RC_COMMENT, " digest: %#B", &fingerprint);
+
+ /* list validity */
+ certificate->get_validity(certificate, &now, &created, &until);
+ whack_log(RC_COMMENT, " created: %T", &created, utc);
+ whack_log(RC_COMMENT, " until: %T %s%s", &until, utc,
+ check_expiry(until, CA_CERT_WARNING_INTERVAL, TRUE),
+ (until == TIME_32_BIT_SIGNED_MAX) ? " (expires never)":"");
+
+ key = certificate->get_public_key(certificate);
+ if (key)
+ {
+ chunk_t keyid;
+
+ 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(cert)? ", has private key" : "");
+ if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
+ {
+ whack_log(RC_COMMENT, " keyid: %#B", &keyid);
+ }
+ if (key->get_fingerprint(key, KEY_ID_PUBKEY_SHA1, &keyid))
+ {
+ whack_log(RC_COMMENT, " subjkey: %#B", &keyid);
+ }
+ }
+ }
+ cert = cert->next;
}
}
/**
+ * List all X.509 end certificates in a chained list
+ */
+void list_x509_end_certs(bool utc)
+{
+ list_x509cert_chain("End Entity", certs, X509_NONE, utc);
+}
+
+/**
* list all X.509 and OpenPGP end certificates
*/
-void list_certs(bool utc)
+void cert_list(bool utc)
{
list_x509_end_certs(utc);
list_pgp_end_certs(utc);
diff --git a/src/pluto/certs.h b/src/pluto/certs.h
index faf820dae..b2b11eb37 100644
--- a/src/pluto/certs.h
+++ b/src/pluto/certs.h
@@ -18,9 +18,12 @@
#define _CERTS_H
#include <credentials/keys/private_key.h>
+#include <credentials/certificates/certificate.h>
+#include <credentials/certificates/x509.h>
-#include "x509.h"
-#include "pgpcert.h"
+#include <freeswan.h>
+
+#include "defs.h"
/* path definitions for private keys, end certs,
* cacerts, attribute certs and crls
@@ -43,16 +46,16 @@
#define CRL_WARNING_INTERVAL 7 /* days */
#define ACERT_WARNING_INTERVAL 1 /* day */
-/* certificate access structure
- * currently X.509 and OpenPGP certificates are supported
- */
-typedef struct {
- u_char type;
- union {
- x509cert_t *x509;
- pgpcert_t *pgp;
- } u;
-} cert_t;
+/* access structure for a pluto certificate */
+
+typedef struct cert_t cert_t;
+
+struct cert_t {
+ certificate_t *cert;
+ cert_t *next;
+ int count;
+ bool smartcard;
+};
/* used for initialization */
extern const cert_t cert_empty;
@@ -62,18 +65,16 @@ extern const cert_t cert_empty;
*/
extern bool no_cr_send;
-extern public_key_t* cert_get_public_key(const cert_t cert);
-extern chunk_t cert_get_encoding(cert_t cert);
extern private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
key_type_t type);
-extern bool load_cert(char *filename, const char *label, x509_flag_t flags,
- cert_t *cert);
-extern bool load_host_cert(char *filename, cert_t *cert);
-extern bool load_ca_cert(char *filename, cert_t *cert);
-extern bool same_cert(const cert_t *a, const cert_t *b);
-extern void share_cert(cert_t cert);
-extern void release_cert(cert_t cert);
-extern void list_certs(bool utc);
+extern cert_t* load_cert(char *filename, const char *label, x509_flag_t flags);
+extern cert_t* load_host_cert(char *filename);
+extern cert_t* load_ca_cert(char *filename);
+extern cert_t* cert_add(cert_t *cert);
+extern void cert_free(cert_t *cert);
+extern void cert_share(cert_t *cert);
+extern void cert_release(cert_t *cert);
+extern void cert_list(bool utc);
#endif /* _CERTS_H */
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index 45d88a350..e571f6a13 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -39,7 +39,6 @@
#include "x509.h"
#include "ca.h"
#include "crl.h"
-#include "pgpcert.h"
#include "certs.h"
#include "ac.h"
#include "smartcard.h"
@@ -398,9 +397,9 @@ void delete_connection(connection_t *c, bool relations)
gw_delref(&c->gw_info);
lock_certs_and_keys("delete_connection");
- release_cert(c->spd.this.cert);
+ cert_release(c->spd.this.cert);
scx_release(c->spd.this.sc);
- release_cert(c->spd.that.cert);
+ cert_release(c->spd.that.cert);
scx_release(c->spd.that.sc);
unlock_certs_and_keys("delete_connection");
@@ -736,7 +735,7 @@ static void unshare_connection_strings(connection_t *c)
c->spd.this.pool = clone_str(c->spd.this.pool);
c->spd.this.updown = clone_str(c->spd.this.updown);
scx_share(c->spd.this.sc);
- share_cert(c->spd.this.cert);
+ cert_share(c->spd.this.cert);
if (c->spd.this.ca)
{
c->spd.this.ca = c->spd.this.ca->clone(c->spd.this.ca);
@@ -749,7 +748,7 @@ static void unshare_connection_strings(connection_t *c)
c->spd.that.pool = clone_str(c->spd.that.pool);
c->spd.that.updown = clone_str(c->spd.that.updown);
scx_share(c->spd.that.sc);
- share_cert(c->spd.that.cert);
+ cert_share(c->spd.that.cert);
if (c->spd.that.ca)
{
c->spd.that.ca = c->spd.that.ca->clone(c->spd.that.ca);
@@ -767,13 +766,12 @@ static void unshare_connection_strings(connection_t *c)
static void load_end_certificate(char *filename, struct end *dst)
{
time_t valid_until;
- cert_t cert;
- bool valid_cert = FALSE;
+ cert_t *cert = NULL;
+ certificate_t *certificate;
bool cached_cert = FALSE;
-
+
/* initialize end certificate */
- dst->cert.type = CERT_NONE;
- dst->cert.u.x509 = NULL;
+ dst->cert = NULL;
/* initialize smartcard info record */
dst->sc = NULL;
@@ -783,87 +781,73 @@ static void load_end_certificate(char *filename, struct end *dst)
if (scx_on_smartcard(filename))
{
/* load cert from smartcard */
- valid_cert = scx_load_cert(filename, &dst->sc, &cert, &cached_cert);
+ cert = scx_load_cert(filename, &dst->sc, &cached_cert);
}
else
{
/* load cert from file */
- valid_cert = load_host_cert(filename, &cert);
+ cert = load_host_cert(filename);
}
}
- if (valid_cert)
+ if (cert)
{
- switch (cert.type)
- {
- case CERT_PGP:
- dst->id = select_pgpcert_id(cert.u.pgp, dst->id);
+ certificate = cert->cert;
- if (cached_cert)
- {
- dst->cert = cert;
- }
- else
- {
- valid_until = cert.u.pgp->until;
- add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL);
- dst->cert.type = cert.type;
- dst->cert.u.pgp = add_pgpcert(cert.u.pgp);
- }
- break;
- case CERT_X509_SIGNATURE:
- dst->id = select_x509cert_id(cert.u.x509, dst->id);
+ if (dst->id->get_type(dst->id) == ID_ANY ||
+ !certificate->has_subject(certificate, dst->id))
+ {
+ plog( " id '%Y' not confirmed by certificate, defaulting to '%Y'",
+ dst->id, certificate->get_subject(certificate));
+ dst->id->destroy(dst->id);
+ dst->id = certificate->get_subject(certificate);
+ dst->id = dst->id->clone(dst->id);
+ }
- if (cached_cert)
- {
- dst->cert = cert;
- }
- else
+ if (cached_cert)
+ {
+ dst->cert = cert;
+ }
+ else
+ {
+ if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
{
- certificate_t *certificate = cert.u.x509->cert;
-
- if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
- {
- free_x509cert(cert.u.x509);
- break;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
- add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL);
- dst->cert.type = cert.type;
- dst->cert.u.x509 = add_x509cert(cert.u.x509);
+ cert_free(cert);
+ return;
}
+ DBG(DBG_CONTROL,
+ DBG_log("certificate is valid")
+ )
+ add_public_key_from_cert(cert, valid_until, DAL_LOCAL);
+ dst->cert = cert_add(cert);
+ }
+ certificate = dst->cert->cert;
- /* if no CA is defined, use issuer as default */
- if (dst->ca == NULL)
- {
- certificate_t *certificate = dst->cert.u.x509->cert;
- identification_t *issuer = certificate->get_issuer(certificate);
+ /* if no CA is defined, use issuer as default */
+ if (dst->ca == NULL && certificate->get_type(certificate) == CERT_X509)
+ {
+ identification_t *issuer;
- dst->ca = issuer->clone(issuer);
- }
- break;
- default:
- break;
+ issuer = certificate->get_issuer(certificate);
+ dst->ca = issuer->clone(issuer);
}
/* cache the certificate that was last retrieved from the smartcard */
if (dst->sc)
{
- if (!same_cert(&dst->sc->last_cert, &dst->cert))
+ if (!certificate->equals(certificate, dst->sc->last_cert->cert))
{
lock_certs_and_keys("load_end_certificates");
- release_cert(dst->sc->last_cert);
+ cert_release(dst->sc->last_cert);
dst->sc->last_cert = dst->cert;
- share_cert(dst->cert);
+ cert_share(dst->cert);
unlock_certs_and_keys("load_end_certificates");
}
time(&dst->sc->last_load);
}
}
scx_share(dst->sc);
- share_cert(dst->cert);
+ cert_share(dst->cert);
}
static bool extract_end(struct end *dst, const whack_end_t *src,
diff --git a/src/pluto/connections.h b/src/pluto/connections.h
index 5a1281210..ee2e00da6 100644
--- a/src/pluto/connections.h
+++ b/src/pluto/connections.h
@@ -147,7 +147,7 @@ struct end {
u_int16_t host_port; /* host order */
u_int16_t port; /* host order */
u_int8_t protocol;
- cert_t cert; /* end certificate */
+ cert_t *cert; /* end certificate */
identification_t *ca; /* CA distinguished name */
ietf_attributes_t *groups; /* access control groups */
smartcard_t *sc; /* smartcard reader and key info */
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
index f80c7955b..84fe77554 100644
--- a/src/pluto/crl.c
+++ b/src/pluto/crl.c
@@ -113,7 +113,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
crl_t *crl = (crl_t*)cert_crl;
identification_t *issuer = cert_crl->get_issuer(cert_crl);
chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
- x509cert_t *issuer_cert;
+ cert_t *issuer_cert;
x509crl_t *oldcrl;
time_t now, nextUpdate;
bool valid_sig;
@@ -340,8 +340,7 @@ void check_crls(void)
/*
* verify if a cert hasn't been revoked by a crl
*/
-cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
- time_t *revocationDate,
+cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
crl_reason_t *revocationReason)
{
certificate_t *certificate = cert->cert;
@@ -402,7 +401,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
certificate_t *cert_crl = x509crl->crl;
crl_t *crl = (crl_t*)cert_crl;
chunk_t authKeyID = crl->get_authKeyIdentifier(crl);
- x509cert_t *issuer_cert;
+ cert_t *issuer_cert;
bool trusted, valid;
DBG(DBG_CONTROL,
diff --git a/src/pluto/crl.h b/src/pluto/crl.h
index bac0717a0..43bafe145 100644
--- a/src/pluto/crl.h
+++ b/src/pluto/crl.h
@@ -26,7 +26,6 @@ struct x509crl {
certificate_t *crl;
x509crl_t *next;
linked_list_t *distributionPoints;
- chunk_t signature;
};
/* apply a strict CRL policy
@@ -46,7 +45,7 @@ extern long crl_check_interval;
extern void load_crls(void);
extern void check_crls(void);
extern bool insert_crl(x509crl_t *crl, char *crl_uri, bool cache_crl);
-extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
+extern cert_status_t verify_by_crl(cert_t *cert, time_t *until,
time_t *revocationDate,
crl_reason_t *revocationReason);
extern void list_crls(bool utc, bool strict);
diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c
index 3528a62ef..7521dd33b 100644
--- a/src/pluto/ike_alg.c
+++ b/src/pluto/ike_alg.c
@@ -199,9 +199,10 @@ struct db_context *ike_alg_db_new(connection_t *c, lset_t policy)
key_type_t key_type = KEY_ANY;
- if (c->spd.this.cert.type != CERT_NONE)
+ if (c->spd.this.cert)
{
- public_key_t *key = cert_get_public_key(c->spd.this.cert);
+ certificate_t *certificate = c->spd.this.cert->cert;
+ public_key_t *key = certificate->get_public_key(certificate);
if (key == NULL)
{
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index b7f5fcea1..1f8917d79 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -905,7 +905,6 @@ main_outI1(int whack_sock, connection_t *c, struct state *predecessor
struct state *st = new_state();
pb_stream reply; /* not actually a reply, but you know what I mean */
pb_stream rbody;
-
int vids_to_send = 0;
/* set up new state */
@@ -925,7 +924,8 @@ main_outI1(int whack_sock, connection_t *c, struct state *predecessor
{
vids_to_send++;
}
- if (c->spd.this.cert.type == CERT_PGP)
+ if (c->spd.this.cert &&
+ c->spd.this.cert->cert->get_type(c->spd.this.cert->cert) == CERT_GPG)
{
vids_to_send++;
}
@@ -1022,7 +1022,8 @@ main_outI1(int whack_sock, connection_t *c, struct state *predecessor
/* if we have an OpenPGP certificate we assume an
* OpenPGP peer and have to send the Vendor ID
*/
- if (c->spd.this.cert.type == CERT_PGP)
+ if (c->spd.this.cert &&
+ c->spd.this.cert->cert->get_type(c->spd.this.cert->cert) == CERT_GPG)
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
, &rbody, VID_OPENPGP))
@@ -2166,12 +2167,12 @@ static void decode_cert(struct msg_digest *md)
blob.len = pbs_left(&p->pbs);
if (cert->isacert_type == CERT_X509_SIGNATURE)
{
- x509cert_t x509cert = empty_x509cert;
+ cert_t x509cert = cert_empty;
x509cert.cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, blob,
- BUILD_END);
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, blob,
+ BUILD_END);
if (x509cert.cert)
{
if (verify_x509cert(&x509cert, strict_crl_policy, &valid_until))
@@ -2179,7 +2180,7 @@ static void decode_cert(struct msg_digest *md)
DBG(DBG_PARSING,
DBG_log("Public key validated")
)
- add_x509_public_key(&x509cert, valid_until, DAL_SIGNED);
+ add_public_key_from_cert(&x509cert, valid_until, DAL_SIGNED);
}
else
{
@@ -3518,7 +3519,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
connection_t *c = st->st_connection;
certpolicy_t cert_policy = c->spd.this.sendcert;
- cert_t mycert = c->spd.this.cert;
+ cert_t *mycert = c->spd.this.cert;
bool requested, send_cert, send_cr;
bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
@@ -3548,8 +3549,9 @@ stf_status main_inR2_outI3(struct msg_digest *md)
* or are requested to send it
*/
requested = cert_policy == CERT_SEND_IF_ASKED && c->got_certrequest;
- send_cert = pubkey_auth && mycert.type != CERT_NONE
- && (cert_policy == CERT_ALWAYS_SEND || requested);
+ send_cert = pubkey_auth && mycert &&
+ mycert->cert->get_type(mycert->cert) == CERT_X509 &&
+ (cert_policy == CERT_ALWAYS_SEND || requested);
/* send certificate request if we don't have a preloaded RSA public key */
send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
@@ -3599,7 +3601,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
DBG(DBG_CONTROL,
DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
)
- if (mycert.type != CERT_NONE)
+ if (mycert && mycert->cert->get_type(mycert->cert) == CERT_X509)
{
const char *request_text = "";
@@ -3623,13 +3625,13 @@ stf_status main_inR2_outI3(struct msg_digest *md)
struct isakmp_cert cert_hd;
cert_hd.isacert_np = (send_cr)? ISAKMP_NEXT_CR : ISAKMP_NEXT_SIG;
- cert_hd.isacert_type = mycert.type;
+ cert_hd.isacert_type = CERT_X509_SIGNATURE;
if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
{
return STF_INTERNAL_ERROR;
}
- cert_encoding = cert_get_encoding(mycert);
+ cert_encoding = mycert->cert->get_encoding(mycert->cert);
success = out_chunk(cert_encoding, &cert_pbs, "CERT");
free(cert_encoding.ptr);
if (!success)
@@ -3645,7 +3647,7 @@ stf_status main_inR2_outI3(struct msg_digest *md)
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))
+ if (!build_and_ship_CR(CERT_X509_SIGNATURE, cr, &md->rbody, ISAKMP_NEXT_SIG))
{
return STF_INTERNAL_ERROR;
}
@@ -3971,7 +3973,7 @@ main_inI3_outR3_tail(struct msg_digest *md
u_int8_t auth_payload;
pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy;
- cert_t mycert;
+ cert_t *mycert;
bool pubkey_auth, send_cert, requested;
/* ID and HASH_I or SIG_I in
@@ -3996,7 +3998,8 @@ main_inI3_outR3_tail(struct msg_digest *md
requested = cert_policy == CERT_SEND_IF_ASKED
&& st->st_connection->got_certrequest;
pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
- send_cert = pubkey_auth && mycert.type != CERT_NONE &&
+ send_cert = pubkey_auth && mycert &&
+ mycert->cert->get_type(mycert->cert) == CERT_X509 &&
(cert_policy == CERT_ALWAYS_SEND || requested);
/*************** build output packet HDR*;IDir;HASH/SIG_R ***************/
@@ -4039,7 +4042,7 @@ main_inI3_outR3_tail(struct msg_digest *md
DBG(DBG_CONTROL,
DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
)
- if (mycert.type != CERT_NONE)
+ if (mycert && mycert->cert->get_type(mycert->cert) == CERT_X509)
{
const char *request_text = "";
@@ -4063,13 +4066,13 @@ main_inI3_outR3_tail(struct msg_digest *md
struct isakmp_cert cert_hd;
cert_hd.isacert_np = ISAKMP_NEXT_SIG;
- cert_hd.isacert_type = mycert.type;
+ cert_hd.isacert_type = CERT_X509_SIGNATURE;
if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
{
return STF_INTERNAL_ERROR;
}
- cert_encoding = cert_get_encoding(mycert);
+ cert_encoding = mycert->cert->get_encoding(mycert->cert);
success = out_chunk(cert_encoding, &cert_pbs, "CERT");
free(cert_encoding.ptr);
if (!success)
diff --git a/src/pluto/keys.c b/src/pluto/keys.c
index f054a6bd9..8cf28ace1 100644
--- a/src/pluto/keys.c
+++ b/src/pluto/keys.c
@@ -36,11 +36,11 @@
#include <library.h>
#include <asn1/asn1.h>
+#include <credentials/certificates/pgp_certificate.h>
#include "constants.h"
#include "defs.h"
#include "x509.h"
-#include "pgpcert.h"
#include "certs.h"
#include "smartcard.h"
#include "connections.h"
@@ -111,9 +111,11 @@ static const secret_t* get_secret(const connection_t *c,
identification_t *my_id, *his_id;
/* is there a certificate assigned to this connection? */
- if (kind == PPK_PUBKEY && c->spd.this.cert.type != CERT_NONE)
+ if (kind == PPK_PUBKEY && c->spd.this.cert)
{
- public_key_t *pub_key = cert_get_public_key(c->spd.this.cert);
+ certificate_t *certificate = c->spd.this.cert->cert;
+
+ public_key_t *pub_key = certificate->get_public_key(certificate);
for (s = secrets; s != NULL; s = s->next)
{
@@ -262,11 +264,11 @@ const chunk_t* get_preshared_secret(const connection_t *c)
/* check the existence of a private key matching a public key contained
* in an X.509 or OpenPGP certificate
*/
-bool has_private_key(cert_t cert)
+bool has_private_key(cert_t *cert)
{
secret_t *s;
bool has_key = FALSE;
- public_key_t *pub_key = cert_get_public_key(cert);
+ public_key_t *pub_key = cert->cert->get_public_key(cert->cert);
for (s = secrets; s != NULL; s = s->next)
{
@@ -284,7 +286,7 @@ bool has_private_key(cert_t cert)
/*
* get the matching private key belonging to a given X.509 certificate
*/
-private_key_t* get_x509_private_key(const x509cert_t *cert)
+private_key_t* get_x509_private_key(const cert_t *cert)
{
public_key_t *public_key = cert->cert->get_public_key(cert->cert);
private_key_t *private_key = NULL;
@@ -1272,80 +1274,86 @@ bool add_public_key(identification_t *id, enum dns_auth_level dns_auth_level,
return TRUE;
}
-/* extract id and public key from x.509 certificate and
- * insert it into a pubkeyrec
+/**
+ * Extract id and public key a certificate and insert it into a pubkeyrec
*/
-void add_x509_public_key(x509cert_t *cert , time_t until,
- enum dns_auth_level dns_auth_level)
+void add_public_key_from_cert(cert_t *cert , time_t until,
+ enum dns_auth_level dns_auth_level)
{
certificate_t *certificate = cert->cert;
- x509_t *x509 = (x509_t*)certificate;
identification_t *subject = certificate->get_subject(certificate);
- identification_t *issuer = certificate->get_issuer(certificate);
+ identification_t *issuer = NULL;
identification_t *id;
- chunk_t serialNumber = x509->get_serial(x509);
+ chunk_t serialNumber = chunk_empty;
pubkey_t *pk;
key_type_t pk_type;
- enumerator_t *enumerator;
/* ID type: ID_DER_ASN1_DN (X.509 subject field) */
pk = malloc_thing(pubkey_t);
zero(pk);
pk->public_key = certificate->get_public_key(certificate);
+ pk_type = pk->public_key->get_type(pk->public_key);
pk->id = subject->clone(subject);
pk->dns_auth_level = dns_auth_level;
pk->until_time = until;
- pk->issuer = issuer->clone(issuer);
- pk->serial = chunk_clone(serialNumber);
- pk_type = pk->public_key->get_type(pk->public_key);
+ if (certificate->get_type(certificate) == CERT_X509)
+ {
+ x509_t *x509 = (x509_t*)certificate;
+
+ issuer = certificate->get_issuer(certificate);
+ serialNumber = x509->get_serial(x509);
+ 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);
- /* insert all subjectAltNames */
- enumerator = x509->create_subjectAltName_enumerator(x509);
- while (enumerator->enumerate(enumerator, &id))
+ if (certificate->get_type(certificate) == CERT_X509)
{
- if (id->get_type(id) != ID_ANY)
+ x509_t *x509 = (x509_t*)certificate;
+ enumerator_t *enumerator;
+
+ /* insert all subjectAltNames from X.509 certificates */
+ enumerator = x509->create_subjectAltName_enumerator(x509);
+ while (enumerator->enumerate(enumerator, &id))
{
- pk = malloc_thing(pubkey_t);
- zero(pk);
- 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->clone(issuer);
- pk->serial = chunk_clone(serialNumber);
- delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
- install_public_key(pk, &pubkeys);
+ if (id->get_type(id) != ID_ANY)
+ {
+ pk = malloc_thing(pubkey_t);
+ zero(pk);
+ 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->clone(issuer);
+ pk->serial = chunk_clone(serialNumber);
+ delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
+ install_public_key(pk, &pubkeys);
+ }
}
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ pgp_certificate_t *pgp_cert = (pgp_certificate_t*)certificate;
+ chunk_t fingerprint = pgp_cert->get_fingerprint(pgp_cert);
+
+ /* add v3 or v4 PGP fingerprint */
+ pk = malloc_thing(pubkey_t);
+ zero(pk);
+ pk->id = identification_create_from_encoding(ID_KEY_ID, fingerprint);
+ pk->public_key = certificate->get_public_key(certificate);
+ pk->dns_auth_level = dns_auth_level;
+ pk->until_time = until;
+ delete_public_keys(pk->id, pk_type, pk->issuer, pk->serial);
+ install_public_key(pk, &pubkeys);
}
- enumerator->destroy(enumerator);
-}
-
-/* extract id and public key from OpenPGP certificate and
- * insert it into a pubkeyrec
- */
-void add_pgp_public_key(pgpcert_t *cert , time_t until,
- enum dns_auth_level dns_auth_level)
-{
- pubkey_t *pk;
- key_type_t pk_type;
-
- pk = malloc_thing(pubkey_t);
- zero(pk);
- pk->public_key = cert->public_key->get_ref(cert->public_key);
- 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, NULL, chunk_empty);
- install_public_key(pk, &pubkeys);
}
/* when a X.509 certificate gets revoked, all instances of
* the corresponding public key must be removed
*/
-void remove_x509_public_key(const x509cert_t *cert)
+void remove_x509_public_key(const cert_t *cert)
{
public_key_t *revoked_key = cert->cert->get_public_key(cert->cert);
pubkey_list_t *p, **pp;
diff --git a/src/pluto/keys.h b/src/pluto/keys.h
index 558a44f1b..d856c0009 100644
--- a/src/pluto/keys.h
+++ b/src/pluto/keys.h
@@ -45,7 +45,7 @@ struct connection;
extern const chunk_t *get_preshared_secret(const struct connection *c);
extern private_key_t *get_private_key(const struct connection *c);
-extern private_key_t *get_x509_private_key(const x509cert_t *cert);
+extern private_key_t *get_x509_private_key(const cert_t *cert);
/* public key machinery */
@@ -84,12 +84,10 @@ extern bool add_public_key(identification_t *id,
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);
-extern void add_pgp_public_key(pgpcert_t *cert, time_t until
- , enum dns_auth_level dns_auth_level);
-extern void remove_x509_public_key(const x509cert_t *cert);
+extern bool has_private_key(cert_t *cert);
+extern void add_public_key_from_cert(cert_t *cert, time_t until,
+ enum dns_auth_level dns_auth_level);
+extern void remove_x509_public_key(const cert_t *cert);
extern void list_public_keys(bool utc);
struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c
index 2674aa2ab..d1533cc5a 100644
--- a/src/pluto/ocsp.c
+++ b/src/pluto/ocsp.c
@@ -145,7 +145,7 @@ static chunk_t ocsp_default_uri;
static ocsp_location_t *ocsp_cache = NULL;
/* static temporary storage for ocsp requestor information */
-static x509cert_t *ocsp_requestor_cert = NULL;
+static cert_t *ocsp_requestor_cert = NULL;
static smartcard_t *ocsp_requestor_sc = NULL;
@@ -281,7 +281,7 @@ static const asn1Object_t singleResponseObjects[] = {
* Build an ocsp location from certificate information
* without unsharing its contents
*/
-static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
+static bool build_ocsp_location(const cert_t *cert, ocsp_location_t *location)
{
certificate_t *certificate = cert->cert;
identification_t *issuer = certificate->get_issuer(certificate);
@@ -329,7 +329,7 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio
if (authKeyID.ptr == NULL)
{
- x509cert_t *authcert = get_authcert(issuer, authKeyID, X509_CA);
+ cert_t *authcert = get_authcert(issuer, authKeyID, X509_CA);
if (authcert)
{
@@ -416,7 +416,7 @@ static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
/**
* Verify the ocsp status of a certificate
*/
-cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
+cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until,
time_t *revocationDate,
crl_reason_t *revocationReason)
{
@@ -646,7 +646,7 @@ void list_ocsp_cache(bool utc, bool strict)
static bool get_ocsp_requestor_cert(ocsp_location_t *location)
{
- x509cert_t *cert = NULL;
+ cert_t *cert = NULL;
/* initialize temporary static storage */
ocsp_requestor_cert = NULL;
@@ -962,7 +962,7 @@ chunk_t build_ocsp_request(ocsp_location_t *location)
static bool valid_ocsp_response(response_t *res)
{
int pathlen, pathlen_constraint;
- x509cert_t *authcert;
+ cert_t *authcert;
lock_authcert_list("valid_ocsp_response");
@@ -992,7 +992,7 @@ static bool valid_ocsp_response(response_t *res)
for (pathlen = -1; pathlen <= X509_MAX_PATH_LEN; pathlen++)
{
- x509cert_t *cert = authcert;
+ cert_t *cert = authcert;
certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate;
identification_t *subject = certificate->get_subject(certificate);
@@ -1133,10 +1133,10 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
break;
case BASIC_RESPONSE_CERTIFICATE:
{
- x509cert_t *cert = malloc_thing(x509cert_t);
+ cert_t *cert = malloc_thing(cert_t);
x509_t *x509;
- *cert = empty_x509cert;
+ *cert = cert_empty;
cert->cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, object,
@@ -1146,7 +1146,7 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
DBG(DBG_CONTROL | DBG_PARSING,
DBG_log("parsing of embedded ocsp certificate failed")
)
- free_x509cert(cert);
+ cert_free(cert);
break;
}
x509 = (x509_t*)cert->cert;
@@ -1161,7 +1161,7 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
DBG(DBG_CONTROL | DBG_PARSING,
DBG_log("embedded ocsp certificate rejected")
)
- free_x509cert(cert);
+ cert_free(cert);
}
}
break;
diff --git a/src/pluto/ocsp.h b/src/pluto/ocsp.h
index a3ba6c0a3..977cca3c8 100644
--- a/src/pluto/ocsp.h
+++ b/src/pluto/ocsp.h
@@ -69,11 +69,11 @@ extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc
extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info
, ocsp_location_t **chain, bool request);
extern void check_ocsp(void);
-extern cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until
+extern cert_status_t verify_by_ocsp(const cert_t *cert, time_t *until
, time_t *revocationTime, crl_reason_t *revocationReason);
extern bool ocsp_set_request_cert(char* path);
extern void ocsp_set_default_uri(char* uri);
-extern void ocsp_cache_add_cert(const x509cert_t* cert);
+extern void ocsp_cache_add_cert(const cert_t* cert);
extern chunk_t build_ocsp_request(ocsp_location_t* location);
extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
extern void list_ocsp_locations(ocsp_location_t *location, bool requests
diff --git a/src/pluto/pgpcert.c b/src/pluto/pgpcert.c
index 3e9831ef8..380186cfd 100644
--- a/src/pluto/pgpcert.c
+++ b/src/pluto/pgpcert.c
@@ -32,476 +32,4 @@
#include "whack.h"
#include "keys.h"
-typedef enum pgp_packet_tag_t pgp_packet_tag_t;
-
-/**
- * OpenPGP packet tags as defined in section 4.3 of RFC 4880
- */
-enum pgp_packet_tag_t {
- PGP_PKT_RESERVED = 0,
- PGP_PKT_PUBKEY_ENC_SESSION_KEY = 1,
- PGP_PKT_SIGNATURE = 2,
- PGP_PKT_SYMKEY_ENC_SESSION_KEY = 3,
- PGP_PKT_ONE_PASS_SIGNATURE_PKT = 4,
- PGP_PKT_SECRET_KEY = 5,
- PGP_PKT_PUBLIC_KEY = 6,
- PGP_PKT_SECRET_SUBKEY = 7,
- PGP_PKT_COMPRESSED_DATA = 8,
- PGP_PKT_SYMKEY_ENC_DATA = 9,
- PGP_PKT_MARKER = 10,
- PGP_PKT_LITERAL_DATA = 11,
- PGP_PKT_TRUST = 12,
- PGP_PKT_USER_ID = 13,
- PGP_PKT_PUBLIC_SUBKEY = 14,
- PGP_PKT_USER_ATTRIBUTE = 17,
- PGP_PKT_SYM_ENC_INT_PROT_DATA = 18,
- PGP_PKT_MOD_DETECT_CODE = 19
-};
-
-ENUM_BEGIN(pgp_packet_tag_names, PGP_PKT_RESERVED, PGP_PKT_PUBLIC_SUBKEY,
- "Reserved",
- "Public-Key Encrypted Session Key Packet",
- "Signature Packet",
- "Symmetric-Key Encrypted Session Key Packet",
- "One-Pass Signature Packet",
- "Secret Key Packet",
- "Public Key Packet",
- "Secret Subkey Packet",
- "Compressed Data Packet",
- "Symmetrically Encrypted Data Packet",
- "Marker Packet",
- "Literal Data Packet",
- "Trust Packet",
- "User ID Packet",
- "Public Subkey Packet"
-);
-ENUM_NEXT(pgp_packet_tag_names, PGP_PKT_USER_ATTRIBUTE, PGP_PKT_MOD_DETECT_CODE, PGP_PKT_PUBLIC_SUBKEY,
- "User Attribute Packet",
- "Sym. Encrypted and Integrity Protected Data Packet",
- "Modification Detection Code Packet"
-);
-ENUM_END(pgp_packet_tag_names, PGP_PKT_MOD_DETECT_CODE);
-
-/**
- * Chained list of OpenPGP end certificates
- */
-static pgpcert_t *pgpcerts = NULL;
-
-/**
- * Size of PGP Key ID
- */
-#define PGP_KEYID_SIZE 8
-
-const pgpcert_t pgpcert_empty = {
- NULL , /* next */
- 0 , /* version */
- 0 , /* count */
- { NULL, 0 }, /* certificate */
- 0 , /* created */
- 0 , /* until */
- NULL , /* public key */
- NULL /* fingerprint */
-};
-
-#define PGP_INVALID_LENGTH 0xffffffff
-
-/**
- * Returns the length of an OpenPGP (RFC 4880) packet
- * The blob pointer is advanced past the length field.
- */
-static size_t pgp_length(chunk_t *blob, size_t len)
-{
- size_t size = 0;
-
- if (len > blob->len)
- {
- return PGP_INVALID_LENGTH;
- }
- blob->len -= len;
-
- while (len-- > 0)
- {
- size = 256*size + *blob->ptr++;
- }
- return size;
-}
-
-/**
- * Extracts the length of a PGP packet
- */
-static size_t pgp_old_packet_length(chunk_t *blob)
-{
- /* bits 0 and 1 define the packet length type */
- int len_type = 0x03 & *blob->ptr++;
-
- blob->len--;
-
- /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */
- return pgp_length(blob, (len_type == 0)? 1: len_type << 1);
-}
-
-/**
- * Extracts PGP packet version (V3 or V4)
- */
-static u_char pgp_version(chunk_t *blob)
-{
- u_char version = *blob->ptr++;
- blob->len--;
- DBG(DBG_PARSING,
- DBG_log("L3 - version:");
- DBG_log(" V%d", version)
- )
- return version;
-}
-
-/**
- * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 4880
- */
-static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
-{
- time_t created;
- chunk_t keyid;
- u_char sig_type;
- u_char version = pgp_version(packet);
-
- /* we parse only V3 signature packets */
- if (version != 3)
- {
- return TRUE;
- }
-
- /* size byte must have the value 5 */
- if (pgp_length(packet, 1) != 5)
- {
- plog(" size must be 5");
- return FALSE;
- }
-
- /* signature type - 1 byte */
- sig_type = (u_char)pgp_length(packet, 1);
- DBG(DBG_PARSING,
- DBG_log("L3 - signature type: 0x%2x", sig_type)
- )
-
- /* creation date - 4 bytes */
- created = (time_t)pgp_length(packet, 4);
- DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %T", &cert->created, TRUE)
- )
-
- /* key ID of signer - 8 bytes */
- keyid.ptr = packet->ptr;
- keyid.len = PGP_KEYID_SIZE;
- DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
-
- return TRUE;
-}
-
-/**
- * Parses the version and validity of an OpenPGP public key packet
- */
-static bool parse_pgp_pubkey_version_validity(chunk_t *packet, pgpcert_t *cert)
-{
- cert->version = pgp_version(packet);
-
- if (cert->version < 3 || cert->version > 4)
- {
- plog("OpenPGP packet version V%d not supported", cert->version);
- return FALSE;
- }
-
- /* creation date - 4 bytes */
- cert->created = (time_t)pgp_length(packet, 4);
- DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %T", &cert->created, TRUE)
- )
-
- if (cert->version == 3)
- {
- /* validity in days - 2 bytes */
- cert->until = (time_t)pgp_length(packet, 2);
-
- /* validity of 0 days means that the key never expires */
- if (cert->until > 0)
- {
- cert->until = cert->created + 24*3600*cert->until;
- }
- DBG(DBG_PARSING,
- DBG_log("L3 - until:");
- DBG_log(" %T", &cert->until, TRUE);
- )
- }
- return TRUE;
-}
-
-/**
- * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 4880
- */
-static bool parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
-{
- chunk_t pubkey_packet = *packet;
-
- if (!parse_pgp_pubkey_version_validity(packet, cert))
- {
- return FALSE;
- }
-
- cert->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
- BUILD_BLOB_PGP, *packet, BUILD_END);
- if (cert->public_key == NULL)
- {
- return FALSE;
- }
-
- /* compute V4 or V3 fingerprint according to section 12.2 of RFC 4880 */
- if (cert->version == 4)
- {
- chunk_t pubkey_packet_header = chunk_from_chars(
- 0x99, pubkey_packet.len / 256, pubkey_packet.len % 256
- );
- chunk_t hash;
- hasher_t *hasher;
-
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (hasher == NULL)
- {
- plog("no SHA-1 hasher available");
- return FALSE;
- }
- hasher->allocate_hash(hasher, pubkey_packet_header, NULL);
- hasher->allocate_hash(hasher, pubkey_packet, &hash);
- hasher->destroy(hasher);
- cert->fingerprint = identification_create_from_encoding(ID_KEY_ID, hash);
- free(hash.ptr);
- }
- else
- {
- chunk_t fp;
-
- /* V3 fingerprint is computed by public_key_t class */
- if (!cert->public_key->get_fingerprint(cert->public_key, KEY_ID_PGPV3,
- &fp))
- {
- return FALSE;
- }
- cert->fingerprint = identification_create_from_encoding(ID_KEY_ID, fp);
- }
- return TRUE;
-}
-
-bool parse_pgp(chunk_t blob, pgpcert_t *cert)
-{
- DBG(DBG_PARSING,
- DBG_log("L0 - PGP file:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", blob);
-
- if (cert == NULL)
- {
- /* should not occur, nothing to parse */
- return FALSE;
- }
-
- /* parse a PGP certificate file */
- cert->certificate = blob;
-
- while (blob.len > 0)
- {
- chunk_t packet = chunk_empty;
- u_char packet_tag = *blob.ptr;
-
- DBG(DBG_PARSING,
- DBG_log("L1 - PGP packet: tag= 0x%2x", packet_tag)
- )
-
- /* bit 7 must be set */
- if (!(packet_tag & 0x80))
- {
- plog(" incorrect Packet Tag");
- return FALSE;
- }
-
- /* bit 6 set defines new packet format */
- if (packet_tag & 0x40)
- {
- plog(" new PGP packet format not supported");
- return FALSE;
- }
- else
- {
- int packet_type = (packet_tag & 0x3C) >> 2;
-
- packet.len = pgp_old_packet_length(&blob);
- packet.ptr = blob.ptr;
- blob.ptr += packet.len;
- blob.len -= packet.len;
- DBG(DBG_PARSING,
- DBG_log(" %N (%d), old format, %u bytes",
- pgp_packet_tag_names, packet_type,
- packet_type, packet.len);
- DBG_log("L2 - body:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", packet);
-
- /* parse a PGP certificate */
- switch (packet_type)
- {
- case PGP_PKT_PUBLIC_KEY:
- if (!parse_pgp_pubkey_packet(&packet, cert))
- {
- return FALSE;
- }
- break;
- case PGP_PKT_SIGNATURE:
- if (!parse_pgp_signature_packet(&packet, cert))
- {
- return FALSE;
- }
- break;
- case PGP_PKT_USER_ID:
- DBG(DBG_PARSING,
- DBG_log("L3 - user ID:");
- DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
- )
- break;
- default:
- break;
- }
- }
- }
- return TRUE;
-}
-
-/**
- * Compare two OpenPGP certificates
- */
-static bool same_pgpcert(pgpcert_t *a, pgpcert_t *b)
-{
- return a->certificate.len == b->certificate.len &&
- memeq(a->certificate.ptr, b->certificate.ptr, b->certificate.len);
-}
-
-/**
- * For each link pointing to the certificate increase the count by one
- */
-void share_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL)
- {
- cert->count++;
- }
-}
-
-/**
- * Select the OpenPGP keyid as ID
- */
-identification_t* select_pgpcert_id(pgpcert_t *cert, identification_t *id)
-{
- id->destroy(id);
-
- return cert->fingerprint->clone(cert->fingerprint);
-}
-
-/**
- * Add an OpenPGP user/host certificate to the chained list
- */
-pgpcert_t* add_pgpcert(pgpcert_t *cert)
-{
- pgpcert_t *c = pgpcerts;
-
- while (c != NULL)
- {
- if (same_pgpcert(c, cert)) /* already in chain, free cert */
- {
- free_pgpcert(cert);
- return c;
- }
- c = c->next;
- }
-
- /* insert new cert at the root of the chain */
- cert->next = pgpcerts;
- pgpcerts = cert;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" pgp cert inserted")
- )
- return cert;
-}
-
-/**
- * Release of a certificate decreases the count by one.
- * The certificate is freed when the counter reaches zero
- */
-void release_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL && --cert->count == 0)
- {
- pgpcert_t **pp = &pgpcerts;
- while (*pp != cert)
- {
- pp = &(*pp)->next;
- }
- *pp = cert->next;
- free_pgpcert(cert);
- }
-}
-
-/**
- * Free a PGP certificate
- */
-void free_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL)
- {
- DESTROY_IF(cert->public_key);
- DESTROY_IF(cert->fingerprint);
- free(cert->certificate.ptr);
- free(cert);
- }
-}
-
-/**
- * List all PGP end certificates in a chained list
- */
-void list_pgp_end_certs(bool utc)
-{
- pgpcert_t *cert = pgpcerts;
- time_t now;
-
- /* determine the current time */
- time(&now);
-
- if (cert != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of PGP End Entity Certificates:");
- }
-
- while (cert != NULL)
- {
- public_key_t *key = cert->public_key;
- chunk_t keyid;
- cert_t c;
-
- c.type = CERT_PGP;
- 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,
- check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
- 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);
- }
- cert = cert->next;
- }
-}
diff --git a/src/pluto/pgpcert.h b/src/pluto/pgpcert.h
index 27c1605cf..fa589829f 100644
--- a/src/pluto/pgpcert.h
+++ b/src/pluto/pgpcert.h
@@ -17,40 +17,6 @@
#ifndef _PGPCERT_H
#define _PGPCERT_H
-#include <utils/identification.h>
-#include <crypto/hashers/hasher.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/keys/public_key.h>
-
-/*
- * Length of PGP V3 fingerprint
- */
-#define PGP_FINGERPRINT_SIZE HASH_SIZE_MD5
-
-typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
-
-/* access structure for an OpenPGP certificate */
-
-typedef struct pgpcert pgpcert_t;
-
-struct pgpcert {
- pgpcert_t *next;
- int version;
- int count;
- chunk_t certificate;
- time_t created;
- time_t until;
- public_key_t *public_key;
- identification_t *fingerprint;
-};
-
-extern const pgpcert_t pgpcert_empty;
-extern bool parse_pgp(chunk_t blob, pgpcert_t *cert);
-extern void share_pgpcert(pgpcert_t *cert);
-extern identification_t* select_pgpcert_id(pgpcert_t *cert, identification_t *id);
-extern pgpcert_t* add_pgpcert(pgpcert_t *cert);
extern void list_pgp_end_certs(bool utc);
-extern void release_pgpcert(pgpcert_t *cert);
-extern void free_pgpcert(pgpcert_t *cert);
#endif /* _PGPCERT_H */
diff --git a/src/pluto/rcv_whack.c b/src/pluto/rcv_whack.c
index 79e63d27a..826a1aa6e 100644
--- a/src/pluto/rcv_whack.c
+++ b/src/pluto/rcv_whack.c
@@ -476,7 +476,7 @@ void whack_handle(int whackctlfd)
if (msg.whack_list & LIST_CERTS)
{
- list_certs(msg.whack_utc);
+ cert_list(msg.whack_utc);
}
if (msg.whack_list & LIST_CACERTS)
diff --git a/src/pluto/smartcard.c b/src/pluto/smartcard.c
index 1c96615bc..f1a3932a6 100644
--- a/src/pluto/smartcard.c
+++ b/src/pluto/smartcard.c
@@ -59,21 +59,21 @@ static smartcard_t *smartcards = NULL;
static int sc_number = 0;
const smartcard_t empty_sc = {
- NULL , /* next */
- 0 , /* last_load */
- { CERT_NONE, {NULL} }, /* last_cert */
- 0 , /* count */
- 0 , /* number */
- 999999 , /* slot */
- NULL , /* id */
- NULL , /* label */
- { NULL, 0 } , /* pin */
- FALSE , /* pinpad */
- FALSE , /* valid */
- FALSE , /* session_opened */
- FALSE , /* logged_in */
- TRUE , /* any_slot */
- 0L , /* session */
+ NULL , /* next */
+ 0 , /* last_load */
+ NULL , /* last_cert */
+ 0 , /* count */
+ 0 , /* number */
+ 999999 , /* slot */
+ NULL , /* id */
+ NULL , /* label */
+ { NULL, 0 } , /* pin */
+ FALSE , /* pinpad */
+ FALSE , /* valid */
+ FALSE , /* session_opened */
+ FALSE , /* logged_in */
+ TRUE , /* any_slot */
+ 0L , /* session */
};
#ifdef SMARTCARD /* compile with smartcard support */
@@ -437,14 +437,13 @@ failed: scx_unload_pkcs11_module(mod);
/*
* retrieve a certificate object
*/
-static bool scx_find_cert_object(CK_SESSION_HANDLE session,
- CK_OBJECT_HANDLE object,
- smartcard_t *sc, cert_t *cert)
+static cert_t* scx_find_cert_object(CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, smartcard_t *sc)
{
size_t hex_len, label_len;
u_char *hex_id = NULL;
+ cert_t *cert;
chunk_t blob;
- x509cert_t *x509cert;
CK_ATTRIBUTE attr[] = {
{ CKA_ID, NULL_PTR, 0L },
@@ -452,16 +451,13 @@ static bool scx_find_cert_object(CK_SESSION_HANDLE session,
{ CKA_VALUE, NULL_PTR, 0L }
};
- /* initialize the return argument */
- *cert = cert_empty;
-
/* get the length of the attributes first */
CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
if (rv != CKR_OK)
{
plog("couldn't read the attribute sizes: %s"
, enum_show(&pkcs11_return_names, rv));
- return FALSE;
+ return NULL;
}
free(sc->label);
@@ -486,7 +482,7 @@ static bool scx_find_cert_object(CK_SESSION_HANDLE session,
free(hex_id);
free(sc->label);
free(blob.ptr);
- return FALSE;
+ return NULL;
}
free(sc->id);
@@ -500,22 +496,23 @@ static bool scx_find_cert_object(CK_SESSION_HANDLE session,
sc->label[label_len] = '\0';
/* parse the retrieved cert */
- x509cert = malloc_thing(x509cert_t);
- *x509cert = empty_x509cert;
- x509cert->smartcard = TRUE;
- x509cert->cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, blob,
- BUILD_END);
- if (x509cert->cert)
- {
- cert->type = CERT_X509_SIGNATURE;
- cert->u.x509 = x509cert;
- return TRUE;
+
+ /* initialize the return argument */
+ cert = malloc_thing(cert_t);
+ *cert = cert_empty;
+ cert->smartcard = TRUE;
+ cert->cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, blob,
+ BUILD_END);
+ if (cert->cert)
+ {
+ return cert;
}
+
plog("failed to load cert from smartcard, error in X.509 certificate");
- free_x509cert(x509cert);
- return FALSE;
+ cert_free(cert);
+ return NULL;
}
@@ -542,7 +539,7 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
CK_ULONG obj_count = 0;
time_t valid_until;
smartcard_t *sc;
- x509cert_t *cert;
+ certificate_t *certificate;
x509_t *x509;
rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
@@ -562,8 +559,8 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
*sc = empty_sc;
sc->any_slot = FALSE;
sc->slot = slot;
-
- if (!scx_find_cert_object(session, object, sc, &sc->last_cert))
+ sc->last_cert = scx_find_cert_object(session, object, sc);
+ if (sc->last_cert == NULL)
{
scx_free(sc);
continue;
@@ -574,10 +571,9 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
)
/* check validity of certificate */
- cert = sc->last_cert.u.x509;
- if (!cert->cert->get_validity(cert->cert, NULL, NULL, &valid_until))
+ certificate = sc->last_cert->cert;
+ if (!certificate->get_validity(certificate, NULL, NULL, &valid_until))
{
- free_x509cert(cert);
scx_free(sc);
continue;
}
@@ -586,20 +582,20 @@ static void scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
)
sc = scx_add(sc);
- x509 = (x509_t*)cert->cert;
+ x509 = (x509_t*)certificate;
/* put end entity and ca certificates into different chains */
if (x509->get_flags(x509) & X509_CA)
{
- sc->last_cert.u.x509 = add_authcert(cert, X509_CA);
+ sc->last_cert = add_authcert(sc->last_cert, X509_CA);
}
else
{
- add_x509_public_key(cert, valid_until, DAL_LOCAL);
- sc->last_cert.u.x509 = add_x509cert(cert);
+ add_public_key_from_cert(sc->last_cert, valid_until, DAL_LOCAL);
+ sc->last_cert = cert_add(sc->last_cert);
}
- share_cert(sc->last_cert);
+ cert_share(sc->last_cert);
time(&sc->last_load);
}
@@ -1070,67 +1066,66 @@ void scx_release_context(smartcard_t *sc)
/*
* Load host certificate from smartcard
*/
-bool scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert,
- bool *cached)
+cert_t* scx_load_cert(const char *filename, smartcard_t **scp, bool *cached)
{
#ifdef SMARTCARD /* compile with smartcard support */
- CK_OBJECT_HANDLE object;
-
const char *number_slot_id = filename + strlen(SCX_TOKEN);
-
- smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
+ CK_OBJECT_HANDLE object;
+ smartcard_t *sc;
+ cert_t *cert = NULL;
/* return the smartcard object */
- *scp = sc;
+ *scp = sc = scx_add(scx_parse_number_slot_id(number_slot_id));
/* is there a cached smartcard certificate? */
- *cached = sc->last_cert.type != CERT_NONE
- && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
+ *cached = sc->last_cert &&
+ (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
if (*cached)
{
- *cert = sc->last_cert;
plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
, sc->number
, scx_print_slot(sc, "")
, sc->id
, sc->label);
- return TRUE;
+ return sc->last_cert;
}
if (!scx_establish_context(sc))
{
scx_release_context(sc);
- return FALSE;
+ return NULL;
}
/* find the certificate object */
if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
{
scx_release_context(sc);
- return FALSE;
+ return NULL;
}
/* retrieve the certificate object */
- if (!scx_find_cert_object(sc->session, object, sc, cert))
+ cert = scx_find_cert_object(sc->session, object, sc);
+ if (cert == NULL)
{
scx_release_context(sc);
- return FALSE;
+ return NULL;
}
if (!pkcs11_keep_state)
+ {
scx_release_context(sc);
-
+ }
plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
, sc->number
, scx_print_slot(sc, "")
, sc->id
, sc->label);
- return TRUE;
+ return cert;
#else
plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
- return FALSE;
+ return NULL;
#endif
}
@@ -1793,6 +1788,7 @@ void scx_free(smartcard_t *sc)
if (sc != NULL)
{
scx_release_context(sc);
+ cert_release(sc->last_cert);
free(sc->id);
free(sc->label);
scx_free_pin(&sc->pin);
@@ -1811,7 +1807,6 @@ void scx_release(smartcard_t *sc)
while (*pp != sc)
pp = &(*pp)->next;
*pp = sc->next;
- release_cert(sc->last_cert);
scx_free(sc);
}
}
@@ -1875,14 +1870,16 @@ smartcard_t* scx_add(smartcard_t *smartcard)
/*
* get the smartcard that belongs to an X.509 certificate
*/
-smartcard_t* scx_get(x509cert_t *cert)
+smartcard_t* scx_get(cert_t *cert)
{
smartcard_t *sc = smartcards;
while (sc != NULL)
{
- if (sc->last_cert.u.x509 == cert)
+ if (sc->last_cert == cert)
+ {
return sc;
+ }
sc = sc->next;
}
return NULL;
@@ -1929,9 +1926,9 @@ void scx_list(bool utc)
whack_log(RC_COMMENT, " id: %s", sc->id);
if (sc->label != NULL)
whack_log(RC_COMMENT, " label: '%s'", sc->label);
- if (sc->last_cert.type == CERT_X509_SIGNATURE)
+ if (sc->last_cert)
{
- certificate_t *certificate = sc->last_cert.u.x509->cert;
+ certificate_t *certificate = sc->last_cert->cert;
whack_log(RC_COMMENT, " subject: '%Y'",
certificate->get_subject(certificate));
diff --git a/src/pluto/smartcard.h b/src/pluto/smartcard.h
index 60a0fccfc..7a2229794 100644
--- a/src/pluto/smartcard.h
+++ b/src/pluto/smartcard.h
@@ -42,7 +42,7 @@ typedef struct smartcard smartcard_t;
struct smartcard {
smartcard_t *next;
time_t last_load;
- cert_t last_cert;
+ cert_t *last_cert;
int count;
int number;
unsigned long slot;
@@ -75,8 +75,7 @@ extern void scx_finalize(void);
extern bool scx_establish_context(smartcard_t *sc);
extern bool scx_login(smartcard_t *sc);
extern bool scx_on_smartcard(const char *filename);
-extern bool scx_load_cert(const char *filename, smartcard_t **scp
- , cert_t *cert, bool *cached);
+extern cert_t* scx_load_cert(const char *filename, smartcard_t **scp, bool *cached);
extern bool scx_verify_pin(smartcard_t *sc);
extern void scx_share(smartcard_t *sc);
extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
@@ -90,7 +89,7 @@ extern bool scx_op_via_whack(const char* msg, int inbase, int outbase
extern bool scx_get_pin(smartcard_t *sc, int whackfd);
extern size_t scx_get_keylength(smartcard_t *sc);
extern smartcard_t* scx_add(smartcard_t *sc);
-extern smartcard_t* scx_get(x509cert_t *cert);
+extern smartcard_t* scx_get(cert_t *cert);
extern void scx_release(smartcard_t *sc);
extern void scx_release_context(smartcard_t *sc);
extern void scx_free_pin(chunk_t *pin);
diff --git a/src/pluto/x509.c b/src/pluto/x509.c
index a612a70ed..705ff2c57 100644
--- a/src/pluto/x509.c
+++ b/src/pluto/x509.c
@@ -43,100 +43,6 @@
#include "ocsp.h"
/**
- * Chained lists of X.509 end certificates
- */
-static x509cert_t *x509certs = NULL;
-
-const x509cert_t empty_x509cert = {
- NULL , /* cert */
- NULL , /* *next */
- 0 , /* count */
- FALSE /* smartcard */
-};
-
-/* coding of X.501 distinguished name */
-
-/**
- * For each link pointing to the certificate increase the count by one
- */
-void share_x509cert(x509cert_t *cert)
-{
- if (cert != NULL)
- {
- cert->count++;
- }
-}
-
-/**
- * Add a X.509 user/host certificate to the chained list
- */
-x509cert_t* add_x509cert(x509cert_t *cert)
-{
- certificate_t *certificate = cert->cert;
- x509cert_t *c = x509certs;
-
- while (c != NULL)
- {
- if (certificate->equals(certificate, c->cert)) /* already in chain, free cert */
- {
- free_x509cert(cert);
- return c;
- }
- c = c->next;
- }
-
- /* insert new cert at the root of the chain */
- lock_certs_and_keys("add_x509cert");
- cert->next = x509certs;
- x509certs = cert;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" x509 cert inserted")
- )
- unlock_certs_and_keys("add_x509cert");
- return cert;
-}
-
-/**
- * Choose either subject DN or a subjectAltName as connection end ID
- */
-identification_t* select_x509cert_id(x509cert_t *cert, identification_t *id)
-{
- certificate_t *certificate = cert->cert;
- x509_t *x509 = (x509_t*)certificate;
- identification_t *subject, *subjectAltName;
-
- bool copy_subject_dn = TRUE; /* ID is subject DN */
-
- if (id->get_type(id) != ID_ANY) /* check for a matching subjectAltName */
- {
- enumerator_t *enumerator;
-
- enumerator = x509->create_subjectAltName_enumerator(x509);
- while (enumerator->enumerate(enumerator, &subjectAltName))
- {
- if (id->equals(id, subjectAltName))
- {
- copy_subject_dn = FALSE; /* take subjectAltName instead */
- break;
- }
- }
- enumerator->destroy(enumerator);
- }
- if (copy_subject_dn)
- {
- id->destroy(id);
- subject = certificate->get_subject(certificate);
- plog(" no subjectAltName matches ID '%Y', replaced by subject DN", id);
-
- return subject->clone(subject);
- }
- else
- {
- return id;
- }
-}
-
-/**
* Check for equality between two key identifiers
*/
bool same_keyid(chunk_t a, chunk_t b)
@@ -151,9 +57,9 @@ 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(identification_t *issuer, chunk_t keyid, x509cert_t *chain)
+cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, cert_t *chain)
{
- x509cert_t *cert = chain ? chain->next : x509certs;
+ cert_t *cert = chain->next;
while (cert)
{
@@ -172,47 +78,11 @@ x509cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, x509cert_t *ch
}
/**
- * Free a X.509 certificate
- */
-void free_x509cert(x509cert_t *cert)
-{
- if (cert)
- {
- certificate_t *certificate = cert->cert;
-
- if (certificate)
- {
- certificate->destroy(certificate);
- }
- free(cert);
- cert = NULL;
- }
-}
-
-/**
- * Release of a certificate decreases the count by one
- * the certificate is freed when the counter reaches zero
- */
-void release_x509cert(x509cert_t *cert)
-{
- if (cert && --cert->count == 0)
- {
- x509cert_t **pp = &x509certs;
- while (*pp != cert)
- {
- pp = &(*pp)->next;
- }
- *pp = cert->next;
- free_x509cert(cert);
- }
-}
-
-/**
* Stores a chained list of end certs and CA certs
*/
void store_x509certs(linked_list_t *certs, bool strict)
{
- x509cert_t *x509cert, *cacerts = NULL;
+ cert_t *x509cert, *cacerts = NULL;
certificate_t *cert;
enumerator_t *enumerator;
@@ -235,8 +105,8 @@ void store_x509certs(linked_list_t *certs, bool strict)
else
{
/* insertion into temporary chain of candidate CA certs */
- x509cert = malloc_thing(x509cert_t);
- *x509cert = empty_x509cert;
+ x509cert = malloc_thing(cert_t);
+ *x509cert = cert_empty;
x509cert->cert = cert->get_ref(cert);
x509cert->next = cacerts;
cacerts = x509cert;
@@ -249,7 +119,7 @@ void store_x509certs(linked_list_t *certs, bool strict)
while (cacerts)
{
- x509cert_t *cert = cacerts;
+ cert_t *cert = cacerts;
cacerts = cacerts->next;
@@ -260,7 +130,7 @@ void store_x509certs(linked_list_t *certs, bool strict)
else
{
plog("intermediate cacert rejected");
- free_x509cert(cert);
+ cert_free(cert);
}
}
@@ -274,8 +144,8 @@ void store_x509certs(linked_list_t *certs, bool strict)
if (!(x509->get_flags(x509) & X509_CA))
{
- x509cert = malloc_thing(x509cert_t);
- *x509cert = empty_x509cert;
+ x509cert = malloc_thing(cert_t);
+ *x509cert = cert_empty;
x509cert->cert = cert->get_ref(cert);
if (verify_x509cert(x509cert, strict, &valid_until))
@@ -283,12 +153,12 @@ void store_x509certs(linked_list_t *certs, bool strict)
DBG(DBG_CONTROL | DBG_PARSING,
DBG_log("public key validated")
)
- add_x509_public_key(x509cert, valid_until, DAL_SIGNED);
+ add_public_key_from_cert(x509cert, valid_until, DAL_SIGNED);
}
else
{
plog("X.509 certificate rejected");
- free_x509cert(x509cert);
+ cert_free(x509cert);
}
}
}
@@ -342,7 +212,7 @@ chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
/**
* Verifies a X.509 certificate
*/
-bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
+bool verify_x509cert(cert_t *cert, bool strict, time_t *until)
{
int pathlen, pathlen_constraint;
@@ -355,7 +225,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
identification_t *issuer = certificate->get_issuer(certificate);
x509_t *x509 = (x509_t*)certificate;
chunk_t authKeyID = x509->get_authKeyIdentifier(x509);
- x509cert_t *issuer_cert;
+ cert_t *issuer_cert;
time_t notBefore, notAfter;
bool valid;
@@ -497,7 +367,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
/**
* List all X.509 certs in a chained list
*/
-void list_x509cert_chain(const char *caption, x509cert_t* cert,
+void list_x509cert_chain(const char *caption, cert_t* cert,
x509_flag_t flags, bool utc)
{
bool first = TRUE;
@@ -511,7 +381,8 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
certificate_t *certificate = cert->cert;
x509_t *x509 = (x509_t*)certificate;
- if (flags == X509_NONE || (flags & x509->get_flags(x509)))
+ if (certificate->get_type(certificate) == CERT_X509 &&
+ (flags == X509_NONE || (flags & x509->get_flags(x509))))
{
enumerator_t *enumerator;
char buf[BUF_LEN];
@@ -522,10 +393,6 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
time_t notBefore, notAfter;
public_key_t *key;
chunk_t serial, keyid, subjkey, authkey;
- cert_t c;
-
- c.type = CERT_X509_SIGNATURE;
- c.u.x509 = cert;
if (first)
{
@@ -581,7 +448,7 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
key_type_names, key->get_type(key),
key->get_keysize(key) * BITS_PER_BYTE,
cert->smartcard ? ", on smartcard" :
- (has_private_key(c)? ", has private key" : ""));
+ (has_private_key(cert)? ", has private key" : ""));
if (key->get_fingerprint(key, KEY_ID_PUBKEY_INFO_SHA1, &keyid))
{
@@ -613,10 +480,3 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
}
}
-/**
- * List all X.509 end certificates in a chained list
- */
-void list_x509_end_certs(bool utc)
-{
- list_x509cert_chain("End Entity", x509certs, X509_NONE, utc);
-}
diff --git a/src/pluto/x509.h b/src/pluto/x509.h
index 40e7e7e5d..615b2ab57 100644
--- a/src/pluto/x509.h
+++ b/src/pluto/x509.h
@@ -20,43 +20,21 @@
#include <utils/identification.h>
#include <utils/linked_list.h>
-#include <credentials/keys/public_key.h>
#include <credentials/keys/private_key.h>
#include <credentials/certificates/x509.h>
#include "constants.h"
-
-/* access structure for an X.509v3 certificate */
-
-typedef struct x509cert x509cert_t;
-
-struct x509cert {
- certificate_t *cert;
- x509cert_t *next;
- int count;
- bool smartcard;
-};
-
-/* used for initialization */
-extern const x509cert_t empty_x509cert;
+#include "certs.h"
extern bool same_keyid(chunk_t a, chunk_t b);
-extern identification_t* select_x509cert_id(x509cert_t *cert, identification_t *id);
-extern void parse_authorityKeyIdentifier(chunk_t blob, int level0,
- chunk_t *authKeyID,
- chunk_t *authKeySerialNumber);
extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
certificate_t *issuer_cert);
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(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);
+extern bool verify_x509cert(cert_t *cert, bool strict, time_t *until);
+extern cert_t* get_x509cert(identification_t *issuer, chunk_t keyid, cert_t* chain);
extern void store_x509certs(linked_list_t *certs, bool strict);
-extern void list_x509cert_chain(const char *caption, x509cert_t* cert,
+extern void list_x509cert_chain(const char *caption, cert_t* cert,
x509_flag_t flags, bool utc);
extern void list_x509_end_certs(bool utc);
diff --git a/src/whack/whack.h b/src/whack/whack.h
index 6d5f0fb4f..3f66a7b4f 100644
--- a/src/whack/whack.h
+++ b/src/whack/whack.h
@@ -18,6 +18,7 @@
#include <freeswan.h>
#include <defs.h>
+#include <constants.h>
/* copy of smartcard operations, defined in smartcard.h */
#ifndef SC_OP_T