libfreerdp-core: licensing cryptographic response

This commit is contained in:
Marc-André Moreau 2011-07-13 10:21:12 -04:00
parent fe6cab1761
commit 685c8d4635
8 changed files with 147 additions and 12 deletions

View File

@ -261,8 +261,8 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
{
printf(", Terminal Server Certificate\n");
freerdp_hexdump(certificate->x509_cert_chain->array[i].data, certificate->x509_cert_chain->array[i].length);
certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->termserv_cert_info);
printf("modulus length:%d\n", certificate->termserv_cert_info.modulus.length);
certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->cert_info);
printf("modulus length:%d\n", certificate->cert_info.modulus.length);
}
else
printf("\n");

View File

@ -58,7 +58,7 @@ typedef struct
struct rdp_certificate
{
struct rdp_rdp* rdp;
CERT_INFO termserv_cert_info;
CERT_INFO cert_info;
X509_CERT_CHAIN* x509_cert_chain;
};

View File

@ -127,6 +127,31 @@ exit:
return status;
}
void crypto_rsa(int length, uint8* in, uint8* out, uint32 modulus_length, uint8* modulus, uint8* exponent)
{
BN_CTX* ctx;
int out_length;
BIGNUM mod, exp, x, y;
ctx = BN_CTX_new();
BN_init(&mod);
BN_init(&exp);
BN_init(&x);
BN_init(&y);
BN_bin2bn(modulus, modulus_length, &mod);
BN_bin2bn(exponent, 4, &exp);
BN_bin2bn(in, length, &x);
BN_mod_exp(&y, &x, &exp, &mod, ctx);
out_length = BN_bn2bin(&y, out);
BN_free(&y);
BN_clear_free(&x);
BN_free(&exp);
BN_free(&mod);
BN_CTX_free(ctx);
}
void crypto_nonce(uint8* nonce, int size)
{
RAND_bytes((void*) nonce, size);

View File

@ -80,6 +80,8 @@ void crypto_cert_free(CryptoCert cert);
boolean crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert);
boolean crypto_cert_get_public_key(CryptoCert cert, BLOB* public_key);
void crypto_rsa(int length, uint8* in, uint8* out, uint32 modulus_length, uint8* modulus, uint8* exponent);
void crypto_nonce(uint8* nonce, int size);
#endif /* __CRYPTO_H */

View File

@ -161,8 +161,17 @@ void license_generate_keys(rdpLicense* license)
security_licensing_encryption_key(license->session_key_blob, license->client_random,
license->server_random, license->licensing_encryption_key); /* LicensingEncryptionKey */
/* EncryptedPremasterSecret */
license->encrypted_pre_master_secret->length = 72;
license->encrypted_pre_master_secret->type = BB_ANY_BLOB;
license->encrypted_pre_master_secret->data = (uint8*) xzalloc(72);
#if 0
crypto_rsa(PREMASTER_SECRET_LENGTH, license->premaster_secret, license->encrypted_pre_master_secret->data,
license->certificate->cert_info.modulus.length, license->certificate->cert_info.modulus.data,
license->certificate->cert_info.exponent);
#endif
}
/**
@ -408,6 +417,9 @@ void license_read_license_request_packet(rdpLicense* license, STREAM* s)
/* Parse Server Certificate */
certificate_read_server_certificate(license->certificate,
license->server_certificate->data, license->server_certificate->length);
license_generate_keys(license);
license_generate_hwid(license);
}
/**
@ -419,14 +431,35 @@ void license_read_license_request_packet(rdpLicense* license, STREAM* s)
void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s)
{
CryptoRc4 rc4;
uint8* platform_challenge;
DEBUG_LICENSE("Receiving Platform Challenge Packet");
stream_seek(s, 4); /* ConnectFlags, Reserved (4 bytes) */
/* EncryptedPlatformChallenge */
license_read_binary_blob(s, license->encrypted_platform_challenge);
/* MACData (16 bytes) */
stream_seek(s, 16);
printf("encrypted platform challenge\n", license->encrypted_platform_challenge->length);
freerdp_hexdump(license->encrypted_platform_challenge->data, license->encrypted_platform_challenge->length);
platform_challenge = (uint8*) xmalloc(license->encrypted_platform_challenge->length);
rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
crypto_rc4(rc4, license->encrypted_platform_challenge->length,
license->encrypted_platform_challenge->data, platform_challenge);
printf("decrypted platform challenge\n", license->encrypted_platform_challenge->length);
freerdp_hexdump(platform_challenge, license->encrypted_platform_challenge->length);
license->encrypted_platform_challenge->type = BB_ENCRYPTED_DATA_BLOB;
crypto_rc4_free(rc4);
}
/**
@ -515,8 +548,6 @@ void license_send_new_license_request_packet(rdpLicense* license)
license->client_machine_name->data = license->rdp->settings->hostname;
license->client_machine_name->length = strlen(license->rdp->settings->hostname);
license_generate_keys(license);
license_write_new_license_request_packet(license, s);
license_send(license, s, NEW_LICENSE_REQUEST);
@ -533,18 +564,19 @@ void license_send_new_license_request_packet(rdpLicense* license)
* @msdn{cc241922}
* @param license license module
* @param s stream
* @param mac_data signature
*/
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s)
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, uint8* mac_data)
{
license_generate_hwid(license);
/* EncryptedPlatformChallengeResponse */
license_read_binary_blob(s, license->encrypted_platform_challenge);
license_write_binary_blob(s, license->encrypted_platform_challenge);
/* EncryptedHWID */
license_write_binary_blob(s, license->encrypted_hwid);
/* MACData */
stream_write(s, mac_data, 16);
}
/**
@ -556,11 +588,27 @@ void license_write_platform_challenge_response_packet(rdpLicense* license, STREA
void license_send_platform_challenge_response_packet(rdpLicense* license)
{
STREAM* s;
int length;
uint8* buffer;
CryptoRc4 rc4;
uint8 mac_data[16];
s = license_send_stream_init(license);
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
license_write_platform_challenge_response_packet(license, s);
length = license->encrypted_platform_challenge->length + license->encrypted_hwid->length;
buffer = (uint8*) xmalloc(length);
security_mac_data(license->mac_salt_key, buffer, length, mac_data);
xfree(buffer);
buffer = (uint8*) xmalloc(HWID_LENGTH);
rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer);
license->encrypted_hwid->data = buffer;
license->encrypted_hwid->length = HWID_LENGTH;
license_write_platform_challenge_response_packet(license, s, mac_data);
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
@ -588,6 +636,7 @@ rdpLicense* license_new(rdpRdp* rdp)
license->client_user_name = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB);
license->client_machine_name = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB);
license->encrypted_platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
license->encrypted_hwid = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB);
license->scope_list = license_new_scope_list();
}
@ -611,6 +660,7 @@ void license_free(rdpLicense* license)
license_free_binary_blob(license->client_user_name);
license_free_binary_blob(license->client_machine_name);
license_free_binary_blob(license->encrypted_platform_challenge);
license_free_binary_blob(license->encrypted_hwid);
license_free_scope_list(license->scope_list);
xfree(license);
}

View File

@ -121,6 +121,7 @@ struct rdp_license
LICENSE_BLOB* client_machine_name;
LICENSE_BLOB* encrypted_pre_master_secret;
LICENSE_BLOB* encrypted_platform_challenge;
LICENSE_BLOB* encrypted_hwid;
SCOPE_LIST* scope_list;
};
@ -153,7 +154,7 @@ void license_read_error_alert_packet(rdpLicense* license, STREAM* s);
void license_write_new_license_request_packet(rdpLicense* license, STREAM* s);
void license_send_new_license_request_packet(rdpLicense* license);
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s);
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, uint8* mac_data);
void license_send_platform_challenge_response_packet(rdpLicense* license);
rdpLicense* license_new(rdpRdp* rdp);

View File

@ -19,6 +19,27 @@
#include "security.h"
/* 0x36 repeated 40 times */
static uint8 pad1[40] =
{
"\x36\x36\x36\x36\x36\x36\x36\x36"
"\x36\x36\x36\x36\x36\x36\x36\x36"
"\x36\x36\x36\x36\x36\x36\x36\x36"
"\x36\x36\x36\x36\x36\x36\x36\x36"
"\x36\x36\x36\x36\x36\x36\x36\x36"
};
/* 0x5C repeated 48 times */
static uint8 pad2[48] =
{
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
"\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C"
};
void security_salted_hash(uint8* salt, uint8* input, int length, uint8* client_random, uint8* server_random, uint8* output)
{
CryptoMd5 md5;
@ -89,3 +110,38 @@ void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_ra
crypto_md5_final(md5, output);
}
void security_uint32_le(uint8* output, uint32 value)
{
output[0] = (value) & 0xFF;
output[1] = (value >> 8) & 0xFF;
output[2] = (value >> 16) & 0xFF;
output[3] = (value >> 24) & 0xFF;
}
void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output)
{
CryptoMd5 md5;
CryptoSha1 sha1;
uint8 length_le[4];
uint8 sha1_digest[20];
/* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */
security_uint32_le(length_le, length); /* length must be little-endian */
/* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */
sha1 = crypto_sha1_init();
crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */
crypto_sha1_update(sha1, data, length); /* data */
crypto_sha1_final(sha1, sha1_digest);
/* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */
md5 = crypto_md5_init();
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
crypto_md5_update(md5, sha1_digest, 20); /* SHA1_Digest */
crypto_md5_final(md5, output);
}

View File

@ -33,5 +33,6 @@ void security_master_hash(uint8* input, int length, uint8* master_secret, uint8*
void security_session_key_blob(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output);
void security_mac_salt_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output);
void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output);
void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output);
#endif /* __SECURITY_H */