ikev2: Enumerate RSA/PSS schemes and use them if enabled
authorTobias Brunner <tobias@strongswan.org>
Mon, 16 Oct 2017 16:09:38 +0000 (18:09 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Nov 2017 15:48:10 +0000 (16:48 +0100)
conf/options/charon.opt
src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
src/libstrongswan/credentials/keys/public_key.c
src/libstrongswan/credentials/keys/public_key.h
src/libstrongswan/tests/suites/test_utils.c
src/pki/pki.c

index 900b9b4..161ebb7 100644 (file)
@@ -341,6 +341,9 @@ charon.routing_table
 charon.routing_table_prio
        Priority of the routing table.
 
+charon.rsa_pss = no
+       Whether to use RSA with PSS padding instead of PKCS#1 padding by default.
+
 charon.send_delay = 0
        Delay in ms for sending packets, to simulate larger RTT.
 
index 08d15ef..b34b508 100644 (file)
@@ -176,16 +176,20 @@ static array_t *select_signature_schemes(keymat_v2_t *keymat,
                 * and supported by the other peer */
                enumerator = signature_schemes_for_key(key_type,
                                                                                           private->get_keysize(private));
-               while (enumerator->enumerate(enumerator, &scheme))
+               while (enumerator->enumerate(enumerator, &config))
                {
+                       if (config->scheme == SIGN_RSA_EMSA_PSS &&
+                               !lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
+                                                                                lib->ns))
+                       {
+                               continue;
+                       }
                        if (keymat->hash_algorithm_supported(keymat,
-                                                                               hasher_from_signature_scheme(scheme,
-                                                                                                                                        NULL)))
+                                                               hasher_from_signature_scheme(config->scheme,
+                                                                                                                        config->params)))
                        {
-                               INIT(config,
-                                       .scheme = scheme,
-                               )
-                               array_insert(selected, ARRAY_TAIL, config);
+                               array_insert(selected, ARRAY_TAIL,
+                                                        signature_params_clone(config));
                        }
                }
                enumerator->destroy(enumerator);
index 74a27d0..89fa9b3 100644 (file)
@@ -18,6 +18,7 @@
 #include <asn1/oid.h>
 
 #include "public_key.h"
+#include "signature_params.h"
 
 ENUM(key_type_names, KEY_ANY, KEY_BLISS,
        "ANY",
@@ -244,26 +245,42 @@ int signature_scheme_to_oid(signature_scheme_t scheme)
 }
 
 /**
+ * Parameters for RSA/PSS signature schemes
+ */
+#define PSS_PARAMS(bits) static rsa_pss_params_t pss_params_sha##bits = { \
+       .hash = HASH_SHA##bits, \
+       .mgf1_hash = HASH_SHA##bits, \
+       .salt_len = RSA_PSS_SALT_LEN_DEFAULT, \
+}
+
+PSS_PARAMS(256);
+PSS_PARAMS(384);
+PSS_PARAMS(512);
+
+/**
  * Map for signature schemes to the key type and maximum key size allowed.
  * We only cover schemes with hash algorithms supported by IKEv2 signature
  * authentication.
  */
 static struct {
-       signature_scheme_t scheme;
        key_type_t type;
        int max_keysize;
+       signature_params_t params;
 } 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_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 }
+       { KEY_RSA,  3072, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha256, }},
+       { KEY_RSA,  7680, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha384, }},
+       { KEY_RSA,     0, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha512, }},
+       { KEY_RSA,  3072, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256 }},
+       { KEY_RSA,  7680, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_384 }},
+       { KEY_RSA,     0, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_512 }},
+       { KEY_ECDSA, 256, { .scheme = SIGN_ECDSA_WITH_SHA256_DER }},
+       { KEY_ECDSA, 384, { .scheme = SIGN_ECDSA_WITH_SHA384_DER }},
+       { KEY_ECDSA,   0, { .scheme = SIGN_ECDSA_WITH_SHA512_DER }},
+       { KEY_ED25519, 0, { .scheme = SIGN_ED25519 }},
+       { KEY_ED448,   0, { .scheme = SIGN_ED448 }},
+       { KEY_BLISS, 128, { .scheme = SIGN_BLISS_WITH_SHA2_256 }},
+       { KEY_BLISS, 192, { .scheme = SIGN_BLISS_WITH_SHA2_384 }},
+       { KEY_BLISS,   0, { .scheme = SIGN_BLISS_WITH_SHA2_512 }},
 };
 
 /**
@@ -279,9 +296,9 @@ typedef struct  {
 METHOD(enumerator_t, signature_schemes_enumerate, bool,
        private_enumerator_t *this, va_list args)
 {
-       signature_scheme_t *scheme;
+       signature_params_t **params;
 
-       VA_ARGS_VGET(args, scheme);
+       VA_ARGS_VGET(args, params);
 
        while (++this->index < countof(scheme_map))
        {
@@ -289,7 +306,7 @@ METHOD(enumerator_t, signature_schemes_enumerate, bool,
                   (this->size <= scheme_map[this->index].max_keysize ||
                        !scheme_map[this->index].max_keysize))
                {
-                       *scheme = scheme_map[this->index].scheme;
+                       *params = &scheme_map[this->index].params;
                        return TRUE;
                }
        }
index d6a0a7b..877ed20 100644 (file)
@@ -281,11 +281,11 @@ int signature_scheme_to_oid(signature_scheme_t scheme);
 
 /**
  * Enumerate signature schemes that are appropriate for a key of the given type
- * and size|strength.
+ * and size|strength ordered by increasing strength.
  *
  * @param type                 type of the key
  * @param size                 size or strength of the key
- * @return                             enumerator over signature_scheme_t (increasing strength)
+ * @return                             enumerator over signature_params_t* (by strength)
  */
 enumerator_t *signature_schemes_for_key(key_type_t type, int size);
 
index 3428f23..353010a 100644 (file)
@@ -904,15 +904,20 @@ END_TEST
 static struct {
        key_type_t type;
        int size;
-       signature_scheme_t expected[4];
+       signature_scheme_t expected[7];
 } scheme_data[] = {
-       {KEY_RSA,   1024, { SIGN_RSA_EMSA_PKCS1_SHA2_256, SIGN_RSA_EMSA_PKCS1_SHA2_384,
-                                               SIGN_RSA_EMSA_PKCS1_SHA2_512, SIGN_UNKNOWN }},
-       {KEY_RSA,   2048, { SIGN_RSA_EMSA_PKCS1_SHA2_256, SIGN_RSA_EMSA_PKCS1_SHA2_384,
-                                               SIGN_RSA_EMSA_PKCS1_SHA2_512, SIGN_UNKNOWN }},
-       {KEY_RSA,   4096, { SIGN_RSA_EMSA_PKCS1_SHA2_384, SIGN_RSA_EMSA_PKCS1_SHA2_512,
+       {KEY_RSA,   1024, { SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PSS,
+                                               SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PKCS1_SHA2_256,
+                                               SIGN_RSA_EMSA_PKCS1_SHA2_384, SIGN_RSA_EMSA_PKCS1_SHA2_512,
                                                SIGN_UNKNOWN }},
-       {KEY_RSA,   8192, { SIGN_RSA_EMSA_PKCS1_SHA2_512, SIGN_UNKNOWN }},
+       {KEY_RSA,   2048, { SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PSS,
+                                               SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PKCS1_SHA2_256,
+                                               SIGN_RSA_EMSA_PKCS1_SHA2_384, SIGN_RSA_EMSA_PKCS1_SHA2_512,
+                                               SIGN_UNKNOWN }},
+       {KEY_RSA,   4096, { SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PSS,
+                                               SIGN_RSA_EMSA_PKCS1_SHA2_384, SIGN_RSA_EMSA_PKCS1_SHA2_512,
+                                               SIGN_UNKNOWN }},
+       {KEY_RSA,   8192, { SIGN_RSA_EMSA_PSS, SIGN_RSA_EMSA_PKCS1_SHA2_512, SIGN_UNKNOWN }},
        {KEY_ECDSA,  256, { SIGN_ECDSA_WITH_SHA256_DER, SIGN_ECDSA_WITH_SHA384_DER,
                                                SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
        {KEY_ECDSA,  384, { SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER,
@@ -928,16 +933,16 @@ static struct {
 START_TEST(test_signature_schemes_for_key)
 {
        enumerator_t  *enumerator;
-       signature_scheme_t scheme;
+       signature_params_t *params;
        int i;
 
        enumerator = signature_schemes_for_key(scheme_data[_i].type, scheme_data[_i].size);
        for (i = 0; scheme_data[_i].expected[i] != SIGN_UNKNOWN; i++)
        {
-               ck_assert(enumerator->enumerate(enumerator, &scheme));
-               ck_assert_int_eq(scheme_data[_i].expected[i], scheme);
+               ck_assert(enumerator->enumerate(enumerator, &params));
+               ck_assert_int_eq(scheme_data[_i].expected[i], params->scheme);
        }
-       ck_assert(!enumerator->enumerate(enumerator, &scheme));
+       ck_assert(!enumerator->enumerate(enumerator, &params));
        enumerator->destroy(enumerator);
 }
 END_TEST
index 44fe1f7..805a795 100644 (file)
@@ -243,14 +243,14 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc)
 hash_algorithm_t get_default_digest(private_key_t *private)
 {
        enumerator_t *enumerator;
-       signature_scheme_t scheme;
+       signature_params_t *params;
        hash_algorithm_t alg = HASH_UNKNOWN;
 
        enumerator = signature_schemes_for_key(private->get_type(private),
                                                                                   private->get_keysize(private));
-       if (enumerator->enumerate(enumerator, &scheme))
+       if (enumerator->enumerate(enumerator, &params))
        {
-               alg = hasher_from_signature_scheme(scheme, NULL);
+               alg = hasher_from_signature_scheme(params->scheme, params->params);
        }
        enumerator->destroy(enumerator);