mirror of https://github.com/FreeRDP/FreeRDP
libfreerdp-core: licensing cryptographic response
This commit is contained in:
parent
fe6cab1761
commit
685c8d4635
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue