Sorry, again git bugged me. Somehow the last pull merged together with my local changes and everything is in one commit now.
So, the attached patch is not in git-format-patch format and a ChangeLog entry is missing: 2013-07-16 Tim Ruehsen <[email protected]> * NTLM support using libnettle * Requested and tested by Tom Merriam Regards, Tim
diff --git a/configure.ac b/configure.ac
index a413b75..f36c71b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -339,11 +339,25 @@ then
AC_LIBOBJ([http-ntlm])
fi
else
- dnl If SSL is unavailable and the user explicitly requested NTLM,
- dnl abort.
- if test x"$ENABLE_NTLM" = xyes
+ AC_CHECK_LIB(nettle, nettle_md4_init, [with_nettle=yes; AC_SUBST(NETTLE_LIBS, "-lnettle") AC_DEFINE([WITH_NETTLE], [1], [Use libnettle])], [with_nettle=no; AC_MSG_WARN(*** libnettle was not found. You will not be able to use NTLM)])
+ AM_CONDITIONAL([WITH_NETTLE], [test "x$with_nettle" = "xyes"])
+
+ if test x"$with_nettle" = xyes
then
- AC_MSG_ERROR([NTLM authorization requested and OpenSSL not found; aborting])
+ if test x"$ENABLE_NTLM" != xno
+ then
+ AC_DEFINE([ENABLE_NTLM], 1,
+ [Define if you want the NTLM authorization support compiled in.])
+ AC_LIBOBJ([http-ntlm])
+ LIBS="$NETTLE_LIBS $LIBS"
+ fi
+ else
+ dnl If SSL is unavailable and the user explicitly requested NTLM,
+ dnl abort.
+ if test x"$ENABLE_NTLM" = xyes
+ then
+ AC_MSG_ERROR([NTLM authorization requested and SSL not enabled; aborting])
+ fi
fi
fi
diff --git a/src/http-ntlm.c b/src/http-ntlm.c
index 86eca66..63b1262 100644
--- a/src/http-ntlm.c
+++ b/src/http-ntlm.c
@@ -42,27 +42,33 @@ as that of the covered work. */
#include <string.h>
#include <stdlib.h>
-#include <openssl/des.h>
-#include <openssl/md4.h>
-#include <openssl/opensslv.h>
-
#include "utils.h"
#include "http-ntlm.h"
-#if OPENSSL_VERSION_NUMBER < 0x00907001L
-#define DES_key_schedule des_key_schedule
-#define DES_cblock des_cblock
-#define DES_set_odd_parity des_set_odd_parity
-#define DES_set_key des_set_key
-#define DES_ecb_encrypt des_ecb_encrypt
-
-/* This is how things were done in the old days */
-#define DESKEY(x) x
-#define DESKEYARG(x) x
+#ifdef WITH_NETTLE
+# include <nettle/md4.h>
+# include <nettle/des.h>
#else
-/* Modern version */
-#define DESKEYARG(x) *x
-#define DESKEY(x) &x
+# include <openssl/des.h>
+# include <openssl/md4.h>
+# include <openssl/opensslv.h>
+
+# if OPENSSL_VERSION_NUMBER < 0x00907001L
+# define DES_key_schedule des_key_schedule
+# define DES_cblock des_cblock
+# define DES_set_odd_parity des_set_odd_parity
+# define DES_set_key des_set_key
+# define DES_ecb_encrypt des_ecb_encrypt
+
+ /* This is how things were done in the old days */
+# define DESKEY(x) x
+# define DESKEYARG(x) x
+# else
+ /* Modern version */
+# define DESKEYARG(x) *x
+# define DESKEY(x) &x
+# endif
+
#endif
/* Define this to make the type-3 message include the NT response message */
@@ -176,6 +182,25 @@ ntlm_input (struct ntlmdata *ntlm, const char *header)
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
* key schedule ks is also set.
*/
+#ifdef WITH_NETTLE
+static void
+setup_des_key(unsigned char *key_56,
+ struct des_ctx *des)
+{
+ unsigned char key[8];
+
+ key[0] = key_56[0];
+ key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
+ key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
+ key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
+ key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
+ key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
+ key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
+ key[7] = (key_56[6] << 1) & 0xFF;
+
+ nettle_des_set_key(des, key);
+}
+#else
static void
setup_des_key(unsigned char *key_56,
DES_key_schedule DESKEYARG(ks))
@@ -194,7 +219,7 @@ setup_des_key(unsigned char *key_56,
DES_set_odd_parity(&key);
DES_set_key(&key, ks);
}
-
+#endif
/*
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
* 8 byte plaintext is encrypted with each key and the resulting 24
@@ -203,6 +228,18 @@ setup_des_key(unsigned char *key_56,
static void
calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
{
+#ifdef WITH_NETTLE
+ struct des_ctx des;
+
+ setup_des_key(keys, &des);
+ nettle_des_encrypt(&des, 8, results, plaintext);
+
+ setup_des_key(keys + 7, &des);
+ nettle_des_encrypt(&des, 8, results + 8, plaintext);
+
+ setup_des_key(keys + 14, &des);
+ nettle_des_encrypt(&des, 8, results + 16, plaintext);
+#else
DES_key_schedule ks;
setup_des_key(keys, DESKEY(ks));
@@ -216,6 +253,7 @@ calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
setup_des_key(keys+14, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
DESKEY(ks), DES_ENCRYPT);
+#endif
}
/*
@@ -255,6 +293,15 @@ mkhash(const char *password,
{
/* create LanManager hashed password */
+#ifdef WITH_NETTLE
+ struct des_ctx des;
+
+ setup_des_key(pw, &des);
+ nettle_des_encrypt(&des, 8, lmbuffer, magic);
+
+ setup_des_key(pw + 7, &des);
+ nettle_des_encrypt(&des, 8, lmbuffer + 8, magic);
+#else
DES_key_schedule ks;
setup_des_key(pw, DESKEY(ks));
@@ -264,7 +311,7 @@ mkhash(const char *password,
setup_des_key(pw+7, DESKEY(ks));
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
DESKEY(ks), DES_ENCRYPT);
-
+#endif
memset(lmbuffer+16, 0, 5);
}
/* create LM responses */
@@ -272,8 +319,11 @@ mkhash(const char *password,
#ifdef USE_NTRESPONSES
{
- /* create NT hashed password */
+#ifdef WITH_NETTLE
+ struct md4_ctx MD4;
+#else
MD4_CTX MD4;
+#endif
len = strlen(password);
@@ -282,9 +332,16 @@ mkhash(const char *password,
pw[2*i+1] = 0;
}
+#ifdef WITH_NETTLE
+ nettle_md4_init(&MD4);
+ nettle_md4_update(&MD4, 2*len, pw);
+ nettle_md4_digest(&MD4, MD4_DIGEST_SIZE, ntbuffer);
+#else
+ /* create NT hashed password */
MD4_Init(&MD4);
MD4_Update(&MD4, pw, 2*len);
MD4_Final(ntbuffer, &MD4);
+#endif
memset(ntbuffer+16, 0, 5);
}
signature.asc
Description: This is a digitally signed message part.
