libfreerdp-crypto: NLA debug output improvements

This commit is contained in:
Marc-André Moreau
2012-06-15 22:39:12 -04:00
parent b55f958e5d
commit 1bf69d644e
2 changed files with 92 additions and 99 deletions

View File

@@ -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})

View File

@@ -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;