2
* FreeRDP: A Remote Desktop Protocol Client
5
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7
* Licensed under the Apache License, Version 2.0 (the "License");
8
* you may not use this file except in compliance with the License.
9
* You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
20
#include "redirection.h"
24
#ifdef WITH_DEBUG_LICENSE
25
static const char* const LICENSE_MESSAGE_STRINGS[] =
32
"", "", "", "", "", "",
33
"", "", "", "", "", "",
36
"New License Request",
38
"Platform Challenge Response",
39
"", "", "", "", "", "", "", "", "",
43
static const char* const error_codes[] =
46
"ERR_INVALID_SERVER_CERTIFICATE",
51
"ERR_NO_LICENSE_SERVER",
52
"STATUS_VALID_CLIENT",
56
"ERR_INVALID_PRODUCT_ID",
57
"ERR_INVALID_MESSAGE_LENGTH"
60
static const char* const state_transitions[] =
65
"ST_RESET_PHASE_TO_START",
66
"ST_RESEND_LAST_MESSAGE"
71
* Read a licensing preamble.\n
74
* @param bMsgType license message type
75
* @param flags message flags
76
* @param wMsgSize message size
79
void license_read_preamble(STREAM* s, uint8* bMsgType, uint8* flags, uint16* wMsgSize)
81
/* preamble (4 bytes) */
82
stream_read_uint8(s, *bMsgType); /* bMsgType (1 byte) */
83
stream_read_uint8(s, *flags); /* flags (1 byte) */
84
stream_read_uint16(s, *wMsgSize); /* wMsgSize (2 bytes) */
88
* Write a licensing preamble.\n
91
* @param bMsgType license message type
92
* @param flags message flags
93
* @param wMsgSize message size
96
void license_write_preamble(STREAM* s, uint8 bMsgType, uint8 flags, uint16 wMsgSize)
98
/* preamble (4 bytes) */
99
stream_write_uint8(s, bMsgType); /* bMsgType (1 byte) */
100
stream_write_uint8(s, flags); /* flags (1 byte) */
101
stream_write_uint16(s, wMsgSize); /* wMsgSize (2 bytes) */
105
* Initialize a license packet stream.\n
106
* @param license license module
110
STREAM* license_send_stream_init(rdpLicense* license)
113
s = transport_send_stream_init(license->rdp->transport, 4096);
114
stream_seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH);
119
* Send an RDP licensing packet.\n
121
* @param license license module
125
boolean license_send(rdpLicense* license, STREAM* s, uint8 type)
132
DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]);
134
length = stream_get_length(s);
135
stream_set_pos(s, 0);
137
sec_flags = SEC_LICENSE_PKT;
138
wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4;
140
* Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when
141
* running in server mode! This flag seems to be incorrectly documented.
143
flags = PREAMBLE_VERSION_3_0;
145
rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
146
rdp_write_security_header(s, sec_flags);
147
license_write_preamble(s, type, flags, wMsgSize);
149
#ifdef WITH_DEBUG_LICENSE
150
printf("Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize);
151
freerdp_hexdump(s->p - 4, wMsgSize);
154
stream_set_pos(s, length);
155
if (transport_write(license->rdp->transport, s) < 0)
162
* Receive an RDP licensing packet.\n
164
* @param license license module
168
boolean license_recv(rdpLicense* license, STREAM* s)
177
if (!rdp_read_header(license->rdp, s, &length, &channelId))
179
printf("Incorrect RDP header.\n");
183
rdp_read_security_header(s, &sec_flags);
184
if (!(sec_flags & SEC_LICENSE_PKT))
186
stream_rewind(s, RDP_SECURITY_HEADER_LENGTH);
187
if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != true)
189
printf("Unexpected license packet.\n");
195
license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */
197
DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]);
201
case LICENSE_REQUEST:
202
license_read_license_request_packet(license, s);
203
license_send_new_license_request_packet(license);
206
case PLATFORM_CHALLENGE:
207
license_read_platform_challenge_packet(license, s);
208
license_send_platform_challenge_response_packet(license);
212
license_read_new_license_packet(license, s);
215
case UPGRADE_LICENSE:
216
license_read_upgrade_license_packet(license, s);
220
license_read_error_alert_packet(license, s);
224
printf("invalid bMsgType:%d\n", bMsgType);
231
void license_generate_randoms(rdpLicense* license)
234
crypto_nonce(license->client_random, CLIENT_RANDOM_LENGTH); /* ClientRandom */
235
crypto_nonce(license->premaster_secret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
237
memset(license->client_random, 0, CLIENT_RANDOM_LENGTH); /* ClientRandom */
238
memset(license->premaster_secret, 0, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
243
* Generate License Cryptographic Keys.
244
* @param license license module
247
void license_generate_keys(rdpLicense* license)
249
security_master_secret(license->premaster_secret, license->client_random,
250
license->server_random, license->master_secret); /* MasterSecret */
252
security_session_key_blob(license->master_secret, license->client_random,
253
license->server_random, license->session_key_blob); /* SessionKeyBlob */
255
security_mac_salt_key(license->session_key_blob, license->client_random,
256
license->server_random, license->mac_salt_key); /* MacSaltKey */
258
security_licensing_encryption_key(license->session_key_blob, license->client_random,
259
license->server_random, license->licensing_encryption_key); /* LicensingEncryptionKey */
261
#ifdef WITH_DEBUG_LICENSE
262
printf("ClientRandom:\n");
263
freerdp_hexdump(license->client_random, CLIENT_RANDOM_LENGTH);
265
printf("ServerRandom:\n");
266
freerdp_hexdump(license->server_random, SERVER_RANDOM_LENGTH);
268
printf("PremasterSecret:\n");
269
freerdp_hexdump(license->premaster_secret, PREMASTER_SECRET_LENGTH);
271
printf("MasterSecret:\n");
272
freerdp_hexdump(license->master_secret, MASTER_SECRET_LENGTH);
274
printf("SessionKeyBlob:\n");
275
freerdp_hexdump(license->session_key_blob, SESSION_KEY_BLOB_LENGTH);
277
printf("MacSaltKey:\n");
278
freerdp_hexdump(license->mac_salt_key, MAC_SALT_KEY_LENGTH);
280
printf("LicensingEncryptionKey:\n");
281
freerdp_hexdump(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
286
* Generate Unique Hardware Identifier (CLIENT_HARDWARE_ID).\n
287
* @param license license module
290
void license_generate_hwid(rdpLicense* license)
295
memset(license->hwid, 0, HWID_LENGTH);
296
mac_address = license->rdp->transport->tcp->mac_address;
298
md5 = crypto_md5_init();
299
crypto_md5_update(md5, mac_address, 6);
300
crypto_md5_final(md5, &license->hwid[HWID_PLATFORM_ID_LENGTH]);
303
void license_encrypt_premaster_secret(rdpLicense* license)
305
uint8* encrypted_premaster_secret;
310
rdpCertificate *certificate;
312
if (license->server_certificate->length)
313
certificate = license->certificate;
315
certificate = license->rdp->settings->server_cert;
317
exponent = certificate->cert_info.exponent;
318
modulus = certificate->cert_info.modulus.data;
319
key_length = certificate->cert_info.modulus.length;
321
#ifdef WITH_DEBUG_LICENSE
322
printf("modulus (%d bits):\n", key_length * 8);
323
freerdp_hexdump(modulus, key_length);
325
printf("exponent:\n");
326
freerdp_hexdump(exponent, 4);
329
encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE);
330
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
332
crypto_rsa_public_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH,
333
key_length, modulus, exponent, encrypted_premaster_secret);
335
license->encrypted_premaster_secret->type = BB_RANDOM_BLOB;
336
license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH;
337
license->encrypted_premaster_secret->data = encrypted_premaster_secret;
339
encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE);
340
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
342
license->encrypted_premaster_secret->type = BB_RANDOM_BLOB;
343
license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH;
344
license->encrypted_premaster_secret->data = encrypted_premaster_secret;
348
void license_decrypt_platform_challenge(rdpLicense* license)
352
license->platform_challenge->data =
353
(uint8*) xmalloc(license->encrypted_platform_challenge->length);
354
license->platform_challenge->length =
355
license->encrypted_platform_challenge->length;
357
rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
359
crypto_rc4(rc4, license->encrypted_platform_challenge->length,
360
license->encrypted_platform_challenge->data,
361
license->platform_challenge->data);
363
#ifdef WITH_DEBUG_LICENSE
364
printf("encrypted_platform challenge:\n");
365
freerdp_hexdump(license->encrypted_platform_challenge->data,
366
license->encrypted_platform_challenge->length);
368
printf("platform challenge:\n");
369
freerdp_hexdump(license->platform_challenge->data, license->platform_challenge->length);
372
crypto_rc4_free(rc4);
376
* Read Product Information (PRODUCT_INFO).\n
379
* @param productInfo product information
382
void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo)
384
stream_read_uint32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
386
stream_read_uint32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
388
productInfo->pbCompanyName = (uint8*) xmalloc(productInfo->cbCompanyName);
389
stream_read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
391
stream_read_uint32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
393
productInfo->pbProductId = (uint8*) xmalloc(productInfo->cbProductId);
394
stream_read(s, productInfo->pbProductId, productInfo->cbProductId);
398
* Allocate New Product Information (PRODUCT_INFO).\n
400
* @return new product information
403
PRODUCT_INFO* license_new_product_info()
405
PRODUCT_INFO* productInfo;
407
productInfo = (PRODUCT_INFO*) xmalloc(sizeof(PRODUCT_INFO));
409
productInfo->dwVersion = 0;
410
productInfo->cbCompanyName = 0;
411
productInfo->pbCompanyName = NULL;
412
productInfo->cbProductId = 0;
413
productInfo->pbProductId = NULL;
419
* Free Product Information (PRODUCT_INFO).\n
421
* @param productInfo product information
424
void license_free_product_info(PRODUCT_INFO* productInfo)
426
if (productInfo->pbCompanyName != NULL)
427
xfree(productInfo->pbCompanyName);
429
if (productInfo->pbProductId != NULL)
430
xfree(productInfo->pbProductId);
436
* Read License Binary Blob (LICENSE_BINARY_BLOB).\n
439
* @param blob license binary blob
442
void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob)
446
stream_read_uint16(s, wBlobType); /* wBlobType (2 bytes) */
447
stream_read_uint16(s, blob->length); /* wBlobLen (2 bytes) */
450
* Server can choose to not send data by setting len to 0.
451
* If so, it may not bother to set the type, so shortcut the warning
453
if (blob->type != BB_ANY_BLOB && blob->length == 0)
456
if (blob->type != wBlobType && blob->type != BB_ANY_BLOB)
458
printf("license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type);
461
blob->type = wBlobType;
462
blob->data = (uint8*) xmalloc(blob->length);
464
stream_read(s, blob->data, blob->length); /* blobData */
468
* Write License Binary Blob (LICENSE_BINARY_BLOB).\n
471
* @param blob license binary blob
474
void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob)
476
stream_write_uint16(s, blob->type); /* wBlobType (2 bytes) */
477
stream_write_uint16(s, blob->length); /* wBlobLen (2 bytes) */
479
if (blob->length > 0)
480
stream_write(s, blob->data, blob->length); /* blobData */
483
void license_write_padded_binary_blob(STREAM* s, LICENSE_BLOB* blob)
487
pad_len = 72 % blob->length;
488
stream_write_uint16(s, blob->type); /* wBlobType (2 bytes) */
489
stream_write_uint16(s, blob->length + pad_len); /* wBlobLen (2 bytes) */
491
if (blob->length > 0)
492
stream_write(s, blob->data, blob->length); /* blobData */
494
stream_write_zero(s, pad_len);
498
* Allocate New License Binary Blob (LICENSE_BINARY_BLOB).\n
500
* @return new license binary blob
503
LICENSE_BLOB* license_new_binary_blob(uint16 type)
507
blob = (LICENSE_BLOB*) xmalloc(sizeof(LICENSE_BLOB));
516
* Free License Binary Blob (LICENSE_BINARY_BLOB).\n
518
* @param blob license binary blob
521
void license_free_binary_blob(LICENSE_BLOB* blob)
523
if (blob->data != NULL)
530
* Read License Scope List (SCOPE_LIST).\n
533
* @param scopeList scope list
536
void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList)
541
stream_read_uint32(s, scopeCount); /* ScopeCount (4 bytes) */
543
scopeList->count = scopeCount;
544
scopeList->array = (LICENSE_BLOB*) xmalloc(sizeof(LICENSE_BLOB) * scopeCount);
547
for (i = 0; i < scopeCount; i++)
549
scopeList->array[i].type = BB_SCOPE_BLOB;
550
license_read_binary_blob(s, &scopeList->array[i]);
555
* Allocate New License Scope List (SCOPE_LIST).\n
557
* @return new scope list
560
SCOPE_LIST* license_new_scope_list()
562
SCOPE_LIST* scopeList;
564
scopeList = (SCOPE_LIST*) xmalloc(sizeof(SCOPE_LIST));
565
scopeList->count = 0;
566
scopeList->array = NULL;
572
* Free License Scope List (SCOPE_LIST).\n
574
* @param scopeList scope list
577
void license_free_scope_list(SCOPE_LIST* scopeList)
581
for (i = 0; i < scopeList->count; i++)
583
license_free_binary_blob(&scopeList->array[i]);
590
* Read a LICENSE_REQUEST packet.\n
592
* @param license license module
596
void license_read_license_request_packet(rdpLicense* license, STREAM* s)
598
/* ServerRandom (32 bytes) */
599
stream_read(s, license->server_random, 32);
602
license_read_product_info(s, license->product_info);
604
/* KeyExchangeList */
605
license_read_binary_blob(s, license->key_exchange_list);
607
/* ServerCertificate */
608
license_read_binary_blob(s, license->server_certificate);
611
license_read_scope_list(s, license->scope_list);
613
/* Parse Server Certificate */
614
certificate_read_server_certificate(license->certificate,
615
license->server_certificate->data, license->server_certificate->length);
617
license_generate_keys(license);
618
license_generate_hwid(license);
619
license_encrypt_premaster_secret(license);
623
* Read a PLATFORM_CHALLENGE packet.\n
625
* @param license license module
629
void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s)
631
DEBUG_LICENSE("Receiving Platform Challenge Packet");
633
stream_seek(s, 4); /* ConnectFlags, Reserved (4 bytes) */
635
/* EncryptedPlatformChallenge */
636
license->encrypted_platform_challenge->type = BB_ANY_BLOB;
637
license_read_binary_blob(s, license->encrypted_platform_challenge);
638
license->encrypted_platform_challenge->type = BB_ENCRYPTED_DATA_BLOB;
640
/* MACData (16 bytes) */
643
license_decrypt_platform_challenge(license);
647
* Read a NEW_LICENSE packet.\n
649
* @param license license module
653
void license_read_new_license_packet(rdpLicense* license, STREAM* s)
655
DEBUG_LICENSE("Receiving New License Packet");
656
license->state = LICENSE_STATE_COMPLETED;
660
* Read an UPGRADE_LICENSE packet.\n
662
* @param license license module
666
void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s)
668
DEBUG_LICENSE("Receiving Upgrade License Packet");
669
license->state = LICENSE_STATE_COMPLETED;
673
* Read an ERROR_ALERT packet.\n
675
* @param license license module
679
void license_read_error_alert_packet(rdpLicense* license, STREAM* s)
682
uint32 dwStateTransition;
684
stream_read_uint32(s, dwErrorCode); /* dwErrorCode (4 bytes) */
685
stream_read_uint32(s, dwStateTransition); /* dwStateTransition (4 bytes) */
686
license_read_binary_blob(s, license->error_info); /* bbErrorInfo */
688
#ifdef WITH_DEBUG_LICENSE
689
printf("dwErrorCode: %s, dwStateTransition: %s\n",
690
error_codes[dwErrorCode], state_transitions[dwStateTransition]);
693
if (dwErrorCode == STATUS_VALID_CLIENT)
695
license->state = LICENSE_STATE_COMPLETED;
699
switch (dwStateTransition)
702
license->state = LICENSE_STATE_ABORTED;
705
case ST_NO_TRANSITION:
706
license->state = LICENSE_STATE_COMPLETED;
709
case ST_RESET_PHASE_TO_START:
710
license->state = LICENSE_STATE_AWAIT;
713
case ST_RESEND_LAST_MESSAGE:
722
* Write Platform ID.\n
724
* @param license license module
728
void license_write_platform_id(rdpLicense* license, STREAM* s)
730
stream_write_uint8(s, 0); /* Client Operating System Version */
731
stream_write_uint8(s, 0); /* Independent Software Vendor (ISV) */
732
stream_write_uint16(s, 0); /* Client Software Build */
736
* Write a NEW_LICENSE_REQUEST packet.\n
738
* @param license license module
742
void license_write_new_license_request_packet(rdpLicense* license, STREAM* s)
744
stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* PreferredKeyExchangeAlg (4 bytes) */
745
license_write_platform_id(license, s); /* PlatformId (4 bytes) */
746
stream_write(s, license->client_random, 32); /* ClientRandom (32 bytes) */
747
license_write_padded_binary_blob(s, license->encrypted_premaster_secret); /* EncryptedPremasterSecret */
748
license_write_binary_blob(s, license->client_user_name); /* ClientUserName */
749
license_write_binary_blob(s, license->client_machine_name); /* ClientMachineName */
753
* Send a NEW_LICENSE_REQUEST packet.\n
755
* @param license license module
758
void license_send_new_license_request_packet(rdpLicense* license)
763
s = license_send_stream_init(license);
765
if (license->rdp->settings->username != NULL)
766
username = license->rdp->settings->username;
768
username = "username";
770
license->client_user_name->data = (uint8*) username;
771
license->client_user_name->length = strlen(username) + 1;
773
license->client_machine_name->data = (uint8*) license->rdp->settings->client_hostname;
774
license->client_machine_name->length = strlen(license->rdp->settings->client_hostname) + 1;
776
license_write_new_license_request_packet(license, s);
778
license_send(license, s, NEW_LICENSE_REQUEST);
780
license->client_user_name->data = NULL;
781
license->client_user_name->length = 0;
783
license->client_machine_name->data = NULL;
784
license->client_machine_name->length = 0;
788
* Write Client Challenge Response Packet.\n
790
* @param license license module
792
* @param mac_data signature
795
void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, uint8* mac_data)
797
/* EncryptedPlatformChallengeResponse */
798
license_write_binary_blob(s, license->encrypted_platform_challenge);
801
license_write_binary_blob(s, license->encrypted_hwid);
804
stream_write(s, mac_data, 16);
808
* Send Client Challenge Response Packet.\n
810
* @param license license module
813
void license_send_platform_challenge_response_packet(rdpLicense* license)
821
s = license_send_stream_init(license);
822
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
824
license->encrypted_platform_challenge->type = BB_DATA_BLOB;
825
length = license->platform_challenge->length + HWID_LENGTH;
826
buffer = (uint8*) xmalloc(length);
827
memcpy(buffer, license->platform_challenge->data, license->platform_challenge->length);
828
memcpy(&buffer[license->platform_challenge->length], license->hwid, HWID_LENGTH);
829
security_mac_data(license->mac_salt_key, buffer, length, mac_data);
832
buffer = (uint8*) xmalloc(HWID_LENGTH);
833
rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
834
crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer);
835
crypto_rc4_free(rc4);
837
#ifdef WITH_DEBUG_LICENSE
838
printf("Licensing Encryption Key:\n");
839
freerdp_hexdump(license->licensing_encryption_key, 16);
841
printf("HardwareID:\n");
842
freerdp_hexdump(license->hwid, 20);
844
printf("Encrypted HardwareID:\n");
845
freerdp_hexdump(buffer, 20);
848
license->encrypted_hwid->type = BB_DATA_BLOB;
849
license->encrypted_hwid->data = buffer;
850
license->encrypted_hwid->length = HWID_LENGTH;
852
license_write_platform_challenge_response_packet(license, s, mac_data);
854
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
858
* Send Server License Error - Valid Client Packet.\n
860
* @param license license module
863
boolean license_send_valid_client_error_packet(rdpLicense* license)
867
s = license_send_stream_init(license);
869
stream_write_uint32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
870
stream_write_uint32(s, ST_NO_TRANSITION); /* dwStateTransition */
872
license_write_binary_blob(s, license->error_info);
874
license_send(license, s, ERROR_ALERT);
880
* Instantiate new license module.
881
* @param rdp RDP module
882
* @return new license module
885
rdpLicense* license_new(rdpRdp* rdp)
889
license = (rdpLicense*) xzalloc(sizeof(rdpLicense));
894
license->state = LICENSE_STATE_AWAIT;
895
//license->certificate = certificate_new(rdp);
896
license->certificate = certificate_new();
897
license->product_info = license_new_product_info();
898
license->error_info = license_new_binary_blob(BB_ERROR_BLOB);
899
license->key_exchange_list = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB);
900
license->server_certificate = license_new_binary_blob(BB_CERTIFICATE_BLOB);
901
license->client_user_name = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB);
902
license->client_machine_name = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB);
903
license->platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
904
license->encrypted_platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
905
license->encrypted_premaster_secret = license_new_binary_blob(BB_ANY_BLOB);
906
license->encrypted_hwid = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB);
907
license->scope_list = license_new_scope_list();
908
license_generate_randoms(license);
915
* Free license module.
916
* @param license license module to be freed
919
void license_free(rdpLicense* license)
923
certificate_free(license->certificate);
924
license_free_product_info(license->product_info);
925
license_free_binary_blob(license->error_info);
926
license_free_binary_blob(license->key_exchange_list);
927
license_free_binary_blob(license->server_certificate);
928
license_free_binary_blob(license->client_user_name);
929
license_free_binary_blob(license->client_machine_name);
930
license_free_binary_blob(license->platform_challenge);
931
license_free_binary_blob(license->encrypted_platform_challenge);
932
license_free_binary_blob(license->encrypted_premaster_secret);
933
license_free_binary_blob(license->encrypted_hwid);
934
license_free_scope_list(license->scope_list);