keymat: Allow keymat to modify signature scheme(s)
authorThomas Egerer <thomas.egerer@secunet.com>
Thu, 1 Dec 2016 13:40:25 +0000 (14:40 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Feb 2017 09:32:17 +0000 (10:32 +0100)
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
src/conftest/hooks/pretend_auth.c
src/conftest/hooks/rebuild_auth.c
src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
src/libcharon/sa/ikev1/keymat_v1.c
src/libcharon/sa/ikev1/keymat_v1.h
src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
src/libcharon/sa/ikev2/keymat_v2.c
src/libcharon/sa/ikev2/keymat_v2.h

index 54957b0..d80196e 100644 (file)
@@ -238,7 +238,8 @@ static bool build_auth(private_pretend_auth_t *this,
        }
        keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
        if (!keymat->get_auth_octets(keymat, TRUE, this->ike_init,
-                                                                this->nonce, this->id, this->reserved, &octets))
+                                                                this->nonce, this->id, this->reserved,
+                                                                &octets, NULL))
        {
                private->destroy(private);
                return FALSE;
index 42a9cb4..b2df278 100644 (file)
@@ -137,7 +137,7 @@ static bool rebuild_auth(private_rebuild_auth_t *this, ike_sa_t *ike_sa,
        }
        keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
        if (!keymat->get_auth_octets(keymat, FALSE, this->ike_init,
-                                                                this->nonce, id, reserved, &octets))
+                                                                this->nonce, id, reserved, &octets, NULL))
        {
                private->destroy(private);
                id->destroy(id);
index 5debeeb..ddb8c65 100644 (file)
@@ -81,7 +81,7 @@ METHOD(authenticator_t, build, status_t,
        keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
        if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
                                        this->ike_sa->get_id(this->ike_sa), this->sa_payload,
-                                       this->id_payload, &hash))
+                                       this->id_payload, &hash, NULL))
        {
                free(dh.ptr);
                return FAILED;
@@ -118,7 +118,7 @@ METHOD(authenticator_t, process, status_t,
        keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
        if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
                                        this->ike_sa->get_id(this->ike_sa), this->sa_payload,
-                                       this->id_payload, &hash))
+                                       this->id_payload, &hash, NULL))
        {
                free(dh.ptr);
                return FAILED;
index eee7dd1..344c1bf 100644 (file)
@@ -102,7 +102,7 @@ METHOD(authenticator_t, build, status_t,
        keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
        if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
                                        this->ike_sa->get_id(this->ike_sa), this->sa_payload,
-                                       this->id_payload, &hash))
+                                       this->id_payload, &hash, &scheme))
        {
                private->destroy(private);
                free(dh.ptr);
@@ -163,7 +163,7 @@ METHOD(authenticator_t, process, status_t,
        keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
        if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
                                        this->ike_sa->get_id(this->ike_sa), this->sa_payload,
-                                       this->id_payload, &hash))
+                                       this->id_payload, &hash, &scheme))
        {
                free(dh.ptr);
                return FAILED;
index d1d4cbd..29d8ace 100644 (file)
@@ -748,7 +748,8 @@ METHOD(keymat_v1_t, get_hasher, hasher_t*,
 
 METHOD(keymat_v1_t, get_hash, bool,
        private_keymat_v1_t *this, bool initiator, chunk_t dh, chunk_t dh_other,
-       ike_sa_id_t *ike_sa_id, chunk_t sa_i, chunk_t id, chunk_t *hash)
+       ike_sa_id_t *ike_sa_id, chunk_t sa_i, chunk_t id, chunk_t *hash,
+       signature_scheme_t *scheme)
 {
        chunk_t data;
        uint64_t spi, spi_other;
index 46eeea8..b5b959c 100644 (file)
@@ -102,11 +102,14 @@ struct keymat_v1_t {
         * @param sa_i                  encoded SA payload of initiator
         * @param id                    encoded IDii payload for HASH_I (IDir for HASH_R)
         * @param hash                  chunk receiving allocated HASH data
+        * @param scheme                pointer to signature scheme in case it needs to be
+        *                                              modified by the keymat implementation
         * @return                              TRUE if hash allocated successfully
         */
        bool (*get_hash)(keymat_v1_t *this, bool initiator,
                                                chunk_t dh, chunk_t dh_other, ike_sa_id_t *ike_sa_id,
-                                               chunk_t sa_i, chunk_t id, chunk_t *hash);
+                                               chunk_t sa_i, chunk_t id, chunk_t *hash,
+                                               signature_scheme_t *scheme);
 
        /**
         * Get HASH data for integrity/authentication in Phase 2 exchanges.
index 592f497..19ea72d 100644 (file)
@@ -217,7 +217,8 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
        }
 
        if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
-                                                               this->nonce, id, this->reserved, &octets))
+                                                               this->nonce, id, this->reserved, &octets,
+                                                               schemes))
        {
                enumerator = array_create_enumerator(schemes);
                while (enumerator->enumerate(enumerator, &schemep))
@@ -247,6 +248,32 @@ static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
 }
 
 /**
+ * Get the auth octets and the signature scheme (in case it is changed by the
+ * keymat).
+ */
+static bool get_auth_octets_scheme(private_pubkey_authenticator_t *this,
+                                                                  bool verify, identification_t *id,
+                                                                  chunk_t *octets, signature_scheme_t *scheme)
+{
+       keymat_v2_t *keymat;
+       array_t *schemes;
+       bool success = FALSE;
+
+       schemes = array_create(sizeof(signature_scheme_t), 0);
+       array_insert(schemes, ARRAY_TAIL, scheme);
+
+       keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
+       if (keymat->get_auth_octets(keymat, verify, this->ike_sa_init, this->nonce,
+                                                               id, this->reserved, octets, schemes) &&
+               array_get(schemes, 0, &scheme))
+       {
+               success = TRUE;
+       }
+       array_destroy(schemes);
+       return success;
+}
+
+/**
  * Create a classic IKEv2 signature
  */
 static status_t sign_classic(private_pubkey_authenticator_t *this,
@@ -255,7 +282,6 @@ static status_t sign_classic(private_pubkey_authenticator_t *this,
                                                         chunk_t *auth_data)
 {
        signature_scheme_t scheme;
-       keymat_v2_t *keymat;
        chunk_t octets = chunk_empty;
        status_t status = FAILED;
 
@@ -293,9 +319,7 @@ static status_t sign_classic(private_pubkey_authenticator_t *this,
                        return FAILED;
        }
 
-       keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
-       if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
-                                                               this->nonce, id, this->reserved, &octets) &&
+       if (get_auth_octets_scheme(this, FALSE, id, &octets, &scheme) &&
                private->sign(private, scheme, octets, auth_data))
        {
                status = SUCCESS;
@@ -363,7 +387,6 @@ METHOD(authenticator_t, process, status_t,
        key_type_t key_type = KEY_ECDSA;
        signature_scheme_t scheme;
        status_t status = NOT_FOUND;
-       keymat_v2_t *keymat;
        const char *reason = "unsupported";
        bool online;
 
@@ -402,9 +425,7 @@ METHOD(authenticator_t, process, status_t,
                        return INVALID_ARG;
        }
        id = this->ike_sa->get_other_id(this->ike_sa);
-       keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
-       if (!keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
-                                                                this->nonce, id, this->reserved, &octets))
+       if (!get_auth_octets_scheme(this, TRUE, id, &octets, &scheme))
        {
                return FAILED;
        }
index 58efdba..70dacd1 100644 (file)
@@ -629,7 +629,8 @@ METHOD(keymat_t, get_aead, aead_t*,
 
 METHOD(keymat_v2_t, get_auth_octets, bool,
        private_keymat_v2_t *this, bool verify, chunk_t ike_sa_init,
-       chunk_t nonce, identification_t *id, char reserved[3], chunk_t *octets)
+       chunk_t nonce, identification_t *id, char reserved[3], chunk_t *octets,
+       array_t *schemes)
 {
        chunk_t chunk, idx;
        chunk_t skp;
@@ -669,7 +670,8 @@ METHOD(keymat_v2_t, get_psk_sig, bool,
        {       /* EAP uses SK_p if no MSK has been established */
                secret = verify ? this->skp_verify : this->skp_build;
        }
-       if (!get_auth_octets(this, verify, ike_sa_init, nonce, id, reserved, &octets))
+       if (!get_auth_octets(this, verify, ike_sa_init, nonce, id, reserved,
+                                                &octets, NULL))
        {
                return FALSE;
        }
index 927b62b..36bf149 100644 (file)
@@ -22,6 +22,7 @@
 #define KEYMAT_V2_H_
 
 #include <sa/keymat.h>
+#include <collections/array.h>
 
 typedef struct keymat_v2_t keymat_v2_t;
 
@@ -100,11 +101,14 @@ struct keymat_v2_t {
         * @param id                    identity
         * @param reserved              reserved bytes of id_payload
         * @param octests               chunk receiving allocated auth octets
+        * @param schemes               array containing signature schemes in case they
+        *                                              need to be modified by the keymat implementation
         * @return                              TRUE if octets created successfully
         */
        bool (*get_auth_octets)(keymat_v2_t *this, bool verify, chunk_t ike_sa_init,
                                                        chunk_t nonce, identification_t *id,
-                                                       char reserved[3], chunk_t *octets);
+                                                       char reserved[3], chunk_t *octets,
+                                                       array_t *schemes);
        /**
         * Build the shared secret signature used for PSK and EAP authentication.
         *