FreeRDP
license.c
1 /*
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * RDP Licensing
4  *
5  * Copyright 2011-2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
7  * Copyright 2018 David Fort <contact@hardening-consulting.com>
8  * Copyright 2022,2023 Armin Novak <armin.novak@thincast.com>
9  * Copyright 2022,2023 Thincast Technologies GmbH
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 #include <freerdp/config.h>
25 
26 #include "settings.h"
27 
28 #include <freerdp/license.h>
29 
30 #include <winpr/crt.h>
31 #include <winpr/assert.h>
32 #include <winpr/crypto.h>
33 #include <winpr/shell.h>
34 #include <winpr/path.h>
35 #include <winpr/file.h>
36 
37 #include <freerdp/log.h>
38 
39 #include <freerdp/crypto/certificate.h>
40 
41 #include "license.h"
42 
43 #include "../crypto/crypto.h"
44 #include "../crypto/certificate.h"
45 
46 #define TAG FREERDP_TAG("core.license")
47 
48 #if 0
49 #define LICENSE_NULL_CLIENT_RANDOM 1
50 #define LICENSE_NULL_PREMASTER_SECRET 1
51 #endif
52 
53 #define PLATFORM_CHALLENGE_RESPONSE_VERSION 0x0100
54 
56 enum LicenseRequestType
57 {
58  LICENSE_REQUEST = 0x01,
59  PLATFORM_CHALLENGE = 0x02,
60  NEW_LICENSE = 0x03,
61  UPGRADE_LICENSE = 0x04,
62  LICENSE_INFO = 0x12,
63  NEW_LICENSE_REQUEST = 0x13,
64  PLATFORM_CHALLENGE_RESPONSE = 0x15,
65  ERROR_ALERT = 0xFF
66 };
67 
68 // #define LICENSE_PKT_CS_MASK \
69 // (LICENSE_INFO | NEW_LICENSE_REQUEST | PLATFORM_CHALLENGE_RESPONSE | ERROR_ALERT)
70 //#define LICENSE_PKT_SC_MASK \
71 // (LICENSE_REQUEST | PLATFORM_CHALLENGE | NEW_LICENSE | UPGRADE_LICENSE | ERROR_ALERT)
72 //#define LICENSE_PKT_MASK (LICENSE_PKT_CS_MASK | LICENSE_PKT_SC_MASK)
73 
74 #define LICENSE_PREAMBLE_LENGTH 4
75 
76 /* Cryptographic Lengths */
77 
78 #define SERVER_RANDOM_LENGTH 32
79 #define MASTER_SECRET_LENGTH 48
80 #define PREMASTER_SECRET_LENGTH 48
81 #define SESSION_KEY_BLOB_LENGTH 48
82 #define MAC_SALT_KEY_LENGTH 16
83 #define LICENSING_ENCRYPTION_KEY_LENGTH 16
84 #define HWID_PLATFORM_ID_LENGTH 4
85 // #define HWID_UNIQUE_DATA_LENGTH 16
86 #define HWID_LENGTH 20
87 // #define LICENSING_PADDING_SIZE 8
88 
89 /* Preamble Flags */
90 
91 // #define PREAMBLE_VERSION_2_0 0x02
92 #define PREAMBLE_VERSION_3_0 0x03
93 // #define LicenseProtocolVersionMask 0x0F
94 #define EXTENDED_ERROR_MSG_SUPPORTED 0x80
95 
97 enum
98 {
99  BB_ANY_BLOB = 0x0000,
100  BB_DATA_BLOB = 0x0001,
101  BB_RANDOM_BLOB = 0x0002,
102  BB_CERTIFICATE_BLOB = 0x0003,
103  BB_ERROR_BLOB = 0x0004,
104  BB_ENCRYPTED_DATA_BLOB = 0x0009,
105  BB_KEY_EXCHG_ALG_BLOB = 0x000D,
106  BB_SCOPE_BLOB = 0x000E,
107  BB_CLIENT_USER_NAME_BLOB = 0x000F,
108  BB_CLIENT_MACHINE_NAME_BLOB = 0x0010
109 };
110 
111 /* License Key Exchange Algorithms */
112 
113 #define KEY_EXCHANGE_ALG_RSA 0x00000001
114 
117 enum
118 {
119  ERR_INVALID_SERVER_CERTIFICATE = 0x00000001,
120  ERR_NO_LICENSE = 0x00000002,
121  ERR_INVALID_MAC = 0x00000003,
122  ERR_INVALID_SCOPE = 0x00000004,
123  ERR_NO_LICENSE_SERVER = 0x00000006,
124  STATUS_VALID_CLIENT = 0x00000007,
125  ERR_INVALID_CLIENT = 0x00000008,
126  ERR_INVALID_PRODUCT_ID = 0x0000000B,
127  ERR_INVALID_MESSAGE_LENGTH = 0x0000000C
128 };
129 
132 enum
133 {
134  ST_TOTAL_ABORT = 0x00000001,
135  ST_NO_TRANSITION = 0x00000002,
136  ST_RESET_PHASE_TO_START = 0x00000003,
137  ST_RESEND_LAST_MESSAGE = 0x00000004
138 };
139 
142 enum
143 {
144  WIN32_PLATFORM_CHALLENGE_TYPE = 0x0100,
145  WIN16_PLATFORM_CHALLENGE_TYPE = 0x0200,
146  WINCE_PLATFORM_CHALLENGE_TYPE = 0x0300,
147  OTHER_PLATFORM_CHALLENGE_TYPE = 0xFF00
148 };
149 
152 enum
153 {
154  LICENSE_DETAIL_SIMPLE = 0x0001,
155  LICENSE_DETAIL_MODERATE = 0x0002,
156  LICENSE_DETAIL_DETAIL = 0x0003
157 };
158 
159 /*
160  * PlatformId:
161  *
162  * The most significant byte of the PlatformId field contains the operating system version of the
163  * client. The second most significant byte of the PlatformId field identifies the ISV that provided
164  * the client image. The remaining two bytes in the PlatformId field are used by the ISV to identify
165  * the build number of the operating system.
166  *
167  * 0x04010000:
168  *
169  * CLIENT_OS_ID_WINNT_POST_52 (0x04000000)
170  * CLIENT_IMAGE_ID_MICROSOFT (0x00010000)
171  */
172 enum
173 {
174  CLIENT_OS_ID_WINNT_351 = 0x01000000,
175  CLIENT_OS_ID_WINNT_40 = 0x02000000,
176  CLIENT_OS_ID_WINNT_50 = 0x03000000,
177  CLIENT_OS_ID_WINNT_POST_52 = 0x04000000,
178 
179  CLIENT_IMAGE_ID_MICROSOFT = 0x00010000,
180  CLIENT_IMAGE_ID_CITRIX = 0x00020000,
181 };
182 
183 struct rdp_license
184 {
185  LICENSE_STATE state;
186  LICENSE_TYPE type;
187  rdpRdp* rdp;
188  rdpCertificate* certificate;
189  BYTE HardwareId[HWID_LENGTH];
190  BYTE ClientRandom[CLIENT_RANDOM_LENGTH];
191  BYTE ServerRandom[SERVER_RANDOM_LENGTH];
192  BYTE MasterSecret[MASTER_SECRET_LENGTH];
193  BYTE PremasterSecret[PREMASTER_SECRET_LENGTH];
194  BYTE SessionKeyBlob[SESSION_KEY_BLOB_LENGTH];
195  BYTE MacSaltKey[MAC_SALT_KEY_LENGTH];
196  BYTE LicensingEncryptionKey[LICENSING_ENCRYPTION_KEY_LENGTH];
197  LICENSE_PRODUCT_INFO* ProductInfo;
198  LICENSE_BLOB* ErrorInfo;
199  LICENSE_BLOB* LicenseInfo; /* Client -> Server */
200  LICENSE_BLOB* KeyExchangeList;
201  LICENSE_BLOB* ServerCertificate;
202  LICENSE_BLOB* ClientUserName;
203  LICENSE_BLOB* ClientMachineName;
204  LICENSE_BLOB* PlatformChallenge;
205  LICENSE_BLOB* EncryptedPremasterSecret;
206  LICENSE_BLOB* EncryptedPlatformChallenge;
207  LICENSE_BLOB* EncryptedPlatformChallengeResponse;
208  LICENSE_BLOB* EncryptedHardwareId;
209  LICENSE_BLOB* EncryptedLicenseInfo;
210  BYTE MACData[LICENSING_ENCRYPTION_KEY_LENGTH];
211  SCOPE_LIST* ScopeList;
212  UINT32 PacketHeaderLength;
213  UINT32 PreferredKeyExchangeAlg;
214  UINT32 PlatformId;
215  UINT16 ClientType;
216  UINT16 LicenseDetailLevel;
217  BOOL update;
218 };
219 
220 static BOOL license_send_error_alert(rdpLicense* license, UINT32 dwErrorCode,
221  UINT32 dwStateTransition, const LICENSE_BLOB* info);
222 static BOOL license_set_state(rdpLicense* license, LICENSE_STATE state);
223 static const char* license_get_state_string(LICENSE_STATE state);
224 
225 static const char* license_preferred_key_exchange_alg_string(UINT32 alg, char* buffer, size_t size)
226 {
227  const char* name = NULL;
228 
229  switch (alg)
230  {
231  case KEY_EXCHANGE_ALG_RSA:
232  name = "KEY_EXCHANGE_ALG_RSA";
233  break;
234  default:
235  name = "KEY_EXCHANGE_ALG_UNKNOWN";
236  break;
237  }
238 
239  (void)_snprintf(buffer, size, "%s [0x%08" PRIx32 "]", name, alg);
240  return buffer;
241 }
242 
243 static const char* license_request_type_string(UINT32 type)
244 {
245  switch (type)
246  {
247  case LICENSE_REQUEST:
248  return "LICENSE_REQUEST";
249  case PLATFORM_CHALLENGE:
250  return "PLATFORM_CHALLENGE";
251  case NEW_LICENSE:
252  return "NEW_LICENSE";
253  case UPGRADE_LICENSE:
254  return "UPGRADE_LICENSE";
255  case LICENSE_INFO:
256  return "LICENSE_INFO";
257  case NEW_LICENSE_REQUEST:
258  return "NEW_LICENSE_REQUEST";
259  case PLATFORM_CHALLENGE_RESPONSE:
260  return "PLATFORM_CHALLENGE_RESPONSE";
261  case ERROR_ALERT:
262  return "ERROR_ALERT";
263  default:
264  return "LICENSE_REQUEST_TYPE_UNKNOWN";
265  }
266 }
267 
268 static const char* licencse_blob_type_string(UINT16 type)
269 {
270  switch (type)
271  {
272  case BB_ANY_BLOB:
273  return "BB_ANY_BLOB";
274  case BB_DATA_BLOB:
275  return "BB_DATA_BLOB";
276  case BB_RANDOM_BLOB:
277  return "BB_RANDOM_BLOB";
278  case BB_CERTIFICATE_BLOB:
279  return "BB_CERTIFICATE_BLOB";
280  case BB_ERROR_BLOB:
281  return "BB_ERROR_BLOB";
282  case BB_ENCRYPTED_DATA_BLOB:
283  return "BB_ENCRYPTED_DATA_BLOB";
284  case BB_KEY_EXCHG_ALG_BLOB:
285  return "BB_KEY_EXCHG_ALG_BLOB";
286  case BB_SCOPE_BLOB:
287  return "BB_SCOPE_BLOB";
288  case BB_CLIENT_USER_NAME_BLOB:
289  return "BB_CLIENT_USER_NAME_BLOB";
290  case BB_CLIENT_MACHINE_NAME_BLOB:
291  return "BB_CLIENT_MACHINE_NAME_BLOB";
292  default:
293  return "BB_UNKNOWN";
294  }
295 }
296 static wStream* license_send_stream_init(rdpLicense* license);
297 
298 static void license_generate_randoms(rdpLicense* license);
299 static BOOL license_generate_keys(rdpLicense* license);
300 static BOOL license_generate_hwid(rdpLicense* license);
301 static BOOL license_encrypt_premaster_secret(rdpLicense* license);
302 
303 static LICENSE_PRODUCT_INFO* license_new_product_info(void);
304 static void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo);
305 static BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo);
306 
307 static LICENSE_BLOB* license_new_binary_blob(UINT16 type);
308 static void license_free_binary_blob(LICENSE_BLOB* blob);
309 static BOOL license_read_binary_blob_data(LICENSE_BLOB* blob, UINT16 type, const void* data,
310  size_t length);
311 static BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob);
312 static BOOL license_write_binary_blob(wStream* s, const LICENSE_BLOB* blob);
313 
314 static SCOPE_LIST* license_new_scope_list(void);
315 static BOOL license_scope_list_resize(SCOPE_LIST* scopeList, UINT32 count);
316 static void license_free_scope_list(SCOPE_LIST* scopeList);
317 static BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList);
318 static BOOL license_write_scope_list(wStream* s, const SCOPE_LIST* scopeList);
319 
320 static BOOL license_read_license_request_packet(rdpLicense* license, wStream* s);
321 static BOOL license_write_license_request_packet(const rdpLicense* license, wStream* s);
322 
323 static BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s);
324 static BOOL license_send_platform_challenge_packet(rdpLicense* license);
325 static BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s);
326 static BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s);
327 
328 static BOOL license_write_new_license_request_packet(const rdpLicense* license, wStream* s);
329 static BOOL license_read_new_license_request_packet(rdpLicense* license, wStream* s);
330 static BOOL license_answer_license_request(rdpLicense* license);
331 
332 static BOOL license_send_platform_challenge_response(rdpLicense* license);
333 static BOOL license_read_platform_challenge_response(rdpLicense* license, wStream* s);
334 
335 static BOOL license_read_client_platform_challenge_response(rdpLicense* license, wStream* s);
336 static BOOL license_write_client_platform_challenge_response(rdpLicense* license, wStream* s);
337 
338 static BOOL license_read_server_upgrade_license(rdpLicense* license, wStream* s);
339 static BOOL license_write_server_upgrade_license(const rdpLicense* license, wStream* s);
340 
341 static BOOL license_send_license_info(rdpLicense* license, const LICENSE_BLOB* calBlob,
342  const BYTE* signature, size_t signature_length);
343 static BOOL license_read_license_info(rdpLicense* license, wStream* s);
344 static state_run_t license_client_recv(rdpLicense* license, wStream* s);
345 static state_run_t license_server_recv(rdpLicense* license, wStream* s);
346 
347 #define PLATFORMID (CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT)
348 
349 #ifdef WITH_DEBUG_LICENSE
350 
351 static const char* error_codes[] = { "ERR_UNKNOWN",
352  "ERR_INVALID_SERVER_CERTIFICATE",
353  "ERR_NO_LICENSE",
354  "ERR_INVALID_MAC",
355  "ERR_INVALID_SCOPE",
356  "ERR_UNKNOWN",
357  "ERR_NO_LICENSE_SERVER",
358  "STATUS_VALID_CLIENT",
359  "ERR_INVALID_CLIENT",
360  "ERR_UNKNOWN",
361  "ERR_UNKNOWN",
362  "ERR_INVALID_PRODUCT_ID",
363  "ERR_INVALID_MESSAGE_LENGTH" };
364 
365 static const char* state_transitions[] = { "ST_UNKNOWN", "ST_TOTAL_ABORT", "ST_NO_TRANSITION",
366  "ST_RESET_PHASE_TO_START", "ST_RESEND_LAST_MESSAGE" };
367 
368 static void license_print_product_info(const LICENSE_PRODUCT_INFO* productInfo)
369 {
370  char* CompanyName = NULL;
371  char* ProductId = NULL;
372 
373  WINPR_ASSERT(productInfo);
374  WINPR_ASSERT(productInfo->pbCompanyName);
375  WINPR_ASSERT(productInfo->pbProductId);
376 
377  CompanyName = ConvertWCharNToUtf8Alloc((const WCHAR*)productInfo->pbCompanyName,
378  productInfo->cbCompanyName / sizeof(WCHAR), NULL);
379  ProductId = ConvertWCharNToUtf8Alloc((const WCHAR*)productInfo->pbProductId,
380  productInfo->cbProductId / sizeof(WCHAR), NULL);
381  WLog_INFO(TAG, "ProductInfo:");
382  WLog_INFO(TAG, "\tdwVersion: 0x%08" PRIX32 "", productInfo->dwVersion);
383  WLog_INFO(TAG, "\tCompanyName: %s", CompanyName);
384  WLog_INFO(TAG, "\tProductId: %s", ProductId);
385  free(CompanyName);
386  free(ProductId);
387 }
388 
389 static void license_print_scope_list(const SCOPE_LIST* scopeList)
390 {
391  WINPR_ASSERT(scopeList);
392 
393  WLog_INFO(TAG, "ScopeList (%" PRIu32 "):", scopeList->count);
394 
395  for (UINT32 index = 0; index < scopeList->count; index++)
396  {
397  const LICENSE_BLOB* scope = NULL;
398 
399  WINPR_ASSERT(scopeList->array);
400  scope = scopeList->array[index];
401  WINPR_ASSERT(scope);
402 
403  WLog_INFO(TAG, "\t%s", (const char*)scope->data);
404  }
405 }
406 #endif
407 
408 static const char licenseStore[] = "licenses";
409 
410 static BOOL license_ensure_state(rdpLicense* license, LICENSE_STATE state, UINT32 msg)
411 {
412  const LICENSE_STATE cstate = license_get_state(license);
413 
414  WINPR_ASSERT(license);
415 
416  if (cstate != state)
417  {
418  const char* scstate = license_get_state_string(cstate);
419  const char* sstate = license_get_state_string(state);
420  const char* where = license_request_type_string(msg);
421 
422  WLog_WARN(TAG, "Received [%s], but found invalid licensing state %s, expected %s", where,
423  scstate, sstate);
424  return FALSE;
425  }
426  return TRUE;
427 }
428 
429 state_run_t license_recv(rdpLicense* license, wStream* s)
430 {
431  WINPR_ASSERT(license);
432  WINPR_ASSERT(license->rdp);
433  WINPR_ASSERT(license->rdp->settings);
434 
435  if (freerdp_settings_get_bool(license->rdp->settings, FreeRDP_ServerMode))
436  return license_server_recv(license, s);
437  else
438  return license_client_recv(license, s);
439 }
440 
441 static BOOL license_check_stream_length(wStream* s, SSIZE_T expect, const char* where)
442 {
443  const size_t remain = Stream_GetRemainingLength(s);
444 
445  WINPR_ASSERT(where);
446 
447  if (expect < 0)
448  {
449  WLog_WARN(TAG, "invalid %s, expected value %" PRIdz " invalid", where, expect);
450  return FALSE;
451  }
452  if (remain < (size_t)expect)
453  {
454  WLog_WARN(TAG, "short %s, expected %" PRIdz " bytes, got %" PRIuz, where, expect, remain);
455  return FALSE;
456  }
457  return TRUE;
458 }
459 
460 static BOOL license_check_stream_capacity(wStream* s, size_t expect, const char* where)
461 {
462  WINPR_ASSERT(where);
463 
464  if (!Stream_CheckAndLogRequiredCapacityEx(TAG, WLOG_WARN, s, expect, 1, "%s(%s:%" PRIuz ") %s",
465  __func__, __FILE__, (size_t)__LINE__, where))
466  return FALSE;
467 
468  return TRUE;
469 }
470 
471 static BOOL computeCalHash(const char* hostname, char* hashStr, size_t len)
472 {
473  WINPR_DIGEST_CTX* sha1 = NULL;
474  BOOL ret = FALSE;
475  BYTE hash[20] = { 0 };
476 
477  WINPR_ASSERT(hostname);
478  WINPR_ASSERT(hashStr);
479 
480  if (len < 2 * sizeof(hash) + 1)
481  return FALSE;
482 
483  if (!(sha1 = winpr_Digest_New()))
484  goto out;
485  if (!winpr_Digest_Init(sha1, WINPR_MD_SHA1))
486  goto out;
487  if (!winpr_Digest_Update(sha1, (const BYTE*)hostname, strlen(hostname)))
488  goto out;
489  if (!winpr_Digest_Final(sha1, hash, sizeof(hash)))
490  goto out;
491 
492  for (size_t i = 0; i < sizeof(hash); i++, hashStr += 2)
493  (void)sprintf_s(hashStr, 3, "%.2x", hash[i]);
494 
495  ret = TRUE;
496 out:
497  if (!ret)
498  WLog_ERR(TAG, "failed to generate SHA1 of hostname '%s'", hostname);
499  winpr_Digest_Free(sha1);
500  return ret;
501 }
502 
503 static BOOL saveCal(const rdpSettings* settings, const BYTE* data, size_t length,
504  const char* hostname)
505 {
506  char hash[41] = { 0 };
507  FILE* fp = NULL;
508  char* licenseStorePath = NULL;
509  char filename[MAX_PATH] = { 0 };
510  char filenameNew[MAX_PATH] = { 0 };
511  char* filepath = NULL;
512  char* filepathNew = NULL;
513 
514  size_t written = 0;
515  BOOL ret = FALSE;
516  const char* path = freerdp_settings_get_string(settings, FreeRDP_ConfigPath);
517 
518  WINPR_ASSERT(path);
519  WINPR_ASSERT(data || (length == 0));
520  WINPR_ASSERT(hostname);
521 
522  if (!winpr_PathFileExists(path))
523  {
524  if (!winpr_PathMakePath(path, 0))
525  {
526  WLog_ERR(TAG, "error creating directory '%s'", path);
527  goto out;
528  }
529  WLog_INFO(TAG, "creating directory %s", path);
530  }
531 
532  if (!(licenseStorePath = GetCombinedPath(path, licenseStore)))
533  {
534  WLog_ERR(TAG, "Failed to get license store path from '%s' + '%s'", path, licenseStore);
535  goto out;
536  }
537 
538  if (!winpr_PathFileExists(licenseStorePath))
539  {
540  if (!winpr_PathMakePath(licenseStorePath, 0))
541  {
542  WLog_ERR(TAG, "error creating directory '%s'", licenseStorePath);
543  goto out;
544  }
545  WLog_INFO(TAG, "creating directory %s", licenseStorePath);
546  }
547 
548  if (!computeCalHash(hostname, hash, sizeof(hash)))
549  goto out;
550  (void)sprintf_s(filename, sizeof(filename) - 1, "%s.cal", hash);
551  (void)sprintf_s(filenameNew, sizeof(filenameNew) - 1, "%s.cal.new", hash);
552 
553  if (!(filepath = GetCombinedPath(licenseStorePath, filename)))
554  {
555  WLog_ERR(TAG, "Failed to get license file path from '%s' + '%s'", path, filename);
556  goto out;
557  }
558 
559  if (!(filepathNew = GetCombinedPath(licenseStorePath, filenameNew)))
560  {
561  WLog_ERR(TAG, "Failed to get license new file path from '%s' + '%s'", path, filenameNew);
562  goto out;
563  }
564 
565  fp = winpr_fopen(filepathNew, "wb");
566  if (!fp)
567  {
568  WLog_ERR(TAG, "Failed to open license file '%s'", filepathNew);
569  goto out;
570  }
571 
572  written = fwrite(data, length, 1, fp);
573  (void)fclose(fp);
574 
575  if (written != 1)
576  {
577  WLog_ERR(TAG, "Failed to write to license file '%s'", filepathNew);
578  winpr_DeleteFile(filepathNew);
579  goto out;
580  }
581 
582  ret = winpr_MoveFileEx(filepathNew, filepath, MOVEFILE_REPLACE_EXISTING);
583  if (!ret)
584  WLog_ERR(TAG, "Failed to move license file '%s' to '%s'", filepathNew, filepath);
585 
586 out:
587  free(filepathNew);
588  free(filepath);
589  free(licenseStorePath);
590  return ret;
591 }
592 
593 static BYTE* loadCalFile(const rdpSettings* settings, const char* hostname, size_t* dataLen)
594 {
595  char* licenseStorePath = NULL;
596  char* calPath = NULL;
597  char calFilename[MAX_PATH] = { 0 };
598  char hash[41] = { 0 };
599  INT64 length = 0;
600  size_t status = 0;
601  FILE* fp = NULL;
602  BYTE* ret = NULL;
603 
604  WINPR_ASSERT(settings);
605  WINPR_ASSERT(hostname);
606  WINPR_ASSERT(dataLen);
607 
608  if (!computeCalHash(hostname, hash, sizeof(hash)))
609  {
610  WLog_ERR(TAG, "loadCalFile: unable to compute hostname hash");
611  return NULL;
612  }
613 
614  (void)sprintf_s(calFilename, sizeof(calFilename) - 1, "%s.cal", hash);
615 
616  if (!(licenseStorePath = GetCombinedPath(
617  freerdp_settings_get_string(settings, FreeRDP_ConfigPath), licenseStore)))
618  return NULL;
619 
620  if (!(calPath = GetCombinedPath(licenseStorePath, calFilename)))
621  goto error_path;
622 
623  fp = winpr_fopen(calPath, "rb");
624  if (!fp)
625  goto error_open;
626 
627  if (_fseeki64(fp, 0, SEEK_END) != 0)
628  goto error_malloc;
629  length = _ftelli64(fp);
630  if (_fseeki64(fp, 0, SEEK_SET) != 0)
631  goto error_malloc;
632  if (length < 0)
633  goto error_malloc;
634 
635  ret = (BYTE*)malloc((size_t)length);
636  if (!ret)
637  goto error_malloc;
638 
639  status = fread(ret, (size_t)length, 1, fp);
640  if (status == 0)
641  goto error_read;
642 
643  *dataLen = (size_t)length;
644 
645  (void)fclose(fp);
646  free(calPath);
647  free(licenseStorePath);
648  return ret;
649 
650 error_read:
651  free(ret);
652 error_malloc:
653  fclose(fp);
654 error_open:
655  free(calPath);
656 error_path:
657  free(licenseStorePath);
658  return NULL;
659 }
660 
671 static BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsgSize)
672 {
673  WINPR_ASSERT(bMsgType);
674  WINPR_ASSERT(flags);
675  WINPR_ASSERT(wMsgSize);
676 
677  /* preamble (4 bytes) */
678  if (!license_check_stream_length(s, 4, "license preamble"))
679  return FALSE;
680 
681  Stream_Read_UINT8(s, *bMsgType); /* bMsgType (1 byte) */
682  Stream_Read_UINT8(s, *flags); /* flags (1 byte) */
683  Stream_Read_UINT16(s, *wMsgSize); /* wMsgSize (2 bytes) */
684  return license_check_stream_length(s, *wMsgSize - 4ll, "license preamble::wMsgSize");
685 }
686 
697 static BOOL license_write_preamble(wStream* s, BYTE bMsgType, BYTE flags, UINT16 wMsgSize)
698 {
699  if (!Stream_EnsureRemainingCapacity(s, 4))
700  return FALSE;
701 
702  /* preamble (4 bytes) */
703  Stream_Write_UINT8(s, bMsgType); /* bMsgType (1 byte) */
704  Stream_Write_UINT8(s, flags); /* flags (1 byte) */
705  Stream_Write_UINT16(s, wMsgSize); /* wMsgSize (2 bytes) */
706  return TRUE;
707 }
708 
717 wStream* license_send_stream_init(rdpLicense* license)
718 {
719  WINPR_ASSERT(license);
720  WINPR_ASSERT(license->rdp);
721 
722  const BOOL do_crypt = license->rdp->do_crypt;
723 
724  license->rdp->sec_flags = SEC_LICENSE_PKT;
725 
726  /*
727  * Encryption of licensing packets is optional even if the rdp security
728  * layer is used. If the peer has not indicated that it is capable of
729  * processing encrypted licensing packets (rdp->do_crypt_license) we turn
730  * off encryption (via rdp->do_crypt) before initializing the rdp stream
731  * and reenable it afterwards.
732  */
733 
734  if (do_crypt)
735  {
736  license->rdp->sec_flags |= SEC_LICENSE_ENCRYPT_CS;
737  license->rdp->do_crypt = license->rdp->do_crypt_license;
738  }
739 
740  wStream* s = rdp_send_stream_init(license->rdp);
741  if (!s)
742  return NULL;
743 
744  license->rdp->do_crypt = do_crypt;
745  license->PacketHeaderLength = (UINT16)Stream_GetPosition(s);
746  if (!Stream_SafeSeek(s, LICENSE_PREAMBLE_LENGTH))
747  goto fail;
748  return s;
749 
750 fail:
751  Stream_Release(s);
752  return NULL;
753 }
754 
762 static BOOL license_send(rdpLicense* license, wStream* s, BYTE type)
763 {
764  WINPR_ASSERT(license);
765  WINPR_ASSERT(license->rdp);
766 
767  rdpRdp* rdp = license->rdp;
768  WINPR_ASSERT(rdp->settings);
769 
770  DEBUG_LICENSE("Sending %s Packet", license_request_type_string(type));
771  const size_t length = Stream_GetPosition(s);
772  WINPR_ASSERT(length >= license->PacketHeaderLength);
773  WINPR_ASSERT(length <= UINT16_MAX + license->PacketHeaderLength);
774 
775  const UINT16 wMsgSize = (UINT16)(length - license->PacketHeaderLength);
776  Stream_SetPosition(s, license->PacketHeaderLength);
777  BYTE flags = PREAMBLE_VERSION_3_0;
778 
784  if (!rdp->settings->ServerMode)
785  flags |= EXTENDED_ERROR_MSG_SUPPORTED;
786 
787  if (!license_write_preamble(s, type, flags, wMsgSize))
788  return FALSE;
789 
790 #ifdef WITH_DEBUG_LICENSE
791  WLog_DBG(TAG, "Sending %s Packet, length %" PRIu16 "", license_request_type_string(type),
792  wMsgSize);
793  winpr_HexDump(TAG, WLOG_DEBUG, Stream_PointerAs(s, char) - LICENSE_PREAMBLE_LENGTH, wMsgSize);
794 #endif
795  Stream_SetPosition(s, length);
796  const BOOL ret = rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
797  rdp->sec_flags = 0;
798  return ret;
799 }
800 
801 BOOL license_read_server_upgrade_license(rdpLicense* license, wStream* s)
802 {
803  WINPR_ASSERT(license);
804 
805  if (!license_read_binary_blob(s, license->EncryptedLicenseInfo))
806  return FALSE;
807  if (!license_check_stream_length(s, sizeof(license->MACData),
808  "SERVER_UPGRADE_LICENSE::MACData"))
809  return FALSE;
810  Stream_Read(s, license->MACData, sizeof(license->MACData));
811  return TRUE;
812 }
813 
814 BOOL license_write_server_upgrade_license(const rdpLicense* license, wStream* s)
815 {
816  WINPR_ASSERT(license);
817 
818  if (!license_write_binary_blob(s, license->EncryptedLicenseInfo))
819  return FALSE;
820  if (!license_check_stream_capacity(s, sizeof(license->MACData),
821  "SERVER_UPGRADE_LICENSE::MACData"))
822  return FALSE;
823  Stream_Write(s, license->MACData, sizeof(license->MACData));
824  return TRUE;
825 }
826 
827 static BOOL license_server_send_new_or_upgrade_license(rdpLicense* license, BOOL upgrade)
828 {
829  wStream* s = license_send_stream_init(license);
830  const BYTE type = upgrade ? UPGRADE_LICENSE : NEW_LICENSE;
831 
832  if (!s)
833  return FALSE;
834 
835  if (!license_write_server_upgrade_license(license, s))
836  goto fail;
837 
838  return license_send(license, s, type);
839 
840 fail:
841  Stream_Release(s);
842  return FALSE;
843 }
844 
853 state_run_t license_client_recv(rdpLicense* license, wStream* s)
854 {
855  BYTE flags = 0;
856  BYTE bMsgType = 0;
857  UINT16 wMsgSize = 0;
858  const size_t length = Stream_GetRemainingLength(s);
859 
860  WINPR_ASSERT(license);
861 
862  if (!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */
863  return STATE_RUN_FAILED;
864 
865  DEBUG_LICENSE("Receiving %s Packet", license_request_type_string(bMsgType));
866 
867  switch (bMsgType)
868  {
869  case LICENSE_REQUEST:
870  /* Client does not require configuration, so skip this state */
871  if (license_get_state(license) == LICENSE_STATE_INITIAL)
872  license_set_state(license, LICENSE_STATE_CONFIGURED);
873 
874  if (!license_ensure_state(license, LICENSE_STATE_CONFIGURED, bMsgType))
875  return STATE_RUN_FAILED;
876 
877  if (!license_read_license_request_packet(license, s))
878  return STATE_RUN_FAILED;
879 
880  if (!license_answer_license_request(license))
881  return STATE_RUN_FAILED;
882 
883  license_set_state(license, LICENSE_STATE_NEW_REQUEST);
884  break;
885 
886  case PLATFORM_CHALLENGE:
887  if (!license_ensure_state(license, LICENSE_STATE_NEW_REQUEST, bMsgType))
888  return STATE_RUN_FAILED;
889 
890  if (!license_read_platform_challenge_packet(license, s))
891  return STATE_RUN_FAILED;
892 
893  if (!license_send_platform_challenge_response(license))
894  return STATE_RUN_FAILED;
895  license_set_state(license, LICENSE_STATE_PLATFORM_CHALLENGE_RESPONSE);
896  break;
897 
898  case NEW_LICENSE:
899  case UPGRADE_LICENSE:
900  if (!license_ensure_state(license, LICENSE_STATE_PLATFORM_CHALLENGE_RESPONSE, bMsgType))
901  return STATE_RUN_FAILED;
902  if (!license_read_new_or_upgrade_license_packet(license, s))
903  return STATE_RUN_FAILED;
904  break;
905 
906  case ERROR_ALERT:
907  if (!license_read_error_alert_packet(license, s))
908  return STATE_RUN_FAILED;
909  break;
910 
911  default:
912  WLog_ERR(TAG, "invalid bMsgType:%" PRIu8 "", bMsgType);
913  return STATE_RUN_FAILED;
914  }
915 
916  if (!tpkt_ensure_stream_consumed(s, length))
917  return STATE_RUN_FAILED;
918  return STATE_RUN_SUCCESS;
919 }
920 
921 state_run_t license_server_recv(rdpLicense* license, wStream* s)
922 {
923  state_run_t rc = STATE_RUN_FAILED;
924  BYTE flags = 0;
925  BYTE bMsgType = 0;
926  UINT16 wMsgSize = 0;
927  const size_t length = Stream_GetRemainingLength(s);
928 
929  WINPR_ASSERT(license);
930 
931  if (!license_read_preamble(s, &bMsgType, &flags, &wMsgSize)) /* preamble (4 bytes) */
932  goto fail;
933 
934  DEBUG_LICENSE("Receiving %s Packet", license_request_type_string(bMsgType));
935 
936  switch (bMsgType)
937  {
938  case NEW_LICENSE_REQUEST:
939  if (!license_ensure_state(license, LICENSE_STATE_REQUEST, bMsgType))
940  goto fail;
941  if (!license_read_new_license_request_packet(license, s))
942  goto fail;
943  // TODO: Validate if client is allowed
944  if (!license_send_error_alert(license, ERR_INVALID_MAC, ST_TOTAL_ABORT,
945  license->ErrorInfo))
946  goto fail;
947  if (!license_send_platform_challenge_packet(license))
948  goto fail;
949  license->update = FALSE;
950  if (!license_set_state(license, LICENSE_STATE_PLATFORM_CHALLENGE))
951  goto fail;
952  break;
953  case LICENSE_INFO:
954  if (!license_ensure_state(license, LICENSE_STATE_REQUEST, bMsgType))
955  goto fail;
956  if (!license_read_license_info(license, s))
957  goto fail;
958  // TODO: Validate license info
959  if (!license_send_platform_challenge_packet(license))
960  goto fail;
961  if (!license_set_state(license, LICENSE_STATE_PLATFORM_CHALLENGE))
962  goto fail;
963  license->update = TRUE;
964  break;
965 
966  case PLATFORM_CHALLENGE_RESPONSE:
967  if (!license_ensure_state(license, LICENSE_STATE_PLATFORM_CHALLENGE, bMsgType))
968  goto fail;
969  if (!license_read_client_platform_challenge_response(license, s))
970  goto fail;
971 
972  // TODO: validate challenge response
973  if (FALSE)
974  {
975  if (license_send_error_alert(license, ERR_INVALID_CLIENT, ST_TOTAL_ABORT,
976  license->ErrorInfo))
977  goto fail;
978  }
979  else
980  {
981  if (!license_server_send_new_or_upgrade_license(license, license->update))
982  goto fail;
983 
984  license->type = LICENSE_TYPE_ISSUED;
985  license_set_state(license, LICENSE_STATE_COMPLETED);
986 
987  rc = STATE_RUN_CONTINUE; /* License issued, switch state */
988  }
989  break;
990 
991  case ERROR_ALERT:
992  if (!license_read_error_alert_packet(license, s))
993  goto fail;
994  break;
995 
996  default:
997  WLog_ERR(TAG, "invalid bMsgType:%" PRIu8 "", bMsgType);
998  goto fail;
999  }
1000 
1001  if (!tpkt_ensure_stream_consumed(s, length))
1002  goto fail;
1003 
1004  if (!state_run_success(rc))
1005  rc = STATE_RUN_SUCCESS;
1006 
1007 fail:
1008  if (state_run_failed(rc))
1009  {
1010  if (flags & EXTENDED_ERROR_MSG_SUPPORTED)
1011  license_send_error_alert(license, ERR_INVALID_CLIENT, ST_TOTAL_ABORT, NULL);
1012  license_set_state(license, LICENSE_STATE_ABORTED);
1013  }
1014 
1015  return rc;
1016 }
1017 
1018 void license_generate_randoms(rdpLicense* license)
1019 {
1020  WINPR_ASSERT(license);
1021 
1022 #ifdef LICENSE_NULL_CLIENT_RANDOM
1023  ZeroMemory(license->ClientRandom, sizeof(license->ClientRandom)); /* ClientRandom */
1024 #else
1025  winpr_RAND(license->ClientRandom, sizeof(license->ClientRandom)); /* ClientRandom */
1026 #endif
1027 
1028  winpr_RAND(license->ServerRandom, sizeof(license->ServerRandom)); /* ServerRandom */
1029 
1030 #ifdef LICENSE_NULL_PREMASTER_SECRET
1031  ZeroMemory(license->PremasterSecret, sizeof(license->PremasterSecret)); /* PremasterSecret */
1032 #else
1033  winpr_RAND(license->PremasterSecret, sizeof(license->PremasterSecret)); /* PremasterSecret */
1034 #endif
1035 }
1036 
1042 static BOOL license_generate_keys(rdpLicense* license)
1043 {
1044  WINPR_ASSERT(license);
1045 
1046  if (
1047  /* MasterSecret */
1048  !security_master_secret(license->PremasterSecret, sizeof(license->PremasterSecret),
1049  license->ClientRandom, sizeof(license->ClientRandom),
1050  license->ServerRandom, sizeof(license->ServerRandom),
1051  license->MasterSecret, sizeof(license->MasterSecret)) ||
1052  /* SessionKeyBlob */
1053  !security_session_key_blob(license->MasterSecret, sizeof(license->MasterSecret),
1054  license->ClientRandom, sizeof(license->ClientRandom),
1055  license->ServerRandom, sizeof(license->ServerRandom),
1056  license->SessionKeyBlob, sizeof(license->SessionKeyBlob)))
1057  {
1058  return FALSE;
1059  }
1060  security_mac_salt_key(license->SessionKeyBlob, sizeof(license->SessionKeyBlob),
1061  license->ClientRandom, sizeof(license->ClientRandom),
1062  license->ServerRandom, sizeof(license->ServerRandom), license->MacSaltKey,
1063  sizeof(license->MacSaltKey)); /* MacSaltKey */
1064  const BOOL ret = security_licensing_encryption_key(
1065  license->SessionKeyBlob, sizeof(license->SessionKeyBlob), license->ClientRandom,
1066  sizeof(license->ClientRandom), license->ServerRandom, sizeof(license->ServerRandom),
1067  license->LicensingEncryptionKey,
1068  sizeof(license->LicensingEncryptionKey)); /* LicensingEncryptionKey */
1069 
1070 #ifdef WITH_DEBUG_LICENSE
1071  WLog_DBG(TAG, "ClientRandom:");
1072  winpr_HexDump(TAG, WLOG_DEBUG, license->ClientRandom, sizeof(license->ClientRandom));
1073  WLog_DBG(TAG, "ServerRandom:");
1074  winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, sizeof(license->ServerRandom));
1075  WLog_DBG(TAG, "PremasterSecret:");
1076  winpr_HexDump(TAG, WLOG_DEBUG, license->PremasterSecret, sizeof(license->PremasterSecret));
1077  WLog_DBG(TAG, "MasterSecret:");
1078  winpr_HexDump(TAG, WLOG_DEBUG, license->MasterSecret, sizeof(license->MasterSecret));
1079  WLog_DBG(TAG, "SessionKeyBlob:");
1080  winpr_HexDump(TAG, WLOG_DEBUG, license->SessionKeyBlob, sizeof(license->SessionKeyBlob));
1081  WLog_DBG(TAG, "MacSaltKey:");
1082  winpr_HexDump(TAG, WLOG_DEBUG, license->MacSaltKey, sizeof(license->MacSaltKey));
1083  WLog_DBG(TAG, "LicensingEncryptionKey:");
1084  winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey,
1085  sizeof(license->LicensingEncryptionKey));
1086 #endif
1087  return ret;
1088 }
1089 
1095 BOOL license_generate_hwid(rdpLicense* license)
1096 {
1097  const BYTE* hashTarget = NULL;
1098  size_t targetLen = 0;
1099  BYTE macAddress[6] = { 0 };
1100 
1101  WINPR_ASSERT(license);
1102  WINPR_ASSERT(license->rdp);
1103  WINPR_ASSERT(license->rdp->settings);
1104 
1105  ZeroMemory(license->HardwareId, sizeof(license->HardwareId));
1106 
1107  if (license->rdp->settings->OldLicenseBehaviour)
1108  {
1109  hashTarget = macAddress;
1110  targetLen = sizeof(macAddress);
1111  }
1112  else
1113  {
1114  wStream buffer = { 0 };
1115  const char* hostname = license->rdp->settings->ClientHostname;
1116  wStream* s = Stream_StaticInit(&buffer, license->HardwareId, 4);
1117  Stream_Write_UINT32(s, license->PlatformId);
1118 
1119  hashTarget = (const BYTE*)hostname;
1120  targetLen = hostname ? strlen(hostname) : 0;
1121  }
1122 
1123  /* Allow FIPS override for use of MD5 here, really this does not have to be MD5 as we are just
1124  * taking a MD5 hash of the 6 bytes of 0's(macAddress) */
1125  /* and filling in the Data1-Data4 fields of the CLIENT_HARDWARE_ID structure(from MS-RDPELE
1126  * section 2.2.2.3.1). This is for RDP licensing packets */
1127  /* which will already be encrypted under FIPS, so the use of MD5 here is not for sensitive data
1128  * protection. */
1129  return winpr_Digest_Allow_FIPS(WINPR_MD_MD5, hashTarget, targetLen,
1130  &license->HardwareId[HWID_PLATFORM_ID_LENGTH],
1131  WINPR_MD5_DIGEST_LENGTH);
1132 }
1133 
1134 static BOOL license_get_server_rsa_public_key(rdpLicense* license)
1135 {
1136  rdpSettings* settings = NULL;
1137 
1138  WINPR_ASSERT(license);
1139  WINPR_ASSERT(license->certificate);
1140  WINPR_ASSERT(license->rdp);
1141 
1142  settings = license->rdp->settings;
1143  WINPR_ASSERT(settings);
1144 
1145  if (license->ServerCertificate->length < 1)
1146  {
1147  if (!freerdp_certificate_read_server_cert(license->certificate, settings->ServerCertificate,
1148  settings->ServerCertificateLength))
1149  return FALSE;
1150  }
1151 
1152  return TRUE;
1153 }
1154 
1155 BOOL license_encrypt_premaster_secret(rdpLicense* license)
1156 {
1157  WINPR_ASSERT(license);
1158  WINPR_ASSERT(license->certificate);
1159 
1160  if (!license_get_server_rsa_public_key(license))
1161  return FALSE;
1162 
1163  WINPR_ASSERT(license->EncryptedPremasterSecret);
1164 
1165  const rdpCertInfo* info = freerdp_certificate_get_info(license->certificate);
1166  if (!info)
1167  {
1168  WLog_ERR(TAG, "info=%p, license->certificate=%p", info, license->certificate);
1169  return FALSE;
1170  }
1171 
1172 #ifdef WITH_DEBUG_LICENSE
1173  WLog_DBG(TAG, "Modulus (%" PRIu32 " bits):", info->ModulusLength * 8);
1174  winpr_HexDump(TAG, WLOG_DEBUG, info->Modulus, info->ModulusLength);
1175  WLog_DBG(TAG, "Exponent:");
1176  winpr_HexDump(TAG, WLOG_DEBUG, info->exponent, sizeof(info->exponent));
1177 #endif
1178 
1179  BYTE* EncryptedPremasterSecret = (BYTE*)calloc(1, info->ModulusLength);
1180  if (!EncryptedPremasterSecret)
1181  {
1182  WLog_ERR(TAG, "EncryptedPremasterSecret=%p, info->ModulusLength=%" PRIu32,
1183  EncryptedPremasterSecret, info->ModulusLength);
1184  return FALSE;
1185  }
1186 
1187  license->EncryptedPremasterSecret->type = BB_RANDOM_BLOB;
1188  license->EncryptedPremasterSecret->length = sizeof(license->PremasterSecret);
1189 #ifndef LICENSE_NULL_PREMASTER_SECRET
1190  {
1191  const SSIZE_T length =
1192  crypto_rsa_public_encrypt(license->PremasterSecret, sizeof(license->PremasterSecret),
1193  info, EncryptedPremasterSecret, info->ModulusLength);
1194  if ((length < 0) || (length > UINT16_MAX))
1195  {
1196  WLog_ERR(TAG, "RSA public encrypt length=%" PRIdz " < 0 || > %" PRIu16, length,
1197  UINT16_MAX);
1198  return FALSE;
1199  }
1200  license->EncryptedPremasterSecret->length = (UINT16)length;
1201  }
1202 #endif
1203  license->EncryptedPremasterSecret->data = EncryptedPremasterSecret;
1204  return TRUE;
1205 }
1206 
1207 static BOOL license_rc4_with_licenseKey(const rdpLicense* license, const BYTE* input, size_t len,
1208  LICENSE_BLOB* target)
1209 {
1210  WINPR_ASSERT(license);
1211  WINPR_ASSERT(input || (len == 0));
1212  WINPR_ASSERT(target);
1213  WINPR_ASSERT(len <= UINT16_MAX);
1214 
1215  WINPR_RC4_CTX* rc4 = winpr_RC4_New_Allow_FIPS(license->LicensingEncryptionKey,
1216  sizeof(license->LicensingEncryptionKey));
1217  if (!rc4)
1218  {
1219  WLog_ERR(TAG, "Failed to allocate RC4");
1220  return FALSE;
1221  }
1222 
1223  BYTE* buffer = NULL;
1224  if (len > 0)
1225  buffer = realloc(target->data, len);
1226  if (!buffer)
1227  goto error_buffer;
1228 
1229  target->data = buffer;
1230  target->length = (UINT16)len;
1231 
1232  if (!winpr_RC4_Update(rc4, len, input, buffer))
1233  goto error_buffer;
1234 
1235  winpr_RC4_Free(rc4);
1236  return TRUE;
1237 
1238 error_buffer:
1239  WLog_ERR(TAG, "Failed to create/update RC4: len=%" PRIuz ", buffer=%p", len, buffer);
1240  winpr_RC4_Free(rc4);
1241  return FALSE;
1242 }
1243 
1254 static BOOL license_encrypt_and_MAC(rdpLicense* license, const BYTE* input, size_t len,
1255  LICENSE_BLOB* target, BYTE* mac, size_t mac_length)
1256 {
1257  WINPR_ASSERT(license);
1258  return license_rc4_with_licenseKey(license, input, len, target) &&
1259  security_mac_data(license->MacSaltKey, sizeof(license->MacSaltKey), input, len, mac,
1260  mac_length);
1261 }
1262 
1274 static BOOL license_decrypt_and_check_MAC(rdpLicense* license, const BYTE* input, size_t len,
1275  LICENSE_BLOB* target, const BYTE* packetMac)
1276 {
1277  BYTE macData[sizeof(license->MACData)] = { 0 };
1278 
1279  WINPR_ASSERT(license);
1280  WINPR_ASSERT(target);
1281 
1282  if (freerdp_settings_get_bool(license->rdp->settings, FreeRDP_TransportDumpReplay))
1283  {
1284  WLog_DBG(TAG, "TransportDumpReplay active, skipping...");
1285  return TRUE;
1286  }
1287 
1288  if (!license_rc4_with_licenseKey(license, input, len, target))
1289  return FALSE;
1290 
1291  if (!security_mac_data(license->MacSaltKey, sizeof(license->MacSaltKey), target->data, len,
1292  macData, sizeof(macData)))
1293  return FALSE;
1294 
1295  if (memcmp(packetMac, macData, sizeof(macData)) != 0)
1296  {
1297  WLog_ERR(TAG, "packetMac != expectedMac");
1298  return FALSE;
1299  }
1300  return TRUE;
1301 }
1302 
1310 BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
1311 {
1312  WINPR_ASSERT(productInfo);
1313 
1314  if (!license_check_stream_length(s, 8, "license product info::cbCompanyName"))
1315  return FALSE;
1316 
1317  Stream_Read_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
1318  Stream_Read_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
1319 
1320  /* Name must be >0, but there is no upper limit defined, use UINT32_MAX */
1321  if ((productInfo->cbCompanyName < 2) || (productInfo->cbCompanyName % 2 != 0))
1322  {
1323  WLog_WARN(TAG, "license product info invalid cbCompanyName %" PRIu32,
1324  productInfo->cbCompanyName);
1325  return FALSE;
1326  }
1327 
1328  if (!license_check_stream_length(s, productInfo->cbCompanyName,
1329  "license product info::CompanyName"))
1330  return FALSE;
1331 
1332  productInfo->pbProductId = NULL;
1333  productInfo->pbCompanyName = (BYTE*)malloc(productInfo->cbCompanyName);
1334  if (!productInfo->pbCompanyName)
1335  goto out_fail;
1336  Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
1337 
1338  if (!license_check_stream_length(s, 4, "license product info::cbProductId"))
1339  goto out_fail;
1340 
1341  Stream_Read_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
1342 
1343  if ((productInfo->cbProductId < 2) || (productInfo->cbProductId % 2 != 0))
1344  {
1345  WLog_WARN(TAG, "license product info invalid cbProductId %" PRIu32,
1346  productInfo->cbProductId);
1347  goto out_fail;
1348  }
1349 
1350  if (!license_check_stream_length(s, productInfo->cbProductId,
1351  "license product info::ProductId"))
1352  goto out_fail;
1353 
1354  productInfo->pbProductId = (BYTE*)malloc(productInfo->cbProductId);
1355  if (!productInfo->pbProductId)
1356  goto out_fail;
1357  Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId);
1358  return TRUE;
1359 
1360 out_fail:
1361  free(productInfo->pbCompanyName);
1362  free(productInfo->pbProductId);
1363  productInfo->pbCompanyName = NULL;
1364  productInfo->pbProductId = NULL;
1365  return FALSE;
1366 }
1367 
1368 static BOOL license_write_product_info(wStream* s, const LICENSE_PRODUCT_INFO* productInfo)
1369 {
1370  WINPR_ASSERT(productInfo);
1371 
1372  if (!license_check_stream_capacity(s, 8, "license product info::cbCompanyName"))
1373  return FALSE;
1374 
1375  Stream_Write_UINT32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */
1376  Stream_Write_UINT32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */
1377 
1378  /* Name must be >0, but there is no upper limit defined, use UINT32_MAX */
1379  if ((productInfo->cbCompanyName < 2) || (productInfo->cbCompanyName % 2 != 0) ||
1380  !productInfo->pbCompanyName)
1381  {
1382  WLog_WARN(TAG, "license product info invalid cbCompanyName %" PRIu32,
1383  productInfo->cbCompanyName);
1384  return FALSE;
1385  }
1386 
1387  if (!license_check_stream_capacity(s, productInfo->cbCompanyName,
1388  "license product info::CompanyName"))
1389  return FALSE;
1390 
1391  Stream_Write(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
1392 
1393  if (!license_check_stream_capacity(s, 4, "license product info::cbProductId"))
1394  return FALSE;
1395 
1396  Stream_Write_UINT32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */
1397 
1398  if ((productInfo->cbProductId < 2) || (productInfo->cbProductId % 2 != 0) ||
1399  !productInfo->pbProductId)
1400  {
1401  WLog_WARN(TAG, "license product info invalid cbProductId %" PRIu32,
1402  productInfo->cbProductId);
1403  return FALSE;
1404  }
1405 
1406  if (!license_check_stream_capacity(s, productInfo->cbProductId,
1407  "license product info::ProductId"))
1408  return FALSE;
1409 
1410  Stream_Write(s, productInfo->pbProductId, productInfo->cbProductId);
1411  return TRUE;
1412 }
1413 
1420 LICENSE_PRODUCT_INFO* license_new_product_info(void)
1421 {
1422  LICENSE_PRODUCT_INFO* productInfo =
1423  (LICENSE_PRODUCT_INFO*)calloc(1, sizeof(LICENSE_PRODUCT_INFO));
1424  if (!productInfo)
1425  return NULL;
1426  return productInfo;
1427 }
1428 
1435 void license_free_product_info(LICENSE_PRODUCT_INFO* productInfo)
1436 {
1437  if (productInfo)
1438  {
1439  free(productInfo->pbCompanyName);
1440  free(productInfo->pbProductId);
1441  free(productInfo);
1442  }
1443 }
1444 
1445 BOOL license_read_binary_blob_data(LICENSE_BLOB* blob, UINT16 wBlobType, const void* data,
1446  size_t length)
1447 {
1448  WINPR_ASSERT(blob);
1449  WINPR_ASSERT(length <= UINT16_MAX);
1450  WINPR_ASSERT(data || (length == 0));
1451 
1452  blob->length = (UINT16)length;
1453  free(blob->data);
1454  blob->data = NULL;
1455 
1456  if ((blob->type != wBlobType) && (blob->type != BB_ANY_BLOB))
1457  {
1458  WLog_ERR(TAG, "license binary blob::type expected %s, got %s",
1459  licencse_blob_type_string(wBlobType), licencse_blob_type_string(blob->type));
1460  }
1461 
1462  /*
1463  * Server can choose to not send data by setting length to 0.
1464  * If so, it may not bother to set the type, so shortcut the warning
1465  */
1466  if ((blob->type != BB_ANY_BLOB) && (blob->length == 0))
1467  {
1468  WLog_WARN(TAG, "license binary blob::type %s, length=0, skipping.",
1469  licencse_blob_type_string(blob->type));
1470  return TRUE;
1471  }
1472 
1473  blob->type = wBlobType;
1474  blob->data = NULL;
1475  if (blob->length > 0)
1476  blob->data = malloc(blob->length);
1477  if (!blob->data)
1478  {
1479  WLog_ERR(TAG, "license binary blob::length=%" PRIu16 ", blob::data=%p", blob->length,
1480  blob->data);
1481  return FALSE;
1482  }
1483  memcpy(blob->data, data, blob->length); /* blobData */
1484  return TRUE;
1485 }
1486 
1494 BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
1495 {
1496  UINT16 wBlobType = 0;
1497  UINT16 length = 0;
1498 
1499  WINPR_ASSERT(blob);
1500 
1501  if (!license_check_stream_length(s, 4, "license binary blob::type"))
1502  return FALSE;
1503 
1504  Stream_Read_UINT16(s, wBlobType); /* wBlobType (2 bytes) */
1505  Stream_Read_UINT16(s, length); /* wBlobLen (2 bytes) */
1506 
1507  if (!license_check_stream_length(s, length, "license binary blob::length"))
1508  return FALSE;
1509 
1510  if (!license_read_binary_blob_data(blob, wBlobType, Stream_Pointer(s), length))
1511  return FALSE;
1512 
1513  return Stream_SafeSeek(s, length);
1514 }
1515 
1523 BOOL license_write_binary_blob(wStream* s, const LICENSE_BLOB* blob)
1524 {
1525  WINPR_ASSERT(blob);
1526 
1527  if (!Stream_EnsureRemainingCapacity(s, blob->length + 4))
1528  return FALSE;
1529 
1530  Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
1531  Stream_Write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
1532 
1533  if (blob->length > 0)
1534  Stream_Write(s, blob->data, blob->length); /* blobData */
1535  return TRUE;
1536 }
1537 
1538 static BOOL license_write_encrypted_premaster_secret_blob(wStream* s, const LICENSE_BLOB* blob,
1539  UINT32 ModulusLength)
1540 {
1541  const UINT32 length = ModulusLength + 8;
1542 
1543  WINPR_ASSERT(blob);
1544  WINPR_ASSERT(length <= UINT16_MAX);
1545 
1546  if (blob->length > ModulusLength)
1547  {
1548  WLog_ERR(TAG, "invalid blob");
1549  return FALSE;
1550  }
1551 
1552  if (!Stream_EnsureRemainingCapacity(s, length + 4))
1553  return FALSE;
1554  Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
1555  Stream_Write_UINT16(s, (UINT16)length); /* wBlobLen (2 bytes) */
1556 
1557  if (blob->length > 0)
1558  Stream_Write(s, blob->data, blob->length); /* blobData */
1559 
1560  Stream_Zero(s, length - blob->length);
1561  return TRUE;
1562 }
1563 
1564 static BOOL license_read_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob,
1565  UINT32* ModulusLength)
1566 {
1567  if (!license_read_binary_blob(s, blob))
1568  return FALSE;
1569  WINPR_ASSERT(ModulusLength);
1570  *ModulusLength = blob->length;
1571  return TRUE;
1572 }
1573 
1580 LICENSE_BLOB* license_new_binary_blob(UINT16 type)
1581 {
1582  LICENSE_BLOB* blob = (LICENSE_BLOB*)calloc(1, sizeof(LICENSE_BLOB));
1583  if (blob)
1584  blob->type = type;
1585  return blob;
1586 }
1587 
1594 void license_free_binary_blob(LICENSE_BLOB* blob)
1595 {
1596  if (blob)
1597  {
1598  free(blob->data);
1599  free(blob);
1600  }
1601 }
1602 
1610 BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList)
1611 {
1612  UINT32 scopeCount = 0;
1613 
1614  WINPR_ASSERT(scopeList);
1615 
1616  if (!license_check_stream_length(s, 4, "license scope list"))
1617  return FALSE;
1618 
1619  Stream_Read_UINT32(s, scopeCount); /* ScopeCount (4 bytes) */
1620 
1621  if (!license_check_stream_length(s, 4ll * scopeCount, "license scope list::count"))
1622  return FALSE;
1623 
1624  if (!license_scope_list_resize(scopeList, scopeCount))
1625  return FALSE;
1626  /* ScopeArray */
1627  for (UINT32 i = 0; i < scopeCount; i++)
1628  {
1629  if (!license_read_binary_blob(s, scopeList->array[i]))
1630  return FALSE;
1631  }
1632 
1633  return TRUE;
1634 }
1635 
1636 BOOL license_write_scope_list(wStream* s, const SCOPE_LIST* scopeList)
1637 {
1638  WINPR_ASSERT(scopeList);
1639 
1640  if (!license_check_stream_capacity(s, 4, "license scope list"))
1641  return FALSE;
1642 
1643  Stream_Write_UINT32(s, scopeList->count); /* ScopeCount (4 bytes) */
1644 
1645  if (!license_check_stream_capacity(s, scopeList->count * 4ull, "license scope list::count"))
1646  return FALSE;
1647 
1648  /* ScopeArray */
1649  WINPR_ASSERT(scopeList->array || (scopeList->count == 0));
1650  for (UINT32 i = 0; i < scopeList->count; i++)
1651  {
1652  const LICENSE_BLOB* element = scopeList->array[i];
1653 
1654  if (!license_write_binary_blob(s, element))
1655  return FALSE;
1656  }
1657 
1658  return TRUE;
1659 }
1660 
1667 SCOPE_LIST* license_new_scope_list(void)
1668 {
1669  SCOPE_LIST* list = calloc(1, sizeof(SCOPE_LIST));
1670  return list;
1671 }
1672 
1673 BOOL license_scope_list_resize(SCOPE_LIST* scopeList, UINT32 count)
1674 {
1675  WINPR_ASSERT(scopeList);
1676  WINPR_ASSERT(scopeList->array || (scopeList->count == 0));
1677 
1678  for (UINT32 x = count; x < scopeList->count; x++)
1679  {
1680  license_free_binary_blob(scopeList->array[x]);
1681  scopeList->array[x] = NULL;
1682  }
1683 
1684  if (count > 0)
1685  {
1686  LICENSE_BLOB** tmp = realloc(scopeList->array, count * sizeof(LICENSE_BLOB*));
1687  if (!tmp)
1688  return FALSE;
1689  scopeList->array = tmp;
1690  }
1691  else
1692  {
1693  free(scopeList->array);
1694  scopeList->array = NULL;
1695  }
1696 
1697  for (UINT32 x = scopeList->count; x < count; x++)
1698  {
1699  LICENSE_BLOB* blob = license_new_binary_blob(BB_SCOPE_BLOB);
1700  if (!blob)
1701  {
1702  scopeList->count = x;
1703  return FALSE;
1704  }
1705  scopeList->array[x] = blob;
1706  }
1707 
1708  scopeList->count = count;
1709  return TRUE;
1710 }
1711 
1718 void license_free_scope_list(SCOPE_LIST* scopeList)
1719 {
1720  if (!scopeList)
1721  return;
1722 
1723  license_scope_list_resize(scopeList, 0);
1724  free(scopeList);
1725 }
1726 
1727 BOOL license_send_license_info(rdpLicense* license, const LICENSE_BLOB* calBlob,
1728  const BYTE* signature, size_t signature_length)
1729 {
1730  WINPR_ASSERT(calBlob);
1731  WINPR_ASSERT(signature);
1732  WINPR_ASSERT(license->certificate);
1733 
1734  const rdpCertInfo* info = freerdp_certificate_get_info(license->certificate);
1735  if (!info)
1736  return FALSE;
1737 
1738  wStream* s = license_send_stream_init(license);
1739  if (!s)
1740  return FALSE;
1741 
1742  if (!license_check_stream_capacity(s, 8 + sizeof(license->ClientRandom),
1743  "license info::ClientRandom"))
1744  return FALSE;
1745 
1746  Stream_Write_UINT32(s,
1747  license->PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
1748  Stream_Write_UINT32(s, license->PlatformId); /* PlatformId (4 bytes) */
1749 
1750  /* ClientRandom (32 bytes) */
1751  Stream_Write(s, license->ClientRandom, sizeof(license->ClientRandom));
1752 
1753  /* Licensing Binary Blob with EncryptedPreMasterSecret: */
1754  if (!license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret,
1755  info->ModulusLength))
1756  goto error;
1757 
1758  /* Licensing Binary Blob with LicenseInfo: */
1759  if (!license_write_binary_blob(s, calBlob))
1760  goto error;
1761 
1762  /* Licensing Binary Blob with EncryptedHWID */
1763  if (!license_write_binary_blob(s, license->EncryptedHardwareId))
1764  goto error;
1765 
1766  /* MACData */
1767  if (!license_check_stream_capacity(s, signature_length, "license info::MACData"))
1768  goto error;
1769  Stream_Write(s, signature, signature_length);
1770 
1771  return license_send(license, s, LICENSE_INFO);
1772 
1773 error:
1774  Stream_Release(s);
1775  return FALSE;
1776 }
1777 
1778 static BOOL license_check_preferred_alg(rdpLicense* license, UINT32 PreferredKeyExchangeAlg,
1779  const char* where)
1780 {
1781  WINPR_ASSERT(license);
1782  WINPR_ASSERT(where);
1783 
1784  if (license->PreferredKeyExchangeAlg != PreferredKeyExchangeAlg)
1785  {
1786  char buffer1[64] = { 0 };
1787  char buffer2[64] = { 0 };
1788  WLog_WARN(TAG, "%s::PreferredKeyExchangeAlg, expected %s, got %s", where,
1789  license_preferred_key_exchange_alg_string(license->PreferredKeyExchangeAlg,
1790  buffer1, sizeof(buffer1)),
1791  license_preferred_key_exchange_alg_string(PreferredKeyExchangeAlg, buffer2,
1792  sizeof(buffer2)));
1793  return FALSE;
1794  }
1795  return TRUE;
1796 }
1797 
1798 BOOL license_read_license_info(rdpLicense* license, wStream* s)
1799 {
1800  BOOL rc = FALSE;
1801  UINT32 PreferredKeyExchangeAlg = 0;
1802 
1803  WINPR_ASSERT(license);
1804  WINPR_ASSERT(license->certificate);
1805 
1806  const rdpCertInfo* info = freerdp_certificate_get_info(license->certificate);
1807  if (!info)
1808  goto error;
1809 
1810  /* ClientRandom (32 bytes) */
1811  if (!license_check_stream_length(s, 8 + sizeof(license->ClientRandom), "license info"))
1812  goto error;
1813 
1814  Stream_Read_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
1815  if (!license_check_preferred_alg(license, PreferredKeyExchangeAlg, "license info"))
1816  goto error;
1817  Stream_Read_UINT32(s, license->PlatformId); /* PlatformId (4 bytes) */
1818 
1819  /* ClientRandom (32 bytes) */
1820  Stream_Read(s, license->ClientRandom, sizeof(license->ClientRandom));
1821 
1822  /* Licensing Binary Blob with EncryptedPreMasterSecret: */
1823  UINT32 ModulusLength = 0;
1824  if (!license_read_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret,
1825  &ModulusLength))
1826  goto error;
1827 
1828  if (ModulusLength != info->ModulusLength)
1829  {
1830  WLog_WARN(TAG,
1831  "EncryptedPremasterSecret,::ModulusLength[%" PRIu32
1832  "] != rdpCertInfo::ModulusLength[%" PRIu32 "]",
1833  ModulusLength, info->ModulusLength);
1834  goto error;
1835  }
1836  /* Licensing Binary Blob with LicenseInfo: */
1837  if (!license_read_binary_blob(s, license->LicenseInfo))
1838  goto error;
1839 
1840  /* Licensing Binary Blob with EncryptedHWID */
1841  if (!license_read_binary_blob(s, license->EncryptedHardwareId))
1842  goto error;
1843 
1844  /* MACData */
1845  if (!license_check_stream_length(s, sizeof(license->MACData), "license info::MACData"))
1846  goto error;
1847  Stream_Read(s, license->MACData, sizeof(license->MACData));
1848 
1849  rc = TRUE;
1850 
1851 error:
1852  return rc;
1853 }
1854 
1862 BOOL license_read_license_request_packet(rdpLicense* license, wStream* s)
1863 {
1864  WINPR_ASSERT(license);
1865 
1866  /* ServerRandom (32 bytes) */
1867  if (!license_check_stream_length(s, sizeof(license->ServerRandom), "license request"))
1868  return FALSE;
1869 
1870  Stream_Read(s, license->ServerRandom, sizeof(license->ServerRandom));
1871 
1872  /* ProductInfo */
1873  if (!license_read_product_info(s, license->ProductInfo))
1874  return FALSE;
1875 
1876  /* KeyExchangeList */
1877  if (!license_read_binary_blob(s, license->KeyExchangeList))
1878  return FALSE;
1879 
1880  /* ServerCertificate */
1881  if (!license_read_binary_blob(s, license->ServerCertificate))
1882  return FALSE;
1883 
1884  /* ScopeList */
1885  if (!license_read_scope_list(s, license->ScopeList))
1886  return FALSE;
1887 
1888  /* Parse Server Certificate */
1889  if (!freerdp_certificate_read_server_cert(license->certificate,
1890  license->ServerCertificate->data,
1891  license->ServerCertificate->length))
1892  return FALSE;
1893 
1894  if (!license_generate_keys(license) || !license_generate_hwid(license) ||
1895  !license_encrypt_premaster_secret(license))
1896  return FALSE;
1897 
1898 #ifdef WITH_DEBUG_LICENSE
1899  WLog_DBG(TAG, "ServerRandom:");
1900  winpr_HexDump(TAG, WLOG_DEBUG, license->ServerRandom, sizeof(license->ServerRandom));
1901  license_print_product_info(license->ProductInfo);
1902  license_print_scope_list(license->ScopeList);
1903 #endif
1904  return TRUE;
1905 }
1906 
1907 BOOL license_write_license_request_packet(const rdpLicense* license, wStream* s)
1908 {
1909  WINPR_ASSERT(license);
1910 
1911  /* ServerRandom (32 bytes) */
1912  if (!license_check_stream_capacity(s, sizeof(license->ServerRandom), "license request"))
1913  return FALSE;
1914  Stream_Write(s, license->ServerRandom, sizeof(license->ServerRandom));
1915 
1916  /* ProductInfo */
1917  if (!license_write_product_info(s, license->ProductInfo))
1918  return FALSE;
1919 
1920  /* KeyExchangeList */
1921  if (!license_write_binary_blob(s, license->KeyExchangeList))
1922  return FALSE;
1923 
1924  /* ServerCertificate */
1925  if (!license_write_binary_blob(s, license->ServerCertificate))
1926  return FALSE;
1927 
1928  /* ScopeList */
1929  if (!license_write_scope_list(s, license->ScopeList))
1930  return FALSE;
1931 
1932  return TRUE;
1933 }
1934 
1935 static BOOL license_send_license_request_packet(rdpLicense* license)
1936 {
1937  wStream* s = license_send_stream_init(license);
1938  if (!s)
1939  return FALSE;
1940 
1941  if (!license_write_license_request_packet(license, s))
1942  goto fail;
1943 
1944  return license_send(license, s, LICENSE_REQUEST);
1945 
1946 fail:
1947  Stream_Release(s);
1948  return FALSE;
1949 }
1950 
1951 /*
1952  * Read a PLATFORM_CHALLENGE packet.
1953  * msdn{cc241921}
1954  * @param license license module
1955  * @param s stream
1956  */
1957 
1958 BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
1959 {
1960  BYTE macData[LICENSING_ENCRYPTION_KEY_LENGTH] = { 0 };
1961  UINT32 ConnectFlags = 0;
1962 
1963  WINPR_ASSERT(license);
1964 
1965  DEBUG_LICENSE("Receiving Platform Challenge Packet");
1966 
1967  if (!license_check_stream_length(s, 4, "license platform challenge"))
1968  return FALSE;
1969 
1970  Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */
1971 
1972  /* EncryptedPlatformChallenge */
1973  license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
1974  if (!license_read_binary_blob(s, license->EncryptedPlatformChallenge))
1975  return FALSE;
1976  license->EncryptedPlatformChallenge->type = BB_ENCRYPTED_DATA_BLOB;
1977 
1978  /* MACData (16 bytes) */
1979  if (!license_check_stream_length(s, sizeof(macData), "license platform challenge::MAC"))
1980  return FALSE;
1981 
1982  Stream_Read(s, macData, sizeof(macData));
1983  if (!license_decrypt_and_check_MAC(license, license->EncryptedPlatformChallenge->data,
1984  license->EncryptedPlatformChallenge->length,
1985  license->PlatformChallenge, macData))
1986  return FALSE;
1987 
1988 #ifdef WITH_DEBUG_LICENSE
1989  WLog_DBG(TAG, "ConnectFlags: 0x%08" PRIX32 "", ConnectFlags);
1990  WLog_DBG(TAG, "EncryptedPlatformChallenge:");
1991  winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPlatformChallenge->data,
1992  license->EncryptedPlatformChallenge->length);
1993  WLog_DBG(TAG, "PlatformChallenge:");
1994  winpr_HexDump(TAG, WLOG_DEBUG, license->PlatformChallenge->data,
1995  license->PlatformChallenge->length);
1996  WLog_DBG(TAG, "MacData:");
1997  winpr_HexDump(TAG, WLOG_DEBUG, macData, sizeof(macData));
1998 #endif
1999  return TRUE;
2000 }
2001 
2002 BOOL license_send_error_alert(rdpLicense* license, UINT32 dwErrorCode, UINT32 dwStateTransition,
2003  const LICENSE_BLOB* info)
2004 {
2005  wStream* s = license_send_stream_init(license);
2006 
2007  if (!s)
2008  goto fail;
2009 
2010  if (!license_check_stream_capacity(s, 8, "license error alert"))
2011  goto fail;
2012  Stream_Write_UINT32(s, dwErrorCode);
2013  Stream_Write_UINT32(s, dwStateTransition);
2014 
2015  if (info)
2016  {
2017  if (!license_write_binary_blob(s, info))
2018  goto fail;
2019  }
2020 
2021  return license_send(license, s, ERROR_ALERT);
2022 fail:
2023  Stream_Release(s);
2024  return FALSE;
2025 }
2026 
2027 BOOL license_send_platform_challenge_packet(rdpLicense* license)
2028 {
2029  wStream* s = license_send_stream_init(license);
2030 
2031  if (!s)
2032  goto fail;
2033 
2034  DEBUG_LICENSE("Receiving Platform Challenge Packet");
2035 
2036  if (!license_check_stream_capacity(s, 4, "license platform challenge"))
2037  goto fail;
2038 
2039  Stream_Zero(s, 4); /* ConnectFlags, Reserved (4 bytes) */
2040 
2041  /* EncryptedPlatformChallenge */
2042  if (!license_write_binary_blob(s, license->EncryptedPlatformChallenge))
2043  goto fail;
2044 
2045  /* MACData (16 bytes) */
2046  if (!license_check_stream_length(s, sizeof(license->MACData),
2047  "license platform challenge::MAC"))
2048  goto fail;
2049 
2050  Stream_Write(s, license->MACData, sizeof(license->MACData));
2051 
2052  return license_send(license, s, PLATFORM_CHALLENGE);
2053 fail:
2054  Stream_Release(s);
2055  return FALSE;
2056 }
2057 
2058 static BOOL license_read_encrypted_blob(const rdpLicense* license, wStream* s, LICENSE_BLOB* target)
2059 {
2060  UINT16 wBlobType = 0;
2061  UINT16 wBlobLen = 0;
2062 
2063  WINPR_ASSERT(license);
2064  WINPR_ASSERT(target);
2065 
2066  if (!license_check_stream_length(s, 4, "license encrypted blob"))
2067  return FALSE;
2068 
2069  Stream_Read_UINT16(s, wBlobType);
2070  if (wBlobType != BB_ENCRYPTED_DATA_BLOB)
2071  {
2072  WLog_WARN(
2073  TAG,
2074  "expecting BB_ENCRYPTED_DATA_BLOB blob, probably a windows 2003 server, continuing...");
2075  }
2076 
2077  Stream_Read_UINT16(s, wBlobLen);
2078 
2079  BYTE* encryptedData = Stream_Pointer(s);
2080  if (!Stream_SafeSeek(s, wBlobLen))
2081  {
2082  WLog_WARN(TAG,
2083  "short license encrypted blob::length, expected %" PRIu16 " bytes, got %" PRIuz,
2084  wBlobLen, Stream_GetRemainingLength(s));
2085  return FALSE;
2086  }
2087 
2088  return license_rc4_with_licenseKey(license, encryptedData, wBlobLen, target);
2089 }
2090 
2098 BOOL license_read_new_or_upgrade_license_packet(rdpLicense* license, wStream* s)
2099 {
2100  UINT32 os_major = 0;
2101  UINT32 os_minor = 0;
2102  UINT32 cbScope = 0;
2103  UINT32 cbCompanyName = 0;
2104  UINT32 cbProductId = 0;
2105  UINT32 cbLicenseInfo = 0;
2106  wStream sbuffer = { 0 };
2107  wStream* licenseStream = NULL;
2108  BOOL ret = FALSE;
2109  BYTE computedMac[16] = { 0 };
2110  const BYTE* readMac = NULL;
2111 
2112  WINPR_ASSERT(license);
2113 
2114  DEBUG_LICENSE("Receiving Server New/Upgrade License Packet");
2115 
2116  LICENSE_BLOB* calBlob = license_new_binary_blob(BB_DATA_BLOB);
2117  if (!calBlob)
2118  return FALSE;
2119 
2120  /* EncryptedLicenseInfo */
2121  if (!license_read_encrypted_blob(license, s, calBlob))
2122  goto fail;
2123 
2124  /* compute MAC and check it */
2125  readMac = Stream_Pointer(s);
2126  if (!Stream_SafeSeek(s, sizeof(computedMac)))
2127  {
2128  WLog_WARN(TAG, "short license new/upgrade, expected 16 bytes, got %" PRIuz,
2129  Stream_GetRemainingLength(s));
2130  goto fail;
2131  }
2132 
2133  if (!security_mac_data(license->MacSaltKey, sizeof(license->MacSaltKey), calBlob->data,
2134  calBlob->length, computedMac, sizeof(computedMac)))
2135  goto fail;
2136 
2137  if (memcmp(computedMac, readMac, sizeof(computedMac)) != 0)
2138  {
2139  WLog_ERR(TAG, "new or upgrade license MAC mismatch");
2140  goto fail;
2141  }
2142 
2143  licenseStream = Stream_StaticConstInit(&sbuffer, calBlob->data, calBlob->length);
2144  if (!licenseStream)
2145  {
2146  WLog_ERR(TAG, "license::blob::data=%p, license::blob::length=%" PRIu16, calBlob->data,
2147  calBlob->length);
2148  goto fail;
2149  }
2150 
2151  if (!license_check_stream_length(licenseStream, 8, "license new/upgrade::blob::version"))
2152  goto fail;
2153 
2154  Stream_Read_UINT16(licenseStream, os_minor);
2155  Stream_Read_UINT16(licenseStream, os_major);
2156 
2157  WLog_DBG(TAG, "Version: %" PRIu16 ".%" PRIu16, os_major, os_minor);
2158 
2159  /* Scope */
2160  Stream_Read_UINT32(licenseStream, cbScope);
2161  if (!license_check_stream_length(licenseStream, cbScope, "license new/upgrade::blob::scope"))
2162  goto fail;
2163 
2164 #ifdef WITH_DEBUG_LICENSE
2165  WLog_DBG(TAG, "Scope:");
2166  winpr_HexDump(TAG, WLOG_DEBUG, Stream_Pointer(licenseStream), cbScope);
2167 #endif
2168  Stream_Seek(licenseStream, cbScope);
2169 
2170  /* CompanyName */
2171  if (!license_check_stream_length(licenseStream, 4, "license new/upgrade::blob::cbCompanyName"))
2172  goto fail;
2173 
2174  Stream_Read_UINT32(licenseStream, cbCompanyName);
2175  if (!license_check_stream_length(licenseStream, cbCompanyName,
2176  "license new/upgrade::blob::CompanyName"))
2177  goto fail;
2178 
2179 #ifdef WITH_DEBUG_LICENSE
2180  WLog_DBG(TAG, "Company name:");
2181  winpr_HexDump(TAG, WLOG_DEBUG, Stream_Pointer(licenseStream), cbCompanyName);
2182 #endif
2183  Stream_Seek(licenseStream, cbCompanyName);
2184 
2185  /* productId */
2186  if (!license_check_stream_length(licenseStream, 4, "license new/upgrade::blob::cbProductId"))
2187  goto fail;
2188 
2189  Stream_Read_UINT32(licenseStream, cbProductId);
2190 
2191  if (!license_check_stream_length(licenseStream, cbProductId,
2192  "license new/upgrade::blob::ProductId"))
2193  goto fail;
2194 
2195 #ifdef WITH_DEBUG_LICENSE
2196  WLog_DBG(TAG, "Product id:");
2197  winpr_HexDump(TAG, WLOG_DEBUG, Stream_Pointer(licenseStream), cbProductId);
2198 #endif
2199  Stream_Seek(licenseStream, cbProductId);
2200 
2201  /* licenseInfo */
2202  if (!license_check_stream_length(licenseStream, 4, "license new/upgrade::blob::cbLicenseInfo"))
2203  goto fail;
2204 
2205  Stream_Read_UINT32(licenseStream, cbLicenseInfo);
2206  if (!license_check_stream_length(licenseStream, cbLicenseInfo,
2207  "license new/upgrade::blob::LicenseInfo"))
2208  goto fail;
2209 
2210  license->type = LICENSE_TYPE_ISSUED;
2211  ret = license_set_state(license, LICENSE_STATE_COMPLETED);
2212 
2213  if (!license->rdp->settings->OldLicenseBehaviour)
2214  ret = saveCal(license->rdp->settings, Stream_Pointer(licenseStream), cbLicenseInfo,
2215  license->rdp->settings->ClientHostname);
2216 
2217 fail:
2218  license_free_binary_blob(calBlob);
2219  return ret;
2220 }
2221 
2229 BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
2230 {
2231  UINT32 dwErrorCode = 0;
2232  UINT32 dwStateTransition = 0;
2233 
2234  WINPR_ASSERT(license);
2235  WINPR_ASSERT(license->rdp);
2236 
2237  if (!license_check_stream_length(s, 8ul, "error alert"))
2238  return FALSE;
2239 
2240  Stream_Read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */
2241  Stream_Read_UINT32(s, dwStateTransition); /* dwStateTransition (4 bytes) */
2242 
2243  if (!license_read_binary_blob(s, license->ErrorInfo)) /* bbErrorInfo */
2244  return FALSE;
2245 
2246 #ifdef WITH_DEBUG_LICENSE
2247  WLog_DBG(TAG, "dwErrorCode: %s, dwStateTransition: %s", error_codes[dwErrorCode],
2248  state_transitions[dwStateTransition]);
2249 #endif
2250 
2251  if (dwErrorCode == STATUS_VALID_CLIENT)
2252  {
2253  license->type = LICENSE_TYPE_NONE;
2254  return license_set_state(license, LICENSE_STATE_COMPLETED);
2255  }
2256 
2257  switch (dwStateTransition)
2258  {
2259  case ST_TOTAL_ABORT:
2260  license_set_state(license, LICENSE_STATE_ABORTED);
2261  break;
2262  case ST_NO_TRANSITION:
2263  license_set_state(license, LICENSE_STATE_COMPLETED);
2264  break;
2265  case ST_RESET_PHASE_TO_START:
2266  license_set_state(license, LICENSE_STATE_CONFIGURED);
2267  break;
2268  case ST_RESEND_LAST_MESSAGE:
2269  break;
2270  default:
2271  break;
2272  }
2273 
2274  return TRUE;
2275 }
2276 
2284 BOOL license_write_new_license_request_packet(const rdpLicense* license, wStream* s)
2285 {
2286  WINPR_ASSERT(license);
2287 
2288  const rdpCertInfo* info = freerdp_certificate_get_info(license->certificate);
2289  if (!info)
2290  return FALSE;
2291 
2292  if (!license_check_stream_capacity(s, 8 + sizeof(license->ClientRandom), "License Request"))
2293  return FALSE;
2294 
2295  Stream_Write_UINT32(s,
2296  license->PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
2297  Stream_Write_UINT32(s, license->PlatformId); /* PlatformId (4 bytes) */
2298  Stream_Write(s, license->ClientRandom,
2299  sizeof(license->ClientRandom)); /* ClientRandom (32 bytes) */
2300 
2301  if (/* EncryptedPremasterSecret */
2302  !license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret,
2303  info->ModulusLength) ||
2304  /* ClientUserName */
2305  !license_write_binary_blob(s, license->ClientUserName) ||
2306  /* ClientMachineName */
2307  !license_write_binary_blob(s, license->ClientMachineName))
2308  {
2309  return FALSE;
2310  }
2311 
2312 #ifdef WITH_DEBUG_LICENSE
2313  WLog_DBG(TAG, "PreferredKeyExchangeAlg: 0x%08" PRIX32 "", license->PreferredKeyExchangeAlg);
2314  WLog_DBG(TAG, "ClientRandom:");
2315  winpr_HexDump(TAG, WLOG_DEBUG, license->ClientRandom, sizeof(license->ClientRandom));
2316  WLog_DBG(TAG, "EncryptedPremasterSecret");
2317  winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPremasterSecret->data,
2318  license->EncryptedPremasterSecret->length);
2319  WLog_DBG(TAG, "ClientUserName (%" PRIu16 "): %s", license->ClientUserName->length,
2320  (char*)license->ClientUserName->data);
2321  WLog_DBG(TAG, "ClientMachineName (%" PRIu16 "): %s", license->ClientMachineName->length,
2322  (char*)license->ClientMachineName->data);
2323 #endif
2324  return TRUE;
2325 }
2326 
2327 BOOL license_read_new_license_request_packet(rdpLicense* license, wStream* s)
2328 {
2329  UINT32 PreferredKeyExchangeAlg = 0;
2330 
2331  WINPR_ASSERT(license);
2332 
2333  if (!license_check_stream_length(s, 8ull + sizeof(license->ClientRandom),
2334  "new license request"))
2335  return FALSE;
2336 
2337  Stream_Read_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
2338  if (!license_check_preferred_alg(license, PreferredKeyExchangeAlg, "new license request"))
2339  return FALSE;
2340 
2341  Stream_Read_UINT32(s, license->PlatformId); /* PlatformId (4 bytes) */
2342  Stream_Read(s, license->ClientRandom,
2343  sizeof(license->ClientRandom)); /* ClientRandom (32 bytes) */
2344 
2345  /* EncryptedPremasterSecret */
2346  UINT32 ModulusLength = 0;
2347  if (!license_read_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret,
2348  &ModulusLength))
2349  return FALSE;
2350 
2351  const rdpCertInfo* info = freerdp_certificate_get_info(license->certificate);
2352  if (!info)
2353  WLog_WARN(TAG, "Missing license certificate, skipping ModulusLength checks");
2354  else if (ModulusLength != info->ModulusLength)
2355  {
2356  WLog_WARN(TAG,
2357  "EncryptedPremasterSecret expected to be %" PRIu32 " bytes, but read %" PRIu32
2358  " bytes",
2359  info->ModulusLength, ModulusLength);
2360  return FALSE;
2361  }
2362 
2363  /* ClientUserName */
2364  if (!license_read_binary_blob(s, license->ClientUserName))
2365  return FALSE;
2366  /* ClientMachineName */
2367  if (!license_read_binary_blob(s, license->ClientMachineName))
2368  return FALSE;
2369 
2370  return TRUE;
2371 }
2372 
2379 BOOL license_answer_license_request(rdpLicense* license)
2380 {
2381  wStream* s = NULL;
2382  BYTE* license_data = NULL;
2383  size_t license_size = 0;
2384  BOOL status = 0;
2385  char* username = NULL;
2386 
2387  WINPR_ASSERT(license);
2388  WINPR_ASSERT(license->rdp);
2389  WINPR_ASSERT(license->rdp->settings);
2390 
2391  if (!license->rdp->settings->OldLicenseBehaviour)
2392  license_data = loadCalFile(license->rdp->settings, license->rdp->settings->ClientHostname,
2393  &license_size);
2394 
2395  if (license_data)
2396  {
2397  LICENSE_BLOB* calBlob = NULL;
2398  BYTE signature[LICENSING_ENCRYPTION_KEY_LENGTH] = { 0 };
2399 
2400  DEBUG_LICENSE("Sending Saved License Packet");
2401 
2402  WINPR_ASSERT(license->EncryptedHardwareId);
2403  license->EncryptedHardwareId->type = BB_ENCRYPTED_DATA_BLOB;
2404  if (!license_encrypt_and_MAC(license, license->HardwareId, sizeof(license->HardwareId),
2405  license->EncryptedHardwareId, signature, sizeof(signature)))
2406  {
2407  free(license_data);
2408  return FALSE;
2409  }
2410 
2411  calBlob = license_new_binary_blob(BB_DATA_BLOB);
2412  if (!calBlob)
2413  {
2414  free(license_data);
2415  return FALSE;
2416  }
2417  calBlob->data = license_data;
2418  WINPR_ASSERT(license_size <= UINT16_MAX);
2419  calBlob->length = (UINT16)license_size;
2420 
2421  status = license_send_license_info(license, calBlob, signature, sizeof(signature));
2422  license_free_binary_blob(calBlob);
2423 
2424  return status;
2425  }
2426 
2427  DEBUG_LICENSE("Sending New License Packet");
2428 
2429  s = license_send_stream_init(license);
2430  if (!s)
2431  return FALSE;
2432  if (license->rdp->settings->Username != NULL)
2433  username = license->rdp->settings->Username;
2434  else
2435  username = "username";
2436 
2437  {
2438  WINPR_ASSERT(license->ClientUserName);
2439  const size_t len = strlen(username) + 1;
2440  WINPR_ASSERT(len <= UINT16_MAX);
2441 
2442  license->ClientUserName->data = (BYTE*)username;
2443  license->ClientUserName->length = (UINT16)len;
2444  }
2445 
2446  {
2447  WINPR_ASSERT(license->ClientMachineName);
2448  const size_t len = strlen(license->rdp->settings->ClientHostname) + 1;
2449  WINPR_ASSERT(len <= UINT16_MAX);
2450 
2451  license->ClientMachineName->data = (BYTE*)license->rdp->settings->ClientHostname;
2452  license->ClientMachineName->length = (UINT16)len;
2453  }
2454  status = license_write_new_license_request_packet(license, s);
2455 
2456  WINPR_ASSERT(license->ClientUserName);
2457  license->ClientUserName->data = NULL;
2458  license->ClientUserName->length = 0;
2459 
2460  WINPR_ASSERT(license->ClientMachineName);
2461  license->ClientMachineName->data = NULL;
2462  license->ClientMachineName->length = 0;
2463 
2464  if (!status)
2465  {
2466  Stream_Release(s);
2467  return FALSE;
2468  }
2469 
2470  return license_send(license, s, NEW_LICENSE_REQUEST);
2471 }
2472 
2479 BOOL license_send_platform_challenge_response(rdpLicense* license)
2480 {
2481  wStream* s = license_send_stream_init(license);
2482  wStream* challengeRespData = NULL;
2483  BYTE* buffer = NULL;
2484  BOOL status = 0;
2485 
2486  WINPR_ASSERT(license);
2487  WINPR_ASSERT(license->PlatformChallenge);
2488  WINPR_ASSERT(license->MacSaltKey);
2489  WINPR_ASSERT(license->EncryptedPlatformChallenge);
2490  WINPR_ASSERT(license->EncryptedHardwareId);
2491 
2492  DEBUG_LICENSE("Sending Platform Challenge Response Packet");
2493 
2494  license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
2495 
2496  /* prepare the PLATFORM_CHALLENGE_RESPONSE_DATA */
2497  challengeRespData = Stream_New(NULL, 8 + license->PlatformChallenge->length);
2498  if (!challengeRespData)
2499  return FALSE;
2500  Stream_Write_UINT16(challengeRespData, PLATFORM_CHALLENGE_RESPONSE_VERSION); /* wVersion */
2501  Stream_Write_UINT16(challengeRespData, license->ClientType); /* wClientType */
2502  Stream_Write_UINT16(challengeRespData, license->LicenseDetailLevel); /* wLicenseDetailLevel */
2503  Stream_Write_UINT16(challengeRespData, license->PlatformChallenge->length); /* cbChallenge */
2504  Stream_Write(challengeRespData, license->PlatformChallenge->data,
2505  license->PlatformChallenge->length); /* pbChallenge */
2506  Stream_SealLength(challengeRespData);
2507 
2508  /* compute MAC of PLATFORM_CHALLENGE_RESPONSE_DATA + HWID */
2509  const size_t length = Stream_Length(challengeRespData) + sizeof(license->HardwareId);
2510  buffer = (BYTE*)malloc(length);
2511  if (!buffer)
2512  {
2513  Stream_Free(challengeRespData, TRUE);
2514  return FALSE;
2515  }
2516 
2517  CopyMemory(buffer, Stream_Buffer(challengeRespData), Stream_Length(challengeRespData));
2518  CopyMemory(&buffer[Stream_Length(challengeRespData)], license->HardwareId,
2519  sizeof(license->HardwareId));
2520  status = security_mac_data(license->MacSaltKey, sizeof(license->MacSaltKey), buffer, length,
2521  license->MACData, sizeof(license->MACData));
2522  free(buffer);
2523 
2524  if (!status)
2525  {
2526  Stream_Free(challengeRespData, TRUE);
2527  return FALSE;
2528  }
2529 
2530  license->EncryptedHardwareId->type = BB_ENCRYPTED_DATA_BLOB;
2531  if (!license_rc4_with_licenseKey(license, license->HardwareId, sizeof(license->HardwareId),
2532  license->EncryptedHardwareId))
2533  {
2534  Stream_Free(challengeRespData, TRUE);
2535  return FALSE;
2536  }
2537 
2538  status = license_rc4_with_licenseKey(license, Stream_Buffer(challengeRespData),
2539  Stream_Length(challengeRespData),
2540  license->EncryptedPlatformChallengeResponse);
2541  Stream_Free(challengeRespData, TRUE);
2542  if (!status)
2543  return FALSE;
2544 
2545 #ifdef WITH_DEBUG_LICENSE
2546  WLog_DBG(TAG, "LicensingEncryptionKey:");
2547  winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, 16);
2548  WLog_DBG(TAG, "HardwareId:");
2549  winpr_HexDump(TAG, WLOG_DEBUG, license->HardwareId, sizeof(license->HardwareId));
2550  WLog_DBG(TAG, "EncryptedHardwareId:");
2551  winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data,
2552  license->EncryptedHardwareId->length);
2553 #endif
2554  if (license_write_client_platform_challenge_response(license, s))
2555  return license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
2556 
2557  Stream_Release(s);
2558  return FALSE;
2559 }
2560 
2561 BOOL license_read_platform_challenge_response(rdpLicense* license, wStream* s)
2562 {
2563  UINT16 wVersion = 0;
2564  UINT16 cbChallenge = 0;
2565  const BYTE* pbChallenge = NULL;
2566 
2567  WINPR_ASSERT(license);
2568  WINPR_ASSERT(license->PlatformChallenge);
2569  WINPR_ASSERT(license->MacSaltKey);
2570  WINPR_ASSERT(license->EncryptedPlatformChallenge);
2571  WINPR_ASSERT(license->EncryptedHardwareId);
2572 
2573  DEBUG_LICENSE("Receiving Platform Challenge Response Packet");
2574 
2575  if (!license_check_stream_length(s, 8, "PLATFORM_CHALLENGE_RESPONSE_DATA"))
2576  return FALSE;
2577 
2578  Stream_Read_UINT16(s, wVersion);
2579  if (wVersion != PLATFORM_CHALLENGE_RESPONSE_VERSION)
2580  {
2581  WLog_WARN(TAG,
2582  "Invalid PLATFORM_CHALLENGE_RESPONSE_DATA::wVersion 0x%04" PRIx16
2583  ", expected 0x04" PRIx16,
2584  wVersion, PLATFORM_CHALLENGE_RESPONSE_VERSION);
2585  return FALSE;
2586  }
2587  Stream_Read_UINT16(s, license->ClientType);
2588  Stream_Read_UINT16(s, license->LicenseDetailLevel);
2589  Stream_Read_UINT16(s, cbChallenge);
2590 
2591  if (!license_check_stream_length(s, cbChallenge,
2592  "PLATFORM_CHALLENGE_RESPONSE_DATA::pbChallenge"))
2593  return FALSE;
2594 
2595  pbChallenge = Stream_Pointer(s);
2596  if (!license_read_binary_blob_data(license->EncryptedPlatformChallengeResponse, BB_DATA_BLOB,
2597  pbChallenge, cbChallenge))
2598  return FALSE;
2599  return Stream_SafeSeek(s, cbChallenge);
2600 }
2601 
2602 BOOL license_write_client_platform_challenge_response(rdpLicense* license, wStream* s)
2603 {
2604  WINPR_ASSERT(license);
2605 
2606  if (!license_write_binary_blob(s, license->EncryptedPlatformChallengeResponse))
2607  return FALSE;
2608  if (!license_write_binary_blob(s, license->EncryptedHardwareId))
2609  return FALSE;
2610  if (!license_check_stream_capacity(s, sizeof(license->MACData),
2611  "CLIENT_PLATFORM_CHALLENGE_RESPONSE::MACData"))
2612  return FALSE;
2613  Stream_Write(s, license->MACData, sizeof(license->MACData));
2614  return TRUE;
2615 }
2616 
2617 BOOL license_read_client_platform_challenge_response(rdpLicense* license, wStream* s)
2618 {
2619  WINPR_ASSERT(license);
2620 
2621  if (!license_read_binary_blob(s, license->EncryptedPlatformChallengeResponse))
2622  return FALSE;
2623  if (!license_read_binary_blob(s, license->EncryptedHardwareId))
2624  return FALSE;
2625  if (!license_check_stream_length(s, sizeof(license->MACData),
2626  "CLIENT_PLATFORM_CHALLENGE_RESPONSE::MACData"))
2627  return FALSE;
2628  Stream_Read(s, license->MACData, sizeof(license->MACData));
2629  return TRUE;
2630 }
2631 
2641 BOOL license_send_valid_client_error_packet(rdpRdp* rdp)
2642 {
2643  WINPR_ASSERT(rdp);
2644  rdpLicense* license = rdp->license;
2645  WINPR_ASSERT(license);
2646 
2647  license->state = LICENSE_STATE_COMPLETED;
2648  license->type = LICENSE_TYPE_NONE;
2649  return license_send_error_alert(license, STATUS_VALID_CLIENT, ST_NO_TRANSITION,
2650  license->ErrorInfo);
2651 }
2652 
2659 rdpLicense* license_new(rdpRdp* rdp)
2660 {
2661  rdpLicense* license = NULL;
2662  WINPR_ASSERT(rdp);
2663 
2664  license = (rdpLicense*)calloc(1, sizeof(rdpLicense));
2665  if (!license)
2666  return NULL;
2667 
2668  license->PlatformId = PLATFORMID;
2669  license->ClientType = OTHER_PLATFORM_CHALLENGE_TYPE;
2670  license->LicenseDetailLevel = LICENSE_DETAIL_DETAIL;
2671  license->PreferredKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
2672  license->rdp = rdp;
2673 
2674  license_set_state(license, LICENSE_STATE_INITIAL);
2675  if (!(license->certificate = freerdp_certificate_new()))
2676  goto out_error;
2677  if (!(license->ProductInfo = license_new_product_info()))
2678  goto out_error;
2679  if (!(license->ErrorInfo = license_new_binary_blob(BB_ERROR_BLOB)))
2680  goto out_error;
2681  if (!(license->LicenseInfo = license_new_binary_blob(BB_DATA_BLOB)))
2682  goto out_error;
2683  if (!(license->KeyExchangeList = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB)))
2684  goto out_error;
2685  if (!(license->ServerCertificate = license_new_binary_blob(BB_CERTIFICATE_BLOB)))
2686  goto out_error;
2687  if (!(license->ClientUserName = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB)))
2688  goto out_error;
2689  if (!(license->ClientMachineName = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB)))
2690  goto out_error;
2691  if (!(license->PlatformChallenge = license_new_binary_blob(BB_ANY_BLOB)))
2692  goto out_error;
2693  if (!(license->EncryptedPlatformChallenge = license_new_binary_blob(BB_ANY_BLOB)))
2694  goto out_error;
2695  if (!(license->EncryptedPlatformChallengeResponse =
2696  license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB)))
2697  goto out_error;
2698  if (!(license->EncryptedPremasterSecret = license_new_binary_blob(BB_ANY_BLOB)))
2699  goto out_error;
2700  if (!(license->EncryptedHardwareId = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB)))
2701  goto out_error;
2702  if (!(license->EncryptedLicenseInfo = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB)))
2703  goto out_error;
2704  if (!(license->ScopeList = license_new_scope_list()))
2705  goto out_error;
2706 
2707  license_generate_randoms(license);
2708 
2709  return license;
2710 
2711 out_error:
2712  WINPR_PRAGMA_DIAG_PUSH
2713  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2714  license_free(license);
2715  WINPR_PRAGMA_DIAG_POP
2716  return NULL;
2717 }
2718 
2724 void license_free(rdpLicense* license)
2725 {
2726  if (license)
2727  {
2728  freerdp_certificate_free(license->certificate);
2729  license_free_product_info(license->ProductInfo);
2730  license_free_binary_blob(license->ErrorInfo);
2731  license_free_binary_blob(license->LicenseInfo);
2732  license_free_binary_blob(license->KeyExchangeList);
2733  license_free_binary_blob(license->ServerCertificate);
2734  license_free_binary_blob(license->ClientUserName);
2735  license_free_binary_blob(license->ClientMachineName);
2736  license_free_binary_blob(license->PlatformChallenge);
2737  license_free_binary_blob(license->EncryptedPlatformChallenge);
2738  license_free_binary_blob(license->EncryptedPlatformChallengeResponse);
2739  license_free_binary_blob(license->EncryptedPremasterSecret);
2740  license_free_binary_blob(license->EncryptedHardwareId);
2741  license_free_binary_blob(license->EncryptedLicenseInfo);
2742  license_free_scope_list(license->ScopeList);
2743  free(license);
2744  }
2745 }
2746 
2747 LICENSE_STATE license_get_state(const rdpLicense* license)
2748 {
2749  WINPR_ASSERT(license);
2750  return license->state;
2751 }
2752 
2753 LICENSE_TYPE license_get_type(const rdpLicense* license)
2754 {
2755  WINPR_ASSERT(license);
2756  return license->type;
2757 }
2758 
2759 BOOL license_set_state(rdpLicense* license, LICENSE_STATE state)
2760 {
2761  WINPR_ASSERT(license);
2762  license->state = state;
2763  switch (state)
2764  {
2765  case LICENSE_STATE_COMPLETED:
2766  break;
2767  case LICENSE_STATE_ABORTED:
2768  default:
2769  license->type = LICENSE_TYPE_INVALID;
2770  break;
2771  }
2772 
2773  return TRUE;
2774 }
2775 
2776 const char* license_get_state_string(LICENSE_STATE state)
2777 {
2778  switch (state)
2779  {
2780  case LICENSE_STATE_INITIAL:
2781  return "LICENSE_STATE_INITIAL";
2782  case LICENSE_STATE_CONFIGURED:
2783  return "LICENSE_STATE_CONFIGURED";
2784  case LICENSE_STATE_REQUEST:
2785  return "LICENSE_STATE_REQUEST";
2786  case LICENSE_STATE_NEW_REQUEST:
2787  return "LICENSE_STATE_NEW_REQUEST";
2788  case LICENSE_STATE_PLATFORM_CHALLENGE:
2789  return "LICENSE_STATE_PLATFORM_CHALLENGE";
2790  case LICENSE_STATE_PLATFORM_CHALLENGE_RESPONSE:
2791  return "LICENSE_STATE_PLATFORM_CHALLENGE_RESPONSE";
2792  case LICENSE_STATE_COMPLETED:
2793  return "LICENSE_STATE_COMPLETED";
2794  case LICENSE_STATE_ABORTED:
2795  return "LICENSE_STATE_ABORTED";
2796  default:
2797  return "LICENSE_STATE_UNKNOWN";
2798  }
2799 }
2800 
2801 BOOL license_server_send_request(rdpLicense* license)
2802 {
2803  if (!license_ensure_state(license, LICENSE_STATE_CONFIGURED, LICENSE_REQUEST))
2804  return FALSE;
2805  if (!license_send_license_request_packet(license))
2806  return FALSE;
2807  return license_set_state(license, LICENSE_STATE_REQUEST);
2808 }
2809 
2810 static BOOL license_set_string(const char* what, const char* value, BYTE** bdst, UINT32* dstLen)
2811 {
2812  WINPR_ASSERT(what);
2813  WINPR_ASSERT(value);
2814  WINPR_ASSERT(bdst);
2815  WINPR_ASSERT(dstLen);
2816 
2817  union
2818  {
2819  WCHAR** w;
2820  BYTE** b;
2821  } cnv;
2822  cnv.b = bdst;
2823 
2824  size_t len = 0;
2825  *cnv.w = ConvertUtf8ToWCharAlloc(value, &len);
2826  if (!*cnv.w || (len > UINT32_MAX / sizeof(WCHAR)))
2827  {
2828  WLog_ERR(TAG, "license->ProductInfo: %s == %p || %" PRIu32 " > UINT32_MAX", what, *cnv.w,
2829  len);
2830  return FALSE;
2831  }
2832  *dstLen = (UINT32)(len * sizeof(WCHAR));
2833  return TRUE;
2834 }
2835 
2836 BOOL license_server_configure(rdpLicense* license)
2837 {
2838  wStream* s = NULL;
2839  UINT32 algs[] = { KEY_EXCHANGE_ALG_RSA };
2840 
2841  WINPR_ASSERT(license);
2842  WINPR_ASSERT(license->rdp);
2843 
2844  const rdpSettings* settings = license->rdp->settings;
2845 
2846  const char* CompanyName =
2847  freerdp_settings_get_string(settings, FreeRDP_ServerLicenseCompanyName);
2848 
2849  const char* ProductName =
2850  freerdp_settings_get_string(settings, FreeRDP_ServerLicenseProductName);
2851  const UINT32 ProductVersion =
2852  freerdp_settings_get_uint32(settings, FreeRDP_ServerLicenseProductVersion);
2853  const UINT32 issuerCount =
2854  freerdp_settings_get_uint32(settings, FreeRDP_ServerLicenseProductIssuersCount);
2855 
2856  const void* ptr = freerdp_settings_get_pointer(settings, FreeRDP_ServerLicenseProductIssuers);
2857  const char** issuers = WINPR_REINTERPRET_CAST(ptr, const void*, const char**);
2858 
2859  WINPR_ASSERT(CompanyName);
2860  WINPR_ASSERT(ProductName);
2861  WINPR_ASSERT(ProductVersion > 0);
2862  WINPR_ASSERT(issuers || (issuerCount == 0));
2863 
2864  if (!license_ensure_state(license, LICENSE_STATE_INITIAL, LICENSE_REQUEST))
2865  return FALSE;
2866 
2867  license->ProductInfo->dwVersion = ProductVersion;
2868  if (!license_set_string("pbCompanyName", CompanyName, &license->ProductInfo->pbCompanyName,
2869  &license->ProductInfo->cbCompanyName))
2870  return FALSE;
2871 
2872  if (!license_set_string("pbProductId", ProductName, &license->ProductInfo->pbProductId,
2873  &license->ProductInfo->cbProductId))
2874  return FALSE;
2875 
2876  if (!license_read_binary_blob_data(license->KeyExchangeList, BB_KEY_EXCHG_ALG_BLOB, algs,
2877  sizeof(algs)))
2878  return FALSE;
2879 
2880  if (!freerdp_certificate_read_server_cert(license->certificate, settings->ServerCertificate,
2881  settings->ServerCertificateLength))
2882  return FALSE;
2883 
2884  s = Stream_New(NULL, 1024);
2885  if (!s)
2886  return FALSE;
2887  else
2888  {
2889  BOOL r = FALSE;
2890  SSIZE_T res =
2891  freerdp_certificate_write_server_cert(license->certificate, CERT_CHAIN_VERSION_2, s);
2892  if (res >= 0)
2893  r = license_read_binary_blob_data(license->ServerCertificate, BB_CERTIFICATE_BLOB,
2894  Stream_Buffer(s), Stream_GetPosition(s));
2895 
2896  Stream_Free(s, TRUE);
2897  if (!r)
2898  return FALSE;
2899  }
2900 
2901  if (!license_scope_list_resize(license->ScopeList, issuerCount))
2902  return FALSE;
2903  for (size_t x = 0; x < issuerCount; x++)
2904  {
2905  LICENSE_BLOB* blob = license->ScopeList->array[x];
2906  const char* name = issuers[x];
2907  const size_t length = strnlen(name, UINT16_MAX) + 1;
2908  if ((length == 0) || (length > UINT16_MAX))
2909  {
2910  WLog_WARN(TAG,
2911  "%s: Invalid issuer at position %" PRIuz ": length 0 < %" PRIuz " <= %" PRIu16
2912  " ['%s']",
2913  x, length, UINT16_MAX, name);
2914  return FALSE;
2915  }
2916  if (!license_read_binary_blob_data(blob, BB_SCOPE_BLOB, name, length))
2917  return FALSE;
2918  }
2919 
2920  return license_set_state(license, LICENSE_STATE_CONFIGURED);
2921 }
2922 
2923 rdpLicense* license_get(rdpContext* context)
2924 {
2925  WINPR_ASSERT(context);
2926  WINPR_ASSERT(context->rdp);
2927  return context->rdp->license;
2928 }
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.