From 0eafa987a3379e00a548b4a66047069dfb3a9162 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 30 Jan 2014 13:53:33 +0100
Subject: [PATCH v2] NTLM: use a fake entropy for debug builds with
 CURL_ENTROPY set

Curl_rand() will return a dummy and repatable random value for this
case. Makes it possible to write test cases that verify output.

Also, fake timestamp with CURL_FORCETIME set.

Only when built debug enabled of course.

Curl_ssl_random() was not used anymore so it has been
removed. Curl_rand() is enough.
---
 lib/curl_ntlm_core.c | 10 ++++++----
 lib/curl_ntlm_msgs.c | 26 ++++++++++++--------------
 lib/curl_sasl.c      | 12 +++---------
 lib/vtls/vtls.c      | 31 ++++++++++++++++++-------------
 lib/vtls/vtls.h      |  4 +---
 tests/runtests.pl    |  2 ++
 6 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 4420981..7a55cc1 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -554,11 +554,13 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
   CURLcode res = CURLE_OK;
 
   /* Calculate the timestamp */
-#if defined(DEBUGBUILD)
-  tw = 11644473600ULL * 10000000ULL;
-#else
-  tw = ((long long)time(NULL) + 11644473600ULL) * 10000000ULL;
+#ifdef DEBUGBUILD
+  char *force_timestamp = getenv("CURL_FORCETIME");
+  if(force_timestamp)
+    tw = 11644473600ULL * 10000000ULL;
+  else
 #endif
+  tw = ((long long)time(NULL) + 11644473600ULL) * 10000000ULL;
 
   /* Calculate the response len */
   len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c
index 050ffe2..fec3d9e 100644
--- a/lib/curl_ntlm_msgs.c
+++ b/lib/curl_ntlm_msgs.c
@@ -760,16 +760,11 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
 #if USE_NTRESPONSES
   if(ntlm->target_info_len) {
     unsigned char ntbuffer[0x18];
-    unsigned char entropy[8];
+    unsigned int entropy[2];
     unsigned char ntlmv2hash[0x18];
 
-#if defined(DEBUGBUILD)
-    /* Use static client nonce in debug (Test Suite) builds */
-    memcpy(entropy, "12345678", sizeof(entropy));
-#else
-    /* Create an 8 byte random client nonce */
-    Curl_ssl_random(data, entropy, sizeof(entropy));
-#endif
+    entropy[0] = Curl_rand(data);
+    entropy[1] = Curl_rand(data);
 
     res = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
     if(res)
@@ -781,14 +776,16 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
       return res;
 
     /* LMv2 response */
-    res = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy, &ntlm->nonce[0],
-                                      lmresp);
+    res = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
+                                      (unsigned char *)&entropy[0],
+                                      &ntlm->nonce[0], lmresp);
     if(res)
       return res;
 
     /* NTLMv2 response */
-    res = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy, ntlm, &ntlmv2resp,
-                                        &ntresplen);
+    res = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
+                                        (unsigned char *)&entropy[0],
+                                        ntlm, &ntlmv2resp, &ntresplen);
     if(res)
       return res;
 
@@ -803,10 +800,11 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
     unsigned char ntbuffer[0x18];
     unsigned char tmp[0x18];
     unsigned char md5sum[MD5_DIGEST_LENGTH];
-    unsigned char entropy[8];
+    unsigned int entropy[2];
 
     /* Need to create 8 bytes random data */
-    Curl_ssl_random(data, entropy, sizeof(entropy));
+    entropy[0] = Curl_rand(data);
+    entropy[1] = Curl_rand(data);
 
     /* 8 bytes random data as challenge in lmresp */
     memcpy(lmresp, entropy, 8);
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index 648daed..86b2451 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -351,9 +351,6 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
                                              const char *service,
                                              char **outptr, size_t *outlen)
 {
-#ifndef DEBUGBUILD
-  static const char table16[] = "0123456789abcdef";
-#endif
   CURLcode result = CURLE_OK;
   size_t i;
   MD5_context *ctxt;
@@ -364,16 +361,13 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
   char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
 
   char nonceCount[] = "00000001";
-  char cnonce[]     = "12345678"; /* will be changed */
+  char cnonce[17];
   char method[]     = "AUTHENTICATE";
   char qop[]        = "auth";
   char uri[128];
 
-#ifndef DEBUGBUILD
-  /* Generate 64 bits of random data */
-  for(i = 0; i < 8; i++)
-    cnonce[i] = table16[Curl_rand(data)%16];
-#endif
+  snprintf(cnonce, sizeof(cnonce), "%08x%08x",
+           Curl_rand(data), Curl_rand(data));
 
   /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
   ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index ab7274a..6c2295a 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -197,11 +197,27 @@ unsigned int Curl_rand(struct SessionHandle *data)
   static unsigned int randseed;
   static bool seeded = FALSE;
 
+#ifdef CURLDEBUG
+  char *force_entropy = getenv("CURL_ENTROPY");
+  if(force_entropy) {
+    if(!seeded) {
+      size_t elen = strlen(force_entropy);
+      size_t clen = sizeof(randseed);
+      size_t min = elen < clen ? elen : clen;
+      memcpy((char *)&randseed, force_entropy, min);
+      seeded = TRUE;
+    }
+    else
+      randseed++;
+    return randseed;
+  }
+#endif
+
 #ifndef have_curlssl_random
   (void)data;
 #else
   if(data) {
-    Curl_ssl_random(data, (unsigned char *)&r, sizeof(r));
+    curlssl_random(data, (unsigned char *)&r, sizeof(r));
     return r;
   }
 #endif
@@ -665,17 +681,6 @@ CURLcode Curl_ssl_push_certinfo(struct SessionHandle *data,
   return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
 }
 
-/* these functions are only provided by some SSL backends */
-
-#ifdef have_curlssl_random
-void Curl_ssl_random(struct SessionHandle *data,
-                     unsigned char *entropy,
-                     size_t length)
-{
-  curlssl_random(data, entropy, length);
-}
-#endif
-
 #ifdef have_curlssl_md5sum
 void Curl_ssl_md5sum(unsigned char *tmp, /* input */
                      size_t tmplen,
diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h
index 823c041..54c3b9b 100644
--- a/lib/vtls/vtls.h
+++ b/lib/vtls/vtls.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -89,8 +89,6 @@ void Curl_ssl_kill_session(struct curl_ssl_session *session);
 void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
 
 /* get N random bytes into the buffer */
-void Curl_ssl_random(struct SessionHandle *data, unsigned char *buffer,
-                     size_t length);
 void Curl_ssl_md5sum(unsigned char *tmp, /* input */
                      size_t tmplen,
                      unsigned char *md5sum, /* output */
diff --git a/tests/runtests.pl b/tests/runtests.pl
index cbd40e7..6751a49 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -311,6 +311,8 @@ if (!$USER) {
 
 # enable memory debugging if curl is compiled with it
 $ENV{'CURL_MEMDEBUG'} = $memdump;
+$ENV{'CURL_ENTROPY'}="12345678";
+$ENV{'CURL_FORCETIME'}="1";
 $ENV{'HOME'}=$pwd;
 
 sub catch_zap {
-- 
1.9.0

