gsasl-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gsasl branch, master, updated. gsasl-1-2-78-g1286203


From: Simon Josefsson
Subject: [SCM] GNU gsasl branch, master, updated. gsasl-1-2-78-g1286203
Date: Fri, 11 Sep 2009 09:56:14 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gsasl".

http://git.savannah.gnu.org/cgit/gsasl.git/commit/?id=12862032ef23cc749db2f2330809d8c4f50c7f27

The branch, master has been updated
       via  12862032ef23cc749db2f2330809d8c4f50c7f27 (commit)
      from  c9411a2d5392e31c6ae75bab3b257276784c780b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 12862032ef23cc749db2f2330809d8c4f50c7f27
Author: Simon Josefsson <address@hidden>
Date:   Fri Sep 11 11:56:10 2009 +0200

    SCRAM: Check clientproof on server side.  Fix mem leaks.

-----------------------------------------------------------------------

Summary of changes:
 lib/scram/client.c |   19 ++++--
 lib/scram/server.c |  168 +++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 173 insertions(+), 14 deletions(-)

diff --git a/lib/scram/client.c b/lib/scram/client.c
index 3aa2c74..8d230dc 100644
--- a/lib/scram/client.c
+++ b/lib/scram/client.c
@@ -206,6 +206,10 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
                    strlen (state->cf.client_nonce)) != 0)
          return GSASL_AUTHENTICATION_ERROR;
 
+       state->cl.nonce = strdup (state->sf.nonce);
+       if (!state->cl.nonce)
+         return GSASL_MALLOC_ERROR;
+
        /* Save salt/iter as properties, so that client callback can
           access them. */
        {
@@ -215,14 +219,12 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
          if (n < 0 || str == NULL)
            return GSASL_MALLOC_ERROR;
          gsasl_property_set (sctx, GSASL_SCRAM_ITER, str);
+         free (str);
        }
 
        gsasl_property_set (sctx, GSASL_SCRAM_SALT, state->sf.salt);
 
-       state->cl.nonce = strdup (state->sf.nonce);
-       if (!state->cl.nonce)
-         return GSASL_MALLOC_ERROR;
-
+       /* Generate ClientProof. */
        {
          char saltedpassword[20];
          char *clientkey;
@@ -232,6 +234,7 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
          char clientproof[20];
          const char *p;
 
+         /* Get SaltedPassword. */
          p = gsasl_property_get (sctx, GSASL_SCRAM_SALTED_PASSWORD);
          if (p && strlen (p) == 40 && hex_p (p))
            sha1_hex_to_byte (saltedpassword, p);
@@ -250,6 +253,7 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
              err = gc_pbkdf2_sha1 (p, strlen (p),
                                    salt, saltlen,
                                    state->sf.iter, saltedpassword, 20);
+             free (salt);
              if (err != GC_OK)
                return GSASL_MALLOC_ERROR;
            }
@@ -257,7 +261,7 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
            return GSASL_NO_PASSWORD;
 
          /* ClientKey := HMAC(SaltedPassword, "Client Key") */
-#define CLIENT_KEY "Client key"
+#define CLIENT_KEY "Client Key"
          rc = gsasl_hmac_sha1 (saltedpassword, 20,
                                CLIENT_KEY, strlen (CLIENT_KEY),
                                &clientkey);
@@ -282,12 +286,14 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
                    input_len, input,
                    strlen (*output) - 4,
                    *output);
+         free (*output);
 
          /* ClientSignature := HMAC(StoredKey, AuthMessage) */
          rc = gsasl_hmac_sha1 (storedkey, 20,
                                authmessage, strlen (authmessage),
                                &clientsignature);
          free (authmessage);
+         free (storedkey);
          if (rc != 0)
            return rc;
 
@@ -295,6 +301,9 @@ _gsasl_scram_sha1_client_step (Gsasl_session * sctx,
          memcpy (clientproof, clientkey, 20);
          memxor (clientproof, clientsignature, 20);
 
+         free (clientkey);
+         free (clientsignature);
+
          rc = gsasl_base64_to (clientproof, 20, &state->cl.proof, NULL);
          if (rc != 0)
            return rc;
diff --git a/lib/scram/server.c b/lib/scram/server.c
index e06c3fc..d707757 100644
--- a/lib/scram/server.c
+++ b/lib/scram/server.c
@@ -42,6 +42,8 @@
 #include "tokens.h"
 #include "parser.h"
 #include "printer.h"
+#include "gc.h"
+#include "memxor.h"
 
 #define DEFAULT_SALT_BYTES 12
 #define SNONCE_ENTROPY_BYTES 18
@@ -49,8 +51,10 @@
 struct scram_server_state
 {
   int step;
+  char *cfmb_str; /* copy of client first message bare */
+  char *sf_str; /* copy of server first message */
   char *snonce;
-  char *salt;
+  char *clientproof;
   struct scram_client_first cf;
   struct scram_server_first sf;
   struct scram_client_final cl;
@@ -82,7 +86,7 @@ _gsasl_scram_sha1_server_start (Gsasl_session * sctx, void 
**mech_data)
     goto end;
 
   rc = gsasl_base64_to (buf, DEFAULT_SALT_BYTES,
-                       &state->salt, NULL);
+                       &state->sf.salt, NULL);
   if (rc != GSASL_OK)
     goto end;
 
@@ -91,7 +95,7 @@ _gsasl_scram_sha1_server_start (Gsasl_session * sctx, void 
**mech_data)
   return GSASL_OK;
 
  end:
-  free (state->salt);
+  free (state->sf.salt);
   free (state->snonce);
   free (state);
   return rc;
@@ -121,6 +125,24 @@ _gsasl_scram_sha1_server_step (Gsasl_session * sctx,
        if (scram_parse_client_first (input, &state->cf) < 0)
          return GSASL_MECHANISM_PARSE_ERROR;
 
+       {
+         const char *p;
+
+         /* Save "bare" for next step. */
+         p = strchr (input, ',');
+         if (!p)
+           return GSASL_AUTHENTICATION_ERROR;
+         p++;
+         p = strchr (p, ',');
+         if (!p)
+           return GSASL_AUTHENTICATION_ERROR;
+         p++;
+
+         state->cfmb_str = strdup (p);
+         if (!state->cfmb_str)
+           return GSASL_MALLOC_ERROR;
+       }
+
        /* Create new nonce. */
        {
          size_t cnlen = strlen (state->cf.client_nonce);
@@ -146,14 +168,19 @@ _gsasl_scram_sha1_server_step (Gsasl_session * sctx,
        {
          const char *p = gsasl_property_get (sctx, GSASL_SCRAM_SALT);
          if (p)
-           state->sf.salt = strdup (p);
-         else
-           state->sf.salt = strdup (state->salt);
+           {
+             free (state->sf.salt);
+             state->sf.salt = strdup (p);
+           }
        }
 
-       rc = scram_print_server_first (&state->sf, output);
+       rc = scram_print_server_first (&state->sf, &state->sf_str);
        if (rc != 0)
          return GSASL_MALLOC_ERROR;
+
+       *output = strdup (state->sf_str);
+       if (!*output)
+         return GSASL_MALLOC_ERROR;
        *output_len = strlen (*output);
 
        state->step++;
@@ -172,7 +199,128 @@ _gsasl_scram_sha1_server_step (Gsasl_session * sctx,
        if (strcmp (state->cl.nonce, state->sf.nonce) != 0)
          return GSASL_AUTHENTICATION_ERROR;
 
-       state->sl.verifier = strdup ("verifier");
+       /* Base64 decode client proof and check that length matches
+          SHA-1 size. */
+       {
+         size_t len;
+
+         rc = gsasl_base64_from (state->cl.proof, strlen (state->cl.proof),
+                                 &state->clientproof, &len);
+         if (rc != 0)
+           return rc;
+         if (len != 20)
+           return GSASL_MECHANISM_PARSE_ERROR;
+       }
+
+       {
+         char *storedkey;
+         char *serverkey;
+         const char *p;
+
+         /* Get StoredKey */
+         if ((p = gsasl_property_get (sctx, GSASL_PASSWORD)))
+           {
+             Gc_rc err;
+             char *salt;
+             size_t saltlen;
+             char saltedpassword[20];
+             char *clientkey;
+
+             rc = gsasl_base64_from (state->sf.salt, strlen (state->sf.salt),
+                                     &salt, &saltlen);
+             if (rc != 0)
+               return rc;
+
+             /* SaltedPassword := Hi(password, salt) */
+             err = gc_pbkdf2_sha1 (p, strlen (p),
+                                   salt, saltlen,
+                                   state->sf.iter, saltedpassword, 20);
+             free (salt);
+             if (err != GC_OK)
+               return GSASL_MALLOC_ERROR;
+
+             /* ClientKey := HMAC(SaltedPassword, "Client Key") */
+#define CLIENT_KEY "Client Key"
+             rc = gsasl_hmac_sha1 (saltedpassword, 20,
+                                   CLIENT_KEY, strlen (CLIENT_KEY),
+                                   &clientkey);
+             if (rc != 0)
+               return rc;
+
+             /* StoredKey := H(ClientKey) */
+             rc = gsasl_sha1 (clientkey, 20, &storedkey);
+             free (clientkey);
+             if (rc != 0)
+               return rc;
+
+             /* ServerKey := HMAC(SaltedPassword, "Server Key") */
+#define SERVER_KEY "Server Key"
+             rc = gsasl_hmac_sha1 (saltedpassword, 20,
+                                   SERVER_KEY, strlen (SERVER_KEY),
+                                   &serverkey);
+             if (rc != 0)
+               return rc;
+           }
+         else
+           return GSASL_NO_PASSWORD;
+
+         /* Check client proof. */
+         {
+           char *authmessage;
+           char *clientsignature;
+
+           /* Compute AuthMessage */
+           {
+             size_t len;
+
+             /* Get client-final-message-without-proof. */
+             p = strstr (input, ",p=");
+             if (!p)
+               return GSASL_MECHANISM_PARSE_ERROR;
+             len = p - input;
+
+             asprintf (&authmessage, "%s,%.*s,%.*s",
+                       state->cfmb_str,
+                       strlen (state->sf_str), state->sf_str,
+                       len, input);
+           }
+
+           /* ClientSignature := HMAC(StoredKey, AuthMessage) */
+           rc = gsasl_hmac_sha1 (storedkey, 20,
+                                 authmessage, strlen (authmessage),
+                                 &clientsignature);
+           free (authmessage);
+           if (rc != 0)
+             return rc;
+
+           /* Derive ClientKey from input and check against
+              StoredKey. */
+           {
+             char *maybe_storedkey;
+
+             /* ClientKey := ClientProof XOR ClientSignature */
+             memxor (clientsignature, state->clientproof, 20);
+
+             rc = gsasl_sha1 (clientsignature, 20, &maybe_storedkey);
+             free (clientsignature);
+             if (rc != 0)
+               return rc;
+
+             rc = memcmp (storedkey, maybe_storedkey, 20);
+             free (maybe_storedkey);
+             if (rc != 0)
+               return GSASL_AUTHENTICATION_ERROR;
+           }
+         }
+
+         /* Generate server verifier. */
+         {
+           state->sl.verifier = strdup ("verifier");
+         }
+
+         free (storedkey);
+         free (serverkey);
+       }
 
        rc = scram_print_server_final (&state->sl, output);
        if (rc != 0)
@@ -199,8 +347,10 @@ _gsasl_scram_sha1_server_finish (Gsasl_session * sctx, 
void *mech_data)
   if (!state)
     return;
   
+  free (state->cfmb_str);
+  free (state->sf_str);
   free (state->snonce);
-  free (state->salt);
+  free (state->clientproof);
   scram_free_client_first (&state->cf);
   scram_free_server_first (&state->sf);
   scram_free_client_final (&state->cl);


hooks/post-receive
-- 
GNU gsasl




reply via email to

[Prev in Thread] Current Thread [Next in Thread]