mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-crypto: NLA debug output improvements
This commit is contained in:
@@ -109,7 +109,10 @@ target_link_libraries(freerdp-core freerdp-locale)
|
||||
target_link_libraries(freerdp-core winpr-utils)
|
||||
target_link_libraries(freerdp-core winpr-rpc)
|
||||
target_link_libraries(freerdp-core winpr-sspi)
|
||||
target_link_libraries(freerdp-core winpr-registry)
|
||||
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(freerdp-core winpr-registry)
|
||||
endif()
|
||||
|
||||
target_link_libraries(freerdp-core freerdp-crypto)
|
||||
target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES})
|
||||
|
||||
@@ -82,7 +82,8 @@ void credssp_send(rdpCredssp* credssp);
|
||||
int credssp_recv(rdpCredssp* credssp);
|
||||
void credssp_buffer_print(rdpCredssp* credssp);
|
||||
void credssp_buffer_free(rdpCredssp* credssp);
|
||||
SECURITY_STATUS credssp_verify_public_key_echo(rdpCredssp* credssp);
|
||||
SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp);
|
||||
SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp);
|
||||
void credssp_encode_ts_credentials(rdpCredssp* credssp);
|
||||
SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp);
|
||||
SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp);
|
||||
@@ -216,12 +217,11 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
have_context = false;
|
||||
have_input_buffer = false;
|
||||
have_pub_key_auth = false;
|
||||
memset(&input_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&output_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&credssp->ContextSizes, 0, sizeof(SecPkgContext_Sizes));
|
||||
ZeroMemory(&input_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&output_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
|
||||
|
||||
fContextReq = ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_IDENTIFY |
|
||||
ISC_REQ_EXTENDED_ERROR | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT;
|
||||
fContextReq = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_EXTENDED_ERROR;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -257,52 +257,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (have_pub_key_auth)
|
||||
{
|
||||
BYTE* p;
|
||||
SecBuffer Buffers[2];
|
||||
SecBufferDesc Message;
|
||||
SECURITY_STATUS encrypt_status;
|
||||
|
||||
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
|
||||
Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
|
||||
|
||||
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
|
||||
Buffers[0].pvBuffer = xzalloc(Buffers[0].cbBuffer);
|
||||
|
||||
Buffers[1].cbBuffer = credssp->PublicKey.cbBuffer;
|
||||
Buffers[1].pvBuffer = malloc(Buffers[1].cbBuffer);
|
||||
CopyMemory(Buffers[1].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[1].cbBuffer);
|
||||
|
||||
Message.cBuffers = 2;
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
|
||||
sspi_SecBufferAlloc(&credssp->pubKeyAuth, Buffers[0].cbBuffer + Buffers[1].cbBuffer);
|
||||
|
||||
encrypt_status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, 0);
|
||||
|
||||
if (encrypt_status != SEC_E_OK)
|
||||
{
|
||||
printf("EncryptMessage status: 0x%08X\n", encrypt_status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_CREDSSP
|
||||
printf("CredSSP.Signature: (%d)\n", (int) Buffers[0].cbBuffer);
|
||||
winpr_HexDump((BYTE*) Buffers[0].pvBuffer, Buffers[0].cbBuffer);
|
||||
printf("CredSSP.PublicKey: (%d)\n", (int) credssp->PublicKey.cbBuffer);
|
||||
winpr_HexDump((BYTE*) credssp->PublicKey.pvBuffer, credssp->PublicKey.cbBuffer);
|
||||
printf("CredSSP.PublicKey (encrypted) (%d):\n", (int) Buffers[1].cbBuffer);
|
||||
winpr_HexDump((BYTE*) Buffers[1].pvBuffer, Buffers[1].cbBuffer);
|
||||
#endif
|
||||
|
||||
p = (BYTE*) credssp->pubKeyAuth.pvBuffer;
|
||||
CopyMemory(p, Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Message Signature */
|
||||
CopyMemory(&p[Buffers[0].cbBuffer], Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Encrypted Public Key */
|
||||
free(Buffers[0].pvBuffer);
|
||||
free(Buffers[1].pvBuffer);
|
||||
}
|
||||
credssp_encrypt_public_key_echo(credssp);
|
||||
|
||||
if (status == SEC_I_COMPLETE_NEEDED)
|
||||
status = SEC_E_OK;
|
||||
@@ -360,11 +315,14 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
||||
|
||||
/* Verify Server Public Key Echo */
|
||||
|
||||
status = credssp_verify_public_key_echo(credssp);
|
||||
status = credssp_decrypt_public_key_echo(credssp);
|
||||
credssp_buffer_free(credssp);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
return 0;
|
||||
{
|
||||
printf("Could not verify public key echo!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send encrypted credentials */
|
||||
|
||||
@@ -422,7 +380,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
INIT_SECURITY_INTERFACE InitSecurityInterface;
|
||||
PSecurityFunctionTable pSecurityInterface = NULL;
|
||||
|
||||
hSSPI = LoadLibrary(_T("secur32.dll"));
|
||||
hSSPI = LoadLibrary(_T("security.dll"));
|
||||
|
||||
#ifdef UNICODE
|
||||
InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW");
|
||||
@@ -446,7 +404,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
cbMaxToken = pPackageInfo->cbMaxToken;
|
||||
|
||||
status = credssp->table->AcquireCredentialsHandle(NULL, NTLMSP_NAME,
|
||||
SECPKG_CRED_INBOUND, NULL, &credssp->identity, NULL, NULL, &credentials, &expiration);
|
||||
SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &credentials, &expiration);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
@@ -461,8 +419,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
ZeroMemory(&output_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
|
||||
|
||||
fContextReq = ASC_REQ_REPLAY_DETECT | ASC_REQ_SEQUENCE_DETECT |
|
||||
ASC_REQ_CONFIDENTIALITY | ASC_REQ_DELEGATE;
|
||||
fContextReq = ASC_REQ_CONFIDENTIALITY | ASC_REQ_INTEGRITY | ASC_REQ_EXTENDED_ERROR;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -505,7 +462,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
|
||||
status = credssp->table->AcceptSecurityContext(&credentials,
|
||||
have_context? &credssp->context: NULL,
|
||||
&input_buffer_desc, fContextReq, SECURITY_NETWORK_DREP, &credssp->context,
|
||||
&input_buffer_desc, fContextReq, SECURITY_NATIVE_DREP, &credssp->context,
|
||||
&output_buffer_desc, &pfContextAttr, &expiration);
|
||||
|
||||
if (input_buffer.pvBuffer != NULL)
|
||||
@@ -531,43 +488,15 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
credssp_verify_public_key_echo(credssp);
|
||||
printf("verifying public key echo\n");
|
||||
|
||||
credssp_decrypt_public_key_echo(credssp);
|
||||
|
||||
sspi_SecBufferFree(&credssp->negoToken);
|
||||
credssp->negoToken.pvBuffer = NULL;
|
||||
credssp->negoToken.cbBuffer = 0;
|
||||
|
||||
if (have_pub_key_auth)
|
||||
{
|
||||
BYTE* p;
|
||||
SecBuffer Buffers[2];
|
||||
SecBufferDesc Message;
|
||||
|
||||
Buffers[0].BufferType = SECBUFFER_DATA; /* TLS Public Key */
|
||||
Buffers[1].BufferType = SECBUFFER_TOKEN; /* Signature */
|
||||
|
||||
Buffers[0].cbBuffer = credssp->PublicKey.cbBuffer;
|
||||
Buffers[0].pvBuffer = malloc(Buffers[0].cbBuffer);
|
||||
CopyMemory(Buffers[0].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[0].cbBuffer);
|
||||
|
||||
Buffers[1].cbBuffer = credssp->ContextSizes.cbMaxSignature;
|
||||
Buffers[1].pvBuffer = xzalloc(Buffers[1].cbBuffer);
|
||||
|
||||
Message.cBuffers = 2;
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
|
||||
p = (BYTE*) Buffers[0].pvBuffer;
|
||||
p[0]++; /* Public Key +1 */
|
||||
|
||||
sspi_SecBufferAlloc(&credssp->pubKeyAuth, Buffers[0].cbBuffer + Buffers[1].cbBuffer);
|
||||
|
||||
credssp->table->EncryptMessage(&credssp->context, 0, &Message, 0);
|
||||
|
||||
p = (BYTE*) credssp->pubKeyAuth.pvBuffer;
|
||||
CopyMemory(p, Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Message Signature */
|
||||
CopyMemory(&p[Buffers[1].cbBuffer], Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Encrypted Public Key */
|
||||
}
|
||||
credssp_encrypt_public_key_echo(credssp);
|
||||
|
||||
if (status == SEC_I_COMPLETE_NEEDED)
|
||||
status = SEC_E_OK;
|
||||
@@ -641,7 +570,54 @@ int credssp_authenticate(rdpCredssp* credssp)
|
||||
return credssp_client_authenticate(credssp);
|
||||
}
|
||||
|
||||
SECURITY_STATUS credssp_verify_public_key_echo(rdpCredssp* credssp)
|
||||
SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp)
|
||||
{
|
||||
BYTE* p;
|
||||
SecBuffer Buffers[2];
|
||||
SecBufferDesc Message;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
|
||||
Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
|
||||
|
||||
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
|
||||
Buffers[0].pvBuffer = malloc(Buffers[0].cbBuffer);
|
||||
ZeroMemory(Buffers[0].pvBuffer, Buffers[0].cbBuffer);
|
||||
|
||||
Buffers[1].cbBuffer = credssp->PublicKey.cbBuffer;
|
||||
Buffers[1].pvBuffer = malloc(Buffers[1].cbBuffer);
|
||||
CopyMemory(Buffers[1].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[1].cbBuffer);
|
||||
|
||||
if (credssp->server)
|
||||
{
|
||||
p = (BYTE*) Buffers[1].pvBuffer;
|
||||
p[0]++; /* server echos the public key +1 */
|
||||
}
|
||||
|
||||
Message.cBuffers = 2;
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
|
||||
sspi_SecBufferAlloc(&credssp->pubKeyAuth, Buffers[0].cbBuffer + Buffers[1].cbBuffer);
|
||||
|
||||
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
printf("EncryptMessage status: 0x%08X\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
p = (BYTE*) credssp->pubKeyAuth.pvBuffer;
|
||||
CopyMemory(p, Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Message Signature */
|
||||
CopyMemory(&p[Buffers[0].cbBuffer], Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Encrypted Public Key */
|
||||
free(Buffers[0].pvBuffer);
|
||||
free(Buffers[1].pvBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp)
|
||||
{
|
||||
int length;
|
||||
ULONG pfQOP;
|
||||
@@ -672,7 +648,7 @@ SECURITY_STATUS credssp_verify_public_key_echo(rdpCredssp* credssp)
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
|
||||
status = credssp->table->DecryptMessage(&credssp->context, &Message, 0, &pfQOP);
|
||||
status = credssp->table->DecryptMessage(&credssp->context, &Message, credssp->recv_seq_num++, &pfQOP);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
@@ -902,7 +878,7 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp)
|
||||
|
||||
sspi_SecBufferAlloc(&credssp->authInfo, Buffers[0].cbBuffer + Buffers[1].cbBuffer);
|
||||
|
||||
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, 1);
|
||||
status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, credssp->send_seq_num++);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
return status;
|
||||
@@ -920,6 +896,7 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp)
|
||||
SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp)
|
||||
{
|
||||
BYTE* p;
|
||||
ULONG pfQOP;
|
||||
SecBuffer Buffers[2];
|
||||
SecBufferDesc Message;
|
||||
SECURITY_STATUS status;
|
||||
@@ -927,6 +904,12 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp)
|
||||
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
|
||||
Buffers[1].BufferType = SECBUFFER_DATA; /* TSCredentials */
|
||||
|
||||
if (credssp->authInfo.cbBuffer < 1)
|
||||
{
|
||||
printf("credssp_decrypt_ts_credentials missing authInfo buffer\n");
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
}
|
||||
|
||||
Buffers[0].cbBuffer = 16;
|
||||
Buffers[0].pvBuffer = malloc(Buffers[0].cbBuffer);
|
||||
CopyMemory(Buffers[0].pvBuffer, credssp->authInfo.pvBuffer, Buffers[0].cbBuffer);
|
||||
@@ -942,7 +925,7 @@ SECURITY_STATUS credssp_decrypt_ts_credentials(rdpCredssp* credssp)
|
||||
|
||||
sspi_SecBufferAlloc(&credssp->authInfo, Buffers[0].cbBuffer + Buffers[1].cbBuffer);
|
||||
|
||||
status = credssp->table->DecryptMessage(&credssp->context, &Message, 1, 0);
|
||||
status = credssp->table->DecryptMessage(&credssp->context, &Message, credssp->recv_seq_num++, &pfQOP);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
return status;
|
||||
@@ -1049,6 +1032,9 @@ void credssp_send(rdpCredssp* credssp)
|
||||
ber_write_octet_string(s, credssp->pubKeyAuth.pvBuffer, length);
|
||||
}
|
||||
|
||||
//printf("Sending TSRequest: (%d)\n", stream_get_length(s));
|
||||
//freerdp_hexdump(s->data, stream_get_length(s));
|
||||
|
||||
tls_write(credssp->tls, s->data, stream_get_length(s));
|
||||
stream_free(s);
|
||||
}
|
||||
@@ -1069,6 +1055,7 @@ int credssp_recv(rdpCredssp* credssp)
|
||||
s = stream_new(4096);
|
||||
|
||||
status = tls_read_all(credssp->tls, s->p, stream_get_left(s));
|
||||
s->size = status;
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@@ -1077,6 +1064,9 @@ int credssp_recv(rdpCredssp* credssp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
//printf("Receiving TSRequest: (%d)\n", s->size);
|
||||
//freerdp_hexdump(s->data, s->size);
|
||||
|
||||
/* TSRequest */
|
||||
ber_read_sequence_tag(s, &length);
|
||||
ber_read_contextual_tag(s, 0, &length, true);
|
||||
@@ -1165,9 +1155,9 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings)
|
||||
credssp->tls = tls;
|
||||
credssp->send_seq_num = 0;
|
||||
credssp->recv_seq_num = 0;
|
||||
memset(&credssp->negoToken, 0, sizeof(SecBuffer));
|
||||
memset(&credssp->pubKeyAuth, 0, sizeof(SecBuffer));
|
||||
memset(&credssp->authInfo, 0, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->negoToken, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->pubKeyAuth, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->authInfo, sizeof(SecBuffer));
|
||||
}
|
||||
|
||||
return credssp;
|
||||
|
||||
Reference in New Issue
Block a user