krb5_wrap: use our own code to calculate the ENCTYPE_ARCFOUR_HMAC key
authorStefan Metzmacher <metze@samba.org>
Tue, 21 Feb 2017 11:15:07 +0000 (12:15 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 21 Feb 2017 19:08:16 +0000 (20:08 +0100)
Our own convert_string_talloc() function handles a wider range
of unicode code points than the MIT krb5 or heimdal code.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12262

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Ralph B√∂hme <slow@samba.org>
Autobuild-Date(master): Tue Feb 21 20:08:16 CET 2017 on sn-devel-144

lib/krb5_wrap/krb5_samba.c

index bb0b5df..0c98147 100644 (file)
@@ -23,6 +23,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include "krb5_samba.h"
+#include "lib/crypto/crypto.h"
 
 #ifdef HAVE_COM_ERR_H
 #include <com_err.h>
@@ -300,6 +301,42 @@ int smb_krb5_create_key_from_string(krb5_context context,
                return -1;
        }
 
+       if ((int)enctype == (int)ENCTYPE_ARCFOUR_HMAC) {
+               TALLOC_CTX *frame = talloc_stackframe();
+               uint8_t *utf16 = NULL;
+               size_t utf16_size = 0;
+               uint8_t nt_hash[16];
+               bool ok;
+
+               ok = convert_string_talloc(frame, CH_UNIX, CH_UTF16LE,
+                                          password->data, password->length,
+                                          (void **)&utf16, &utf16_size);
+               if (!ok) {
+                       if (errno == 0) {
+                               errno = EINVAL;
+                       }
+                       ret = errno;
+                       TALLOC_FREE(frame);
+                       return ret;
+               }
+
+               mdfour(nt_hash, utf16, utf16_size);
+               memset(utf16, 0, utf16_size);
+               ret = smb_krb5_keyblock_init_contents(context,
+                                                     ENCTYPE_ARCFOUR_HMAC,
+                                                     nt_hash,
+                                                     sizeof(nt_hash),
+                                                     key);
+               ZERO_STRUCT(nt_hash);
+               if (ret != 0) {
+                       TALLOC_FREE(frame);
+                       return ret;
+               }
+
+               TALLOC_FREE(frame);
+               return 0;
+       }
+
 #if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_C_STRING_TO_KEY)
 {/* MIT */
        krb5_data _salt;