ntlm: support libnettle.

This commit is contained in:
Tim Ruehsen 2013-07-22 13:12:57 +02:00 committed by Giuseppe Scrivano
parent a300f1e47d
commit c19d76c024
3 changed files with 101 additions and 21 deletions

View File

@ -339,11 +339,27 @@ 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, [HAVE_NETTLE=yes], [HAVE_NETTLE=no; AC_MSG_WARN(*** libnettle was not found. You will not be able to use NTLM)])
AM_CONDITIONAL([HAVE_NETTLE], [test "x$HAVE_NETTLE" = "xyes"])
if test x"$HAVE_NETTLE" = xyes
then
AC_MSG_ERROR([NTLM authorization requested and OpenSSL not found; aborting])
AC_SUBST(NETTLE_LIBS, "-lnettle")
AC_DEFINE([HAVE_NETTLE], [1], [Use libnettle])
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

View File

@ -1,8 +1,13 @@
2013-07-13 Giuseppe Scrivano <gscrivano@gnu.org>
2013-07-13 Tim Ruehsen <tim.ruehsen@gmx.de>
* http.c (digest_authentication_encode): Fix a crash when the algorithm
is not specified in the server response. Free dynamic memory used by
the function when the function exits.
* http-ntlm.c [HAVE_NETTLE]: Include <nettle/md4.h> and <nettle/des.h>.
(setup_des_key) [HAVE_NETTLE]: New function to deal with
libnettle.
(calc_resp) [HAVE_NETTLE]: Add support for libnettle.
(mkhash) [HAVE_NETTLE]: Likewise.
Reported by: Tim Ruehsen <tim.ruehsen@gmx.de>.
2013-07-13 Steven M. Schweda <sms@antinode.info>

View File

@ -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
#ifdef HAVE_NETTLE
# include <nettle/md4.h>
# include <nettle/des.h>
#else
# 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
# define DESKEY(x) x
# define DESKEYARG(x) x
# else
/* Modern version */
#define DESKEYARG(x) *x
#define DESKEY(x) &x
# 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 HAVE_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,6 +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
@ -203,6 +229,18 @@ setup_des_key(unsigned char *key_56,
static void
calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
{
#ifdef HAVE_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 +254,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 +294,15 @@ mkhash(const char *password,
{
/* create LanManager hashed password */
#ifdef HAVE_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,6 +312,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);
}
@ -272,8 +321,11 @@ mkhash(const char *password,
#ifdef USE_NTRESPONSES
{
/* create NT hashed password */
#ifdef HAVE_NETTLE
struct md4_ctx MD4;
#else
MD4_CTX MD4;
#endif
len = strlen(password);
@ -282,9 +334,16 @@ mkhash(const char *password,
pw[2*i+1] = 0;
}
#ifdef HAVE_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);
}