Support signing of RADIUS response messages
authorMartin Willi <martin@revosec.ch>
Wed, 22 Feb 2012 13:22:50 +0000 (14:22 +0100)
committerMartin Willi <martin@revosec.ch>
Mon, 5 Mar 2012 17:06:13 +0000 (18:06 +0100)
src/libcharon/plugins/eap_radius/radius_message.c
src/libcharon/plugins/eap_radius/radius_message.h
src/libcharon/plugins/eap_radius/radius_socket.c

index 8a2074b..9d7bf3e 100644 (file)
@@ -279,14 +279,21 @@ METHOD(radius_message_t, add, void,
 }
 
 METHOD(radius_message_t, sign, void,
-       private_radius_message_t *this, rng_t *rng, signer_t *signer,
-       hasher_t *hasher, chunk_t secret)
+       private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
+       hasher_t *hasher, signer_t *signer, rng_t *rng)
 {
-       if (this->msg->code == RMC_ACCOUNTING_REQUEST)
+       if (rng == NULL)
        {
                chunk_t msg;
 
-               memset(this->msg->authenticator, 0, sizeof(this->msg->authenticator));
+               if (req_auth)
+               {
+                       memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
+               }
+               else
+               {
+                       memset(this->msg->authenticator, 0, sizeof(this->msg->authenticator));
+               }
                msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
                hasher->get_hash(hasher, msg, NULL);
                hasher->get_hash(hasher, secret, this->msg->authenticator);
index 7f1c456..3557145 100644 (file)
@@ -242,21 +242,22 @@ struct radius_message_t {
        /**
         * Calculate and add the Message-Authenticator attribute to the message.
         *
-        * @param rng                   RNG to create Request-Authenticator
+        * @param req_auth              16 byte Authenticator of request, or NULL
+        * @param secret                shared RADIUS secret
         * @param signer                HMAC-MD5 signer with secret set
         * @param hasher                MD5 hasher
-        * @param secret                shared RADIUS secret
+        * @param rng                   RNG to create Message-Authenticator, NULL to omit
         */
-       void (*sign)(radius_message_t *this, rng_t *rng, signer_t *signer,
-                                hasher_t *hasher, chunk_t secret);
+       void (*sign)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
+                                hasher_t *hasher, signer_t *signer, rng_t *rng);
 
        /**
         * Verify the integrity of a received RADIUS message.
         *
         * @param req_auth              16 byte Authenticator of request, or NULL
         * @param secret                shared RADIUS secret
-        * @param hasher                hasher to verify Response-Authenticator
-        * @param signer                signer to verify Message-Authenticator attribute
+        * @param signer                HMAC-MD5 signer with secret set
+        * @param hasher                MD5 hasher
         */
        bool (*verify)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
                                   hasher_t *hasher, signer_t *signer);
index 96eafb8..875bd61 100644 (file)
@@ -140,11 +140,7 @@ METHOD(radius_socket_t, request, radius_message_t*,
        chunk_t data;
        int i, *fd;
        u_int16_t port;
-
-       /* set Message Identifier */
-       request->set_identifier(request, this->identifier++);
-       /* sign the request */
-       request->sign(request, this->rng, this->signer, this->hasher, this->secret);
+       rng_t *rng = NULL;
 
        if (request->get_code(request) == RMC_ACCOUNTING_REQUEST)
        {
@@ -155,7 +151,14 @@ METHOD(radius_socket_t, request, radius_message_t*,
        {
                fd = &this->auth_fd;
                port = this->auth_port;
+               rng = this->rng;
        }
+
+       /* set Message Identifier */
+       request->set_identifier(request, this->identifier++);
+       /* sign the request */
+       request->sign(request, NULL, this->secret, this->hasher, this->signer, rng);
+
        if (!check_connection(this, fd, port))
        {
                return NULL;