libfreerdp-core: add new unit tests for licensing, fix encryption of premaster secret
This commit is contained in:
parent
08c14ddf33
commit
288aacb6e9
@ -46,6 +46,9 @@ int add_license_suite(void)
|
||||
add_test_suite(license);
|
||||
|
||||
add_test_function(license);
|
||||
add_test_function(license_generate_keys);
|
||||
add_test_function(license_encrypt_premaster_secret);
|
||||
add_test_function(license_decrypt_platform_challenge);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -322,6 +325,7 @@ void test_license(void)
|
||||
s->p = s->data + LICENSE_PREAMBLE_LENGTH;
|
||||
license_read_license_request_packet(license, s);
|
||||
|
||||
#if 0
|
||||
printf("\n");
|
||||
|
||||
printf("client random:\n");
|
||||
@ -361,14 +365,136 @@ void test_license(void)
|
||||
freerdp_hexdump(license->certificate->cert_info.exponent, 4);
|
||||
printf("\n");
|
||||
|
||||
/* the encrypted premaster secret is 256 + 8 bytes long, with 8 bytes of padding */
|
||||
|
||||
printf("encrypted premaster secret:\n");
|
||||
freerdp_hexdump(license->encrypted_pre_master_secret->data,
|
||||
license->encrypted_pre_master_secret->length);
|
||||
freerdp_hexdump(license->encrypted_premaster_secret->data,
|
||||
license->encrypted_premaster_secret->length);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
s->data = server_platform_challenge;
|
||||
s->p = s->data + LICENSE_PREAMBLE_LENGTH;
|
||||
license_read_platform_challenge_packet(license, s);
|
||||
}
|
||||
|
||||
uint8 test_client_random[32] =
|
||||
"\xdc\x73\xa0\xc8\x69\x25\x6b\x18\xaf\x0b\x94\x7a\xa9\xa5\x20\xaf"
|
||||
"\x8b\xbc\x0d\xcc\xa3\x95\xb7\xb9\xeb\x81\x5d\xbe\x0a\x10\x9c\xd8";
|
||||
|
||||
uint8 test_server_random[32] =
|
||||
"\x16\x7e\xf8\x71\x48\x16\x1a\x4f\xa5\x2c\xcd\x73\x63\x60\xa6\xc3"
|
||||
"\xb9\x19\x1b\x4b\x6b\xb2\x0a\xb8\xec\xf1\x8d\x95\x4e\xa8\x21\xc5";
|
||||
|
||||
uint8 test_premaster_secret[48] =
|
||||
"\xcf\x7a\xdb\xcb\xfb\x0e\x15\x23\x87\x1c\x84\x81\xba\x9d\x4e\x15"
|
||||
"\xbb\xd2\x56\xbd\xd8\xf7\xf3\x16\xcc\x35\x3b\xe1\x93\x42\x78\xdd"
|
||||
"\x92\x9a\xe4\x7a\xe2\x99\xd4\x73\xb1\xaa\x6f\x55\x94\x3b\xc9\xbc";
|
||||
|
||||
uint8 test_modulus[64] =
|
||||
"\x23\xc9\xec\x0e\x9f\x1e\x0e\x1a\x78\xaf\xa5\x14\xd4\xf5\x45\xe4"
|
||||
"\x04\x6e\xf4\x01\xe9\xdf\x45\xd1\xc2\xae\xf4\x7f\xd3\xb9\xcb\xf3"
|
||||
"\x1a\x23\xa1\x0d\x4b\xd4\xd1\x4a\xd2\xd1\xc9\x7c\xab\x24\x8b\xb1"
|
||||
"\x5a\x93\xca\x34\x44\x17\xb5\xe4\xfe\xf7\x9a\xaa\x72\x0d\x41\x95";
|
||||
|
||||
uint8 test_exponent[4] = "\x01\x00\x01\x00";
|
||||
|
||||
uint8 test_master_secret[48] =
|
||||
"\xbe\x51\xee\x63\x23\x90\xd0\xf4\x3a\xce\x3a\x37\x65\xc3\xdd\xcf"
|
||||
"\xed\xf0\xc8\x19\xed\x77\x33\x4e\xfd\x2b\x7d\x5a\xe2\xca\xf3\x0a"
|
||||
"\xf1\x16\xe5\x0c\x78\x59\x7e\xd4\x4b\x57\xce\x17\x60\x3a\x5a\xb3";
|
||||
|
||||
uint8 test_session_key_blob[48] =
|
||||
"\x07\x4f\xa0\x2e\xee\xc4\x5a\x46\x21\x8c\xae\x01\x45\x02\x26\xe4"
|
||||
"\x54\x6b\x59\x10\xcc\x5b\xd1\x96\xd0\x5c\xeb\xc2\x96\x9b\x44\x7b"
|
||||
"\x1c\xd9\x66\xb1\x9e\x24\xaa\x60\x4f\x89\xd1\x4e\xf8\xb9\x55\x3b";
|
||||
|
||||
uint8 test_mac_salt_key[16] =
|
||||
"\x07\x4f\xa0\x2e\xee\xc4\x5a\x46\x21\x8c\xae\x01\x45\x02\x26\xe4";
|
||||
|
||||
uint8 test_licensing_encryption_key[16] =
|
||||
"\xf3\xb1\xe0\x3b\xfe\xb4\xf2\xc5\x28\xa9\x48\xcd\x90\xf1\x93\xe5";
|
||||
|
||||
uint8 test_encrypted_premaster_secret[64] =
|
||||
"\x6b\xbc\x77\x9f\x20\x0c\x98\x39\xc1\x85\x77\xc8\x19\x87\xd8\x82"
|
||||
"\x93\xbd\x21\x69\x5f\x87\xe0\xd6\x4e\xad\x5e\x23\x13\x80\x8c\x63"
|
||||
"\x3e\xd6\x6e\x60\xc9\x40\xe9\x86\x08\x8c\xd5\xaa\xa9\x54\xfe\x27"
|
||||
"\x4c\x1f\x87\x57\xde\xca\xd4\xc7\x1e\x46\x9e\x00\x7a\xdb\x47\x23";
|
||||
|
||||
void test_license_generate_keys(void)
|
||||
{
|
||||
STREAM* s;
|
||||
s = stream_new(0);
|
||||
|
||||
memcpy(license->client_random, client_random, sizeof(client_random));
|
||||
memcpy(license->server_random, test_server_random, sizeof(test_server_random));
|
||||
memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret));
|
||||
memcpy(license->certificate->cert_info.exponent, test_exponent, sizeof(test_exponent));
|
||||
memcpy(license->certificate->cert_info.modulus.data, test_modulus, sizeof(test_modulus));
|
||||
license->certificate->cert_info.modulus.length = sizeof(test_modulus);
|
||||
|
||||
license_generate_keys(license);
|
||||
license_encrypt_premaster_secret(license);
|
||||
|
||||
s->data = license->master_secret;
|
||||
s->p = s->data + sizeof(test_master_secret);
|
||||
ASSERT_STREAM(s, test_master_secret, sizeof(test_master_secret));
|
||||
|
||||
s->data = license->session_key_blob;
|
||||
s->p = s->data + sizeof(test_session_key_blob);
|
||||
ASSERT_STREAM(s, test_session_key_blob, sizeof(test_session_key_blob));
|
||||
|
||||
s->data = license->mac_salt_key;
|
||||
s->p = s->data + sizeof(test_mac_salt_key);
|
||||
ASSERT_STREAM(s, test_mac_salt_key, sizeof(test_mac_salt_key));
|
||||
|
||||
s->data = license->licensing_encryption_key;
|
||||
s->p = s->data + sizeof(test_licensing_encryption_key);
|
||||
ASSERT_STREAM(s, test_licensing_encryption_key, sizeof(test_licensing_encryption_key));
|
||||
|
||||
s->data = license->encrypted_premaster_secret->data;
|
||||
s->p = s->data + sizeof(test_encrypted_premaster_secret);
|
||||
ASSERT_STREAM(s, test_encrypted_premaster_secret, sizeof(test_encrypted_premaster_secret));
|
||||
}
|
||||
|
||||
void test_license_encrypt_premaster_secret(void)
|
||||
{
|
||||
STREAM* s;
|
||||
s = stream_new(0);
|
||||
|
||||
memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret));
|
||||
memcpy(license->certificate->cert_info.exponent, test_exponent, sizeof(test_exponent));
|
||||
memcpy(license->certificate->cert_info.modulus.data, test_modulus, sizeof(test_modulus));
|
||||
license->certificate->cert_info.modulus.length = sizeof(test_modulus);
|
||||
|
||||
s->data = license->encrypted_premaster_secret->data;
|
||||
s->p = s->data + sizeof(test_encrypted_premaster_secret);
|
||||
ASSERT_STREAM(s, test_encrypted_premaster_secret, sizeof(test_encrypted_premaster_secret));
|
||||
}
|
||||
|
||||
uint8 test_encrypted_platform_challenge[10] =
|
||||
"\x84\x0a\x42\x50\xad\x5e\xc1\x29\x30\xbd";
|
||||
|
||||
uint8 test_platform_challenge[10] =
|
||||
"\x54\x00\x45\x00\x53\x00\x54\x00\x00\x00";
|
||||
|
||||
void test_license_decrypt_platform_challenge(void)
|
||||
{
|
||||
STREAM* s;
|
||||
s = stream_new(0);
|
||||
|
||||
memcpy(license->licensing_encryption_key, test_licensing_encryption_key,
|
||||
sizeof(test_licensing_encryption_key));
|
||||
|
||||
license->encrypted_platform_challenge->data =
|
||||
(uint8*) xmalloc(sizeof(test_encrypted_platform_challenge));
|
||||
license->encrypted_platform_challenge->length =
|
||||
sizeof(test_encrypted_platform_challenge);
|
||||
|
||||
memcpy(license->encrypted_platform_challenge->data, test_encrypted_platform_challenge,
|
||||
sizeof(test_encrypted_platform_challenge));
|
||||
|
||||
license_decrypt_platform_challenge(license);
|
||||
|
||||
s->data = license->platform_challenge->data;
|
||||
s->p = s->data + sizeof(test_platform_challenge);
|
||||
ASSERT_STREAM(s, test_platform_challenge, sizeof(test_platform_challenge));
|
||||
}
|
||||
|
@ -24,3 +24,6 @@ int clean_license_suite(void);
|
||||
int add_license_suite(void);
|
||||
|
||||
void test_license(void);
|
||||
void test_license_generate_keys(void);
|
||||
void test_license_encrypt_premaster_secret(void);
|
||||
void test_license_decrypt_platform_challenge(void);
|
||||
|
@ -251,7 +251,7 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
uint32 certLength;
|
||||
uint32 numCertBlobs;
|
||||
|
||||
printf("\nServer X.509 Certificate Chain\n");
|
||||
DEBUG_CERTIFICATE("Server X.509 Certificate Chain");
|
||||
|
||||
stream_read_uint32(s, numCertBlobs); /* numCertBlobs */
|
||||
|
||||
@ -261,7 +261,7 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
{
|
||||
stream_read_uint32(s, certLength);
|
||||
|
||||
printf("\nX.509 Certificate #%d, length:%d", i + 1, certLength);
|
||||
DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength);
|
||||
|
||||
certificate->x509_cert_chain->array[i].data = (uint8*) xmalloc(certLength);
|
||||
stream_read(s, certificate->x509_cert_chain->array[i].data, certLength);
|
||||
@ -269,25 +269,17 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
|
||||
|
||||
if (numCertBlobs - i == 2)
|
||||
{
|
||||
printf(", License 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->cert_info);
|
||||
|
||||
//printf("license modulus (%d):\n", certificate->cert_info.modulus.length);
|
||||
//freerdp_hexdump(certificate->cert_info.modulus.data, certificate->cert_info.modulus.length);
|
||||
|
||||
//printf("license exponent:\n");
|
||||
//freerdp_hexdump(certificate->cert_info.exponent, 4);
|
||||
CERT_INFO cert_info;
|
||||
DEBUG_CERTIFICATE("License Server Certificate");
|
||||
certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &cert_info);
|
||||
DEBUG_LICENSE("modulus length:%d", cert_info.modulus.length);
|
||||
}
|
||||
else if (numCertBlobs - i == 1)
|
||||
{
|
||||
printf(", Terminal Server Certificate\n");
|
||||
//freerdp_hexdump(certificate->x509_cert_chain->array[i].data, certificate->x509_cert_chain->array[i].length);
|
||||
DEBUG_CERTIFICATE("Terminal Server Certificate");
|
||||
certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->cert_info);
|
||||
printf("modulus length:%d\n", certificate->cert_info.modulus.length);
|
||||
DEBUG_CERTIFICATE("modulus length:%d", certificate->cert_info.modulus.length);
|
||||
}
|
||||
else
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,4 +74,12 @@ void certificate_read_server_certificate(rdpCertificate* certificate, uint8* ser
|
||||
rdpCertificate* certificate_new(rdpRdp* rdp);
|
||||
void certificate_free(rdpCertificate* certificate);
|
||||
|
||||
//#define WITH_DEBUG_CERTIFICATE 1
|
||||
|
||||
#ifdef WITH_DEBUG_CERTIFICATE
|
||||
#define DEBUG_CERTIFICATE(fmt, ...) DEBUG_CLASS(CERTIFICATE, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_CERTIFICATE(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif /* __CERTIFICATE_H */
|
||||
|
@ -127,29 +127,62 @@ exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
void crypto_rsa(int length, uint8* in, uint8* out, uint32 modulus_length, uint8* modulus, uint8* exponent)
|
||||
void crypto_rsa_encrypt(uint8* input, int length, uint32 key_length, uint8* modulus, uint8* exponent, uint8* output)
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
int out_length;
|
||||
int output_length;
|
||||
uint8* input_reverse;
|
||||
uint8* modulus_reverse;
|
||||
uint8* exponent_reverse;
|
||||
BIGNUM mod, exp, x, y;
|
||||
|
||||
input_reverse = (uint8*) xmalloc(2 * MODULUS_MAX_SIZE + EXPONENT_MAX_SIZE);
|
||||
modulus_reverse = input_reverse + MODULUS_MAX_SIZE;
|
||||
exponent_reverse = modulus_reverse + MODULUS_MAX_SIZE;
|
||||
|
||||
memcpy(modulus_reverse, modulus, key_length);
|
||||
crypto_reverse(modulus_reverse, key_length);
|
||||
memcpy(exponent_reverse, exponent, EXPONENT_MAX_SIZE);
|
||||
crypto_reverse(exponent_reverse, EXPONENT_MAX_SIZE);
|
||||
memcpy(input_reverse, input, length);
|
||||
crypto_reverse(input_reverse, length);
|
||||
|
||||
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_bin2bn(modulus_reverse, key_length, &mod);
|
||||
BN_bin2bn(exponent_reverse, EXPONENT_MAX_SIZE, &exp);
|
||||
BN_bin2bn(input_reverse, length, &x);
|
||||
BN_mod_exp(&y, &x, &exp, &mod, ctx);
|
||||
out_length = BN_bn2bin(&y, out);
|
||||
|
||||
output_length = BN_bn2bin(&y, output);
|
||||
crypto_reverse(output, output_length);
|
||||
|
||||
if (output_length < (int) key_length)
|
||||
memset(output + output_length, 0, key_length - output_length);
|
||||
|
||||
BN_free(&y);
|
||||
BN_clear_free(&x);
|
||||
BN_free(&exp);
|
||||
BN_free(&mod);
|
||||
BN_CTX_free(ctx);
|
||||
xfree(input_reverse);
|
||||
}
|
||||
|
||||
void crypto_reverse(uint8* data, int length)
|
||||
{
|
||||
int i, j;
|
||||
uint8 temp;
|
||||
|
||||
for (i = 0, j = length - 1; i < j; i++, j--)
|
||||
{
|
||||
temp = data[i];
|
||||
data[i] = data[j];
|
||||
data[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void crypto_nonce(uint8* nonce, int size)
|
||||
|
@ -35,6 +35,9 @@
|
||||
#define D2I_X509_CONST
|
||||
#endif
|
||||
|
||||
#define EXPONENT_MAX_SIZE 4
|
||||
#define MODULUS_MAX_SIZE 256
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/blob.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
@ -80,8 +83,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_rsa_encrypt(uint8* input, int length, uint32 key_length, uint8* modulus, uint8* exponent, uint8* output);
|
||||
void crypto_reverse(uint8* data, int length);
|
||||
void crypto_nonce(uint8* nonce, int size);
|
||||
|
||||
#endif /* __CRYPTO_H */
|
||||
|
@ -166,6 +166,7 @@ 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 */
|
||||
|
||||
#if 0
|
||||
paddingLength = MODULUS_MAX_SIZE - license->certificate->cert_info.modulus.length;
|
||||
|
||||
memset(license->modulus, 0, paddingLength);
|
||||
@ -177,13 +178,36 @@ void license_generate_keys(rdpLicense* license)
|
||||
|
||||
/* EncryptedPremasterSecret */
|
||||
|
||||
license->encrypted_pre_master_secret->type = BB_ANY_BLOB;
|
||||
license->encrypted_pre_master_secret->length = MODULUS_MAX_SIZE + 8;
|
||||
license->encrypted_pre_master_secret->data = (uint8*) xzalloc(MODULUS_MAX_SIZE + 8);
|
||||
license->encrypted_premaster_secret->type = BB_ANY_BLOB;
|
||||
license->encrypted_premaster_secret->length = 64;
|
||||
license->encrypted_premaster_secret->data = (uint8*) xzalloc(64);
|
||||
#endif
|
||||
|
||||
crypto_rsa(PREMASTER_SECRET_LENGTH, license->premaster_secret,
|
||||
license->encrypted_pre_master_secret->data,
|
||||
#if 0
|
||||
crypto_rsa(MODULUS_MAX_SIZE, license->premaster_secret,
|
||||
license->encrypted_premaster_secret->data,
|
||||
MODULUS_MAX_SIZE, license->modulus, license->exponent);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
//ssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus, uint8 * exponent)
|
||||
|
||||
/*
|
||||
ssl_rsa_encrypt(pEncryptedPreMasterSecret, license_v3->ClientPreMasterSecret,
|
||||
48, license_v3->server_public_key_len, license_v3->modulus,
|
||||
license_v3->exponent);
|
||||
*/
|
||||
|
||||
exponent = license->certificate->cert_info.exponent;
|
||||
modulus = license->certificate->cert_info.modulus.data;
|
||||
key_length = license->certificate->cert_info.modulus.length;
|
||||
|
||||
encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE);
|
||||
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
|
||||
|
||||
crypto_rsa_encrypt(encrypted_premaster_secret,
|
||||
license->premaster_secret, 48, 64, modulus, exponent);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,6 +228,55 @@ void license_generate_hwid(rdpLicense* license)
|
||||
crypto_md5_final(md5, &license->hwid[HWID_PLATFORM_ID_LENGTH]);
|
||||
}
|
||||
|
||||
void license_encrypt_premaster_secret(rdpLicense* license)
|
||||
{
|
||||
int key_length;
|
||||
uint8* modulus;
|
||||
uint8* exponent;
|
||||
uint8* encrypted_premaster_secret;
|
||||
|
||||
exponent = license->certificate->cert_info.exponent;
|
||||
modulus = license->certificate->cert_info.modulus.data;
|
||||
key_length = license->certificate->cert_info.modulus.length;
|
||||
|
||||
encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE);
|
||||
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
|
||||
|
||||
crypto_rsa_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH,
|
||||
key_length, modulus, exponent, encrypted_premaster_secret);
|
||||
|
||||
license->encrypted_premaster_secret->type = BB_ANY_BLOB;
|
||||
license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH;
|
||||
license->encrypted_premaster_secret->data = encrypted_premaster_secret;
|
||||
}
|
||||
|
||||
void license_decrypt_platform_challenge(rdpLicense* license)
|
||||
{
|
||||
CryptoRc4 rc4;
|
||||
|
||||
license->platform_challenge->data =
|
||||
(uint8*) xmalloc(license->encrypted_platform_challenge->length);
|
||||
license->platform_challenge->length =
|
||||
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,
|
||||
license->platform_challenge->data);
|
||||
|
||||
#if 0
|
||||
printf("encrypted_platform challenge:\n");
|
||||
freerdp_hexdump(license->encrypted_platform_challenge->data,
|
||||
license->encrypted_platform_challenge->length);
|
||||
|
||||
printf("platform challenge:\n");
|
||||
freerdp_hexdump(license->platform_challenge->data, license->platform_challenge->length);
|
||||
#endif
|
||||
|
||||
crypto_rc4_free(rc4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Product Information (PRODUCT_INFO).\n
|
||||
* @msdn{cc241915}
|
||||
@ -308,6 +381,17 @@ void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob)
|
||||
stream_write(s, blob->data, blob->length); /* blobData */
|
||||
}
|
||||
|
||||
void license_write_padded_binary_blob(STREAM* s, LICENSE_BLOB* blob)
|
||||
{
|
||||
stream_write_uint16(s, blob->type); /* wBlobType (2 bytes) */
|
||||
stream_write_uint16(s, blob->length + LICENSING_PADDING_SIZE); /* wBlobLen (2 bytes) */
|
||||
|
||||
if (blob->length > 0)
|
||||
stream_write(s, blob->data, blob->length); /* blobData */
|
||||
|
||||
stream_write_zero(s, LICENSING_PADDING_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate New License Binary Blob (LICENSE_BINARY_BLOB).\n
|
||||
* @msdn{cc240481}
|
||||
@ -432,6 +516,7 @@ void license_read_license_request_packet(rdpLicense* license, STREAM* s)
|
||||
|
||||
license_generate_keys(license);
|
||||
license_generate_hwid(license);
|
||||
license_encrypt_premaster_secret(license);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,20 +543,7 @@ void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s)
|
||||
/* MACData (16 bytes) */
|
||||
stream_seek(s, 16);
|
||||
|
||||
printf("encrypted platform challenge\n");
|
||||
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");
|
||||
freerdp_hexdump(platform_challenge, license->encrypted_platform_challenge->length);
|
||||
|
||||
crypto_rc4_free(rc4);
|
||||
license_decrypt_platform_challenge(license);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,7 +608,7 @@ void license_write_new_license_request_packet(rdpLicense* license, STREAM* s)
|
||||
stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* PreferredKeyExchangeAlg (4 bytes) */
|
||||
license_write_platform_id(license, s); /* PlatformId (4 bytes) */
|
||||
stream_write(s, license->client_random, 32); /* ClientRandom (32 bytes) */
|
||||
license_write_binary_blob(s, license->encrypted_pre_master_secret); /* EncryptedPreMasterSecret */
|
||||
license_write_padded_binary_blob(s, license->encrypted_premaster_secret); /* EncryptedPremasterSecret */
|
||||
license_write_binary_blob(s, license->client_user_name); /* ClientUserName */
|
||||
license_write_binary_blob(s, license->client_machine_name); /* ClientMachineName */
|
||||
}
|
||||
@ -644,10 +716,11 @@ rdpLicense* license_new(rdpRdp* rdp)
|
||||
license->product_info = license_new_product_info();
|
||||
license->key_exchange_list = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB);
|
||||
license->server_certificate = license_new_binary_blob(BB_CERTIFICATE_BLOB);
|
||||
license->encrypted_pre_master_secret = license_new_binary_blob(BB_RANDOM_BLOB);
|
||||
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->platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
|
||||
license->encrypted_platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
|
||||
license->encrypted_premaster_secret = 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();
|
||||
license_generate_randoms(license);
|
||||
@ -669,10 +742,11 @@ void license_free(rdpLicense* license)
|
||||
license_free_product_info(license->product_info);
|
||||
license_free_binary_blob(license->key_exchange_list);
|
||||
license_free_binary_blob(license->server_certificate);
|
||||
license_free_binary_blob(license->encrypted_pre_master_secret);
|
||||
license_free_binary_blob(license->client_user_name);
|
||||
license_free_binary_blob(license->client_machine_name);
|
||||
license_free_binary_blob(license->platform_challenge);
|
||||
license_free_binary_blob(license->encrypted_platform_challenge);
|
||||
license_free_binary_blob(license->encrypted_premaster_secret);
|
||||
license_free_binary_blob(license->encrypted_hwid);
|
||||
license_free_scope_list(license->scope_list);
|
||||
xfree(license);
|
||||
|
@ -58,8 +58,6 @@ typedef struct rdp_license rdpLicense;
|
||||
#define HWID_PLATFORM_ID_LENGTH 4
|
||||
#define HWID_UNIQUE_DATA_LENGTH 16
|
||||
#define HWID_LENGTH 20
|
||||
#define MODULUS_MAX_SIZE 256
|
||||
#define EXPONENT_MAX_SIZE 4
|
||||
#define LICENSING_PADDING_SIZE 8
|
||||
|
||||
/* Licensing Preamble Flags */
|
||||
@ -124,7 +122,8 @@ struct rdp_license
|
||||
LICENSE_BLOB* server_certificate;
|
||||
LICENSE_BLOB* client_user_name;
|
||||
LICENSE_BLOB* client_machine_name;
|
||||
LICENSE_BLOB* encrypted_pre_master_secret;
|
||||
LICENSE_BLOB* platform_challenge;
|
||||
LICENSE_BLOB* encrypted_premaster_secret;
|
||||
LICENSE_BLOB* encrypted_platform_challenge;
|
||||
LICENSE_BLOB* encrypted_hwid;
|
||||
SCOPE_LIST* scope_list;
|
||||
@ -137,6 +136,8 @@ STREAM* license_send_stream_init(rdpLicense* license);
|
||||
void license_generate_randoms(rdpLicense* license);
|
||||
void license_generate_keys(rdpLicense* license);
|
||||
void license_generate_hwid(rdpLicense* license);
|
||||
void license_encrypt_premaster_secret(rdpLicense* license);
|
||||
void license_decrypt_platform_challenge(rdpLicense* license);
|
||||
|
||||
PRODUCT_INFO* license_new_product_info();
|
||||
void license_free_product_info(PRODUCT_INFO* productInfo);
|
||||
|
Loading…
Reference in New Issue
Block a user