libwinpr-sspi: remove OpenSSL dependency in NTLM SSPI module

This commit is contained in:
Marc-André Moreau 2015-10-08 16:48:58 -04:00
parent 5bff1d0fdf
commit 87c42127c7
4 changed files with 56 additions and 76 deletions

View File

@ -24,12 +24,9 @@
#include <winpr/crt.h>
#include <winpr/sspi.h>
#include <winpr/print.h>
#include <winpr/tchar.h>
#include <winpr/sysinfo.h>
#include <winpr/registry.h>
#include <winpr/tchar.h>
#include <openssl/rc4.h>
#include <openssl/hmac.h>
#include "ntlm.h"
#include "../sspi.h"
@ -158,12 +155,6 @@ NTLM_CONTEXT* ntlm_ContextNew()
if (!context)
return NULL;
context->SendRc4Seal = (void*) calloc(1, sizeof(RC4_KEY));
context->RecvRc4Seal = (void*) calloc(1, sizeof(RC4_KEY));
if (!context->SendRc4Seal || !context->RecvRc4Seal)
return NULL;
context->NTLMv2 = TRUE;
context->UseMIC = FALSE;
context->SendVersionInfo = TRUE;
@ -247,8 +238,6 @@ void ntlm_ContextFree(NTLM_CONTEXT* context)
if (!context)
return;
free(context->SendRc4Seal);
free(context->RecvRc4Seal);
sspi_SecBufferFree(&context->NegotiateMessage);
sspi_SecBufferFree(&context->ChallengeMessage);
sspi_SecBufferFree(&context->AuthenticateMessage);
@ -815,11 +804,11 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
int length;
void* data;
UINT32 SeqNo;
HMAC_CTX hmac;
BYTE digest[16];
BYTE checksum[8];
BYTE* signature;
ULONG version = 1;
WINPR_HMAC_CTX hmac;
NTLM_CONTEXT* context;
PSecBuffer data_buffer = NULL;
PSecBuffer signature_buffer = NULL;
@ -849,17 +838,15 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
CopyMemory(data, data_buffer->pvBuffer, length);
/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, context->SendSigningKey, 16, EVP_md5(), NULL);
HMAC_Update(&hmac, (void*) &(SeqNo), 4);
HMAC_Update(&hmac, (void*) data, length);
HMAC_Final(&hmac, digest, NULL);
HMAC_CTX_cleanup(&hmac);
winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->SendSigningKey, 16);
winpr_HMAC_Update(&hmac, (void*) &(SeqNo), 4);
winpr_HMAC_Update(&hmac, (void*) data, length);
winpr_HMAC_Final(&hmac, digest);
/* Encrypt message using with RC4, result overwrites original buffer */
if (context->confidentiality)
RC4((RC4_KEY*) context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
winpr_RC4_Update(&context->SendRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
else
CopyMemory(data_buffer->pvBuffer, data, length);
@ -871,7 +858,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
#endif
free(data);
/* RC4-encrypt first 8 bytes of digest */
RC4((RC4_KEY*) context->SendRc4Seal, 8, digest, checksum);
winpr_RC4_Update(&context->SendRc4Seal, 8, digest, checksum);
signature = (BYTE*) signature_buffer->pvBuffer;
/* Concatenate version, ciphertext and sequence number to build signature */
CopyMemory(signature, (void*) &version, 4);
@ -891,10 +878,10 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
int length;
void* data;
UINT32 SeqNo;
HMAC_CTX hmac;
BYTE digest[16];
BYTE checksum[8];
UINT32 version = 1;
WINPR_HMAC_CTX hmac;
NTLM_CONTEXT* context;
BYTE expected_signature[16];
PSecBuffer data_buffer = NULL;
@ -928,17 +915,15 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
/* Decrypt message using with RC4, result overwrites original buffer */
if (context->confidentiality)
RC4((RC4_KEY*) context->RecvRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
winpr_RC4_Update(&context->RecvRc4Seal, length, (BYTE*) data, (BYTE*) data_buffer->pvBuffer);
else
CopyMemory(data_buffer->pvBuffer, data, length);
/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, context->RecvSigningKey, 16, EVP_md5(), NULL);
HMAC_Update(&hmac, (void*) &(SeqNo), 4);
HMAC_Update(&hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer);
HMAC_Final(&hmac, digest, NULL);
HMAC_CTX_cleanup(&hmac);
winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->RecvSigningKey, 16);
winpr_HMAC_Update(&hmac, (void*) &(SeqNo), 4);
winpr_HMAC_Update(&hmac, (void*) data_buffer->pvBuffer, data_buffer->cbBuffer);
winpr_HMAC_Final(&hmac, digest);
#ifdef WITH_DEBUG_NTLM
WLog_DBG(TAG, "Encrypted Data Buffer (length = %d)", length);
winpr_HexDump(TAG, WLOG_DEBUG, data, length);
@ -947,7 +932,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferD
#endif
free(data);
/* RC4-encrypt first 8 bytes of digest */
RC4((RC4_KEY*) context->RecvRc4Seal, 8, digest, checksum);
winpr_RC4_Update(&context->RecvRc4Seal, 8, digest, checksum);
/* Concatenate version, ciphertext and sequence number to build signature */
CopyMemory(expected_signature, (void*) &version, 4);
CopyMemory(&expected_signature[4], (void*) checksum, 8);

View File

@ -24,6 +24,7 @@
#include <winpr/windows.h>
#include <winpr/nt.h>
#include <winpr/crypto.h>
#include "../sspi.h"
@ -224,8 +225,8 @@ struct _NTLM_CONTEXT
BYTE MachineID[32];
BOOL SendVersionInfo;
BOOL confidentiality;
void* SendRc4Seal;
void* RecvRc4Seal;
WINPR_RC4_CTX SendRc4Seal;
WINPR_RC4_CTX RecvRc4Seal;
BYTE* SendSigningKey;
BYTE* RecvSigningKey;
BYTE* SendSealingKey;

View File

@ -30,8 +30,7 @@
#include <winpr/print.h>
#include <winpr/sysinfo.h>
#include <winpr/tchar.h>
#include <openssl/md5.h>
#include <winpr/crypto.h>
#include "ntlm_compute.h"
@ -244,19 +243,19 @@ typedef struct gss_channel_bindings_struct {
} *gss_channel_bindings_t;
*/
static void ntlm_md5_update_uint32_be(MD5_CTX* md5, UINT32 num)
static void ntlm_md5_update_uint32_be(WINPR_MD5_CTX* md5, UINT32 num)
{
BYTE be32[4];
be32[0] = (num >> 0) & 0xFF;
be32[1] = (num >> 8) & 0xFF;
be32[2] = (num >> 16) & 0xFF;
be32[3] = (num >> 24) & 0xFF;
MD5_Update(md5, be32, 4);
winpr_MD5_Update(md5, be32, 4);
}
void ntlm_compute_channel_bindings(NTLM_CONTEXT* context)
{
MD5_CTX md5;
WINPR_MD5_CTX md5;
BYTE* ChannelBindingToken;
UINT32 ChannelBindingTokenLength;
SEC_CHANNEL_BINDINGS* ChannelBindings;
@ -269,14 +268,14 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context)
ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS);
ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset];
MD5_Init(&md5);
winpr_MD5_Init(&md5);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength);
ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength);
MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength);
MD5_Final(context->ChannelBindingsHash, &md5);
winpr_MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength);
winpr_MD5_Final(&md5, context->ChannelBindingsHash);
}
void ntlm_compute_single_host_data(NTLM_CONTEXT* context)

View File

@ -28,12 +28,9 @@
#include <winpr/sam.h>
#include <winpr/ntlm.h>
#include <winpr/print.h>
#include <winpr/crypto.h>
#include <winpr/sysinfo.h>
#include <openssl/md5.h>
#include <openssl/rc4.h>
#include <openssl/hmac.h>
#include "ntlm_compute.h"
#include "../../log.h"
@ -343,7 +340,7 @@ int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context)
response = (BYTE*) context->LmChallengeResponse.pvBuffer;
/* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
HMAC(EVP_md5(), (void*) context->NtlmV2Hash, 16, (BYTE*) value, 16, (BYTE*) response, NULL);
winpr_HMAC(WINPR_MD_MD5, (void*) context->NtlmV2Hash, 16, (BYTE*) value, 16, (BYTE*) response);
/* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */
CopyMemory(&response[16], context->ClientChallenge, 8);
return 1;
@ -412,8 +409,8 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
blob = (BYTE*) ntlm_v2_temp_chal.pvBuffer;
CopyMemory(blob, context->ServerChallenge, 8);
CopyMemory(&blob[8], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
HMAC(EVP_md5(), (BYTE*) context->NtlmV2Hash, 16, (BYTE*) ntlm_v2_temp_chal.pvBuffer,
ntlm_v2_temp_chal.cbBuffer, (BYTE*) nt_proof_str, NULL);
winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, 16, (BYTE*) ntlm_v2_temp_chal.pvBuffer,
ntlm_v2_temp_chal.cbBuffer, (BYTE*) nt_proof_str);
/* NtChallengeResponse, Concatenate NTProofStr with temp */
@ -424,7 +421,7 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
CopyMemory(blob, nt_proof_str, 16);
CopyMemory(&blob[16], ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
/* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */
HMAC(EVP_md5(), (BYTE*) context->NtlmV2Hash, 16, (BYTE*) nt_proof_str, 16, (BYTE*) context->SessionBaseKey, NULL);
winpr_HMAC(WINPR_MD_MD5, (BYTE*) context->NtlmV2Hash, 16, (BYTE*) nt_proof_str, 16, (BYTE*) context->SessionBaseKey);
sspi_SecBufferFree(&ntlm_v2_temp);
sspi_SecBufferFree(&ntlm_v2_temp_chal);
return 1;
@ -440,11 +437,10 @@ int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
void ntlm_rc4k(BYTE* key, int length, BYTE* plaintext, BYTE* ciphertext)
{
RC4_KEY rc4;
/* Initialize RC4 cipher with key */
RC4_set_key(&rc4, 16, (void*) key);
/* Encrypt plaintext with key */
RC4(&rc4, length, (void*) plaintext, (void*) ciphertext);
WINPR_RC4_CTX rc4;
winpr_RC4_Init(&rc4, (void*) key, 16);
winpr_RC4_Update(&rc4, length, (void*) plaintext, (void*) ciphertext);
winpr_RC4_Final(&rc4);
}
/**
@ -456,7 +452,7 @@ void ntlm_generate_client_challenge(NTLM_CONTEXT* context)
{
/* ClientChallenge is used in computation of LMv2 and NTLMv2 responses */
if (memcmp(context->ClientChallenge, NTLM_NULL_BUFFER, 8) == 0)
RAND_bytes(context->ClientChallenge, 8);
winpr_RAND(context->ClientChallenge, 8);
}
/**
@ -467,7 +463,7 @@ void ntlm_generate_client_challenge(NTLM_CONTEXT* context)
void ntlm_generate_server_challenge(NTLM_CONTEXT* context)
{
if (memcmp(context->ServerChallenge, NTLM_NULL_BUFFER, 8) == 0)
RAND_bytes(context->ServerChallenge, 8);
winpr_RAND(context->ServerChallenge, 8);
}
/**
@ -489,7 +485,7 @@ void ntlm_generate_key_exchange_key(NTLM_CONTEXT* context)
void ntlm_generate_random_session_key(NTLM_CONTEXT* context)
{
RAND_bytes(context->RandomSessionKey, 16);
winpr_RAND(context->RandomSessionKey, 16);
}
/**
@ -546,7 +542,7 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic,
{
int length;
BYTE* value;
MD5_CTX md5;
WINPR_MD5_CTX md5;
length = 16 + sign_magic->cbBuffer;
value = (BYTE*) malloc(length);
@ -557,9 +553,9 @@ int ntlm_generate_signing_key(BYTE* exported_session_key, PSecBuffer sign_magic,
/* Concatenate ExportedSessionKey with sign magic */
CopyMemory(value, exported_session_key, 16);
CopyMemory(&value[16], sign_magic->pvBuffer, sign_magic->cbBuffer);
MD5_Init(&md5);
MD5_Update(&md5, value, length);
MD5_Final(signing_key, &md5);
winpr_MD5_Init(&md5);
winpr_MD5_Update(&md5, value, length);
winpr_MD5_Final(&md5, signing_key);
free(value);
return 1;
}
@ -603,7 +599,7 @@ void ntlm_generate_server_signing_key(NTLM_CONTEXT* context)
int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic, BYTE* sealing_key)
{
BYTE* p;
MD5_CTX md5;
WINPR_MD5_CTX md5;
SecBuffer buffer;
if (!sspi_SecBufferAlloc(&buffer, 16 + seal_magic->cbBuffer))
@ -613,9 +609,9 @@ int ntlm_generate_sealing_key(BYTE* exported_session_key, PSecBuffer seal_magic,
/* Concatenate ExportedSessionKey with seal magic */
CopyMemory(p, exported_session_key, 16);
CopyMemory(&p[16], seal_magic->pvBuffer, seal_magic->cbBuffer);
MD5_Init(&md5);
MD5_Update(&md5, buffer.pvBuffer, buffer.cbBuffer);
MD5_Final(sealing_key, &md5);
winpr_MD5_Init(&md5);
winpr_MD5_Update(&md5, buffer.pvBuffer, buffer.cbBuffer);
winpr_MD5_Final(&md5, sealing_key);
sspi_SecBufferFree(&buffer);
return 1;
}
@ -661,8 +657,8 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
context->RecvSigningKey = context->ClientSigningKey;
context->SendSealingKey = context->ClientSealingKey;
context->RecvSealingKey = context->ServerSealingKey;
RC4_set_key((RC4_KEY*) context->SendRc4Seal, 16, context->ServerSealingKey);
RC4_set_key((RC4_KEY*) context->RecvRc4Seal, 16, context->ClientSealingKey);
winpr_RC4_Init(&context->SendRc4Seal, context->ServerSealingKey, 16);
winpr_RC4_Init(&context->RecvRc4Seal, context->ClientSealingKey, 16);
}
else
{
@ -670,23 +666,22 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
context->RecvSigningKey = context->ServerSigningKey;
context->SendSealingKey = context->ServerSealingKey;
context->RecvSealingKey = context->ClientSealingKey;
RC4_set_key((RC4_KEY*) context->SendRc4Seal, 16, context->ClientSealingKey);
RC4_set_key((RC4_KEY*) context->RecvRc4Seal, 16, context->ServerSealingKey);
winpr_RC4_Init(&context->SendRc4Seal, context->ClientSealingKey, 16);
winpr_RC4_Init(&context->RecvRc4Seal, context->ServerSealingKey, 16);
}
}
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context)
{
HMAC_CTX hmac_ctx;
WINPR_HMAC_CTX hmac;
/*
* Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE,
* CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey
*/
HMAC_CTX_init(&hmac_ctx);
HMAC_Init_ex(&hmac_ctx, context->ExportedSessionKey, 16, EVP_md5(), NULL);
HMAC_Update(&hmac_ctx, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
HMAC_Update(&hmac_ctx, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
HMAC_Update(&hmac_ctx, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer);
HMAC_Final(&hmac_ctx, context->MessageIntegrityCheck, NULL);
HMAC_CTX_cleanup(&hmac_ctx);
winpr_HMAC_Init(&hmac, WINPR_MD_MD5, context->ExportedSessionKey, 16);
winpr_HMAC_Update(&hmac, (BYTE*) context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
winpr_HMAC_Update(&hmac, (BYTE*) context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
winpr_HMAC_Update(&hmac, (BYTE*) context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer);
winpr_HMAC_Final(&hmac, context->MessageIntegrityCheck);
}