libfreerdp-core: fix computation of session key blob
This commit is contained in:
parent
2d08b1bd82
commit
08c14ddf33
@ -235,6 +235,46 @@ uint8 client_platform_challenge_response[66] =
|
||||
"\x02\x71\x38\x23\x62\x5d\x10\x8b\x93\xc3\xf1\xe4\x67\x1f\x4a\xb6"
|
||||
"\x00\x0a";
|
||||
|
||||
uint8 license_server_modulus[256] =
|
||||
"\x88\xad\x7c\x8f\x8b\x82\x76\x5a\xbd\x8f\x6f\x62\x18\xe1\xd9\xaa"
|
||||
"\x41\xfd\xed\x68\x01\xc6\x34\x35\xb0\x29\x04\xca\x4a\x4a\x1c\x7e"
|
||||
"\x80\x14\xf7\x8e\x77\xb8\x25\xff\x16\x47\x6f\xbd\xe2\x34\x3d\x2e"
|
||||
"\x02\xb9\x53\xe4\x33\x75\xad\x73\x28\x80\xa0\x4d\xfc\x6c\xc0\x22"
|
||||
"\x53\x1b\x2c\xf8\xf5\x01\x60\x19\x7e\x79\x19\x39\x8d\xb5\xce\x39"
|
||||
"\x58\xdd\x55\x24\x3b\x55\x7b\x43\xc1\x7f\x14\x2f\xb0\x64\x3a\x54"
|
||||
"\x95\x2b\x88\x49\x0c\x61\x2d\xac\xf8\x45\xf5\xda\x88\x18\x5f\xae"
|
||||
"\x42\xf8\x75\xc7\x26\x6d\xb5\xbb\x39\x6f\xcc\x55\x1b\x32\x11\x38"
|
||||
"\x8d\xe4\xe9\x44\x84\x11\x36\xa2\x61\x76\xaa\x4c\xb4\xe3\x55\x0f"
|
||||
"\xe4\x77\x8e\xde\xe3\xa9\xea\xb7\x41\x94\x00\x58\xaa\xc9\x34\xa2"
|
||||
"\x98\xc6\x01\x1a\x76\x14\x01\xa8\xdc\x30\x7c\x77\x5a\x20\x71\x5a"
|
||||
"\xa2\x3f\xaf\x13\x7e\xe8\xfd\x84\xa2\x5b\xcf\x25\xe9\xc7\x8f\xa8"
|
||||
"\xf2\x8b\x84\xc7\x04\x5e\x53\x73\x4e\x0e\x89\xa3\x3c\xe7\x68\x5c"
|
||||
"\x24\xb7\x80\x53\x3c\x54\xc8\xc1\x53\xaa\x71\x71\x3d\x36\x15\xd6"
|
||||
"\x6a\x9d\x7d\xde\xae\xf9\xe6\xaf\x57\xae\xb9\x01\x96\x5d\xe0\x4d"
|
||||
"\xcd\xed\xc8\xd7\xf3\x01\x03\x38\x10\xbe\x7c\x42\x67\x01\xa7\x23";
|
||||
|
||||
uint8 license_server_exponent[4] = "\x00\x01\x00\x01";
|
||||
|
||||
uint8 terminal_server_modulus[256] =
|
||||
"\xc8\x90\x6b\xf0\xc6\x58\x81\xa6\x89\x1c\x0e\xf2\xf6\xd9\x82\x12"
|
||||
"\x71\xa5\x6e\x51\xdb\xe0\x32\x66\xaa\x91\x77\x0e\x88\xab\x44\xb7"
|
||||
"\xd3\x97\xda\x78\x8f\x0e\x44\x26\x46\x7f\x16\xd4\xc6\x63\xeb\xca"
|
||||
"\x55\xe5\x4e\x8b\x2d\xa6\x6d\x83\x95\xa7\xa8\x6a\xfa\xd0\xbe\x26"
|
||||
"\x80\xae\xab\x0a\x64\x90\x32\x8c\xdf\x5c\xf8\xf9\xd0\x7e\xd1\x6b"
|
||||
"\x3a\x29\x7e\x7d\xbd\x02\xa3\x86\x6c\xfd\xa5\x35\x71\xda\x21\xb4"
|
||||
"\xee\xa4\x97\xf3\xa8\xb2\x12\xdb\xa4\x27\x57\x36\xc9\x08\x22\x5c"
|
||||
"\x54\xf7\x99\x7b\xa3\x2f\xb8\x5c\xd5\x16\xb8\x19\x27\x6b\x71\x97"
|
||||
"\x14\x5b\xe8\x1f\x23\xe8\x5c\xb8\x1b\x73\x4b\x6e\x7a\x03\x13\xff"
|
||||
"\x97\xe9\x62\xb9\x4a\xa0\x51\x23\xc3\x6c\x32\x3e\x02\xf2\x63\x97"
|
||||
"\x23\x1c\xc5\x78\xd8\xfc\xb7\x07\x4b\xb0\x56\x0f\x74\xdf\xc5\x56"
|
||||
"\x28\xe4\x96\xfd\x20\x8e\x65\x5a\xe6\x45\xed\xc1\x05\x3e\xab\x58"
|
||||
"\x55\x40\xaf\xe2\x47\xa0\x4c\x49\xa3\x8d\x39\xe3\x66\x5f\x93\x33"
|
||||
"\x6d\xf8\x5f\xc5\x54\xe5\xfb\x57\x3a\xde\x45\x12\xb5\xc7\x05\x4b"
|
||||
"\x88\x1f\xb4\x35\x0f\x7c\xc0\x75\x17\xc6\x67\xdd\x48\x80\xcb\x0a"
|
||||
"\xbe\x9d\xf6\x93\x60\x65\x34\xeb\x97\xaf\x65\x6d\xdf\xbf\x6f\x5b";
|
||||
|
||||
uint8 terminal_server_exponent[4] = "\x00\x01\x00\x01";
|
||||
|
||||
uint8 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";
|
||||
@ -267,6 +307,8 @@ uint8 encrypted_premaster_secret[264] =
|
||||
"\x09\x83\x0b\xbc\x3d\x3e\x05\x47\x65\x96\x31\x8c\x6b\xc5\xe6\xa0"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
|
||||
uint8 platform_challenge[10] = "\x54\x00\x45\x00\x53\x00\x54\x00\x00\x00";
|
||||
|
||||
void test_license(void)
|
||||
{
|
||||
STREAM* s;
|
||||
|
@ -270,6 +270,14 @@ 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);
|
||||
}
|
||||
else if (numCertBlobs - i == 1)
|
||||
{
|
||||
|
@ -152,6 +152,8 @@ void license_generate_randoms(rdpLicense* license)
|
||||
|
||||
void license_generate_keys(rdpLicense* license)
|
||||
{
|
||||
int paddingLength;
|
||||
|
||||
security_master_secret(license->premaster_secret, license->client_random,
|
||||
license->server_random, license->master_secret); /* MasterSecret */
|
||||
|
||||
@ -164,15 +166,24 @@ 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 */
|
||||
|
||||
paddingLength = MODULUS_MAX_SIZE - license->certificate->cert_info.modulus.length;
|
||||
|
||||
memset(license->modulus, 0, paddingLength);
|
||||
memcpy(&license->modulus[paddingLength],
|
||||
license->certificate->cert_info.modulus.data,
|
||||
MODULUS_MAX_SIZE - paddingLength);
|
||||
|
||||
memcpy(license->exponent, license->certificate->cert_info.exponent, EXPONENT_MAX_SIZE);
|
||||
|
||||
/* EncryptedPremasterSecret */
|
||||
|
||||
license->encrypted_pre_master_secret->type = BB_ANY_BLOB;
|
||||
license->encrypted_pre_master_secret->length = RSA_MAX_KEY_LENGTH + 8;
|
||||
license->encrypted_pre_master_secret->data = (uint8*) xzalloc(RSA_MAX_KEY_LENGTH + 8);
|
||||
license->encrypted_pre_master_secret->length = MODULUS_MAX_SIZE + 8;
|
||||
license->encrypted_pre_master_secret->data = (uint8*) xzalloc(MODULUS_MAX_SIZE + 8);
|
||||
|
||||
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);
|
||||
crypto_rsa(PREMASTER_SECRET_LENGTH, license->premaster_secret,
|
||||
license->encrypted_pre_master_secret->data,
|
||||
MODULUS_MAX_SIZE, license->modulus, license->exponent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,9 @@ typedef struct rdp_license rdpLicense;
|
||||
#define HWID_PLATFORM_ID_LENGTH 4
|
||||
#define HWID_UNIQUE_DATA_LENGTH 16
|
||||
#define HWID_LENGTH 20
|
||||
#define RSA_MAX_KEY_LENGTH 256
|
||||
#define MODULUS_MAX_SIZE 256
|
||||
#define EXPONENT_MAX_SIZE 4
|
||||
#define LICENSING_PADDING_SIZE 8
|
||||
|
||||
/* Licensing Preamble Flags */
|
||||
#define PREAMBLE_VERSION_2_0 0x02
|
||||
@ -108,6 +110,8 @@ struct rdp_license
|
||||
struct rdp_rdp* rdp;
|
||||
struct rdp_certificate* certificate;
|
||||
uint8 hwid[HWID_LENGTH];
|
||||
uint8 modulus[MODULUS_MAX_SIZE];
|
||||
uint8 exponent[EXPONENT_MAX_SIZE];
|
||||
uint8 client_random[CLIENT_RANDOM_LENGTH];
|
||||
uint8 server_random[SERVER_RANDOM_LENGTH];
|
||||
uint8 master_secret[MASTER_SECRET_LENGTH];
|
||||
|
@ -40,32 +40,32 @@ static uint8 pad2[48] =
|
||||
"\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)
|
||||
void security_salted_hash(uint8* salt, uint8* input, int length, uint8* salt1, uint8* salt2, uint8* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
uint8 sha1_digest[20];
|
||||
|
||||
/* SaltedHash(Salt, Input) = MD5(S + SHA1(Input + Salt + ClientRandom + ServerRandom)) */
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */
|
||||
|
||||
/* SHA1_Digest = SHA1(Input + Salt + ClientRandom + ServerRandom) */
|
||||
/* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */
|
||||
sha1 = crypto_sha1_init();
|
||||
crypto_sha1_update(sha1, input, length); /* Input */
|
||||
crypto_sha1_update(sha1, salt, 48); /* Salt */
|
||||
crypto_sha1_update(sha1, client_random, 32); /* ClientRandom */
|
||||
crypto_sha1_update(sha1, server_random, 32); /* ServerRandom */
|
||||
crypto_sha1_update(sha1, salt, 48); /* Salt (48 bytes) */
|
||||
crypto_sha1_update(sha1, salt1, 32); /* Salt1 (32 bytes) */
|
||||
crypto_sha1_update(sha1, salt2, 32); /* Salt2 (32 bytes) */
|
||||
crypto_sha1_final(sha1, sha1_digest);
|
||||
|
||||
/* SaltedHash(S, I) = MD5(S + SHA1_Digest) */
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */
|
||||
md5 = crypto_md5_init();
|
||||
crypto_md5_update(md5, salt, 48); /* Salt */
|
||||
crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */
|
||||
crypto_md5_update(md5, sha1_digest, 20); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, output);
|
||||
}
|
||||
|
||||
void security_premaster_hash(uint8* input, int length, uint8* premaster_secret, uint8* client_random, uint8* server_random, uint8* output)
|
||||
{
|
||||
/* PremasterHash(Input) = SaltedHash(PremasterSecret, Input) */
|
||||
/* PremasterHash(Input) = SaltedHash(PremasterSecret, Input, ClientRandom, ServerRandom) */
|
||||
security_salted_hash(premaster_secret, input, length, client_random, server_random, output);
|
||||
}
|
||||
|
||||
@ -79,8 +79,8 @@ void security_master_secret(uint8* premaster_secret, uint8* client_random, uint8
|
||||
|
||||
void security_master_hash(uint8* input, int length, uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output)
|
||||
{
|
||||
/* MasterHash(Input) = SaltedHash(MasterSecret, Input) */
|
||||
security_salted_hash(master_secret, input, length, client_random, server_random, output);
|
||||
/* MasterHash(Input) = SaltedHash(MasterSecret, Input, ServerRandom, ClientRandom) */
|
||||
security_salted_hash(master_secret, input, length, server_random, client_random, output);
|
||||
}
|
||||
|
||||
void security_session_key_blob(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output)
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
void security_salted_hash(uint8* salt, uint8* input, int length, uint8* client_random, uint8* server_random, uint8* output);
|
||||
void security_salted_hash(uint8* salt, uint8* input, int length, uint8* salt1, uint8* salt2, uint8* output);
|
||||
void security_premaster_hash(uint8* input, int length, uint8* premaster_secret, uint8* client_random, uint8* server_random, uint8* output);
|
||||
void security_master_secret(uint8* premaster_secret, uint8* client_random, uint8* server_random, uint8* output);
|
||||
void security_master_hash(uint8* input, int length, uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output);
|
||||
|
Loading…
Reference in New Issue
Block a user