libfreerdp-crypto: fix server-side NLA with certificate store

This commit is contained in:
Marc-André Moreau 2012-06-27 11:10:17 +02:00
parent d0e1d39dbc
commit a1355135c5
2 changed files with 52 additions and 23 deletions

View File

@ -519,7 +519,11 @@ int credssp_server_authenticate(rdpCredssp* credssp)
return 0; return 0;
} }
credssp_decrypt_public_key_echo(credssp); if (credssp_decrypt_public_key_echo(credssp) != SEC_E_OK)
{
printf("Error: could not verify client's public key echo\n");
return -1;
}
sspi_SecBufferFree(&credssp->negoToken); sspi_SecBufferFree(&credssp->negoToken);
credssp->negoToken.pvBuffer = NULL; credssp->negoToken.pvBuffer = NULL;
@ -599,28 +603,69 @@ int credssp_authenticate(rdpCredssp* credssp)
return credssp_client_authenticate(credssp); return credssp_client_authenticate(credssp);
} }
void ap_integer_increment_le(BYTE* number, int size)
{
int index;
for (index = 0; index < size; index++)
{
if (number[index] < 0xFF)
{
number[index]++;
break;
}
else
{
number[index] = 0;
continue;
}
}
}
void ap_integer_decrement_le(BYTE* number, int size)
{
int index;
for (index = 0; index < size; index++)
{
if (number[index] > 0)
{
number[index]--;
break;
}
else
{
number[index] = 0xFF;
continue;
}
}
}
SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp) SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp)
{ {
SecBuffer Buffers[2]; SecBuffer Buffers[2];
SecBufferDesc Message; SecBufferDesc Message;
SECURITY_STATUS status; SECURITY_STATUS status;
int public_key_length;
public_key_length = credssp->PublicKey.cbBuffer;
Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */
Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */ Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */
sspi_SecBufferAlloc(&credssp->pubKeyAuth, credssp->ContextSizes.cbMaxSignature + credssp->PublicKey.cbBuffer); sspi_SecBufferAlloc(&credssp->pubKeyAuth, credssp->ContextSizes.cbMaxSignature + public_key_length);
Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature; Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature;
Buffers[0].pvBuffer = credssp->pubKeyAuth.pvBuffer; Buffers[0].pvBuffer = credssp->pubKeyAuth.pvBuffer;
Buffers[1].cbBuffer = credssp->PublicKey.cbBuffer; Buffers[1].cbBuffer = public_key_length;
Buffers[1].pvBuffer = ((BYTE*) credssp->pubKeyAuth.pvBuffer) + credssp->ContextSizes.cbMaxSignature; Buffers[1].pvBuffer = ((BYTE*) credssp->pubKeyAuth.pvBuffer) + credssp->ContextSizes.cbMaxSignature;
CopyMemory(Buffers[1].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[1].cbBuffer); CopyMemory(Buffers[1].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[1].cbBuffer);
if (credssp->server) if (credssp->server)
{ {
/* server echos the public key +1 */ /* server echos the public key +1 */
((BYTE*) Buffers[1].pvBuffer)[0]++; ap_integer_increment_le((BYTE*) Buffers[1].pvBuffer, Buffers[1].cbBuffer);
} }
Message.cBuffers = 2; Message.cBuffers = 2;
@ -689,7 +734,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp)
if (!credssp->server) if (!credssp->server)
{ {
/* server echos the public key +1 */ /* server echos the public key +1 */
public_key2[0]--; ap_integer_decrement_le(public_key2, public_key_length);
} }
if (memcmp(public_key1, public_key2, public_key_length) != 0) if (memcmp(public_key1, public_key2, public_key_length) != 0)
@ -705,8 +750,6 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp)
return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */ return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */
} }
public_key2[0]++;
free(buffer); free(buffer);
return SEC_E_OK; return SEC_E_OK;

View File

@ -467,7 +467,7 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
if (common_name) if (common_name)
{ {
xfree(common_name); xfree(common_name);
common_name=NULL ; common_name = NULL;
} }
verification_status = true; /* success! */ verification_status = true; /* success! */
@ -508,7 +508,7 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
if (!accept_certificate) if (!accept_certificate)
{ {
/* user did not accept, abort and do not add entry in known_hosts file */ /* user did not accept, abort and do not add entry in known_hosts file */
verification_status = false; /* failure! */ verification_status = false; /* failure! */
} }
else else
{ {
@ -533,20 +533,6 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
xfree(fingerprint); xfree(fingerprint);
} }
#ifndef _WIN32
if (common_name)
xfree(common_name);
if (alt_names)
{
for (index = 0; index < alt_names_count; index++)
xfree(alt_names[index]);
xfree(alt_names);
xfree(alt_names_lengths) ;
}
#endif
if (certificate_data) if (certificate_data)
{ {
xfree(certificate_data->fingerprint); xfree(certificate_data->fingerprint);