コード例 #1
0
ファイル: licence.c プロジェクト: nidelius/FreeRDP
/* Process a Server Platform Challenge packet */
static void
licence_process_platform_challenge(rdpLicence * licence, STREAM s)
{
    uint8 *in_token = NULL, *in_sig;
    uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
    uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
    uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
    uint8 out_sig[LICENCE_SIGNATURE_SIZE];
    CryptoRc4 crypt_key;

    /* Parse incoming packet and save the encrypted token */
    licence_parse_authreq(licence, s, &in_token, &in_sig);
    memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);

    /* Decrypt the token. It should read TEST in Unicode. */
    crypt_key = crypto_rc4_init(licence->licence_key, 16);
    crypto_rc4(crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);
    crypto_rc4_free(crypt_key);

    /* Generate a signature for a buffer of token and HWID */
    licence_generate_hwid(licence, hwid);
    memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
    memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
    sec_sign(out_sig, 16, licence->licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));

    /* Now encrypt the HWID */
    crypt_key = crypto_rc4_init(licence->licence_key, 16);
    crypto_rc4(crypt_key, LICENCE_HWID_SIZE, hwid, crypt_hwid);
    crypto_rc4_free(crypt_key);

    licence_send_authresp(licence, out_token, crypt_hwid, out_sig);
}
コード例 #2
0
ファイル: license.c プロジェクト: Cyclic/FreeRDP
void license_decrypt_platform_challenge(rdpLicense* license)
{
	CryptoRc4 rc4;

	license->platform_challenge->data =
			(uint8*) xmalloc(license->encrypted_platform_challenge->length);
	license->platform_challenge->length =
			license->encrypted_platform_challenge->length;

	rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);

	crypto_rc4(rc4, license->encrypted_platform_challenge->length,
			license->encrypted_platform_challenge->data,
			license->platform_challenge->data);

#ifdef WITH_DEBUG_LICENSE
	printf("encrypted_platform challenge:\n");
	freerdp_hexdump(license->encrypted_platform_challenge->data,
			license->encrypted_platform_challenge->length);

	printf("platform challenge:\n");
	freerdp_hexdump(license->platform_challenge->data, license->platform_challenge->length);
#endif

	crypto_rc4_free(rc4);
}
コード例 #3
0
ファイル: license.c プロジェクト: BUGgs/FreeRDP
BOOL license_decrypt_platform_challenge(rdpLicense* license)
{
	CryptoRc4 rc4;

	license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
	if (!license->PlatformChallenge->data)
		return FALSE;
	license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;

	rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
	if (!rc4)
	{
		WLog_ERR(TAG, "unable to allocate a rc4");
		free(license->PlatformChallenge->data);
		license->PlatformChallenge->data = NULL;
		return FALSE;
	}

	crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
			   license->EncryptedPlatformChallenge->data,
			   license->PlatformChallenge->data);

	crypto_rc4_free(rc4);
	return TRUE;
}
コード例 #4
0
ファイル: kerberos_crypto.c プロジェクト: littlejawa/FreeRDP
rdpBlob* crypto_kdcmsg_decrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
{
	rdpBlob* decmsg;
	uint8* K1;
	uint8* K3;
	uint32 len;
	krbEdata* edata;
	CryptoRc4 rc4;
	K1 = xzalloc(16);
	K3 = xzalloc(16);
	len = msg->length;
	edata = xzalloc(len);
	HMAC(EVP_md5(), (void*) key, 16, (uint8*) &msgtype, 4, (void*) K1, NULL);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*) msg->data , 16, (void*) K3, NULL);
	rc4 = crypto_rc4_init(K3, 16);
	crypto_rc4(rc4, len - 16, (uint8*)(((uint8*) msg->data) + 16), (uint8*) edata->Confounder);
	crypto_rc4_free(rc4);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL);
	if(memcmp(msg->data, &edata->Checksum, 16))
	{
		xfree(edata) ;
		xfree(K1) ;
		xfree(K3) ;
		return NULL;
	}
	decmsg = xnew(rdpBlob);
	freerdp_blob_alloc(decmsg, len);
	memcpy(decmsg->data, edata, len);
	xfree(K1);
	xfree(K3);
	xfree(edata);
	return decmsg;
}
コード例 #5
0
ファイル: kerberos_crypto.c プロジェクト: littlejawa/FreeRDP
rdpBlob* crypto_kdcmsg_encrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
{
	rdpBlob* encmsg;
	uint8* K1;
	uint8* K3;
	uint32 len;
	krbEdata* edata;
	CryptoRc4 rc4;
	K1 = xzalloc(16);
	K3 = xzalloc(16);
	len = ((msg->length > 16) ? msg->length : 16);
	len += sizeof(krbEdata);
	edata = xzalloc(len);
	encmsg = xnew(rdpBlob);
	freerdp_blob_alloc(encmsg, len);
	HMAC(EVP_md5(), (void*) key, 16, (uint8*)&msgtype, 4, (void*) K1, NULL);
	crypto_nonce((uint8*)(edata->Confounder), 8);
	memcpy(&(edata->data[0]), msg->data, msg->length);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*)&(edata->Checksum), 16, (void*)K3, NULL);
	memcpy(encmsg->data, &(edata->Checksum), 16);
	rc4 = crypto_rc4_init(K3, 16);
	crypto_rc4(rc4, len - 16, (uint8*) edata->Confounder, (uint8*)(((uint8*) encmsg->data) + 16));
	crypto_rc4_free(rc4);
	xfree(K1);
	xfree(K3);
	xfree(edata);
	return encmsg;
}
コード例 #6
0
ファイル: license.c プロジェクト: BUGgs/FreeRDP
BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
{
	wStream* s;
	int length;
	BYTE* buffer;
	CryptoRc4 rc4;
	BYTE mac_data[16];
	BOOL status;

	DEBUG_LICENSE("Sending Platform Challenge Response Packet");
	s = license_send_stream_init(license);
	license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
	length = license->PlatformChallenge->length + HWID_LENGTH;

	buffer = (BYTE*) malloc(length);
	if (!buffer)
		return FALSE;

	CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
	CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
	status = security_mac_data(license->MacSaltKey, buffer, length, mac_data);
	free(buffer);

	if (!status)
		return FALSE;

	rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
	if (!rc4)
	{
		WLog_ERR(TAG, "unable to allocate a rc4");
		return FALSE;
	}

	buffer = (BYTE*) malloc(HWID_LENGTH);
	if (!buffer)
		return FALSE;

	crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
	crypto_rc4_free(rc4);
	license->EncryptedHardwareId->type = BB_DATA_BLOB;
	license->EncryptedHardwareId->data = buffer;
	license->EncryptedHardwareId->length = HWID_LENGTH;
#ifdef WITH_DEBUG_LICENSE
	WLog_DBG(TAG, "LicensingEncryptionKey:");
	winpr_HexDump(TAG, WLOG_DEBUG, license->LicensingEncryptionKey, 16);
	WLog_DBG(TAG, "HardwareId:");
	winpr_HexDump(TAG, WLOG_DEBUG, license->HardwareId, HWID_LENGTH);
	WLog_DBG(TAG, "EncryptedHardwareId:");
	winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data, HWID_LENGTH);
#endif
	return license_write_platform_challenge_response_packet(license, s, mac_data) &&
			license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
コード例 #7
0
ファイル: license.c プロジェクト: CTCAdmin/FreeRDP
void license_send_platform_challenge_response_packet(rdpLicense* license)
{
	wStream* s;
	int length;
	BYTE* buffer;
	CryptoRc4 rc4;
	BYTE mac_data[16];

	DEBUG_LICENSE("Sending Platform Challenge Response Packet");

	s = license_send_stream_init(license);

	license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
	length = license->PlatformChallenge->length + HWID_LENGTH;

	buffer = (BYTE*) malloc(length);
	CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
	CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
	security_mac_data(license->MacSaltKey, buffer, length, mac_data);
	free(buffer);

	buffer = (BYTE*) malloc(HWID_LENGTH);
	rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
	if (!rc4)
	{
		fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__);
		return;
	}
	crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
	crypto_rc4_free(rc4);

	license->EncryptedHardwareId->type = BB_DATA_BLOB;
	license->EncryptedHardwareId->data = buffer;
	license->EncryptedHardwareId->length = HWID_LENGTH;

#ifdef WITH_DEBUG_LICENSE
	fprintf(stderr, "LicensingEncryptionKey:\n");
	winpr_HexDump(license->LicensingEncryptionKey, 16);
	fprintf(stderr, "\n");

	fprintf(stderr, "HardwareId:\n");
	winpr_HexDump(license->HardwareId, HWID_LENGTH);
	fprintf(stderr, "\n");

	fprintf(stderr, "EncryptedHardwareId:\n");
	winpr_HexDump(license->EncryptedHardwareId->data, HWID_LENGTH);
	fprintf(stderr, "\n");
#endif

	license_write_platform_challenge_response_packet(license, s, mac_data);

	license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
コード例 #8
0
ファイル: credssp.c プロジェクト: roman-b/FreeRDP-1.0
void credssp_rc4k(uint8* key, int length, uint8* plaintext, uint8* ciphertext)
{
	CryptoRc4 rc4;

	/* Initialize RC4 cipher with key */
	rc4 = crypto_rc4_init((void*) key, 16);

	/* Encrypt plaintext with key */
	crypto_rc4(rc4, length, (void*) plaintext, (void*) ciphertext);

	/* Free RC4 Cipher */
	crypto_rc4_free(rc4);
}
コード例 #9
0
ファイル: license.c プロジェクト: Nigel62/FreeRDP
void license_decrypt_platform_challenge(rdpLicense* license)
{
	CryptoRc4 rc4;

	license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length);
	license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;

	rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);

	crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
			license->EncryptedPlatformChallenge->data,
			license->PlatformChallenge->data);

	crypto_rc4_free(rc4);
}
コード例 #10
0
ファイル: license.c プロジェクト: Cyclic/FreeRDP
void license_send_platform_challenge_response_packet(rdpLicense* license)
{
	STREAM* s;
	int length;
	uint8* buffer;
	CryptoRc4 rc4;
	uint8 mac_data[16];

	s = license_send_stream_init(license);
	DEBUG_LICENSE("Sending Platform Challenge Response Packet");

	license->encrypted_platform_challenge->type = BB_DATA_BLOB;
	length = license->platform_challenge->length + HWID_LENGTH;
	buffer = (uint8*) xmalloc(length);
	memcpy(buffer, license->platform_challenge->data, license->platform_challenge->length);
	memcpy(&buffer[license->platform_challenge->length], license->hwid, HWID_LENGTH);
	security_mac_data(license->mac_salt_key, buffer, length, mac_data);
	xfree(buffer);

	buffer = (uint8*) xmalloc(HWID_LENGTH);
	rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH);
	crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer);
	crypto_rc4_free(rc4);

#ifdef WITH_DEBUG_LICENSE
	printf("Licensing Encryption Key:\n");
	freerdp_hexdump(license->licensing_encryption_key, 16);

	printf("HardwareID:\n");
	freerdp_hexdump(license->hwid, 20);

	printf("Encrypted HardwareID:\n");
	freerdp_hexdump(buffer, 20);
#endif

	license->encrypted_hwid->type = BB_DATA_BLOB;
	license->encrypted_hwid->data = buffer;
	license->encrypted_hwid->length = HWID_LENGTH;

	license_write_platform_challenge_response_packet(license, s, mac_data);

	license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
}
コード例 #11
0
ファイル: license.c プロジェクト: CTCAdmin/FreeRDP
void license_decrypt_platform_challenge(rdpLicense* license)
{
	CryptoRc4 rc4;

	license->PlatformChallenge->data = (BYTE*) malloc(license->EncryptedPlatformChallenge->length);
	license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;

	rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
	if (!rc4)
	{
		fprintf(stderr, "%s: unable to allocate a rc4\n", __FUNCTION__);
		return;
	}

	crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
			license->EncryptedPlatformChallenge->data,
			license->PlatformChallenge->data);

	crypto_rc4_free(rc4);
}
コード例 #12
0
ファイル: licence.c プロジェクト: nidelius/FreeRDP
/* Process a Server New (or Upgrade) License packet */
static void
licence_process_new_license(rdpLicence * licence, STREAM s)
{
    int i;
    uint32 length;
    uint32 os_major;
    uint32 os_minor;
    CryptoRc4 crypt_key;

    /* Licensing Binary BLOB with EncryptedLicenseInfo: */
    in_uint8s(s, 2);	/* wBlobType should be 0x0009 (BB_ENCRYPTED_DATA_BLOB) */
    in_uint16_le(s, length);	/* wBlobLen */

    /* RC4-encrypted New License Information */
    if (!s_check_rem(s, length))
        return;

    crypt_key = crypto_rc4_init(licence->licence_key, 16);
    crypto_rc4(crypt_key, length, s->p, s->p);	/* decrypt in place */
    crypto_rc4_free(crypt_key);

    /* dwVersion */
    in_uint16_le(s, os_major);	/* OS major version */
    in_uint16_le(s, os_minor);	/* OS minor version */

    /* Skip Scope, CompanyName and ProductId */
    for (i = 0; i < 3; i++)
    {
        in_uint32_le(s, length);
        if (!s_check_rem(s, length))
            return;
        in_uint8s(s, length);
    }

    /* LicenseInfo - CAL from license server */
    in_uint32_le(s, length);
    if (!s_check_rem(s, length))
        return;
    licence->licence_issued = True;
    save_licence(s->p, length);
}
コード例 #13
0
ファイル: ntlm.c プロジェクト: mattymo/FreeRDP
SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, uint32 MessageSeqNo, uint32* pfQOP)
{
	int index;
	int length;
	void* data;
	HMAC_CTX hmac;
	uint8 digest[16];
	uint8 checksum[8];
	uint32 version = 1;
	NTLM_CONTEXT* context;
	uint8 expected_signature[16];
	PSecBuffer data_buffer = NULL;
	PSecBuffer signature_buffer = NULL;

	context = sspi_SecureHandleGetLowerPointer(phContext);

	for (index = 0; index < (int) pMessage->cBuffers; index++)
	{
		if (pMessage->pBuffers[index].BufferType == SECBUFFER_DATA)
			data_buffer = &pMessage->pBuffers[index];
		else if (pMessage->pBuffers[index].BufferType == SECBUFFER_TOKEN)
			signature_buffer = &pMessage->pBuffers[index];
	}

	if (!data_buffer)
		return SEC_E_INVALID_TOKEN;

	if (!signature_buffer)
		return SEC_E_INVALID_TOKEN;

	/* Copy original data buffer */
	length = data_buffer->cbBuffer;
	data = xmalloc(length);
	memcpy(data, data_buffer->pvBuffer, length);

	/* Decrypt message using with RC4 */
	crypto_rc4(context->RecvRc4Seal, length, data, data_buffer->pvBuffer);

	/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
	HMAC_CTX_init(&hmac);
	HMAC_Init_ex(&hmac, context->RecvSigningKey, 16, EVP_md5(), NULL);
	HMAC_Update(&hmac, (void*) &(MessageSeqNo), 4);
	HMAC_Update(&hmac, data_buffer->pvBuffer, data_buffer->cbBuffer);
	HMAC_Final(&hmac, digest, NULL);
	HMAC_CTX_cleanup(&hmac);
	xfree(data);

	/* RC4-encrypt first 8 bytes of digest */
	crypto_rc4(context->RecvRc4Seal, 8, digest, checksum);

	/* Concatenate version, ciphertext and sequence number to build signature */
	memcpy(expected_signature, (void*) &version, 4);
	memcpy(&expected_signature[4], (void*) checksum, 8);
	memcpy(&expected_signature[12], (void*) &(MessageSeqNo), 4);
	context->RecvSeqNum++;

	if (memcmp(signature_buffer->pvBuffer, expected_signature, 16) != 0)
	{
		/* signature verification failed! */
		printf("signature verification failed, something nasty is going on!\n");
		return SEC_E_MESSAGE_ALTERED;
	}

	return SEC_E_OK;
}
コード例 #14
0
ファイル: ntlm.c プロジェクト: mattymo/FreeRDP
SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, uint32 fQOP, PSecBufferDesc pMessage, uint32 MessageSeqNo)
{
	int index;
	int length;
	void* data;
	HMAC_CTX hmac;
	uint8 digest[16];
	uint8 checksum[8];
	uint8* signature;
	uint32 version = 1;
	NTLM_CONTEXT* context;
	PSecBuffer data_buffer = NULL;
	PSecBuffer signature_buffer = NULL;

	context = sspi_SecureHandleGetLowerPointer(phContext);

	for (index = 0; index < (int) pMessage->cBuffers; index++)
	{
		if (pMessage->pBuffers[index].BufferType == SECBUFFER_DATA)
			data_buffer = &pMessage->pBuffers[index];
		else if (pMessage->pBuffers[index].BufferType == SECBUFFER_TOKEN)
			signature_buffer = &pMessage->pBuffers[index];
	}

	if (!data_buffer)
		return SEC_E_INVALID_TOKEN;

	if (!signature_buffer)
		return SEC_E_INVALID_TOKEN;

	/* Copy original data buffer */
	length = data_buffer->cbBuffer;
	data = xmalloc(length);
	memcpy(data, data_buffer->pvBuffer, length);

	/* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,data) using the client signing key */
	HMAC_CTX_init(&hmac);
	HMAC_Init_ex(&hmac, context->SendSigningKey, 16, EVP_md5(), NULL);
	HMAC_Update(&hmac, (void*) &(MessageSeqNo), 4);
	HMAC_Update(&hmac, data, length);
	HMAC_Final(&hmac, digest, NULL);
	HMAC_CTX_cleanup(&hmac);

	/* Encrypt message using with RC4, result overwrites original buffer */

	if (context->confidentiality)
		crypto_rc4(context->SendRc4Seal, length, data, data_buffer->pvBuffer);
	else
		memcpy(data_buffer->pvBuffer, data, length);

	xfree(data);

#ifdef WITH_DEBUG_NTLM
	printf("Data Buffer (length = %d)\n", length);
	freerdp_hexdump(data, length);
	printf("\n");

	printf("Encrypted Data Buffer (length = %d)\n", data_buffer->cbBuffer);
	freerdp_hexdump(data_buffer->pvBuffer, data_buffer->cbBuffer);
	printf("\n");
#endif

	/* RC4-encrypt first 8 bytes of digest */
	crypto_rc4(context->SendRc4Seal, 8, digest, checksum);

	signature = (uint8*) signature_buffer->pvBuffer;

	/* Concatenate version, ciphertext and sequence number to build signature */
	memcpy(signature, (void*) &version, 4);
	memcpy(&signature[4], (void*) checksum, 8);
	memcpy(&signature[12], (void*) &(MessageSeqNo), 4);
	context->SendSeqNum++;

#ifdef WITH_DEBUG_NTLM
	printf("Signature (length = %d)\n", signature_buffer->cbBuffer);
	freerdp_hexdump(signature_buffer->pvBuffer, signature_buffer->cbBuffer);
	printf("\n");
#endif

	return SEC_E_OK;
}
コード例 #15
0
ファイル: licence.c プロジェクト: nidelius/FreeRDP
/* Process a Server License Request packet */
static void
licence_process_request(rdpLicence * licence, STREAM s)
{
    uint8 null_data[SEC_MODULUS_SIZE];
    uint8 *server_random;
    uint32 dwVersion;
    uint32 cbCompanyName;
    uint32 cbProductId;
    uint16 wBlobType, wBlobLen;
    uint32 ScopeCount, i;

    uint8 signature[LICENCE_SIGNATURE_SIZE];
    uint8 hwid[LICENCE_HWID_SIZE];
    uint8 *licence_data;
    int licence_size;
    CryptoRc4 crypt_key;

    /* Retrieve the server random from the incoming packet */
    in_uint8p(s, server_random, SEC_RANDOM_SIZE);	/* ServerRandom */
    /* ProductInfo: */
    in_uint32_le(s, dwVersion);
    in_uint32_le(s, cbCompanyName);
    in_uint8s(s, cbCompanyName);	/* pbCompanyName */
    in_uint32_le(s, cbProductId);
    in_uint8s(s, cbProductId);	/* pbProductId - "A02"? */
    /* KeyExchangeList */
    in_uint16_le(s, wBlobType);	/* BB_KEY_EXCHG_ALG_BLOB (0x000D) */
    in_uint16_le(s, wBlobLen);
    in_uint8s(s, wBlobLen);	/* KEY_EXCHANGE_ALG_RSA 0x00000001 */
    /* ServerCertificate */
    in_uint16_le(s, wBlobType);	/* BB_CERTIFICATE_BLOB (0x0003). */
    in_uint16_le(s, wBlobLen);
    in_uint8s(s, wBlobLen);	/* cert to use for licensing instead of the one from MCS Connect Response */
    /* ScopeList */
    in_uint32_le(s, ScopeCount);
    for (i=0; i<ScopeCount; i++)
    {
        in_uint16_le(s, wBlobType);
        in_uint16_le(s, wBlobLen);
        in_uint8s(s, wBlobLen);
    }

    /* We currently use null client keys. This is a bit naughty but, hey,
       the security of licence negotiation isn't exactly paramount. */
    memset(null_data, 0, sizeof(null_data));
    licence_generate_keys(licence, null_data, server_random, null_data);

    licence_size = load_licence(&licence_data);
    if (licence_size > 0)
    {
        /* Generate a signature for the HWID buffer */
        licence_generate_hwid(licence, hwid);
        sec_sign(signature, 16, licence->licence_sign_key, 16, hwid, sizeof(hwid));

        /* Now encrypt the HWID */
        crypt_key = crypto_rc4_init(licence->licence_key, 16);
        crypto_rc4(crypt_key, sizeof(hwid), hwid, hwid);
        crypto_rc4_free(crypt_key);

        licence_present(licence, null_data, null_data, licence_data, licence_size, hwid, signature);
        xfree(licence_data);
        return;
    }

    licence_send_request(licence, null_data, null_data,
                         licence->sec->rdp->settings->username,
                         licence->sec->rdp->settings->hostname);
}