Added support of EdDSA signatures
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 14 Nov 2016 11:37:23 +0000 (12:37 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 14 Dec 2016 10:15:47 +0000 (11:15 +0100)
31 files changed:
src/libstrongswan/asn1/asn1.c
src/libstrongswan/asn1/oid.txt
src/libstrongswan/credentials/builder.c
src/libstrongswan/credentials/builder.h
src/libstrongswan/credentials/cred_encoding.h
src/libstrongswan/credentials/keys/public_key.c
src/libstrongswan/credentials/keys/public_key.h
src/libstrongswan/crypto/hashers/hasher.c
src/libstrongswan/crypto/hashers/hasher.h
src/libstrongswan/plugins/curve25519/Makefile.am
src/libstrongswan/plugins/curve25519/curve25519_drv.h
src/libstrongswan/plugins/curve25519/curve25519_drv_portable.h
src/libstrongswan/plugins/curve25519/curve25519_plugin.c
src/libstrongswan/plugins/curve25519/curve25519_private_key.c [new file with mode: 0644]
src/libstrongswan/plugins/curve25519/curve25519_private_key.h [new file with mode: 0644]
src/libstrongswan/plugins/curve25519/curve25519_public_key.c [new file with mode: 0644]
src/libstrongswan/plugins/curve25519/curve25519_public_key.h [new file with mode: 0644]
src/libstrongswan/plugins/pem/pem_encoder.c
src/libstrongswan/plugins/pem/pem_plugin.c
src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c
src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c
src/pki/commands/gen.c
src/pki/commands/issue.c
src/pki/commands/print.c
src/pki/commands/self.c
src/pki/man/pki---gen.1.in
src/pki/man/pki---issue.1.in
src/pki/man/pki---print.1.in
src/pki/man/pki---self.1.in

index 2ee414a..5ce8403 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2006 Martin Will
- * Copyright (C) 2000-2008 Andreas Steffen
+ * Copyright (C) 2000-2016 Andreas Steffen
  *
  * Hochschule fuer Technik Rapperswil
  *
@@ -47,6 +47,8 @@ chunk_t asn1_algorithmIdentifier(int oid)
                case OID_ECDSA_WITH_SHA256:
                case OID_ECDSA_WITH_SHA384:
                case OID_ECDSA_WITH_SHA512:
+               case OID_ED25519:
+               case OID_ED448:
                        parameters = chunk_empty;
                        break;
                default:
index 761a38a..a0c2aad 100644 (file)
                 0x0C         "brainpoolP384t1"
                 0x0D         "brainpoolP512r1"
                 0x0E         "brainpoolP512t1"
+  0x65                       "Thawte"
+    0x70                     "id-Ed25519"                              OID_ED25519
+    0x71                     "id-Ed448"                                        OID_ED448
   0x81                       ""
     0x04                     "Certicom"
       0x00                   "curve"
index ddb64ef..243dfd7 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -70,5 +71,6 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
        "BUILD_SAFE_PRIMES",
        "BUILD_SHARES",
        "BUILD_THRESHOLD",
+       "BUILD_EDDSA_PRIV_ASN1_DER",
        "BUILD_END",
 );
index 627e093..7d11393 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -151,6 +152,8 @@ enum builder_part_t {
        BUILD_SHARES,
        /** minimum number of participating private key shares */
        BUILD_THRESHOLD,
+       /** DER encoded ASN.1 EdDSA private key */
+       BUILD_EDDSA_PRIV_ASN1_DER,
        /** end of variable argument builder list */
        BUILD_END,
 };
index b4d1f4c..0b65364 100644 (file)
@@ -144,6 +144,10 @@ enum cred_encoding_part_t {
        CRED_PART_PKCS10_ASN1_DER,
        /** a PGP encoded certificate */
        CRED_PART_PGP_CERT,
+       /** a DER encoded EdDSA public key */
+       CRED_PART_EDDSA_PUB_ASN1_DER,
+       /** a DER encoded EdDSA private key */
+       CRED_PART_EDDSA_PRIV_ASN1_DER,
        /** a DER encoded BLISS public key */
        CRED_PART_BLISS_PUB_ASN1_DER,
        /** a DER encoded BLISS private key */
index 03f93b1..2c76ad6 100644 (file)
@@ -24,6 +24,8 @@ ENUM(key_type_names, KEY_ANY, KEY_BLISS,
        "RSA",
        "ECDSA",
        "DSA",
+       "ED25519",
+       "ED448",
        "BLISS"
 );
 
@@ -48,6 +50,8 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA3_512,
        "ECDSA-256",
        "ECDSA-384",
        "ECDSA-521",
+       "ED25519",
+       "ED448",
        "BLISS_WITH_SHA2_256",
        "BLISS_WITH_SHA2_384",
        "BLISS_WITH_SHA2_512",
@@ -151,6 +155,10 @@ signature_scheme_t signature_scheme_from_oid(int oid)
                        return SIGN_ECDSA_WITH_SHA384_DER;
                case OID_ECDSA_WITH_SHA512:
                        return SIGN_ECDSA_WITH_SHA512_DER;
+               case OID_ED25519:
+                       return SIGN_ED25519;
+               case OID_ED448:
+                       return SIGN_ED448;
                case OID_BLISS_PUBLICKEY:
                case OID_BLISS_WITH_SHA2_512:
                        return SIGN_BLISS_WITH_SHA2_512;
@@ -210,6 +218,10 @@ int signature_scheme_to_oid(signature_scheme_t scheme)
                        return OID_ECDSA_WITH_SHA384;
                case SIGN_ECDSA_WITH_SHA512_DER:
                        return OID_ECDSA_WITH_SHA512;
+               case SIGN_ED25519:
+                       return OID_ED25519;
+               case SIGN_ED448:
+                       return OID_ED448;
                case SIGN_BLISS_WITH_SHA2_256:
                        return OID_BLISS_WITH_SHA2_256;
                case SIGN_BLISS_WITH_SHA2_384:
@@ -236,15 +248,17 @@ static struct {
        key_type_t type;
        int max_keysize;
 } scheme_map[] = {
-       { SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA, 3072 },
-       { SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA, 7680 },
-       { SIGN_RSA_EMSA_PKCS1_SHA2_512, KEY_RSA, 0 },
-       { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 },
-       { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 },
-       { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 },
-       { SIGN_BLISS_WITH_SHA2_256,   KEY_BLISS, 128 },
-       { SIGN_BLISS_WITH_SHA2_384,   KEY_BLISS, 192 },
-       { SIGN_BLISS_WITH_SHA2_512,   KEY_BLISS, 0 }
+       { SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA,  3072 },
+       { SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA,  7680 },
+       { SIGN_RSA_EMSA_PKCS1_SHA2_512, KEY_RSA,     0 },
+       { SIGN_ECDSA_WITH_SHA256_DER,   KEY_ECDSA, 256 },
+       { SIGN_ECDSA_WITH_SHA384_DER,   KEY_ECDSA, 384 },
+       { SIGN_ECDSA_WITH_SHA512_DER,   KEY_ECDSA,   0 },
+       { SIGN_ED25519,                 KEY_ED25519, 0 },
+       { SIGN_ED448,                   KEY_ED448,   0 },
+       { SIGN_BLISS_WITH_SHA2_256,     KEY_BLISS, 128 },
+       { SIGN_BLISS_WITH_SHA2_384,     KEY_BLISS, 192 },
+       { SIGN_BLISS_WITH_SHA2_512,     KEY_BLISS,   0 }
 };
 
 /**
@@ -323,6 +337,10 @@ key_type_t key_type_from_signature_scheme(signature_scheme_t scheme)
                case SIGN_ECDSA_384:
                case SIGN_ECDSA_521:
                        return KEY_ECDSA;
+               case SIGN_ED25519:
+                       return KEY_ED25519;
+               case SIGN_ED448:
+                       return KEY_ED448;
                case SIGN_BLISS_WITH_SHA2_256:
                case SIGN_BLISS_WITH_SHA2_384:
                case SIGN_BLISS_WITH_SHA2_512:
index 2361282..a8958fd 100644 (file)
@@ -37,16 +37,19 @@ typedef enum encryption_scheme_t encryption_scheme_t;
  */
 enum key_type_t {
        /** key type wildcard */
-       KEY_ANY   = 0,
+       KEY_ANY     = 0,
        /** RSA crypto system as in PKCS#1 */
-       KEY_RSA   = 1,
+       KEY_RSA     = 1,
        /** ECDSA as in ANSI X9.62 */
-       KEY_ECDSA = 2,
+       KEY_ECDSA   = 2,
        /** DSA */
-       KEY_DSA   = 3,
+       KEY_DSA     = 3,
+       /** Ed25519 PureEdDSA instance as in draft-irtf-cfrg-eddsa */
+       KEY_ED25519 = 4,
+       /** Ed448   PureEdDSA instance as in draft-irtf-cfrg-eddsa */
+       KEY_ED448   = 5,
        /** BLISS */
-       KEY_BLISS = 4,
-       /** ElGamal, ... */
+       KEY_BLISS = 6,
 };
 
 /**
@@ -102,6 +105,10 @@ enum signature_scheme_t {
        SIGN_ECDSA_384,
        /** ECDSA on the P-521 curve with SHA-512 as in RFC 4754           */
        SIGN_ECDSA_521,
+       /** PureEdDSA on Curve25519 as in draft-ietf-curdle-pkix           */
+       SIGN_ED25519,
+       /** PureEdDSA on Curve448 as in draft-ietf-curdle-pkix             */
+       SIGN_ED448,
        /** BLISS with SHA-2_256                                           */
        SIGN_BLISS_WITH_SHA2_256,
        /** BLISS with SHA-2_384                                           */
index d136799..aab18ec 100644 (file)
@@ -20,7 +20,8 @@
 
 #include <asn1/oid.h>
 
-ENUM_BEGIN(hash_algorithm_names, HASH_SHA1, HASH_SHA512,
+ENUM_BEGIN(hash_algorithm_names, HASH_IDENTITY, HASH_SHA512,
+       "HASH_IDENTITY",
        "HASH_SHA1",
        "HASH_SHA256",
        "HASH_SHA384",
@@ -37,7 +38,8 @@ ENUM_NEXT(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA3_512, HASH_SHA512,
        "HASH_SHA3_512");
 ENUM_END(hash_algorithm_names, HASH_SHA3_512);
 
-ENUM_BEGIN(hash_algorithm_short_names, HASH_SHA1, HASH_SHA512,
+ENUM_BEGIN(hash_algorithm_short_names, HASH_IDENTITY, HASH_SHA512,
+       "identity",
        "sha1",
        "sha256",
        "sha384",
@@ -94,6 +96,9 @@ hash_algorithm_t hasher_algorithm_from_oid(int oid)
                case OID_SHA3_512:
                case OID_RSASSA_PKCS1V15_WITH_SHA3_512:
                        return HASH_SHA3_512;
+               case OID_ED25519:
+               case OID_ED448:
+                       return HASH_IDENTITY;
                default:
                        return HASH_UNKNOWN;
        }
@@ -267,6 +272,7 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg,
                case HASH_SHA3_256:
                case HASH_SHA3_384:
                case HASH_SHA3_512:
+               case HASH_IDENTITY:
                case HASH_UNKNOWN:
                        break;
        }
@@ -280,6 +286,7 @@ bool hasher_algorithm_for_ikev2(hash_algorithm_t alg)
 {
        switch (alg)
        {
+               case HASH_IDENTITY:
                case HASH_SHA1:
                case HASH_SHA256:
                case HASH_SHA384:
@@ -396,6 +403,22 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key)
                                default:
                                        return OID_UNKNOWN;
                        }
+               case KEY_ED25519:
+                       switch (alg)
+                       {
+                               case HASH_IDENTITY:
+                                       return OID_ED25519;
+                               default:
+                                       return OID_UNKNOWN;
+                       }
+               case KEY_ED448:
+                       switch (alg)
+                       {
+                               case HASH_IDENTITY:
+                                       return OID_ED448;
+                               default:
+                                       return OID_UNKNOWN;
+                       }
                case KEY_BLISS:
                        switch (alg)
                        {
@@ -430,6 +453,9 @@ hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme)
                case SIGN_RSA_EMSA_PKCS1_NULL:
                case SIGN_ECDSA_WITH_NULL:
                        break;
+               case SIGN_ED25519:
+               case SIGN_ED448:
+                       return HASH_IDENTITY;
                case SIGN_RSA_EMSA_PKCS1_MD5:
                        return HASH_MD5;
                case SIGN_RSA_EMSA_PKCS1_SHA1:
index 2d28b20..8cd9b13 100644 (file)
@@ -1,8 +1,9 @@
 /*
+ * Copyright (C) 2016 Andreas Steffen
  * Copyright (C) 2012-2015 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -35,6 +36,7 @@ typedef struct hasher_t hasher_t;
  * Hash algorithms as defined for IKEv2 by RFC 7427
  */
 enum hash_algorithm_t {
+       HASH_IDENTITY           = 0,
        HASH_SHA1                       = 1,
        HASH_SHA256                     = 2,
        HASH_SHA384                     = 3,
index e97a61c..d5d260b 100644 (file)
@@ -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
index c172580..bdf0c4c 100644 (file)
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup curve25519_drv curve25519_drv
- * @{ @ingroup curve25519
+ * @{ @ingroup curve25519_p
  */
 
 #ifndef CURVE25519_DRV_H_
index 45ad1d9..f0de0bd 100644 (file)
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup curve25519_drv_portable curve25519_drv_portable
- * @{ @ingroup curve25519
+ * @{ @ingroup curve25519_p
  */
 
 #include "curve25519_drv.h"
index 06c540a..0b1e59e 100644 (file)
@@ -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 (file)
index 0000000..0521622
--- /dev/null
@@ -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 (file)
index 0000000..26f474f
--- /dev/null
@@ -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 (file)
index 0000000..56efe3a
--- /dev/null
@@ -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 (file)
index 0000000..5f6ae17
--- /dev/null
@@ -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_ @}*/
index 35ea3e8..76b0b7b 100644 (file)
@@ -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,
index d5bcbb6..662b0fe 100644 (file)
@@ -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),
index 766832d..97e0633 100644 (file)
@@ -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 */
index ec1bdf5..b887740 100644 (file)
@@ -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),
index e93a836..beb8866 100644 (file)
@@ -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;
index 129fbb0..fcd8f11 100644 (file)
@@ -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);
index 8b11854..6f14b52 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Copyright (C) 2014-2015 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -44,6 +44,10 @@ static int gen()
                                {
                                        type = KEY_ECDSA;
                                }
+                               else if (streq(arg, "ed25519"))
+                               {
+                                       type = KEY_ED25519;
+                               }
                                else if (streq(arg, "bliss"))
                                {
                                        type = KEY_BLISS;
@@ -101,6 +105,9 @@ static int gen()
                        case KEY_ECDSA:
                                size = 384;
                                break;
+                       case KEY_ED25519:
+                               size = 256;
+                               break;
                        case KEY_BLISS:
                                size = 1;
                                break;
@@ -159,7 +166,7 @@ static void __attribute__ ((constructor))reg()
 {
        command_register((command_t) {
                gen, 'g', "gen", "generate a new private key",
-               {"  [--type rsa|ecdsa|bliss] [--size bits] [--safe-primes]",
+               {"  [--type rsa|ecdsa|ed25519|bliss] [--size bits] [--safe-primes]",
                 "[--shares n] [--threshold l] [--outform der|pem]"},
                {
                        {"help",                'h', 0, "show usage information"},
index b15f901..d95f53c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Copyright (C) 2015 Andreas Steffen
+ * Copyright (C) 2015-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -112,6 +112,11 @@ static int issue()
                                        type = CRED_PRIVATE_KEY;
                                        subtype = KEY_ECDSA;
                                }
+                               else if (streq(arg, "ed25519"))
+                               {
+                                       type = CRED_PRIVATE_KEY;
+                                       subtype = KEY_ED25519;
+                               }
                                else if (streq(arg, "bliss"))
                                {
                                        type = CRED_PRIVATE_KEY;
@@ -585,7 +590,7 @@ static void __attribute__ ((constructor))reg()
        command_register((command_t) {
                issue, 'i', "issue",
                "issue a certificate using a CA certificate and key",
-               {"[--in file] [--type pub|pkcs10|priv|rsa|ecdsa|bliss] --cakey file|--cakeyid hex",
+               {"[--in file] [--type pub|pkcs10|priv|rsa|ecdsa|ed25519|bliss] --cakey file|--cakeyid hex",
                 " --cacert file [--dn subject-dn] [--san subjectAltName]+",
                 "[--lifetime days] [--serial hex] [--ca] [--pathlen len]",
                 "[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
index 8cb0a7b..8021016 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2010 Martin Willi
  * Copyright (C) 2010 revosec AG
  *
- * Copyright (C) 2015 Andreas Steffen
+ * Copyright (C) 2015-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -106,6 +106,12 @@ static int print()
                                        type = CRED_PRIVATE_KEY;
                                        subtype = KEY_ECDSA;
                                }
+                               else if (streq(arg, "ed25519") ||
+                                                streq(arg, "ed25519-priv"))
+                               {
+                                       type = CRED_PRIVATE_KEY;
+                                       subtype = KEY_ED25519;
+                               }
                                else if (streq(arg, "bliss") ||
                                                 streq(arg, "bliss-priv"))
                                {
@@ -181,7 +187,7 @@ static void __attribute__ ((constructor))reg()
        command_register((command_t)
                { print, 'a', "print",
                "print a credential in a human readable form",
-               {"[--in file] [--type x509|crl|ac|pub|priv|rsa|ecdsa|bliss]"},
+               {"[--in file] [--type x509|crl|ac|pub|priv|rsa|ecdsa|ed25519|bliss]"},
                {
                        {"help",        'h', 0, "show usage information"},
                        {"in",          'i', 1, "input file, default: stdin"},
index 6fb7b75..1899daa 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Copyright (C) 2015 Andreas Steffen
+ * Copyright (C) 2015-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -90,6 +90,10 @@ static int self()
                                {
                                        type = KEY_ECDSA;
                                }
+                               else if (streq(arg, "ed25519"))
+                               {
+                                       type = KEY_ED25519;
+                               }
                                else if (streq(arg, "bliss"))
                                {
                                        type = KEY_BLISS;
@@ -421,7 +425,7 @@ static void __attribute__ ((constructor))reg()
        command_register((command_t) {
                self, 's', "self",
                "create a self signed certificate",
-               {" [--in file|--keyid hex] [--type rsa|ecdsa|bliss|priv]",
+               {" [--in file|--keyid hex] [--type rsa|ecdsa|ed25519|bliss|priv]",
                 " --dn distinguished-name [--san subjectAltName]+",
                 "[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+",
                 "[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
index 138ab61..4c61ead 100644 (file)
@@ -1,4 +1,4 @@
-.TH "PKI \-\-GEN" 1 "2013-07-31" "@PACKAGE_VERSION@" "strongSwan"
+.TH "PKI \-\-GEN" 1 "2016-12-13" "@PACKAGE_VERSION@" "strongSwan"
 .
 .SH "NAME"
 .
@@ -45,7 +45,8 @@ Set debug level, default: 1.
 Read command line options from \fIfile\fR.
 .TP
 .BI "\-t, \-\-type " type
-Type of key to generate. Either \fIrsa\fR or \fIecdsa\fR, defaults to \fIrsa\fR.
+Type of key to generate. Either \fIrsa\fR, \fIecdsa\fR, \fIed25519\fR or
+\fIbliss\fR, defaults to \fIrsa\fR.
 .TP
 .BI "\-s, \-\-size " bits
 Key length in bits. Defaults to 2048 for \fIrsa\fR and 384 for \fIecdsa\fR.
index bfc7bb1..ba5886f 100644 (file)
@@ -1,4 +1,4 @@
-.TH "PKI \-\-ISSUE" 1 "2013-08-12" "@PACKAGE_VERSION@" "strongSwan"
+.TH "PKI \-\-ISSUE" 1 "2016-12-13" "@PACKAGE_VERSION@" "strongSwan"
 .
 .SH "NAME"
 .
@@ -68,9 +68,9 @@ key/request is read from \fISTDIN\fR.
 .TP
 .BI "\-t, \-\-type " type
 Type of the input. One of \fIpub\fR (public key), \fIpriv\fR (private key),
-\fIrsa\fR (RSA private key), \fIecdsa\fR (ECDSA private key), \fIbliss\fR (BLISS
-private key) or \fIpkcs10\fR (PKCS#10 certificate request), defaults to
-\fIpub\fR.
+\fIrsa\fR (RSA private key), \fIecdsa\fR (ECDSA private key),
+\fIed25519\fR (Ed25519 private key) \fIbliss\fR (BLISS private key) or
+\fIpkcs10\fR (PKCS#10 certificate request), defaults to \fIpub\fR.
 .TP
 .BI "\-k, \-\-cakey " file
 CA private key file. Either this or
index 09f81cd..65fb8bc 100644 (file)
@@ -1,4 +1,4 @@
-.TH "PKI \-\-PRINT" 1 "2013-07-31" "@PACKAGE_VERSION@" "strongSwan"
+.TH "PKI \-\-PRINT" 1 "2016-12-13" "@PACKAGE_VERSION@" "strongSwan"
 .
 .SH "NAME"
 .
@@ -47,8 +47,8 @@ Input file. If not given the input is read from \fISTDIN\fR.
 Type of input. One of \fIx509\fR (X.509 certificate), \fIcrl\fR (Certificate
 Revocation List, CRL), \fIac\fR (Attribute Certificate), \fIpub\fR (public key),
 \fpriv\fR (private key), \fIrsa\fR (RSA private key), \fIecdsa\fR (ECDSA private
-key), \fIbliss\fR (BLISS private key), \fIpriv\fR (private key), defaults to
-\fIx509\fR.
+key), \fIed25519\fR (Ed25519 private key), \fIbliss\fR (BLISS private key),
+\fIpriv\fR (private key), defaults to \fIx509\fR.
 .
 .SH "SEE ALSO"
 .
index 9461e3e..81f59bb 100644 (file)
@@ -1,4 +1,4 @@
-.TH "PKI \-\-SELF" 1 "2013-07-31" "@PACKAGE_VERSION@" "strongSwan"
+.TH "PKI \-\-SELF" 1 "2016-12-13" "@PACKAGE_VERSION@" "strongSwan"
 .
 .SH "NAME"
 .
@@ -68,8 +68,8 @@ Private key input file. If not given the key is read from \fISTDIN\fR.
 Key ID of a private key on a smartcard.
 .TP
 .BI "\-t, \-\-type " type
-Type of the input key. Either \fIpriv\fR, \fIrsa\fR, \fIecdsa\fR or \fIbliss\fR,
-defaults to \fIpriv\fR.
+Type of the input key. Either \fIpriv\fR, \fIrsa\fR, \fIecdsa\fR, \fIed25519\fR
+or \fIbliss\fR, defaults to \fIpriv\fR.
 .TP
 .BI "\-d, \-\-dn " distinguished-name
 Subject and issuer distinguished name (DN). Required.