libwinpr-sspi: remove OpenSSL dependency in NTLM SSPI module
This commit is contained in:
parent
5bff1d0fdf
commit
87c42127c7
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user