libcli:drsuapi: Use GnuTLS MD5 in drsuapi_decrypt_attribute_value()
authorAndreas Schneider <asn@samba.org>
Wed, 15 May 2019 06:07:32 +0000 (08:07 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 21 May 2019 00:03:20 +0000 (00:03 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
libcli/drsuapi/repl_decrypt.c

index 1480791abcd0ccf726e298d4547bb29ae5eef405..2742c0074668407925fb4d38c617b32d04a9bc86 100644 (file)
@@ -32,6 +32,9 @@
 #include "libcli/auth/libcli_auth.h"
 #include "dsdb/samdb/samdb.h"
 
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
 WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
                                       const DATA_BLOB *gensec_skey,
                                       bool rid_crypt,
@@ -42,7 +45,7 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
        DATA_BLOB confounder;
        DATA_BLOB enc_buffer;
 
-       MD5_CTX md5;
+       gnutls_hash_hd_t hash_hnd = NULL;
        uint8_t _enc_key[16];
        DATA_BLOB enc_key;
 
@@ -53,6 +56,8 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
        DATA_BLOB checked_buffer;
 
        DATA_BLOB plain_buffer;
+       WERROR result;
+       int rc;
 
        /*
         * users with rid == 0 should not exist
@@ -79,10 +84,26 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
         * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key!
         */
        enc_key = data_blob_const(_enc_key, sizeof(_enc_key));
-       MD5Init(&md5);
-       MD5Update(&md5, gensec_skey->data, gensec_skey->length);
-       MD5Update(&md5, confounder.data, confounder.length);
-       MD5Final(enc_key.data, &md5);
+
+       rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
+       if (rc < 0) {
+               result = WERR_NOT_ENOUGH_MEMORY;
+               goto out;
+       }
+       rc = gnutls_hash(hash_hnd, gensec_skey->data, gensec_skey->length);
+       if (rc < 0) {
+               gnutls_hash_deinit(hash_hnd, NULL);
+               result = WERR_INTERNAL_ERROR;
+               goto out;
+       }
+       rc = gnutls_hash(hash_hnd, confounder.data, confounder.length);
+       if (rc < 0) {
+               gnutls_hash_deinit(hash_hnd, NULL);
+               result = WERR_INTERNAL_ERROR;
+               goto out;
+       }
+
+       gnutls_hash_deinit(hash_hnd, enc_key.data);
 
        /*
         * copy the encrypted buffer part and 
@@ -91,6 +112,8 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
        dec_buffer = data_blob_const(enc_buffer.data, enc_buffer.length);
        arcfour_crypt_blob(dec_buffer.data, dec_buffer.length, &enc_key);
 
+       ZERO_ARRAY_LEN(enc_key.data, enc_key.length);
+
        /* 
         * the first 4 byte are the crc32 checksum
         * of the remaining bytes
@@ -106,7 +129,8 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(plain_buffer.data);
 
        if (crc32_given != crc32_calc) {
-               return W_ERROR(HRES_ERROR_V(HRES_SEC_E_DECRYPT_FAILURE));
+               result = W_ERROR(HRES_ERROR_V(HRES_SEC_E_DECRYPT_FAILURE));
+               goto out;
        }
        /*
         * The following rid_crypt obfuscation isn't session specific
@@ -123,7 +147,8 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
                uint32_t i, num_hashes;
 
                if ((checked_buffer.length % 16) != 0) {
-                       return WERR_DS_DRA_INVALID_PARAMETER;
+                       result = WERR_DS_DRA_INVALID_PARAMETER;
+                       goto out;
                }
 
                num_hashes = plain_buffer.length / 16;
@@ -134,7 +159,9 @@ WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx,
        }
 
        *out = plain_buffer;
-       return WERR_OK;
+       result = WERR_OK;
+out:
+       return result;
 }
 
 WERROR drsuapi_decrypt_attribute(TALLOC_CTX *mem_ctx,