]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
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 2ee414abf1cf8bc852061bb89349d0f74c714a45..5ce84032575e377b569008d12ead95ea7cc1e201 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 761a38ab6970c977ef8278a27fb134774c1cf17f..a0c2aada388f4de2c91d3da86c2b192141b59d55 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 ddb64ef88a8d316f7c48891507295a6d726d6c5d..243dfd7cf9f2b1a40923493f1c0dad1e0c0c5b8a 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 627e0934d00302435272757d63ab1d0804c9e1e3..7d11393480d7c2989156ad420987b648df68622f 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 b4d1f4c3c147d86038f849edd6d3fae945b7b34e..0b65364301e6c2e474d880189c0fce6dbf247f9d 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 03f93b1d39181d6819abb496143d32c7c520b976..2c76ad6805b36032e5e916a130c5da94e2d61ef6 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 236128234b415e5e784d786a9ba31292b05b02c8..a8958fd98414afdac09b5480c0d6d92e5daf6f2f 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 d136799d74293231f341e43e07766c9d9f548bdb..aab18ecf1e475cc6e33a9f803b80514d8a10faea 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 2d28b207d96422fdc154a44457b2ded6d4b17492..8cd9b1346580be7f22ac1fb83020b72dbbf84193 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 e97a61c2c88782434d516412e6b7f0a2c778d611..d5d260bdd6e220a2fd661994ef01ba8591541a4a 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 c172580bc4252d2fb8f680dbc72b7d95d3418e1b..bdf0c4c2964c5907d86904784d28c099dd772040 100644 (file)
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup curve25519_drv curve25519_drv
- * @{ @ingroup curve25519
+ * @{ @ingroup curve25519_p
  */
 
 #ifndef CURVE25519_DRV_H_
index 45ad1d904aad37befdb538db859a20917669fb24..f0de0bd1c48c05c1901e4b6adefe46bce0c4280e 100644 (file)
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup curve25519_drv_portable curve25519_drv_portable
- * @{ @ingroup curve25519
+ * @{ @ingroup curve25519_p
  */
 
 #include "curve25519_drv.h"
index 06c540a829d67a74e2d6d9140181bc17623a1396..0b1e59e979f7a14c001b842369b6c87780e54872 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 35ea3e885992cc96aacaa6ed24b2a4cbf9d1e22e..76b0b7b4091bcd9d98fd4e0400ebbfa09d41c806 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 d5bcbb617d11a52bba77486643fbba4f156da01e..662b0fe8ef9612db82ae4a91498bc59fbbcecfe0 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 766832d396ccbce08bdbddd9683dec1e37a4cb05..97e0633e745807ba41b2a8d86c2f438be9c194f3 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 ec1bdf56548c761c1c2f04155a39a4bda07c650b..b8877404dacb923d9291d4bbab1d05db32b4ca25 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 e93a8361c1de458a29bd1c406cf83e123a217f21..beb8866f885836cec887ed90a38e1504ff81e78b 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 129fbb045daecbe3fead6313966bb55ecabcebe6..fcd8f119eaca339f36b9c93bfb8285a64edbccf3 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 8b11854ad88eb5ef91e0b07c3d7806bc6ebaff8a..6f14b5276b3f4a8773d68b513237f8bb3c9e9663 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 b15f901997c9cba7584622d701622096ddc87453..d95f53c03cae624b61c28473014d260aabcd2b2d 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 8cb0a7b5dceea3597a94c5b10473dc6ad8fe21ca..80210166a5e87fe7446a19bcc52a5a7712f59c0c 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 6fb7b75aed765221c8767d60ad0848506651bd3e..1899daac9dcaf82714ec99b76173d5486c3ee13b 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 138ab612299c1b82ecbbebddd8fca56530848553..4c61ead9cc0a3b157f5d69980ded48f3ff4cee87 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 bfc7bb1a5fd28340013965ae38e1b414b48693cb..ba5886f5f0df94cf47192808f36c8030167afabb 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 09f81cdaaa3054c93852418c844972a55ee7f685..65fb8bc46fc4b72bbf9ec1c9cfcb6c7595c0dc76 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 9461e3effccb67d7e07e62009bed78f061961912..81f59bbb295ef3c3791f2a8813998f39625de045 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.