void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d) { uint8 *p; uint8 signature[16]; rdpBlob encrypted_public_key; NTLMSSP *ntlmssp = credssp->ntlmssp; freerdp_blob_alloc(d, credssp->public_key.length + 16); ntlmssp_encrypt_message(ntlmssp, &credssp->public_key, &encrypted_public_key, signature); #ifdef WITH_DEBUG_NLA printf("Public Key (length = %d)\n", credssp->public_key.length); freerdp_hexdump(credssp->public_key.data, credssp->public_key.length); printf("\n"); printf("Encrypted Public Key (length = %d)\n", encrypted_public_key.length); freerdp_hexdump(encrypted_public_key.data, encrypted_public_key.length); printf("\n"); printf("Signature\n"); freerdp_hexdump(signature, 16); printf("\n"); #endif p = (uint8*) d->data; memcpy(p, signature, 16); /* Message Signature */ memcpy(&p[16], encrypted_public_key.data, encrypted_public_key.length); /* Encrypted Public Key */ freerdp_blob_free(&encrypted_public_key); }
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); }
void credssp_encrypt_ts_credentials(rdpCredssp* credssp, rdpBlob* d) { uint8 *p; uint8 signature[16]; rdpBlob encrypted_ts_credentials; NTLMSSP *ntlmssp = credssp->ntlmssp; freerdp_blob_alloc(d, credssp->ts_credentials.length + 16); ntlmssp_encrypt_message(ntlmssp, &credssp->ts_credentials, &encrypted_ts_credentials, signature); #ifdef WITH_DEBUG_NLA printf("TSCredentials (length = %d)\n", credssp->ts_credentials.length); freerdp_hexdump(credssp->ts_credentials.data, credssp->ts_credentials.length); printf("\n"); printf("Encrypted TSCredentials (length = %d)\n", encrypted_ts_credentials.length); freerdp_hexdump(encrypted_ts_credentials.data, encrypted_ts_credentials.length); printf("\n"); printf("Signature\n"); freerdp_hexdump(signature, 16); printf("\n"); #endif p = (uint8*) d->data; memcpy(p, signature, 16); /* Message Signature */ memcpy(&p[16], encrypted_ts_credentials.data, encrypted_ts_credentials.length); /* Encrypted TSCredentials */ freerdp_blob_free(&encrypted_ts_credentials); }
SECURITY_STATUS credssp_verify_public_key_echo(rdpCredssp* credssp) { int length; uint32 pfQOP; uint8* public_key1; uint8* public_key2; uint8* pub_key_auth; int public_key_length; SEC_BUFFER Buffers[2]; SEC_BUFFER_DESC Message; SECURITY_STATUS status; length = credssp->pubKeyAuth.cbBuffer; pub_key_auth = (uint8*) credssp->pubKeyAuth.pvBuffer; public_key_length = credssp->PublicKey.cbBuffer; Buffers[0].BufferType = SECBUFFER_PADDING; /* Signature */ Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */ Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature; Buffers[0].pvBuffer = xmalloc(Buffers[0].cbBuffer); memcpy(Buffers[0].pvBuffer, pub_key_auth, Buffers[0].cbBuffer); Buffers[1].cbBuffer = length - Buffers[0].cbBuffer; Buffers[1].pvBuffer = xmalloc(Buffers[1].cbBuffer); memcpy(Buffers[1].pvBuffer, &pub_key_auth[Buffers[0].cbBuffer], Buffers[1].cbBuffer); Message.cBuffers = 2; Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (SEC_BUFFER*) &Buffers; status = credssp->table->DecryptMessage(&credssp->context, &Message, 0, &pfQOP); if (status != SEC_E_OK) return status; public_key1 = (uint8*) credssp->PublicKey.pvBuffer; public_key2 = (uint8*) Buffers[1].pvBuffer; public_key2[0]--; /* server echos the public key +1 */ if (memcmp(public_key1, public_key2, public_key_length) != 0) { printf("Could not verify server's public key echo\n"); printf("Expected (length = %d):\n", public_key_length); freerdp_hexdump(public_key1, public_key_length); printf("Actual (length = %d):\n", public_key_length); freerdp_hexdump(public_key2, public_key_length); return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */ } public_key2[0]++; return SEC_E_OK; }
int transport_read(rdpTransport* transport, STREAM* s) { int status = -1; while (True) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_read(transport->tls, stream_get_tail(s), stream_get_left(s)); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_read(transport->tcp, stream_get_tail(s), stream_get_left(s)); if (status == 0 && transport->blocking) { freerdp_usleep(transport->usleep_interval); continue; } break; } #ifdef WITH_DEBUG_TRANSPORT if (status > 0) { printf("Local < Remote\n"); freerdp_hexdump(s->data, status); } #endif return status; }
boolean license_send(rdpLicense* license, STREAM* s, uint8 type) { int length; uint8 flags; uint16 wMsgSize; uint16 sec_flags; DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]); length = stream_get_length(s); stream_set_pos(s, 0); sec_flags = SEC_LICENSE_PKT; wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; /** * Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when * running in server mode! This flag seems to be incorrectly documented. */ flags = PREAMBLE_VERSION_3_0; rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, sec_flags); license_write_preamble(s, type, flags, wMsgSize); #ifdef WITH_DEBUG_LICENSE printf("Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); freerdp_hexdump(s->p - 4, wMsgSize); #endif stream_set_pos(s, length); if (transport_write(license->rdp->transport, s) < 0) return false; return true; }
int transport_read(rdpTransport* transport, STREAM* s) { int status = -1; while (True) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_read(transport->tls, s->data, s->size); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_read(transport->tcp, s->data, s->size); if (status == 0 && transport->blocking) { nanosleep(&transport->ts, NULL); continue; } break; } #ifdef WITH_DEBUG_TRANSPORT if (status > 0) { printf("Server > Client\n"); freerdp_hexdump(s->data, status); } #endif return status; }
int rpch_in_write(rdpRpch* rpch, uint8* data, int length) { rdpRpchHTTP* http_in = rpch->http_in; rdpTls* tls_in = rpch->tls_in; int status = -1; int sent = 0; LLOGLN(10, ("rpch_in_write:")); if (http_in->remContentLength < length) { printf("RPCH Error: HTTP frame is over.\n"); return -1;/* TODO ChannelRecycling */ } #ifdef WITH_DEBUG_RPCH printf("\nrpch_in_send(): length: %d, remaining content length: %d\n", length, http_in->remContentLength); freerdp_hexdump(data, length); printf("\n"); #endif while (sent < length) { status = tls_write(tls_in, data+sent, length-sent); if (status <= 0) return status;/* TODO no idea how to handle errors */ sent += status; } rpch->BytesSent += sent; http_in->remContentLength -= sent; return sent; }
//----------------------------------------------------------------------------- static int emulate_client_send_channel_data( freerdp* freerdp, int channelId, uint8* data, int size ) { DEBUG_RAIL("Client send to server:"); freerdp_hexdump(data, size); // add to global dumps list }
void license_encrypt_premaster_secret(rdpLicense* license) { uint8* encrypted_premaster_secret; #if 0 int key_length; uint8* modulus; uint8* exponent; rdpCertificate *certificate; if (license->server_certificate->length) certificate = license->certificate; else certificate = license->rdp->settings->server_cert; exponent = certificate->cert_info.exponent; modulus = certificate->cert_info.modulus.data; key_length = certificate->cert_info.modulus.length; #ifdef WITH_DEBUG_LICENSE printf("modulus (%d bits):\n", key_length * 8); freerdp_hexdump(modulus, key_length); printf("exponent:\n"); freerdp_hexdump(exponent, 4); #endif encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE); memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE); crypto_rsa_public_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH, key_length, modulus, exponent, encrypted_premaster_secret); license->encrypted_premaster_secret->type = BB_RANDOM_BLOB; license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH; license->encrypted_premaster_secret->data = encrypted_premaster_secret; #else encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE); memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE); license->encrypted_premaster_secret->type = BB_RANDOM_BLOB; license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH; license->encrypted_premaster_secret->data = encrypted_premaster_secret; #endif }
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); }
int transport_write(rdpTransport* transport, STREAM* s) { int status = -1; int length; length = stream_get_length(s); stream_set_pos(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { printf("Local > Remote\n"); freerdp_hexdump(s->data, length); } #endif while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->tls, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->tcp, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_write(transport->tsg, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* blocking while sending */ freerdp_usleep(transport->usleep_interval); /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) wait_obj_set(transport->recv_event); } } length -= status; stream_seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } return status; }
void credssp_buffer_print(rdpCredssp* credssp) { if (credssp->negoToken.cbBuffer > 0) { printf("CredSSP.negoToken (length = %d):\n", credssp->negoToken.cbBuffer); freerdp_hexdump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); } if (credssp->pubKeyAuth.cbBuffer > 0) { printf("CredSSP.pubKeyAuth (length = %d):\n", credssp->pubKeyAuth.cbBuffer); freerdp_hexdump(credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); } if (credssp->authInfo.cbBuffer > 0) { printf("CredSSP.authInfo (length = %d):\n", credssp->authInfo.cbBuffer); freerdp_hexdump(credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); } }
void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event) { RAIL_GET_APPID_RESP_ORDER* appid_resp = (RAIL_GET_APPID_RESP_ORDER*)event->user_data; printf("Server Application ID Response PDU: windowId=0x%X " "applicationId=(length=%d dump)\n", appid_resp->windowId, appid_resp->applicationId.length); freerdp_hexdump(appid_resp->applicationId.string, appid_resp->applicationId.length); }
void assert_stream(STREAM* s, uint8* data, int length, const char* func, int line) { int i; char* str; int actual_length; uint8* actual_data; actual_data = s->data; actual_length = stream_get_length(s); if (actual_length != length) { printf("\n %s (%d): length mismatch, actual:%d, expected:%d\n", func, line, actual_length, length); printf("\nActual:\n"); freerdp_hexdump(actual_data, actual_length); printf("Expected:\n"); freerdp_hexdump(data, length); CU_FAIL("assert_stream, length mismatch"); return; } for (i = 0; i < length; i++) { if (actual_data[i] != data[i]) { printf("\n %s (%d): buffer mismatch:\n", func, line); printf("\nActual:\n"); freerdp_hexdump(actual_data, length); printf("Expected:\n"); freerdp_hexdump(data, length); CU_FAIL("assert_stream, buffer mismatch"); return; } } }
int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu) { STREAM* s; int status; int length; BYTE header_buffer[20]; rdpTls* tls_out = rpc->tls_out; /* read first 20 bytes to get RTS PDU Header */ status = tls_read(tls_out, (BYTE*) &header_buffer, 20); if (status <= 0) { printf("rts_recv error\n"); return status; } s = stream_new(0); stream_attach(s, header_buffer, 20); rts_pdu_header_read(s, &(rts_pdu->header)); stream_detach(s); stream_free(s); length = rts_pdu->header.frag_length - 20; rts_pdu->content = (BYTE*) malloc(length); status = tls_read(tls_out, rts_pdu->content, length); if (status < 0) { printf("rts_recv error\n"); return status; } if (rts_pdu->header.ptype != PTYPE_RTS) { printf("rts_recv error: unexpected ptype:%d\n", rts_pdu->header.ptype); return -1; } #ifdef WITH_DEBUG_RTS printf("rts_recv(): length: %d\n", length); freerdp_hexdump(rts_pdu->content, length); printf("\n"); #endif rts_recv_pdu_commands(rpc, rts_pdu); return rts_pdu->header.frag_length; }
STREAM surface_codec_cap(rdpRdp * rdp, uint8 * codec_guid, int codec_id, uint8 * codec_property, int codec_properties_size) { STREAM s; s = 0; if (memcmp(codec_guid, g_rfx_guid, 16) == 0) { //printf("got remotefx guid\n"); if (rdp->settings->rfx_flags) { s = stream_new(1024); out_uint8a(s, g_rfx_guid, 16); out_uint8(s, codec_id); out_uint16_le(s, 29 + 12); out_uint32_le(s, 29 + 12); /* total size */ out_uint32_le(s, 0x00000000); /* Capture Flags */ out_uint32_le(s, 29); /* size after this */ /* struct CbyCaps */ out_uint16_le(s, 0xcbc0); /* CBY_CAPS */ out_uint32_le(s, 8); /* size of this struct */ out_uint16_le(s, 1); /* numCapsets */ /* struct ClyCapset */ out_uint16_le(s, 0xcbc1); /* CBY_CAPSET */ out_uint32_le(s, 21); /* size of this struct */ out_uint8(s, 1); /* codec id */ out_uint16_le(s, 0xcfc0); /* CLY_CAPSET */ out_uint16_le(s, 1); /* numIcaps */ out_uint16_le(s, 8); /* icapLen */ /* 64x64 tiles */ out_uint16_le(s, 0x100); /* version */ out_uint16_le(s, 64); /* tile size */ out_uint8(s, 0); /* flags */ out_uint8(s, 1); /* colConvBits */ out_uint8(s, 1); /* transformBits */ out_uint8(s, 1); /* entropyBits */ s_mark_end(s); } } else if (memcmp(codec_guid, g_nsc_guid, 16) == 0) { //printf("got nscodec guid\n"); } else { //printf("unknown guid\n"); freerdp_hexdump(codec_guid, 16); } return s; }
int rpc_in_write(rdpRpc* rpc, BYTE* data, int length) { int status; #ifdef WITH_DEBUG_TSG rpc_pdu_header_print((rpcconn_hdr_t*) data); printf("Sending PDU (length: %d)\n", length); freerdp_hexdump(data, length); #endif status = tls_write_all(rpc->TlsIn, data, length); return status; }
int rpc_out_write(rdpRpc* rpc, uint8* data, int length) { int status; #ifdef WITH_DEBUG_RPC printf("rpc_out_write(): length: %d\n", length); freerdp_hexdump(data, length); printf("\n"); #endif status = tls_write_all(rpc->tls_out, data, length); return status; }
//----------------------------------------------------------------------------- int stream_equal_dump(void * dataS, size_t sizeS, void * data, size_t size) { size_t i; if (sizeS != size) { printf("----------------- stream_equal_dump -----------------\n"); printf("Stream and dump have different length (%d != %d)\n", (int) sizeS, (int) size); printf("Stream hexdump:\n"); freerdp_hexdump(dataS, sizeS); printf("Dump hexdump:\n"); freerdp_hexdump(data, size); printf("----------------- stream_equal_dump -----------------\n"); return 0; } for (i=0; i < size; i++) { if (((uint8*)dataS)[i] != ((uint8*)data)[i]) { printf("----------------- stream_equal_dump -----------------\n"); printf("Stream and dump have different content from %d offset.\n", (int) i); printf("Stream hexdump:\n"); freerdp_hexdump(dataS, sizeS); printf("Dump hexdump:\n"); freerdp_hexdump(data, size); printf("----------------- stream_equal_dump -----------------\n"); return 0; } } return 1; }
//----------------------------------------------------------------------------- static int emulate_client_send_channel_data( freerdp* freerdp, int channelId, uint8* data, int size ) { static int counter = 0; counter++; printf("Client send to server (%d packet):\n", counter); freerdp_hexdump(data, size); // add to global dumps list save_dump(data, size); return 0; }
//----------------------------------------------------------------------------- static void emulate_server_send_channel_data( freerdp* instance, void* data, size_t size ) { static int counter = 0; counter++; printf("Emulate server packet (%d packet):\n", counter); freerdp_hexdump(data, size); freerdp_channels_data(instance, 0, (char*)data, size, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, size); usleep(10*1000); }
int transport_write(rdpTransport* transport, STREAM* s) { int status = -1; int length; int sent = 0; length = stream_get_length(s); stream_set_pos(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { printf("Client > Server\n"); freerdp_hexdump(s->data, length); } #endif while (sent < length) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->tls, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->tcp, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* blocking while sending */ nanosleep(&transport->ts, NULL); /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) transport_read_nonblocking(transport); } sent += status; stream_seek(s, status); } if (!transport->blocking) transport_check_fds(transport); return status; }
int rpc_in_write(rdpRpc* rpc, uint8* data, int length) { int status; #ifdef WITH_DEBUG_RPC printf("rpc_in_write() length: %d\n", length); freerdp_hexdump(data, length); printf("\n"); #endif status = tls_write_all(rpc->tls_in, data, length); if (status > 0) rpc->VirtualConnection->DefaultInChannel->BytesSent += status; return status; }
int transport_write(rdpTransport* transport, STREAM* s) { int status = -1; int length; length = stream_get_length(s); stream_set_pos(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { printf("Local > Remote\n"); freerdp_hexdump(s->data, length); } #endif while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->tls, stream_get_tail(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->tcp, stream_get_tail(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* blocking while sending */ freerdp_usleep(transport->usleep_interval); } length -= status; stream_seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } return status; }
int rpch_out_write(rdpRpch* rpch, uint8* data, int length) { rdpRpchHTTP* http_out = rpch->http_out; rdpTls* tls_out = rpch->tls_out; int status = -1; int sent = 0; LLOGLN(10, ("rpch_out_write: in length %d", length)); if (http_out->remContentLength < length) { LLOGLN(0, ("rpch_out_write: RPCH Error: HTTP frame is over.")); return -1;/* TODO ChannelRecycling */ } #ifdef WITH_DEBUG_RPCH printf("rpch_out_write(): length: %d\n", length); freerdp_hexdump(data, length); printf("\n"); #endif while (sent < length) { status = tls_write(tls_out, data + sent, length - sent); if (status <= 0) { LLOGLN(0, ("rpch_out_write: error")); return status; /* TODO no idea how to handle errors */ } sent += status; } http_out->remContentLength -= sent; LLOGLN(10, ("rpch_out_write: out sent %d", sent)); return sent; }
void license_generate_keys(rdpLicense* license) { security_master_secret(license->premaster_secret, license->client_random, license->server_random, license->master_secret); /* MasterSecret */ security_session_key_blob(license->master_secret, license->client_random, license->server_random, license->session_key_blob); /* SessionKeyBlob */ security_mac_salt_key(license->session_key_blob, license->client_random, license->server_random, license->mac_salt_key); /* MacSaltKey */ security_licensing_encryption_key(license->session_key_blob, license->client_random, license->server_random, license->licensing_encryption_key); /* LicensingEncryptionKey */ #ifdef WITH_DEBUG_LICENSE printf("ClientRandom:\n"); freerdp_hexdump(license->client_random, CLIENT_RANDOM_LENGTH); printf("ServerRandom:\n"); freerdp_hexdump(license->server_random, SERVER_RANDOM_LENGTH); printf("PremasterSecret:\n"); freerdp_hexdump(license->premaster_secret, PREMASTER_SECRET_LENGTH); printf("MasterSecret:\n"); freerdp_hexdump(license->master_secret, MASTER_SECRET_LENGTH); printf("SessionKeyBlob:\n"); freerdp_hexdump(license->session_key_blob, SESSION_KEY_BLOB_LENGTH); printf("MacSaltKey:\n"); freerdp_hexdump(license->mac_salt_key, MAC_SALT_KEY_LENGTH); printf("LicensingEncryptionKey:\n"); freerdp_hexdump(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); #endif }
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; }
int credssp_client_authenticate(rdpCredssp* credssp) { uint32 cbMaxToken; uint32 fContextReq; uint32 pfContextAttr; SECURITY_STATUS status; CredHandle credentials; TimeStamp expiration; SecPkgInfo* pPackageInfo; PSecBuffer p_buffer; SecBuffer input_buffer; SecBuffer output_buffer; SecBufferDesc input_buffer_desc; SecBufferDesc output_buffer_desc; boolean have_context; boolean have_input_buffer; boolean have_pub_key_auth; sspi_GlobalInit(); if (credssp_ntlm_client_init(credssp) == 0) return 0; credssp->table = InitSecurityInterface(); status = QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &pPackageInfo); if (status != SEC_E_OK) { printf("QuerySecurityPackageInfo status: 0x%08X\n", status); return 0; } cbMaxToken = pPackageInfo->cbMaxToken; status = credssp->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &credssp->identity, NULL, NULL, &credentials, &expiration); if (status != SEC_E_OK) { printf("AcquireCredentialsHandle status: 0x%08X\n", status); return 0; } have_context = false; have_input_buffer = false; have_pub_key_auth = false; memset(&input_buffer, 0, sizeof(SecBuffer)); memset(&output_buffer, 0, sizeof(SecBuffer)); memset(&credssp->ContextSizes, 0, sizeof(SecPkgContext_Sizes)); fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE; while (true) { output_buffer_desc.ulVersion = SECBUFFER_VERSION; output_buffer_desc.cBuffers = 1; output_buffer_desc.pBuffers = &output_buffer; output_buffer.BufferType = SECBUFFER_TOKEN; output_buffer.cbBuffer = cbMaxToken; output_buffer.pvBuffer = xmalloc(output_buffer.cbBuffer); status = credssp->table->InitializeSecurityContext(&credentials, (have_context) ? &credssp->context : NULL, NULL, fContextReq, 0, SECURITY_NATIVE_DREP, (have_input_buffer) ? &input_buffer_desc : NULL, 0, &credssp->context, &output_buffer_desc, &pfContextAttr, &expiration); if (input_buffer.pvBuffer != NULL) { xfree(input_buffer.pvBuffer); input_buffer.pvBuffer = NULL; } if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK)) { if (credssp->table->CompleteAuthToken != NULL) credssp->table->CompleteAuthToken(&credssp->context, &output_buffer_desc); have_pub_key_auth = true; if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK) { printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); return 0; } if (have_pub_key_auth) { uint8* p; SecBuffer Buffers[2]; SecBufferDesc Message; SECURITY_STATUS encrypt_status; Buffers[0].BufferType = SECBUFFER_DATA; /* TLS Public Key */ Buffers[1].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[0].cbBuffer = credssp->PublicKey.cbBuffer; Buffers[0].pvBuffer = xmalloc(Buffers[0].cbBuffer); memcpy(Buffers[0].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[0].cbBuffer); Buffers[1].cbBuffer = credssp->ContextSizes.cbMaxSignature; Buffers[1].pvBuffer = xzalloc(Buffers[1].cbBuffer); Message.cBuffers = 2; Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; sspi_SecBufferAlloc(&credssp->pubKeyAuth, Buffers[0].cbBuffer + Buffers[1].cbBuffer); encrypt_status = credssp->table->EncryptMessage(&credssp->context, 0, &Message, 0); if (encrypt_status != SEC_E_OK) { printf("EncryptMessage status: 0x%08X\n", encrypt_status); return 0; } p = (uint8*) credssp->pubKeyAuth.pvBuffer; memcpy(p, Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Message Signature */ memcpy(&p[Buffers[1].cbBuffer], Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Encrypted Public Key */ xfree(Buffers[0].pvBuffer); xfree(Buffers[1].pvBuffer); } if (status == SEC_I_COMPLETE_NEEDED) status = SEC_E_OK; else if (status == SEC_I_COMPLETE_AND_CONTINUE) status = SEC_I_CONTINUE_NEEDED; } /* send authentication token to server */ if (output_buffer.cbBuffer > 0) { p_buffer = &output_buffer_desc.pBuffers[0]; credssp->negoToken.pvBuffer = p_buffer->pvBuffer; credssp->negoToken.cbBuffer = p_buffer->cbBuffer; #ifdef WITH_DEBUG_CREDSSP printf("Sending Authentication Token\n"); freerdp_hexdump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); #endif credssp_send(credssp); credssp_buffer_free(credssp); } if (status != SEC_I_CONTINUE_NEEDED) break; /* receive server response and place in input buffer */ input_buffer_desc.ulVersion = SECBUFFER_VERSION; input_buffer_desc.cBuffers = 1; input_buffer_desc.pBuffers = &input_buffer; input_buffer.BufferType = SECBUFFER_TOKEN; if (credssp_recv(credssp) < 0) return -1; #ifdef WITH_DEBUG_CREDSSP printf("Receiving Authentication Token\n"); freerdp_hexdump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); #endif p_buffer = &input_buffer_desc.pBuffers[0]; p_buffer->pvBuffer = credssp->negoToken.pvBuffer; p_buffer->cbBuffer = credssp->negoToken.cbBuffer; have_input_buffer = true; have_context = true; } /* Encrypted Public Key +1 */ if (credssp_recv(credssp) < 0) return -1; /* Verify Server Public Key Echo */ status = credssp_verify_public_key_echo(credssp); credssp_buffer_free(credssp); if (status != SEC_E_OK) return 0; /* Send encrypted credentials */ status = credssp_encrypt_ts_credentials(credssp); if (status != SEC_E_OK) { printf("credssp_encrypt_ts_credentials status: 0x%08X\n", status); return 0; } credssp_send(credssp); credssp_buffer_free(credssp); /* Free resources */ FreeCredentialsHandle(&credentials); FreeContextBuffer(pPackageInfo); return 1; }
void scard_device_control(SCARD_DEVICE* scard, IRP* irp) { uint32 output_len, input_len, ioctl_code; uint32 stream_len, result; uint32 pos, pad_len; uint32 irp_len; uint32 irp_result_pos, output_len_pos, result_pos; stream_read_uint32(irp->input, output_len); stream_read_uint32(irp->input, input_len); stream_read_uint32(irp->input, ioctl_code); stream_seek(irp->input, 20); /* padding */ // stream_seek(irp->input, 4); /* TODO: parse len, le, v1 */ // stream_seek(irp->input, 4); /* 0xcccccccc */ // stream_seek(irp->input, 4); /* rpce len */ /* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */ stream_extend(irp->output, 2048); irp_result_pos = stream_get_pos(irp->output); stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ /* [MS-RPCE] 2.2.6.1 */ stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_uint32(irp->output, 0xcccccccc); /* filler */ output_len_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* size */ stream_write_uint32(irp->output, 0x0); /* filler */ result_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* result */ /* body */ switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: result = handle_EstablishContext(irp); break; case SCARD_IOCTL_IS_VALID_CONTEXT: result = handle_IsValidContext(irp); break; case SCARD_IOCTL_RELEASE_CONTEXT: result = handle_ReleaseContext(irp); break; case SCARD_IOCTL_LIST_READERS: result = handle_ListReaders(irp, 0); break; case SCARD_IOCTL_LIST_READERS + 4: result = handle_ListReaders(irp, 1); break; case SCARD_IOCTL_LIST_READER_GROUPS: case SCARD_IOCTL_LIST_READER_GROUPS + 4: /* typically not used unless list_readers fail */ result = SCARD_F_INTERNAL_ERROR; break; case SCARD_IOCTL_GET_STATUS_CHANGE: result = handle_GetStatusChange(irp, 0); break; case SCARD_IOCTL_GET_STATUS_CHANGE + 4: result = handle_GetStatusChange(irp, 1); break; case SCARD_IOCTL_CANCEL: result = handle_Cancel(irp); break; case SCARD_IOCTL_CONNECT: result = handle_Connect(irp, 0); break; case SCARD_IOCTL_CONNECT + 4: result = handle_Connect(irp, 1); break; case SCARD_IOCTL_RECONNECT: result = handle_Reconnect(irp); break; case SCARD_IOCTL_DISCONNECT: result = handle_Disconnect(irp); break; case SCARD_IOCTL_BEGIN_TRANSACTION: result = handle_BeginTransaction(irp); break; case SCARD_IOCTL_END_TRANSACTION: result = handle_EndTransaction(irp); break; case SCARD_IOCTL_STATE: result = handle_State(irp); break; case SCARD_IOCTL_STATUS: result = handle_Status(irp, 0); break; case SCARD_IOCTL_STATUS + 4: result = handle_Status(irp, 1); break; case SCARD_IOCTL_TRANSMIT: result = handle_Transmit(irp); break; case SCARD_IOCTL_CONTROL: result = handle_Control(irp); break; case SCARD_IOCTL_GETATTRIB: result = handle_GetAttrib(irp); break; case SCARD_IOCTL_ACCESS_STARTED_EVENT: result = handle_AccessStartedEvent(irp); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: result = handle_LocateCardsByATR(irp, 0); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: result = handle_LocateCardsByATR(irp, 1); break; default: result = 0xc0000001; printf("scard unknown ioctl 0x%x\n", ioctl_code); break; } /* look for NTSTATUS errors */ if ((result & 0xc0000000) == 0xc0000000) return scard_error(scard, irp, result); /* per Ludovic Rousseau, map different usage of this particular * error code between pcsc-lite & windows */ if (result == 0x8010001F) result = 0x80100022; /* handle response packet */ pos = stream_get_pos(irp->output); stream_len = pos - irp_result_pos - 4; stream_set_pos(irp->output, output_len_pos); stream_write_uint32(irp->output, stream_len - 24); stream_set_pos(irp->output, result_pos); stream_write_uint32(irp->output, result); stream_set_pos(irp->output, pos); /* pad stream to 16 byte align */ pad_len = stream_len % 16; stream_write_zero(irp->output, pad_len); pos = stream_get_pos(irp->output); irp_len = stream_len + pad_len; stream_set_pos(irp->output, irp_result_pos); stream_write_uint32(irp->output, irp_len); stream_set_pos(irp->output, pos); #ifdef WITH_DEBUG_SCARD freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output)); #endif irp->IoStatus = 0; irp->Complete(irp); }