Blame winpr/libwinpr/utils/ntlm.c

Packit Service fa4841
/**
Packit Service fa4841
 * WinPR: Windows Portable Runtime
Packit Service fa4841
 * NTLM Utils
Packit Service fa4841
 *
Packit Service fa4841
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit Service fa4841
 *
Packit Service fa4841
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit Service fa4841
 * you may not use this file except in compliance with the License.
Packit Service fa4841
 * You may obtain a copy of the License at
Packit Service fa4841
 *
Packit Service fa4841
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit Service fa4841
 *
Packit Service fa4841
 * Unless required by applicable law or agreed to in writing, software
Packit Service fa4841
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit Service fa4841
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service fa4841
 * See the License for the specific language governing permissions and
Packit Service fa4841
 * limitations under the License.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_CONFIG_H
Packit Service fa4841
#include "config.h"
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <winpr/ntlm.h>
Packit Service fa4841
Packit Service fa4841
#include <winpr/crt.h>
Packit Service fa4841
#include <winpr/crypto.h>
Packit Service fa4841
Packit Service fa4841
/**
Packit Service fa4841
 * Define NTOWFv1(Password, User, Domain) as
Packit Service fa4841
 * 	MD4(UNICODE(Password))
Packit Service fa4841
 * EndDefine
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
BOOL NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash)
Packit Service fa4841
{
Packit Service fa4841
	if (!Password || !NtHash)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!winpr_Digest(WINPR_MD_MD4, (BYTE*)Password, (size_t)PasswordLength, NtHash,
Packit Service fa4841
	                  WINPR_MD4_DIGEST_LENGTH))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	return TRUE;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash)
Packit Service fa4841
{
Packit Service fa4841
	LPWSTR PasswordW = NULL;
Packit Service fa4841
	BOOL result = FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!NtHash)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!(PasswordW = (LPWSTR)calloc(PasswordLength, 2)))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	MultiByteToWideChar(CP_ACP, 0, Password, PasswordLength, PasswordW, PasswordLength);
Packit Service fa4841
Packit Service fa4841
	if (!NTOWFv1W(PasswordW, PasswordLength * 2, NtHash))
Packit Service fa4841
		goto out_fail;
Packit Service fa4841
Packit Service fa4841
	result = TRUE;
Packit Service fa4841
out_fail:
Packit Service fa4841
	free(PasswordW);
Packit Service fa4841
	return result;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
/**
Packit Service fa4841
 * Define NTOWFv2(Password, User, Domain) as
Packit Service fa4841
 * 	HMAC_MD5(MD4(UNICODE(Password)),
Packit Service fa4841
 * 		UNICODE(ConcatenationOf(UpperCase(User), Domain)))
Packit Service fa4841
 * EndDefine
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
BOOL NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User, UINT32 UserLength, LPWSTR Domain,
Packit Service fa4841
              UINT32 DomainLength, BYTE* NtHash)
Packit Service fa4841
{
Packit Service fa4841
	BYTE NtHashV1[WINPR_MD5_DIGEST_LENGTH];
Packit Service fa4841
Packit Service fa4841
	if ((!User) || (!Password) || (!NtHash))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!NTOWFv1W(Password, PasswordLength, NtHashV1))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	return NTOWFv2FromHashW(NtHashV1, User, UserLength, Domain, DomainLength, NtHash);
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User, UINT32 UserLength, LPSTR Domain,
Packit Service fa4841
              UINT32 DomainLength, BYTE* NtHash)
Packit Service fa4841
{
Packit Service fa4841
	LPWSTR UserW = NULL;
Packit Service fa4841
	LPWSTR DomainW = NULL;
Packit Service fa4841
	LPWSTR PasswordW = NULL;
Packit Service fa4841
	BOOL result = FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!NtHash)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	UserW = (LPWSTR)calloc(UserLength, 2);
Packit Service fa4841
	DomainW = (LPWSTR)calloc(DomainLength, 2);
Packit Service fa4841
	PasswordW = (LPWSTR)calloc(PasswordLength, 2);
Packit Service fa4841
Packit Service fa4841
	if (!UserW || !DomainW || !PasswordW)
Packit Service fa4841
		goto out_fail;
Packit Service fa4841
Packit Service fa4841
	MultiByteToWideChar(CP_ACP, 0, User, UserLength, UserW, UserLength);
Packit Service fa4841
	MultiByteToWideChar(CP_ACP, 0, Domain, DomainLength, DomainW, DomainLength);
Packit Service fa4841
	MultiByteToWideChar(CP_ACP, 0, Password, PasswordLength, PasswordW, PasswordLength);
Packit Service fa4841
Packit Service fa4841
	if (!NTOWFv2W(PasswordW, PasswordLength * 2, UserW, UserLength * 2, DomainW, DomainLength * 2,
Packit Service fa4841
	              NtHash))
Packit Service fa4841
		goto out_fail;
Packit Service fa4841
Packit Service fa4841
	result = TRUE;
Packit Service fa4841
out_fail:
Packit Service fa4841
	free(UserW);
Packit Service fa4841
	free(DomainW);
Packit Service fa4841
	free(PasswordW);
Packit Service fa4841
	return result;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, LPWSTR Domain,
Packit Service fa4841
                      UINT32 DomainLength, BYTE* NtHash)
Packit Service fa4841
{
Packit Service fa4841
	BYTE* buffer;
Packit Service fa4841
	BYTE result = FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!User || !NtHash)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!(buffer = (BYTE*)malloc(UserLength + DomainLength)))
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	/* Concatenate(UpperCase(User), Domain) */
Packit Service fa4841
	CopyMemory(buffer, User, UserLength);
Packit Service fa4841
	CharUpperBuffW((LPWSTR)buffer, UserLength / 2);
Packit Service fa4841
Packit Service fa4841
	if (DomainLength > 0)
Packit Service fa4841
	{
Packit Service fa4841
		CopyMemory(&buffer[UserLength], Domain, DomainLength);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	/* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is
Packit Service fa4841
	 * the NTLMv2 hash */
Packit Service fa4841
	if (!winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLength + DomainLength, NtHash,
Packit Service fa4841
	                WINPR_MD5_DIGEST_LENGTH))
Packit Service fa4841
		goto out_fail;
Packit Service fa4841
Packit Service fa4841
	result = TRUE;
Packit Service fa4841
out_fail:
Packit Service fa4841
	free(buffer);
Packit Service fa4841
	return result;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
BOOL NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, LPSTR Domain,
Packit Service fa4841
                      UINT32 DomainLength, BYTE* NtHash)
Packit Service fa4841
{
Packit Service fa4841
	LPWSTR UserW = NULL;
Packit Service fa4841
	LPWSTR DomainW = NULL;
Packit Service fa4841
	BOOL result = FALSE;
Packit Service fa4841
Packit Service fa4841
	if (!NtHash)
Packit Service fa4841
		return FALSE;
Packit Service fa4841
Packit Service fa4841
	UserW = (LPWSTR)calloc(UserLength, 2);
Packit Service fa4841
	DomainW = (LPWSTR)calloc(DomainLength, 2);
Packit Service fa4841
Packit Service fa4841
	if (!UserW || !DomainW)
Packit Service fa4841
		goto out_fail;
Packit Service fa4841
Packit Service fa4841
	MultiByteToWideChar(CP_ACP, 0, User, UserLength, UserW, UserLength);
Packit Service fa4841
	MultiByteToWideChar(CP_ACP, 0, Domain, DomainLength, DomainW, DomainLength);
Packit Service fa4841
Packit Service fa4841
	if (!NTOWFv2FromHashW(NtHashV1, UserW, UserLength * 2, DomainW, DomainLength * 2, NtHash))
Packit Service fa4841
		goto out_fail;
Packit Service fa4841
Packit Service fa4841
	result = TRUE;
Packit Service fa4841
out_fail:
Packit Service fa4841
	free(UserW);
Packit Service fa4841
	free(DomainW);
Packit Service fa4841
	return result;
Packit Service fa4841
}