diff options
Diffstat (limited to 'src/libstrongswan/plugins')
14 files changed, 769 insertions, 14 deletions
diff --git a/src/libstrongswan/plugins/curve25519/Makefile.am b/src/libstrongswan/plugins/curve25519/Makefile.am index e97a61c2c..d5d260bdd 100644 --- a/src/libstrongswan/plugins/curve25519/Makefile.am +++ b/src/libstrongswan/plugins/curve25519/Makefile.am @@ -14,6 +14,8 @@ libstrongswan_curve25519_la_SOURCES = \ curve25519_dh.h curve25519_dh.c \ curve25519_drv.h curve25519_drv.c \ curve25519_drv_portable.h curve25519_drv_portable.c \ + curve25519_private_key.h curve25519_private_key.c \ + curve25519_public_key.h curve25519_public_key.c \ curve25519_plugin.h curve25519_plugin.c libstrongswan_curve25519_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/curve25519/curve25519_drv.h b/src/libstrongswan/plugins/curve25519/curve25519_drv.h index c172580bc..bdf0c4c29 100644 --- a/src/libstrongswan/plugins/curve25519/curve25519_drv.h +++ b/src/libstrongswan/plugins/curve25519/curve25519_drv.h @@ -15,7 +15,7 @@ /** * @defgroup curve25519_drv curve25519_drv - * @{ @ingroup curve25519 + * @{ @ingroup curve25519_p */ #ifndef CURVE25519_DRV_H_ diff --git a/src/libstrongswan/plugins/curve25519/curve25519_drv_portable.h b/src/libstrongswan/plugins/curve25519/curve25519_drv_portable.h index 45ad1d904..f0de0bd1c 100644 --- a/src/libstrongswan/plugins/curve25519/curve25519_drv_portable.h +++ b/src/libstrongswan/plugins/curve25519/curve25519_drv_portable.h @@ -15,7 +15,7 @@ /** * @defgroup curve25519_drv_portable curve25519_drv_portable - * @{ @ingroup curve25519 + * @{ @ingroup curve25519_p */ #include "curve25519_drv.h" diff --git a/src/libstrongswan/plugins/curve25519/curve25519_plugin.c b/src/libstrongswan/plugins/curve25519/curve25519_plugin.c index 06c540a82..0b1e59e97 100644 --- a/src/libstrongswan/plugins/curve25519/curve25519_plugin.c +++ b/src/libstrongswan/plugins/curve25519/curve25519_plugin.c @@ -2,6 +2,9 @@ * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * + * Copyright (C) 2016 Andreas Steffen + * HSR 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 @@ -15,6 +18,8 @@ #include "curve25519_plugin.h" #include "curve25519_dh.h" +#include "curve25519_private_key.h" +#include "curve25519_public_key.h" #include <library.h> @@ -41,9 +46,25 @@ METHOD(plugin_t, get_features, int, private_curve25519_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { + /* X25519 DH group */ PLUGIN_REGISTER(DH, curve25519_dh_create), PLUGIN_PROVIDE(DH, CURVE_25519), PLUGIN_DEPENDS(RNG, RNG_STRONG), + /* Ed25519 private/public keys */ + PLUGIN_REGISTER(PRIVKEY, curve25519_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519), + PLUGIN_REGISTER(PRIVKEY_GEN, curve25519_private_key_gen, FALSE), + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519), + PLUGIN_DEPENDS(RNG, RNG_TRUE), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + PLUGIN_REGISTER(PUBKEY, curve25519_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_ED25519), + /* Ed25519 signature scheme, private */ + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + /* Ed25519 signature verification scheme, public */ + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), }; *features = f; return countof(f); diff --git a/src/libstrongswan/plugins/curve25519/curve25519_private_key.c b/src/libstrongswan/plugins/curve25519/curve25519_private_key.c new file mode 100644 index 000000000..05216226d --- /dev/null +++ b/src/libstrongswan/plugins/curve25519/curve25519_private_key.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2016 Andreas Steffen + * HSR 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 "curve25519_private_key.h" +#include "curve25519_public_key.h" + +#include <asn1/asn1.h> +#include <asn1/oid.h> + +#define _GNU_SOURCE +#include <stdlib.h> + +typedef struct private_curve25519_private_key_t private_curve25519_private_key_t; + +/** + * Private data of a curve25519_private_key_t object. + */ +struct private_curve25519_private_key_t { + /** + * Public interface for this signer. + */ + curve25519_private_key_t public; + + /** + * Ed25519 private key + */ + chunk_t key; + + /** + * Ed25519 public key + */ + chunk_t pubkey; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(private_key_t, get_type, key_type_t, + private_curve25519_private_key_t *this) +{ + return KEY_ED25519; +} + +METHOD(private_key_t, sign, bool, + private_curve25519_private_key_t *this, signature_scheme_t scheme, + chunk_t data, chunk_t *signature) +{ + if (scheme != SIGN_ED25519) + { + DBG1(DBG_LIB, "signature scheme %N not supported by Ed25519", + signature_scheme_names, scheme); + return FALSE; + } + return FALSE; +} + +METHOD(private_key_t, decrypt, bool, + private_curve25519_private_key_t *this, encryption_scheme_t scheme, + chunk_t crypto, chunk_t *plain) +{ + DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names, + scheme); + return FALSE; +} + +METHOD(private_key_t, get_keysize, int, + private_curve25519_private_key_t *this) +{ + return 8 * ED25519_KEY_LEN; +} + +METHOD(private_key_t, get_public_key, public_key_t*, + private_curve25519_private_key_t *this) +{ + public_key_t *public; + chunk_t pubkey; + + pubkey = curve25519_public_key_info_encode(this->pubkey); + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519, + BUILD_BLOB_ASN1_DER, pubkey, BUILD_END); + free(pubkey.ptr); + + return public; +} + +METHOD(private_key_t, get_encoding, bool, + private_curve25519_private_key_t *this, cred_encoding_type_t type, + chunk_t *encoding) +{ + switch (type) + { + case PRIVKEY_ASN1_DER: + case PRIVKEY_PEM: + { + bool success = TRUE; + + *encoding = asn1_wrap(ASN1_SEQUENCE, "cms", + ASN1_INTEGER_0, + asn1_algorithmIdentifier(OID_ED25519), + asn1_wrap(ASN1_OCTET_STRING, "s", + asn1_simple_object(ASN1_OCTET_STRING, this->key) + ) + ); + if (type == PRIVKEY_PEM) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM, + NULL, encoding, CRED_PART_EDDSA_PRIV_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + return success; + } + default: + return FALSE; + } +} + +METHOD(private_key_t, get_fingerprint, bool, + private_curve25519_private_key_t *this, cred_encoding_type_t type, + chunk_t *fp) +{ + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + success = curve25519_public_key_fingerprint(this->pubkey, type, fp); + if (success) + { + lib->encoding->cache(lib->encoding, type, this, *fp); + } + return success; +} + +METHOD(private_key_t, get_ref, private_key_t*, + private_curve25519_private_key_t *this) +{ + ref_get(&this->ref); + return &this->public.key; +} + +METHOD(private_key_t, destroy, void, + private_curve25519_private_key_t *this) +{ + if (ref_put(&this->ref)) + { + lib->encoding->clear_cache(lib->encoding, this); + chunk_clear(&this->key); + chunk_free(&this->pubkey); + free(this); + } +} + +/** + * Internal generic constructor + */ +static private_curve25519_private_key_t *curve25519_private_key_create(chunk_t key) +{ + private_curve25519_private_key_t *this; + uint8_t buf[HASH_SIZE_SHA512]; + hasher_t *hasher; + + /* derive public key */ + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512); + if (!hasher || !hasher->get_hash(hasher, key, buf)) + { + return NULL; + } + buf[ 0] &= 0xf8; + buf[31] &= 0x7f; + buf[31] |= 0x40; + + INIT(this, + .public = { + .key = { + .get_type = _get_type, + .sign = _sign, + .decrypt = _decrypt, + .get_keysize = _get_keysize, + .get_public_key = _get_public_key, + .equals = private_key_equals, + .belongs_to = private_key_belongs_to, + .get_fingerprint = _get_fingerprint, + .has_fingerprint = private_key_has_fingerprint, + .get_encoding = _get_encoding, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .key = key, + .pubkey = chunk_clone(chunk_create(buf, ED25519_KEY_LEN)), + .ref = 1, + ); + + return this; +} + +/** + * See header. + */ +curve25519_private_key_t *curve25519_private_key_gen(key_type_t type, + va_list args) +{ + private_curve25519_private_key_t *this; + chunk_t key; + rng_t *rng; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_KEY_SIZE: + /* key_size argument is not needed */ + va_arg(args, u_int); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + /* generate 256 bit true random private key */ + rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE); + if (!rng || !rng->allocate_bytes(rng, ED25519_KEY_LEN, &key)) + { + DESTROY_IF(rng); + return NULL; + } + rng->destroy(rng); + + this = curve25519_private_key_create(key); + + return this ? &this->public : NULL; +} + +/** + * See header. + */ +curve25519_private_key_t *curve25519_private_key_load(key_type_t type, + va_list args) +{ + private_curve25519_private_key_t *this; + chunk_t key = chunk_empty; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_EDDSA_PRIV_ASN1_DER: + key = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (!asn1_parse_simple_object(&key, ASN1_OCTET_STRING, 0, "EdPrivateKey") || + key.len != ED25519_KEY_LEN) + { + return NULL; + } + this = curve25519_private_key_create(chunk_clone(key)); + + return this ? &this->public : NULL; +} diff --git a/src/libstrongswan/plugins/curve25519/curve25519_private_key.h b/src/libstrongswan/plugins/curve25519/curve25519_private_key.h new file mode 100644 index 000000000..26f474ffb --- /dev/null +++ b/src/libstrongswan/plugins/curve25519/curve25519_private_key.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Andreas Steffen + * HSR 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 curve25519_private_key curve25519_private_key + * @{ @ingroup curve25519_p + */ + +#ifndef CURVE25519_PRIVATE_KEY_H_ +#define CURVE25519_PRIVATE_KEY_H_ + +#include <credentials/builder.h> +#include <credentials/keys/private_key.h> + +typedef struct curve25519_private_key_t curve25519_private_key_t; + +/** + * Private_key_t implementation of Ed25519 signature algorithm. + */ +struct curve25519_private_key_t { + + /** + * Implements private_key_t interface + */ + private_key_t key; +}; + +/** + * Generate an Ed25519 private key. + * + * @param type type of the key, must be KEY_ED25519 + * @param args builder_part_t argument list + * @return generated key, NULL on failure + */ +curve25519_private_key_t *curve25519_private_key_gen(key_type_t type, + va_list args); + +/** + * Load an Ed25519 private key. + * + * @param type type of the key, must be KEY_ED25519 + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +curve25519_private_key_t *curve25519_private_key_load(key_type_t type, + va_list args); + +#endif /** CURVE25519_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c new file mode 100644 index 000000000..56efe3a0f --- /dev/null +++ b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2016 Andreas Steffen + * HSR 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 "curve25519_public_key.h" + +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <asn1/oid.h> + +typedef struct private_curve25519_public_key_t private_curve25519_public_key_t; + +/** + * Private data structure with signing context. + */ +struct private_curve25519_public_key_t { + /** + * Public interface for this signer. + */ + curve25519_public_key_t public; + + /** + * Ed25519 public key + */ + chunk_t pubkey; + + /** + * Reference counter + */ + refcount_t ref; +}; + +METHOD(public_key_t, get_type, key_type_t, + private_curve25519_public_key_t *this) +{ + return KEY_ED25519; +} + + +METHOD(public_key_t, verify, bool, + private_curve25519_public_key_t *this, signature_scheme_t scheme, + chunk_t data, chunk_t signature) +{ + if (scheme != SIGN_ED25519) + { + DBG1(DBG_LIB, "signature scheme %N not supported by Ed25519", + signature_scheme_names, scheme); + return FALSE; + } + /* TODO Implement signature verification */ + + return FALSE; +} + + +METHOD(public_key_t, encrypt_, bool, + private_curve25519_public_key_t *this, encryption_scheme_t scheme, + chunk_t plain, chunk_t *crypto) +{ + DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names, + scheme); + return FALSE; +} + +METHOD(public_key_t, get_keysize, int, + private_curve25519_public_key_t *this) +{ + return 8 * ED25519_KEY_LEN; +} + +METHOD(public_key_t, get_encoding, bool, + private_curve25519_public_key_t *this, cred_encoding_type_t type, + chunk_t *encoding) +{ + bool success = TRUE; + + *encoding = curve25519_public_key_info_encode(this->pubkey); + + if (type != PUBKEY_SPKI_ASN1_DER) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, type, + NULL, encoding, CRED_PART_EDDSA_PUB_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + return success; +} + +METHOD(public_key_t, get_fingerprint, bool, + private_curve25519_public_key_t *this, cred_encoding_type_t type, + chunk_t *fp) +{ + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + success = curve25519_public_key_fingerprint(this->pubkey, type, fp); + if (success) + { + lib->encoding->cache(lib->encoding, type, this, *fp); + } + return success; +} + +METHOD(public_key_t, get_ref, public_key_t*, + private_curve25519_public_key_t *this) +{ + ref_get(&this->ref); + return &this->public.key; +} + +METHOD(public_key_t, destroy, void, + private_curve25519_public_key_t *this) +{ + if (ref_put(&this->ref)) + { + lib->encoding->clear_cache(lib->encoding, this); + free(this->pubkey.ptr); + free(this); + } +} + +/** + * ASN.1 definition of an Ed25519 public key + */ +static const asn1Object_t pubkeyObjects[] = { + { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */ + { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; + +#define ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM 1 +#define ED25519_SUBJECT_PUBLIC_KEY 2 + +/** + * See header. + */ +curve25519_public_key_t *curve25519_public_key_load(key_type_t type, + va_list args) +{ + private_curve25519_public_key_t *this; + chunk_t blob = chunk_empty, object; + asn1_parser_t *parser; + bool success = FALSE; + int objectID, oid; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + INIT(this, + .public = { + .key = { + .get_type = _get_type, + .verify = _verify, + .encrypt = _encrypt_, + .equals = public_key_equals, + .get_keysize = _get_keysize, + .get_fingerprint = _get_fingerprint, + .has_fingerprint = public_key_has_fingerprint, + .get_encoding = _get_encoding, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .ref = 1, + ); + + parser = asn1_parser_create(pubkeyObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case ED25519_SUBJECT_PUBLIC_KEY_ALGORITHM: + { + oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser) + 1, NULL); + if (oid != OID_ED25519) + { + goto end; + } + break; + } + case ED25519_SUBJECT_PUBLIC_KEY: + { + /* encoded as an ASN1 BIT STRING */ + if (object.len != 1 + ED25519_KEY_LEN) + { + goto end; + } + this->pubkey = chunk_clone(chunk_skip(object, 1)); + break; + } + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + destroy(this); + return NULL; + } + return &this->public; +} + +/** + * See header. + */ +chunk_t curve25519_public_key_info_encode(chunk_t pubkey) +{ + return asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_wrap(ASN1_SEQUENCE, "m", + asn1_build_known_oid(OID_ED25519)), + asn1_bitstring("c", pubkey)); +} + +/** + * See header. + */ +bool curve25519_public_key_fingerprint(chunk_t pubkey, + cred_encoding_type_t type, chunk_t *fp) +{ + hasher_t *hasher; + chunk_t key; + + switch (type) + { + case KEYID_PUBKEY_SHA1: + key = chunk_clone(pubkey); + break; + case KEYID_PUBKEY_INFO_SHA1: + key = curve25519_public_key_info_encode(pubkey); + break; + default: + return FALSE; + } + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || !hasher->allocate_hash(hasher, key, fp)) + { + DBG1(DBG_LIB, "SHA1 hash algorithm not supported, " + "fingerprinting failed"); + DESTROY_IF(hasher); + free(key.ptr); + return FALSE; + } + hasher->destroy(hasher); + free(key.ptr); + return TRUE; +} diff --git a/src/libstrongswan/plugins/curve25519/curve25519_public_key.h b/src/libstrongswan/plugins/curve25519/curve25519_public_key.h new file mode 100644 index 000000000..5f6ae175a --- /dev/null +++ b/src/libstrongswan/plugins/curve25519/curve25519_public_key.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 Andreas Steffen + * HSR 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 curve25519_public_key curve25519_public_key + * @{ @ingroup curve25519_p + */ + +#ifndef CURVE25519_PUBLIC_KEY_H_ +#define CURVE25519_PUBLIC_KEY_H_ + +#include <credentials/builder.h> +#include <credentials/cred_encoding.h> +#include <credentials/keys/public_key.h> + +typedef struct curve25519_public_key_t curve25519_public_key_t; + +#define ED25519_KEY_LEN 32 + +/** + * public_key_t implementation of Ed25519 signature algorithm + */ +struct curve25519_public_key_t { + + /** + * Implements the public_key_t interface + */ + public_key_t key; +}; + +/** + * Load an Ed25519 public key. + * + * @param type type of the key, must be KEY_ED25519 + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +curve25519_public_key_t *curve25519_public_key_load(key_type_t type, + va_list args); + +/* The following functions are shared with the curve25519_private_key class */ + +/** + * Encode a Ed25519 subjectPublicKeyInfo record in ASN.1 DER format + * + * @param pubkey Ed25519 public key + * @result ASN.1 encoded subjectPublicKeyInfo record + */ +chunk_t curve25519_public_key_info_encode(chunk_t pubkey); + +/** + * Generate a Ed25519 public key fingerprint + * + * @param pubkey Ed25519 public key + * @param type type of fingerprint to be generated + * @param fp generated fingerprint (must be freed by caller) + * @result TRUE if generation was successful + */ +bool curve25519_public_key_fingerprint(chunk_t pubkey, + cred_encoding_type_t type, chunk_t *fp); + +#endif /** CURVE25519_PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c index 35ea3e885..76b0b7b40 100644 --- a/src/libstrongswan/plugins/pem/pem_encoder.c +++ b/src/libstrongswan/plugins/pem/pem_encoder.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2010 Andreas Steffen - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2016 Andreas Steffen + * HSR 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 @@ -37,7 +37,11 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER, &asn1, CRED_PART_END) || cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER, - &asn1, CRED_PART_END)) + &asn1, CRED_PART_END) || + cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER, + &asn1, CRED_PART_END) || + cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER, + &asn1, CRED_PART_END)) { break; } @@ -53,11 +57,6 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, break; } } - if (cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER, - &asn1, CRED_PART_END)) - { - break; - } return FALSE; case PRIVKEY_PEM: label ="RSA PRIVATE KEY"; @@ -97,6 +96,12 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, label ="BLISS PRIVATE KEY"; break; } + if (cred_encoding_args(args, CRED_PART_EDDSA_PRIV_ASN1_DER, + &asn1, CRED_PART_END)) + { + label ="PRIVATE KEY"; + break; + } return FALSE; case CERT_PEM: if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER, diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index d5bcbb617..662b0fe8e 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -63,6 +63,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS), PLUGIN_DEPENDS(PRIVKEY, KEY_BLISS), + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519), + PLUGIN_DEPENDS(PRIVKEY, KEY_ED25519), /* public key PEM decoding */ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), @@ -79,6 +82,10 @@ METHOD(plugin_t, get_features, int, PLUGIN_DEPENDS(PUBKEY, KEY_DSA), PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_BLISS), + PLUGIN_DEPENDS(PUBKEY, KEY_BLISS), + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_ED25519), + PLUGIN_DEPENDS(PUBKEY, KEY_ED25519), /* certificate PEM decoding */ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c index 766832d39..97e0633e7 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c @@ -75,6 +75,13 @@ static public_key_t *parse_public_key(chunk_t blob) KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END); goto end; } + else if (oid == OID_ED25519) + { + /* Need the whole subjectPublicKeyInfo for Ed25519 public keys */ + key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, + KEY_ED25519, BUILD_BLOB_ASN1_DER, blob, BUILD_END); + goto end; + } else { /* key type not supported */ diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c index ec1bdf565..b8877404d 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c @@ -52,6 +52,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PUBKEY, KEY_ANY), PLUGIN_SDEPEND(PUBKEY, KEY_RSA), PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), + PLUGIN_SDEPEND(PUBKEY, KEY_ED25519), + PLUGIN_SDEPEND(PUBKEY, KEY_ED448), + PLUGIN_SDEPEND(PUBKEY, KEY_BLISS), PLUGIN_SDEPEND(PUBKEY, KEY_DSA), PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_RSA), diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c index e93a8361c..beb8866f8 100644 --- a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c @@ -47,6 +47,7 @@ static private_key_t *parse_private_key(chunk_t blob) int objectID; private_key_t *key = NULL; key_type_t type = KEY_ANY; + builder_part_t part = BUILD_BLOB_ASN1_DER; parser = asn1_parser_create(pkinfoObjects, blob); parser->set_flags(parser, FALSE, TRUE); @@ -68,6 +69,14 @@ static private_key_t *parse_private_key(chunk_t blob) case OID_EC_PUBLICKEY: type = KEY_ECDSA; break; + case OID_ED25519: + type = KEY_ED25519; + part = BUILD_EDDSA_PRIV_ASN1_DER; + break; + case OID_ED448: + type = KEY_ED448; + part = BUILD_EDDSA_PRIV_ASN1_DER; + break; default: /* key type not supported */ goto end; @@ -81,14 +90,12 @@ static private_key_t *parse_private_key(chunk_t blob) { key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type, BUILD_BLOB_ALGID_PARAMS, - params, BUILD_BLOB_ASN1_DER, - object, BUILD_END); + params, part, object, BUILD_END); } else { key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, - type, BUILD_BLOB_ASN1_DER, object, - BUILD_END); + type, part, object, BUILD_END); } DBG2(DBG_ASN, "-- < --"); break; diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c index 129fbb045..fcd8f119e 100644 --- a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c @@ -46,6 +46,8 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA), + PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519), + PLUGIN_PROVIDE(PRIVKEY, KEY_ED448), }; *features = f; return countof(f); |