aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2012-04-30 00:31:42 +0200
committerAndreas Steffen <andreas.steffen@strongswan.org>2012-04-30 00:31:42 +0200
commit5f1931ada11a826733162d0b7f587174416f249f (patch)
treea2d4a2e7807c22a2f478eea49509b5e5e3074e83
parent2338b9f019037ed98ecaeb8077ffd8bc1a2a95fc (diff)
downloadstrongswan-5f1931ada11a826733162d0b7f587174416f249f.tar.bz2
strongswan-5f1931ada11a826733162d0b7f587174416f249f.tar.xz
added support for raw RSA public keys to stroke
-rw-r--r--NEWS4
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c10
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c73
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.h11
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c5
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c2
-rw-r--r--src/libstrongswan/plugins/pem/pem_builder.c33
-rw-r--r--src/starter/starterstroke.c1
-rw-r--r--src/stroke/stroke_msg.h1
9 files changed, 130 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 18343444b..79e6c896d 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,10 @@ strongswan-4.6.3
- The resolve plugin automatically installs nameservers via resolvconf(8),
if it is installed, instead of modifying /etc/resolv.conf directly.
+- The IKEv2 charon daemon supports now raw RSA public keys in RFC 3110
+ DNSKEY and PKCS#1 file format.
+
+
strongswan-4.6.2
----------------
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 5a6c22fb3..c94c18595 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -264,7 +264,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
{
identification_t *identity;
certificate_t *certificate;
- char *auth, *id, *cert, *ca;
+ char *auth, *id, *pubkey, *cert, *ca;
stroke_end_t *end, *other_end;
auth_cfg_t *cfg;
char eap_buf[32];
@@ -400,6 +400,14 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
cfg->add(cfg, AUTH_RULE_IDENTITY, identity);
+ /* add raw RSA public key */
+ pubkey = end->rsakey;
+ if (pubkey && !streq(pubkey, "") && !streq(pubkey, "%cert"))
+ {
+ certificate = this->cred->load_pubkey(this->cred, KEY_RSA, pubkey,
+ identity);
+ }
+
/* CA constraint */
if (ca)
{
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 2b96833fe..a2a6d6d9f 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -158,6 +158,78 @@ METHOD(stroke_cred_t, load_peer, certificate_t*,
return NULL;
}
+METHOD(stroke_cred_t, load_pubkey, certificate_t*,
+ private_stroke_cred_t *this, key_type_t type, char *filename,
+ identification_t *identity)
+{
+ certificate_t *cert;
+ char path[PATH_MAX];
+
+ if (streq(filename, "%dns"))
+ {
+
+ }
+ else if (strncaseeq(filename, "0x", 2) || strncaseeq(filename, "0s", 2))
+ {
+ chunk_t printable_key, rfc3110_key;
+ public_key_t *key;
+
+ printable_key = chunk_create(filename + 2, strlen(filename) - 2);
+ rfc3110_key = strncaseeq(filename, "0x", 2) ?
+ chunk_from_hex(printable_key, NULL) :
+ chunk_from_base64(printable_key, NULL);
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_DNSKEY, rfc3110_key,
+ BUILD_END);
+ free(rfc3110_key.ptr);
+ if (key)
+ {
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_TRUSTED_PUBKEY,
+ BUILD_PUBLIC_KEY, key,
+ BUILD_SUBJECT, identity,
+ BUILD_END);
+ key->destroy(key);
+ if (cert)
+ {
+ cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
+ DBG1(DBG_CFG, " loaded %N public key for \"%Y\"",
+ key_type_names, type, identity);
+ return cert;
+ }
+ }
+ DBG1(DBG_CFG, " loading %N public key for \"%Y\" failed",
+ key_type_names, type, identity);
+ }
+ else
+ {
+ if (*filename == '/')
+ {
+ snprintf(path, sizeof(path), "%s", filename);
+ }
+ else
+ {
+ snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
+ }
+
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
+ BUILD_FROM_FILE, path,
+ BUILD_SUBJECT, identity,
+ BUILD_END);
+ if (cert)
+ {
+ cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
+ DBG1(DBG_CFG, " loaded %N public key for \"%Y\" from '%s'",
+ key_type_names, type, identity, filename);
+ return cert;
+ }
+ DBG1(DBG_CFG, " loading %N public key for \"%Y\" from '%s' failed",
+ key_type_names, type, identity, filename);
+ }
+ return NULL;
+}
+
/**
* load trusted certificates from a directory
*/
@@ -1098,6 +1170,7 @@ stroke_cred_t *stroke_cred_create()
.reread = _reread,
.load_ca = _load_ca,
.load_peer = _load_peer,
+ .load_pubkey = _load_pubkey,
.add_shared = _add_shared,
.cachecrl = _cachecrl,
.destroy = _destroy,
diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h
index 89b235f54..83e648819 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.h
+++ b/src/libcharon/plugins/stroke/stroke_cred.h
@@ -66,6 +66,17 @@ struct stroke_cred_t {
certificate_t* (*load_peer)(stroke_cred_t *this, char *filename);
/**
+ * Load a raw public key and serve it through the credential_set.
+ *
+ * @param type type of the raw public key (RSA or ECDSA)
+ * @param filename file to load raw public key from
+ * @param identity identity of the raw public key owner
+ * @return reference to loaded raw public key, or NULL
+ */
+ certificate_t* (*load_pubkey)(stroke_cred_t *this, key_type_t type,
+ char *filename, identification_t *identity);
+
+ /**
* Add a shared secret to serve through the credential_set.
*
* @param shared shared key to add, gets owned
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index 7ba967aba..2cdadff48 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -705,6 +705,7 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
while (enumerator->enumerate(enumerator, (void**)&cert))
{
+ identification_t *subject = cert->get_subject(cert);
public_key_t *public = cert->get_public_key(cert);
if (public)
@@ -717,6 +718,10 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
}
fprintf(out, "\n");
+ if (subject->get_type(subject) != ID_KEY_ID)
+ {
+ fprintf(out, " subject: %#Y\n", subject);
+ }
list_public_key(public, out);
public->destroy(public);
}
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index d51cdafde..57648feb8 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -185,6 +185,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->auth2);
pop_string(msg, &end->id);
pop_string(msg, &end->id2);
+ pop_string(msg, &end->rsakey);
pop_string(msg, &end->cert);
pop_string(msg, &end->cert2);
pop_string(msg, &end->ca);
@@ -200,6 +201,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
DBG2(DBG_CFG, " %sauth2=%s", label, end->auth2);
DBG2(DBG_CFG, " %sid=%s", label, end->id);
DBG2(DBG_CFG, " %sid2=%s", label, end->id2);
+ DBG2(DBG_CFG, " %srsakey=%s", label, end->rsakey);
DBG2(DBG_CFG, " %scert=%s", label, end->cert);
DBG2(DBG_CFG, " %scert2=%s", label, end->cert2);
DBG2(DBG_CFG, " %sca=%s", label, end->ca);
diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c
index f05d348ee..46a5e7240 100644
--- a/src/libstrongswan/plugins/pem/pem_builder.c
+++ b/src/libstrongswan/plugins/pem/pem_builder.c
@@ -355,7 +355,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
* load the credential from a blob
*/
static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
- x509_flag_t flags)
+ identification_t *subject, x509_flag_t flags)
{
void *cred = NULL;
bool pgp = FALSE;
@@ -381,10 +381,19 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
{
subtype = pgp ? CERT_GPG : CERT_X509;
}
- cred = lib->creds->create(lib->creds, type, subtype,
+ if (type == CRED_CERTIFICATE && subtype == CERT_TRUSTED_PUBKEY && subject)
+ {
+ cred = lib->creds->create(lib->creds, type, subtype,
+ BUILD_BLOB_ASN1_DER, blob, BUILD_SUBJECT, subject,
+ BUILD_END);
+ }
+ else
+ {
+ cred = lib->creds->create(lib->creds, type, subtype,
pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob,
flags ? BUILD_X509_FLAG : BUILD_END,
flags, BUILD_END);
+ }
chunk_clear(&blob);
return cred;
}
@@ -393,7 +402,7 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
* load the credential from a file
*/
static void *load_from_file(char *file, credential_type_t type, int subtype,
- x509_flag_t flags)
+ identification_t *subject, x509_flag_t flags)
{
void *cred = NULL;
struct stat sb;
@@ -423,7 +432,8 @@ static void *load_from_file(char *file, credential_type_t type, int subtype,
return NULL;
}
- cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype, flags);
+ cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype,
+ subject,flags);
munmap(addr, sb.st_size);
close(fd);
@@ -434,7 +444,7 @@ static void *load_from_file(char *file, credential_type_t type, int subtype,
* load the credential from a file descriptor
*/
static void *load_from_fd(int fd, credential_type_t type, int subtype,
- x509_flag_t flags)
+ identification_t *subject, x509_flag_t flags)
{
char buf[8096];
char *pos = buf;
@@ -460,7 +470,8 @@ static void *load_from_fd(int fd, credential_type_t type, int subtype,
return NULL;
}
}
- return load_from_blob(chunk_create(buf, total), type, subtype, flags);
+ return load_from_blob(chunk_create(buf, total), type, subtype,
+ subject, flags);
}
/**
@@ -471,6 +482,7 @@ static void *pem_load(credential_type_t type, int subtype, va_list args)
char *file = NULL;
int fd = -1;
chunk_t pem = chunk_empty;
+ identification_t *subject;
int flags = 0;
while (TRUE)
@@ -486,6 +498,9 @@ static void *pem_load(credential_type_t type, int subtype, va_list args)
case BUILD_BLOB_PEM:
pem = va_arg(args, chunk_t);
continue;
+ case BUILD_SUBJECT:
+ subject = va_arg(args, identification_t*);
+ continue;
case BUILD_X509_FLAG:
flags = va_arg(args, int);
continue;
@@ -499,15 +514,15 @@ static void *pem_load(credential_type_t type, int subtype, va_list args)
if (pem.len)
{
- return load_from_blob(pem, type, subtype, flags);
+ return load_from_blob(pem, type, subtype, subject, flags);
}
if (file)
{
- return load_from_file(file, type, subtype, flags);
+ return load_from_file(file, type, subtype, subject, flags);
}
if (fd != -1)
{
- return load_from_fd(fd, type, subtype, flags);
+ return load_from_fd(fd, type, subtype, subject, flags);
}
return NULL;
}
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index e399b1c04..ae04c20dd 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -162,6 +162,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
msg_end->auth2 = push_string(msg, conn_end->auth2);
msg_end->id = push_string(msg, conn_end->id);
msg_end->id2 = push_string(msg, conn_end->id2);
+ msg_end->rsakey = push_string(msg, conn_end->rsakey);
msg_end->cert = push_string(msg, conn_end->cert);
msg_end->cert2 = push_string(msg, conn_end->cert2);
msg_end->cert_policy = push_string(msg, conn_end->cert_policy);
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 7a469d3ac..434122511 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -146,6 +146,7 @@ struct stroke_end_t {
char *id;
char *id2;
char *eap_id;
+ char *rsakey;
char *cert;
char *cert2;
char *ca;