diff options
author | Martin Willi <martin@strongswan.org> | 2009-08-17 14:45:52 +0200 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-08-26 11:23:51 +0200 |
commit | 5ef478aaee11cf8d4b21da603b290c19565210c6 (patch) | |
tree | 38c234e1c544a4570fd3c74183cf8a3e2e17cad2 /src | |
parent | 3addf4e937dd8f3f436df42d1f513e74dceb372c (diff) | |
download | strongswan-5ef478aaee11cf8d4b21da603b290c19565210c6.tar.bz2 strongswan-5ef478aaee11cf8d4b21da603b290c19565210c6.tar.xz |
implemented RFC3110 key builder in a plugin, added generic DNSKEY RR parsing
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/Makefile.am | 4 | ||||
-rw-r--r-- | src/libstrongswan/plugins/dnskey/Makefile.am | 12 | ||||
-rw-r--r-- | src/libstrongswan/plugins/dnskey/dnskey_builder.c | 186 | ||||
-rw-r--r-- | src/libstrongswan/plugins/dnskey/dnskey_builder.h | 34 | ||||
-rw-r--r-- | src/libstrongswan/plugins/dnskey/dnskey_plugin.c | 60 | ||||
-rw-r--r-- | src/libstrongswan/plugins/dnskey/dnskey_plugin.h | 47 |
6 files changed, 343 insertions, 0 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 23c42f674..d3f46ad54 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -169,6 +169,10 @@ if USE_PGP SUBDIRS += plugins/pgp endif +if USE_DNSKEY + SUBDIRS += plugins/dnskey +endif + if USE_PEM SUBDIRS += plugins/pem endif diff --git a/src/libstrongswan/plugins/dnskey/Makefile.am b/src/libstrongswan/plugins/dnskey/Makefile.am new file mode 100644 index 000000000..fd020f505 --- /dev/null +++ b/src/libstrongswan/plugins/dnskey/Makefile.am @@ -0,0 +1,12 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = -rdynamic + +plugin_LTLIBRARIES = libstrongswan-dnskey.la + +libstrongswan_dnskey_la_SOURCES = dnskey_plugin.h dnskey_plugin.c \ + dnskey_builder.h dnskey_builder.c + +libstrongswan_dnskey_la_LDFLAGS = -module -avoid-version + diff --git a/src/libstrongswan/plugins/dnskey/dnskey_builder.c b/src/libstrongswan/plugins/dnskey/dnskey_builder.c new file mode 100644 index 000000000..6d79d589c --- /dev/null +++ b/src/libstrongswan/plugins/dnskey/dnskey_builder.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "dnskey_builder.h" + +#include <debug.h> +#include <credentials/keys/private_key.h> + + +typedef struct dnskey_rr_t dnskey_rr_t; +typedef enum dnskey_algorithm_t dnskey_algorithm_t; + +/** + * Header of a DNSKEY resource record + */ +struct dnskey_rr_t { + u_int16_t flags; + u_int8_t protocol; + u_int8_t algorithm; + u_int8_t data[]; +} __attribute__((__packed__)); + +/** + * DNSSEC algorithms, RFC4034 Appendix A.1. + */ +enum dnskey_algorithm_t { + DNSKEY_ALG_RSA_MD5 = 1, + DNSKEY_ALG_DH = 2, + DNSKEY_ALG_DSA = 3, + DNSKEY_ALG_ECC = 4, + DNSKEY_ALG_RSA_SHA1 = 5, +}; + +/** + * Load a generic public key from a DNSKEY RR blob + */ +static public_key_t *parse_public_key(chunk_t blob) +{ + dnskey_rr_t *rr = (dnskey_rr_t*)blob.ptr; + + if (blob.len < sizeof(dnskey_rr_t)) + { + DBG1("DNSKEY too short"); + return NULL; + } + blob = chunk_skip(blob, sizeof(dnskey_rr_t)); + + switch (rr->algorithm) + { + case DNSKEY_ALG_RSA_SHA1: + return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, + BUILD_BLOB_DNSKEY, blob, BUILD_END); + default: + DBG1("DNSKEY public key algorithm %d not supported", rr->algorithm); + return NULL; + } +} + +/** + * Load a RSA public key from DNSKEY RR data + */ +static public_key_t *parse_rsa_public_key(chunk_t blob) +{ + chunk_t n, e; + + if (blob.len < 3) + { + DBG1("RFC 3110 public key blob too short for exponent length"); + return NULL; + } + + if (blob.ptr[0]) + { + e.len = blob.ptr[0]; + blob = chunk_skip(blob, 1); + } + else + { + e.len = blob.ptr[1] * 256 + blob.ptr[2]; + blob = chunk_skip(blob, 3); + } + e.ptr = blob.ptr; + if (e.len >= blob.len) + { + DBG1("RFC 3110 public key blob too short for exponent"); + return NULL; + } + n = chunk_skip(blob, e.len); + + return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, + BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, + BUILD_END); +} + +typedef struct private_builder_t private_builder_t; + +/** + * Builder implementation for private/public key loading + */ +struct private_builder_t { + /** implements the builder interface */ + builder_t public; + /** dnskey packet data */ + chunk_t blob; + /** type of key to build */ + key_type_t type; +}; + +/** + * Implementation of builder_t.build for public keys + */ +static public_key_t *build_public(private_builder_t *this) +{ + public_key_t *key = NULL; + + switch (this->type) + { + case KEY_ANY: + key = parse_public_key(this->blob); + break; + case KEY_RSA: + key = parse_rsa_public_key(this->blob); + break; + default: + break; + } + free(this); + return key; +} + +/** + * Implementation of builder_t.add for public keys + */ +static void add_public(private_builder_t *this, builder_part_t part, ...) +{ + va_list args; + + switch (part) + { + case BUILD_BLOB_DNSKEY: + { + va_start(args, part); + this->blob = va_arg(args, chunk_t); + va_end(args); + break; + } + default: + builder_cancel(&this->public); + break; + } +} + +/** + * Builder construction function for public keys + */ +builder_t *dnskey_public_key_builder(key_type_t type) +{ + private_builder_t *this; + + if (type != KEY_ANY && type != KEY_RSA) + { + return NULL; + } + + this = malloc_thing(private_builder_t); + + this->blob = chunk_empty; + this->type = type; + this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add_public; + this->public.build = (void*(*)(builder_t *this))build_public; + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/dnskey/dnskey_builder.h b/src/libstrongswan/plugins/dnskey/dnskey_builder.h new file mode 100644 index 000000000..aa4a1692a --- /dev/null +++ b/src/libstrongswan/plugins/dnskey/dnskey_builder.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup dnskey_public_key dnskey_public_key + * @{ @ingroup dnskey_p + */ + +#ifndef DNSKEY_BUILDER_H_ +#define DNSKEY_BUILDER_H_ + +#include <credentials/keys/public_key.h> + +/** + * Create the builder for a generic or an RSA public key. + * + * @param type type of the key, either KEY_ANY or KEY_RSA + * @return builder instance + */ +builder_t *dnskey_public_key_builder(key_type_t type); + +#endif /** DNSKEY_BUILDER_H_ @}*/ diff --git a/src/libstrongswan/plugins/dnskey/dnskey_plugin.c b/src/libstrongswan/plugins/dnskey/dnskey_plugin.c new file mode 100644 index 000000000..9f4dd4827 --- /dev/null +++ b/src/libstrongswan/plugins/dnskey/dnskey_plugin.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "dnskey_plugin.h" + +#include <library.h> +#include "dnskey_builder.h" + +typedef struct private_dnskey_plugin_t private_dnskey_plugin_t; + +/** + * private data of dnskey_plugin + */ +struct private_dnskey_plugin_t { + + /** + * public functions + */ + dnskey_plugin_t public; +}; + +/** + * Implementation of dnskey_plugin_t.dnskeytroy + */ +static void destroy(private_dnskey_plugin_t *this) +{ + lib->creds->remove_builder(lib->creds, + (builder_constructor_t)dnskey_public_key_builder); + free(this); +} + +/* + * see header file + */ +plugin_t *plugin_create() +{ + private_dnskey_plugin_t *this = malloc_thing(private_dnskey_plugin_t); + + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + + lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, + (builder_constructor_t)dnskey_public_key_builder); + lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, + (builder_constructor_t)dnskey_public_key_builder); + + return &this->public.plugin; +} + diff --git a/src/libstrongswan/plugins/dnskey/dnskey_plugin.h b/src/libstrongswan/plugins/dnskey/dnskey_plugin.h new file mode 100644 index 000000000..17790e1c6 --- /dev/null +++ b/src/libstrongswan/plugins/dnskey/dnskey_plugin.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup dnskey_p dnskey + * @ingroup plugins + * + * @defgroup dnskey_plugin dnskey_plugin + * @{ @ingroup dnskey_p + */ + +#ifndef DNSKEY_PLUGIN_H_ +#define DNSKEY_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct dnskey_plugin_t dnskey_plugin_t; + +/** + * Plugin providing RFC4034 public key decoding functions. + */ +struct dnskey_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +/** + * Create a dnskey_plugin instance. + */ +plugin_t *plugin_create(); + +#endif /** DNSKEY_PLUGIN_H_ @}*/ |