2 * FreeRDP: A Remote Desktop Protocol Client
3 * NT LAN Manager Security Support Provider (NTLMSSP)
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 #include <openssl/des.h>
22 #include <openssl/md4.h>
23 #include <openssl/hmac.h>
24 #include <openssl/rand.h>
25 #include <openssl/engine.h>
26 #include <freerdp/utils/memory.h>
30 #define NTLMSSP_NEGOTIATE_56 0x80000000 /* W (0) */
31 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 /* V (1) */
32 #define NTLMSSP_NEGOTIATE_128 0x20000000 /* U (2) */
33 #define NTLMSSP_RESERVED1 0x10000000 /* r1 (3) */
34 #define NTLMSSP_RESERVED2 0x08000000 /* r2 (4) */
35 #define NTLMSSP_RESERVED3 0x04000000 /* r3 (5) */
36 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000 /* T (6) */
37 #define NTLMSSP_RESERVED4 0x01000000 /* r4 (7) */
38 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 /* S (8) */
39 #define NTLMSSP_RESERVEDEQUEST_NON_NT_SESSION_KEY 0x00400000 /* R (9) */
40 #define NTLMSSP_RESERVED5 0x00200000 /* r5 (10) */
41 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000 /* Q (11) */
42 #define NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY 0x00080000 /* P (12) */
43 #define NTLMSSP_RESERVED6 0x00040000 /* r6 (13) */
44 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000 /* O (14) */
45 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000 /* N (15) */
46 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 /* M (16) */
47 #define NTLMSSP_RESERVED7 0x00004000 /* r7 (17) */
48 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000 /* L (18) */
49 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000 /* K (19) */
50 #define NTLMSSP_NEGOTIATE_ANONYMOUS 0x00000800 /* J (20) */
51 #define NTLMSSP_RESERVED8 0x00000400 /* r8 (21) */
52 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200 /* H (22) */
53 #define NTLMSSP_RESERVED9 0x00000100 /* r9 (23) */
54 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 /* G (24) */
55 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040 /* F (25) */
56 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020 /* E (26) */
57 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010 /* D (27) */
58 #define NTLMSSP_RESERVED10 0x00000008 /* r10 (28) */
59 #define NTLMSSP_REQUEST_TARGET 0x00000004 /* C (29) */
60 #define NTLMSSP_NEGOTIATE_OEM 0x00000002 /* B (30) */
61 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 /* A (31) */
63 #define WINDOWS_MAJOR_VERSION_5 0x05
64 #define WINDOWS_MAJOR_VERSION_6 0x06
65 #define WINDOWS_MINOR_VERSION_0 0x00
66 #define WINDOWS_MINOR_VERSION_1 0x01
67 #define WINDOWS_MINOR_VERSION_2 0x02
68 #define NTLMSSP_REVISION_W2K3 0x0F
70 static const char ntlm_signature[] = "NTLMSSP";
71 static const char lm_magic[] = "KGS!@#$%";
73 static const char client_sign_magic[] = "session key to client-to-server signing key magic constant";
74 static const char server_sign_magic[] = "session key to server-to-client signing key magic constant";
75 static const char client_seal_magic[] = "session key to client-to-server sealing key magic constant";
76 static const char server_seal_magic[] = "session key to server-to-client sealing key magic constant";
78 static const char* const NTLMSSP_NEGOTIATE_STRINGS[] =
80 "NTLMSSP_NEGOTIATE_56",
81 "NTLMSSP_NEGOTIATE_KEY_EXCH",
82 "NTLMSSP_NEGOTIATE_128",
86 "NTLMSSP_NEGOTIATE_VERSION",
88 "NTLMSSP_NEGOTIATE_TARGET_INFO",
89 "NTLMSSP_REQUEST_NON_NT_SESSION_KEY",
91 "NTLMSSP_NEGOTIATE_IDENTIFY",
92 "NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY",
94 "NTLMSSP_TARGET_TYPE_SERVER",
95 "NTLMSSP_TARGET_TYPE_DOMAIN",
96 "NTLMSSP_NEGOTIATE_ALWAYS_SIGN",
98 "NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED",
99 "NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED",
100 "NTLMSSP_NEGOTIATE_ANONYMOUS",
102 "NTLMSSP_NEGOTIATE_NTLM",
104 "NTLMSSP_NEGOTIATE_LM_KEY",
105 "NTLMSSP_NEGOTIATE_DATAGRAM",
106 "NTLMSSP_NEGOTIATE_SEAL",
107 "NTLMSSP_NEGOTIATE_SIGN",
108 "NTLMSSP_RESERVED10",
109 "NTLMSSP_REQUEST_TARGET",
110 "NTLMSSP_NEGOTIATE_OEM",
111 "NTLMSSP_NEGOTIATE_UNICODE"
114 static const char* const AV_PAIRS_STRINGS[] =
117 "MsvAvNbComputerName",
119 "MsvAvDnsComputerName",
120 "MsvAvDnsDomainName",
130 * Set NTLMSSP username.
132 * @param username username
135 void ntlmssp_set_username(NTLMSSP* ntlmssp, char* username)
137 freerdp_blob_free(&ntlmssp->username);
139 if (username != NULL)
141 ntlmssp->username.data = freerdp_uniconv_out(ntlmssp->uniconv, username, (size_t*) &(ntlmssp->username.length));
146 * Set NTLMSSP domain name.
148 * @param domain domain name
151 void ntlmssp_set_domain(NTLMSSP* ntlmssp, char* domain)
153 freerdp_blob_free(&ntlmssp->domain);
157 ntlmssp->domain.data = freerdp_uniconv_out(ntlmssp->uniconv, domain, (size_t*) &(ntlmssp->domain.length));
162 * Set NTLMSSP password.
164 * @param password password
167 void ntlmssp_set_password(NTLMSSP* ntlmssp, char* password)
169 freerdp_blob_free(&ntlmssp->password);
171 if (password != NULL)
173 ntlmssp->password.data = freerdp_uniconv_out(ntlmssp->uniconv, password, (size_t*) &(ntlmssp->password.length));
178 * Set NTLMSSP workstation.
180 * @param workstation workstation
183 void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation)
185 freerdp_blob_free(&ntlmssp->workstation);
187 if (workstation != NULL)
189 ntlmssp->workstation.data = freerdp_uniconv_out(ntlmssp->uniconv, workstation, (size_t*) &(ntlmssp->workstation.length));
194 * Generate client challenge (8-byte nonce).
198 void ntlmssp_generate_client_challenge(NTLMSSP* ntlmssp)
200 /* ClientChallenge in computation of LMv2 and NTLMv2 responses */
201 crypto_nonce(ntlmssp->client_challenge, 8);
205 * Generate KeyExchangeKey (the 128-bit SessionBaseKey).\n
210 void ntlmssp_generate_key_exchange_key(NTLMSSP* ntlmssp)
212 /* In NTLMv2, KeyExchangeKey is the 128-bit SessionBaseKey */
213 memcpy(ntlmssp->key_exchange_key, ntlmssp->session_base_key, 16);
217 * Generate RandomSessionKey (16-byte nonce).
221 void ntlmssp_generate_random_session_key(NTLMSSP* ntlmssp)
223 crypto_nonce(ntlmssp->random_session_key, 16);
227 * Generate ExportedSessionKey (the RandomSessionKey, exported)
231 void ntlmssp_generate_exported_session_key(NTLMSSP* ntlmssp)
233 memcpy(ntlmssp->exported_session_key, ntlmssp->random_session_key, 16);
237 * Encrypt RandomSessionKey (RC4-encrypted RandomSessionKey, using KeyExchangeKey as the key).
241 void ntlmssp_encrypt_random_session_key(NTLMSSP* ntlmssp)
243 /* In NTLMv2, EncryptedRandomSessionKey is the ExportedSessionKey RC4-encrypted with the KeyExchangeKey */
244 credssp_rc4k(ntlmssp->key_exchange_key, 16, ntlmssp->random_session_key, ntlmssp->encrypted_random_session_key);
248 * Generate timestamp for AUTHENTICATE_MESSAGE.
252 void ntlmssp_generate_timestamp(NTLMSSP* ntlmssp)
254 credssp_current_time(ntlmssp->timestamp);
256 if (ntlmssp->ntlm_v2)
258 if (ntlmssp->av_pairs->Timestamp.length == 8)
260 memcpy(ntlmssp->av_pairs->Timestamp.value, ntlmssp->timestamp, 8);
266 if (ntlmssp->av_pairs->Timestamp.length != 8)
268 ntlmssp->av_pairs->Timestamp.length = 8;
269 ntlmssp->av_pairs->Timestamp.value = xmalloc(ntlmssp->av_pairs->Timestamp.length);
271 memcpy(ntlmssp->av_pairs->Timestamp.value, ntlmssp->timestamp, 8);
276 * Generate signing key.\n
278 * @param exported_session_key ExportedSessionKey
279 * @param sign_magic Sign magic string
280 * @param signing_key Destination signing key
283 void ntlmssp_generate_signing_key(uint8* exported_session_key, rdpBlob* sign_magic, uint8* signing_key)
289 length = 16 + sign_magic->length;
290 value = (uint8*) xmalloc(length);
292 /* Concatenate ExportedSessionKey with sign magic */
293 memcpy(value, exported_session_key, 16);
294 memcpy(&value[16], sign_magic->data, sign_magic->length);
296 md5 = crypto_md5_init();
297 crypto_md5_update(md5, value, length);
298 crypto_md5_final(md5, signing_key);
304 * Generate client signing key (ClientSigningKey).\n
309 void ntlmssp_generate_client_signing_key(NTLMSSP* ntlmssp)
312 sign_magic.data = (void*) client_sign_magic;
313 sign_magic.length = sizeof(client_sign_magic);
314 ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &sign_magic, ntlmssp->client_signing_key);
318 * Generate server signing key (ServerSigningKey).\n
323 void ntlmssp_generate_server_signing_key(NTLMSSP* ntlmssp)
326 sign_magic.data = (void*) server_sign_magic;
327 sign_magic.length = sizeof(server_sign_magic);
328 ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &sign_magic, ntlmssp->server_signing_key);
332 * Generate sealing key.\n
334 * @param exported_session_key ExportedSessionKey
335 * @param seal_magic Seal magic string
336 * @param sealing_key Destination sealing key
339 void ntlmssp_generate_sealing_key(uint8* exported_session_key, rdpBlob* seal_magic, uint8* sealing_key)
345 freerdp_blob_alloc(&blob, 16 + seal_magic->length);
346 p = (uint8*) blob.data;
348 /* Concatenate ExportedSessionKey with seal magic */
349 memcpy(p, exported_session_key, 16);
350 memcpy(&p[16], seal_magic->data, seal_magic->length);
352 md5 = crypto_md5_init();
353 crypto_md5_update(md5, blob.data, blob.length);
354 crypto_md5_final(md5, sealing_key);
356 freerdp_blob_free(&blob);
360 * Generate client sealing key (ClientSealingKey).\n
365 void ntlmssp_generate_client_sealing_key(NTLMSSP* ntlmssp)
368 seal_magic.data = (void*) client_seal_magic;
369 seal_magic.length = sizeof(client_seal_magic);
370 ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &seal_magic, ntlmssp->client_sealing_key);
374 * Generate server sealing key (ServerSealingKey).\n
379 void ntlmssp_generate_server_sealing_key(NTLMSSP* ntlmssp)
382 seal_magic.data = (void*) server_seal_magic;
383 seal_magic.length = sizeof(server_seal_magic);
384 ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &seal_magic, ntlmssp->server_sealing_key);
388 * Initialize RC4 stream cipher states for sealing.
392 void ntlmssp_init_rc4_seal_states(NTLMSSP* ntlmssp)
394 ntlmssp->send_rc4_seal = crypto_rc4_init(ntlmssp->client_sealing_key, 16);
395 ntlmssp->recv_rc4_seal = crypto_rc4_init(ntlmssp->server_sealing_key, 16);
399 * Get bit from a byte buffer using a bit offset.
400 * @param buffer byte buffer
401 * @param bit bit offset
405 static int get_bit(char* buffer, int bit)
407 return (buffer[(bit - (bit % 8)) / 8] >> (7 - bit % 8) & 1);
411 * Set bit in a byte buffer using a bit offset.
412 * @param buffer byte buffer
413 * @param bit bit offset
414 * @param value bit value
417 static void set_bit(char* buffer, int bit, int value)
419 buffer[(bit - (bit % 8)) / 8] |= value << (7 - bit % 8);
422 static void ntlmssp_compute_des_key(char* text, char* des_key)
428 /* Convert the 7 bytes into a bit stream, and insert a parity-bit (odd parity) after every seven bits. */
430 memset(des_key, '\0', 8);
432 for (i = 0; i < 8; i++)
436 for (j = 0; j < 7; j++)
438 /* copy 7 bits, and count the number of bits that are set */
440 bit = get_bit(text, i*7 + j);
441 set_bit(des_key, i*7 + i + j, bit);
445 /* insert parity bit (odd parity) */
448 set_bit(des_key, i*7 + i + j, 1);
452 void ntlmssp_compute_lm_hash(char* password, char* hash)
461 /* LM("password") = E52CAC67419A9A224A3B108F3FA6CB6D */
463 maxlen = (strlen(password) < 14) ? strlen(password) : 14;
465 /* convert to uppercase */
466 for (i = 0; i < maxlen; i++)
468 if ((password[i] >= 'a') && (password[i] <= 'z'))
469 text[i] = password[i] - 32;
471 text[i] = password[i];
474 /* pad with nulls up to 14 bytes */
475 for (i = maxlen; i < 14; i++)
478 ntlmssp_compute_des_key(text, des_key1);
479 ntlmssp_compute_des_key(&text[7], des_key2);
481 DES_set_key((const_DES_cblock*)des_key1, &ks);
482 DES_ecb_encrypt((const_DES_cblock*) lm_magic, (DES_cblock*)hash, &ks, DES_ENCRYPT);
484 DES_set_key((const_DES_cblock*)des_key2, &ks);
485 DES_ecb_encrypt((const_DES_cblock*) lm_magic, (DES_cblock*)&hash[8], &ks, DES_ENCRYPT);
488 void ntlmssp_compute_ntlm_hash(rdpBlob* password, char* hash)
490 /* NTLMv1("password") = 8846F7EAEE8FB117AD06BDD830B7586C */
494 /* Password needs to be in unicode */
496 /* Apply the MD4 digest algorithm on the password in unicode, the result is the NTLM hash */
499 MD4_Update(&md4_ctx, password->data, password->length);
500 MD4_Final((void*) hash, &md4_ctx);
503 void ntlmssp_compute_ntlm_v2_hash(NTLMSSP* ntlmssp, char* hash)
509 freerdp_blob_alloc(&blob, ntlmssp->username.length + ntlmssp->domain.length);
510 p = (char*) blob.data;
512 /* First, compute the NTLMv1 hash of the password */
513 ntlmssp_compute_ntlm_hash(&ntlmssp->password, ntlm_hash);
515 /* Concatenate(Uppercase(username),domain)*/
516 memcpy(p, ntlmssp->username.data, ntlmssp->username.length);
517 freerdp_uniconv_uppercase(ntlmssp->uniconv, p, ntlmssp->username.length / 2);
519 memcpy(&p[ntlmssp->username.length], ntlmssp->domain.data, ntlmssp->domain.length);
521 /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */
522 HMAC(EVP_md5(), (void*) ntlm_hash, 16, blob.data, blob.length, (void*) hash, NULL);
524 freerdp_blob_free(&blob);
527 void ntlmssp_compute_lm_response(char* password, char* challenge, char* response)
535 /* A LM hash is 16-bytes long, but the LM response uses a LM hash null-padded to 21 bytes */
536 memset(hash, '\0', 21);
537 ntlmssp_compute_lm_hash(password, hash);
539 /* Each 7-byte third of the 21-byte null-padded LM hash is used to create a DES key */
540 ntlmssp_compute_des_key(hash, des_key1);
541 ntlmssp_compute_des_key(&hash[7], des_key2);
542 ntlmssp_compute_des_key(&hash[14], des_key3);
544 /* Encrypt the LM challenge with each key, and concatenate the result. This is the LM response (24 bytes) */
545 DES_set_key((const_DES_cblock*)des_key1, &ks);
546 DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)response, &ks, DES_ENCRYPT);
548 DES_set_key((const_DES_cblock*)des_key2, &ks);
549 DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)&response[8], &ks, DES_ENCRYPT);
551 DES_set_key((const_DES_cblock*)des_key3, &ks);
552 DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)&response[16], &ks, DES_ENCRYPT);
555 void ntlmssp_compute_lm_v2_response(NTLMSSP* ntlmssp)
559 char ntlm_v2_hash[16];
561 /* Compute the NTLMv2 hash */
562 ntlmssp_compute_ntlm_v2_hash(ntlmssp, ntlm_v2_hash);
564 /* Concatenate the server and client challenges */
565 memcpy(value, ntlmssp->server_challenge, 8);
566 memcpy(&value[8], ntlmssp->client_challenge, 8);
568 freerdp_blob_alloc(&ntlmssp->lm_challenge_response, 24);
569 response = (char*) ntlmssp->lm_challenge_response.data;
571 /* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */
572 HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, (void*) value, 16, (void*) response, NULL);
574 /* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */
575 memcpy(&response[16], ntlmssp->client_challenge, 8);
579 * Compute NTLMv2 Response.\n
580 * NTLMv2_RESPONSE @msdn{cc236653}\n
581 * NTLMv2 Authentication @msdn{cc236700}
585 void ntlmssp_compute_ntlm_v2_response(NTLMSSP* ntlmssp)
588 uint8 ntlm_v2_hash[16];
589 uint8 nt_proof_str[16];
590 rdpBlob ntlm_v2_temp;
591 rdpBlob ntlm_v2_temp_chal;
593 freerdp_blob_alloc(&ntlm_v2_temp, ntlmssp->target_info.length + 28);
595 memset(ntlm_v2_temp.data, '\0', ntlm_v2_temp.length);
596 blob = (uint8*) ntlm_v2_temp.data;
598 /* Compute the NTLMv2 hash */
599 ntlmssp_compute_ntlm_v2_hash(ntlmssp, (char*) ntlm_v2_hash);
601 #ifdef WITH_DEBUG_NLA
602 printf("Password (length = %d)\n", ntlmssp->password.length);
603 freerdp_hexdump(ntlmssp->password.data, ntlmssp->password.length);
606 printf("Username (length = %d)\n", ntlmssp->username.length);
607 freerdp_hexdump(ntlmssp->username.data, ntlmssp->username.length);
610 printf("Domain (length = %d)\n", ntlmssp->domain.length);
611 freerdp_hexdump(ntlmssp->domain.data, ntlmssp->domain.length);
614 printf("Workstation (length = %d)\n", ntlmssp->workstation.length);
615 freerdp_hexdump(ntlmssp->workstation.data, ntlmssp->workstation.length);
618 printf("NTOWFv2, NTLMv2 Hash\n");
619 freerdp_hexdump(ntlm_v2_hash, 16);
624 blob[0] = 1; /* RespType (1 byte) */
625 blob[1] = 1; /* HighRespType (1 byte) */
626 /* Reserved1 (2 bytes) */
627 /* Reserved2 (4 bytes) */
628 memcpy(&blob[8], ntlmssp->av_pairs->Timestamp.value, 8); /* Timestamp (8 bytes) */
629 memcpy(&blob[16], ntlmssp->client_challenge, 8); /* ClientChallenge (8 bytes) */
630 /* Reserved3 (4 bytes) */
631 memcpy(&blob[28], ntlmssp->target_info.data, ntlmssp->target_info.length);
633 #ifdef WITH_DEBUG_NLA
634 printf("NTLMv2 Response Temp Blob\n");
635 freerdp_hexdump(ntlm_v2_temp.data, ntlm_v2_temp.length);
639 /* Concatenate server challenge with temp */
640 freerdp_blob_alloc(&ntlm_v2_temp_chal, ntlm_v2_temp.length + 8);
641 blob = (uint8*) ntlm_v2_temp_chal.data;
642 memcpy(blob, ntlmssp->server_challenge, 8);
643 memcpy(&blob[8], ntlm_v2_temp.data, ntlm_v2_temp.length);
645 HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, (void*) ntlm_v2_temp_chal.data,
646 ntlm_v2_temp_chal.length, (void*) nt_proof_str, NULL);
648 /* NtChallengeResponse, Concatenate NTProofStr with temp */
649 freerdp_blob_alloc(&ntlmssp->nt_challenge_response, ntlm_v2_temp.length + 16);
650 blob = (uint8*) ntlmssp->nt_challenge_response.data;
651 memcpy(blob, nt_proof_str, 16);
652 memcpy(&blob[16], ntlm_v2_temp.data, ntlm_v2_temp.length);
654 /* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */
655 HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16,
656 (void*) nt_proof_str, 16, (void*) ntlmssp->session_base_key, NULL);
658 freerdp_blob_free(&ntlm_v2_temp);
659 freerdp_blob_free(&ntlm_v2_temp_chal);
663 * Input NegotiateFlags, a 4-byte bit map.
668 void ntlmssp_input_negotiate_flags(STREAM* s, uint32* flags)
671 stream_read_uint32(s, *flags);
675 * Output NegotiateFlags, a 4-byte bit map.
680 void ntlmssp_output_negotiate_flags(STREAM* s, uint32 flags)
682 stream_write_uint32(s, flags);
685 void ntlmssp_print_negotiate_flags(uint32 flags)
690 printf("negotiateFlags \"0x%08X\"{\n", flags);
692 for (i = 31; i >= 0; i--)
694 if ((flags >> i) & 1)
696 str = NTLMSSP_NEGOTIATE_STRINGS[(31 - i)];
697 printf("\t%s (%d),\n", str, (31 - i));
705 * Output Restriction_Encoding.\n
706 * Restriction_Encoding @msdn{cc236647}
710 static void ntlmssp_output_restriction_encoding(NTLMSSP* ntlmssp)
712 AV_PAIR *restrictions = &ntlmssp->av_pairs->Restrictions;
713 STREAM* s = stream_new(0);
715 uint8 machineID[32] =
716 "\x3A\x15\x8E\xA6\x75\x82\xD8\xF7\x3E\x06\xFA\x7A\xB4\xDF\xFD\x43"
717 "\x84\x6C\x02\x3A\xFD\x5A\x94\xFE\xCF\x97\x0F\x3D\x19\x2C\x38\x20";
719 restrictions->value = xmalloc(48);
720 restrictions->length = 48;
722 s->data = restrictions->value;
723 s->size = restrictions->length;
726 stream_write_uint32(s, 48); /* Size */
727 stream_write_zero(s, 4); /* Z4 (set to zero) */
729 /* IntegrityLevel (bit 31 set to 1) */
730 stream_write_uint8(s, 1);
731 stream_write_zero(s, 3);
733 stream_write_uint32(s, 0x00002000); /* SubjectIntegrityLevel */
734 stream_write(s, machineID, 32); /* MachineID */
740 * Output TargetName.\n
744 void ntlmssp_output_target_name(NTLMSSP* ntlmssp)
746 STREAM* s = stream_new(0);
747 AV_PAIR* target_name = &ntlmssp->av_pairs->TargetName;
750 * TODO: No idea what should be set here (observed MsvAvTargetName = MsvAvDnsComputerName or
751 * MsvAvTargetName should be the name of the service be accessed after authentication)
752 * here used: "TERMSRV/192.168.0.123" in unicode (Dmitrij Jasnov)
755 "\x54\x00\x45\x00\x52\x00\x4d\x00\x53\x00\x52\x00\x56\x00\x2f\x00\x31\x00\x39\x00\x32"
756 "\x00\x2e\x00\x31\x00\x36\x00\x38\x00\x2e\x00\x30\x00\x2e\x00\x31\x00\x32\x00\x33\x00";
758 target_name->length = 42;
759 target_name->value = (uint8*) xmalloc(target_name->length);
761 s->data = target_name->value;
762 s->size = target_name->length;
765 stream_write(s, name, target_name->length);
771 * Output ChannelBindings.\n
775 void ntlmssp_output_channel_bindings(NTLMSSP* ntlmssp)
777 STREAM* s = stream_new(0);
778 AV_PAIR* channel_bindings = &ntlmssp->av_pairs->ChannelBindings;
780 channel_bindings->value = (uint8*) xmalloc(48);
781 channel_bindings->length = 16;
783 s->data = channel_bindings->value;
784 s->size = channel_bindings->length;
787 stream_write_zero(s, 16); /* an all-zero value of the hash is used to indicate absence of channel bindings */
793 * Populate array of AV_PAIRs.\n
794 * AV_PAIR @msdn{cc236646}
798 void ntlmssp_populate_av_pairs(NTLMSSP* ntlmssp)
802 AV_PAIRS *av_pairs = ntlmssp->av_pairs;
805 av_pairs->Flags = 0x00000002; /* Indicates the present of a Message Integrity Check (MIC) */
807 /* Restriction_Encoding */
808 ntlmssp_output_restriction_encoding(ntlmssp);
811 ntlmssp_output_target_name(ntlmssp);
813 /* ChannelBindings */
814 ntlmssp_output_channel_bindings(ntlmssp);
817 s->data = xmalloc(ntlmssp->target_info.length + 512);
820 ntlmssp_output_av_pairs(ntlmssp, s);
821 freerdp_blob_alloc(&target_info, s->p - s->data);
822 memcpy(target_info.data, s->data, target_info.length);
824 ntlmssp->target_info.data = target_info.data;
825 ntlmssp->target_info.length = target_info.length;
829 * Input array of AV_PAIRs.\n
830 * AV_PAIR @msdn{cc236646}
835 void ntlmssp_input_av_pairs(NTLMSSP* ntlmssp, STREAM* s)
840 AV_PAIRS* av_pairs = ntlmssp->av_pairs;
842 #ifdef WITH_DEBUG_NLA
843 printf("AV_PAIRS = {\n");
849 stream_read_uint16(s, AvId);
850 stream_read_uint16(s, AvLen);
854 if (AvId != MsvAvFlags)
856 value = xmalloc(AvLen);
857 stream_read(s, value, AvLen);
861 stream_read_uint32(s, av_pairs->Flags);
867 case MsvAvNbComputerName:
868 av_pairs->NbComputerName.length = AvLen;
869 av_pairs->NbComputerName.value = value;
872 case MsvAvNbDomainName:
873 av_pairs->NbDomainName.length = AvLen;
874 av_pairs->NbDomainName.value = value;
877 case MsvAvDnsComputerName:
878 av_pairs->DnsComputerName.length = AvLen;
879 av_pairs->DnsComputerName.value = value;
882 case MsvAvDnsDomainName:
883 av_pairs->DnsDomainName.length = AvLen;
884 av_pairs->DnsDomainName.value = value;
887 case MsvAvDnsTreeName:
888 av_pairs->DnsTreeName.length = AvLen;
889 av_pairs->DnsTreeName.value = value;
893 av_pairs->Timestamp.length = AvLen;
894 av_pairs->Timestamp.value = value;
897 case MsvAvRestrictions:
898 av_pairs->Restrictions.length = AvLen;
899 av_pairs->Restrictions.value = value;
902 case MsvAvTargetName:
903 av_pairs->TargetName.length = AvLen;
904 av_pairs->TargetName.value = value;
907 case MsvChannelBindings:
908 av_pairs->ChannelBindings.length = AvLen;
909 av_pairs->ChannelBindings.value = value;
918 #ifdef WITH_DEBUG_NLA
920 printf("\tAvId: %s, AvLen: %d\n", AV_PAIRS_STRINGS[AvId], AvLen);
922 printf("\tAvId: %s, AvLen: %d\n", "Unknown", AvLen);
924 freerdp_hexdump(value, AvLen);
927 while (AvId != MsvAvEOL);
929 #ifdef WITH_DEBUG_NLA
935 * Output array of AV_PAIRs.\n
936 * AV_PAIR @msdn{cc236646}
941 void ntlmssp_output_av_pairs(NTLMSSP* ntlmssp, STREAM* s)
943 AV_PAIRS* av_pairs = ntlmssp->av_pairs;
945 if (av_pairs->NbDomainName.length > 0)
947 stream_write_uint16(s, MsvAvNbDomainName); /* AvId */
948 stream_write_uint16(s, av_pairs->NbDomainName.length); /* AvLen */
949 stream_write(s, av_pairs->NbDomainName.value, av_pairs->NbDomainName.length); /* Value */
952 if (av_pairs->NbComputerName.length > 0)
954 stream_write_uint16(s, MsvAvNbComputerName); /* AvId */
955 stream_write_uint16(s, av_pairs->NbComputerName.length); /* AvLen */
956 stream_write(s, av_pairs->NbComputerName.value, av_pairs->NbComputerName.length); /* Value */
959 if (av_pairs->DnsDomainName.length > 0)
961 stream_write_uint16(s, MsvAvDnsDomainName); /* AvId */
962 stream_write_uint16(s, av_pairs->DnsDomainName.length); /* AvLen */
963 stream_write(s, av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length); /* Value */
966 if (av_pairs->DnsComputerName.length > 0)
968 stream_write_uint16(s, MsvAvDnsComputerName); /* AvId */
969 stream_write_uint16(s, av_pairs->DnsComputerName.length); /* AvLen */
970 stream_write(s, av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length); /* Value */
973 if (av_pairs->DnsTreeName.length > 0)
975 stream_write_uint16(s, MsvAvDnsTreeName); /* AvId */
976 stream_write_uint16(s, av_pairs->DnsTreeName.length); /* AvLen */
977 stream_write(s, av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length); /* Value */
980 if (av_pairs->Timestamp.length > 0)
982 stream_write_uint16(s, MsvAvTimestamp); /* AvId */
983 stream_write_uint16(s, av_pairs->Timestamp.length); /* AvLen */
984 stream_write(s, av_pairs->Timestamp.value, av_pairs->Timestamp.length); /* Value */
987 if (av_pairs->Flags > 0)
989 stream_write_uint16(s, MsvAvFlags); /* AvId */
990 stream_write_uint16(s, 4); /* AvLen */
991 stream_write_uint32(s, av_pairs->Flags); /* Value */
994 if (av_pairs->Restrictions.length > 0)
996 stream_write_uint16(s, MsvAvRestrictions); /* AvId */
997 stream_write_uint16(s, av_pairs->Restrictions.length); /* AvLen */
998 stream_write(s, av_pairs->Restrictions.value, av_pairs->Restrictions.length); /* Value */
1001 if (av_pairs->ChannelBindings.length > 0)
1003 stream_write_uint16(s, MsvChannelBindings); /* AvId */
1004 stream_write_uint16(s, av_pairs->ChannelBindings.length); /* AvLen */
1005 stream_write(s, av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length); /* Value */
1008 if (av_pairs->TargetName.length > 0)
1010 stream_write_uint16(s, MsvAvTargetName); /* AvId */
1011 stream_write_uint16(s, av_pairs->TargetName.length); /* AvLen */
1012 stream_write(s, av_pairs->TargetName.value, av_pairs->TargetName.length); /* Value */
1015 /* This indicates the end of the AV_PAIR array */
1016 stream_write_uint16(s, MsvAvEOL); /* AvId */
1017 stream_write_uint16(s, 0); /* AvLen */
1019 if (ntlmssp->ntlm_v2)
1021 stream_write_zero(s, 8);
1026 * Print array of AV_PAIRs.\n
1027 * AV_PAIR @msdn{cc236646}
1032 void ntlmssp_print_av_pairs(NTLMSSP* ntlmssp)
1034 AV_PAIRS* av_pairs = ntlmssp->av_pairs;
1036 printf("AV_PAIRS = {\n");
1038 if (av_pairs->NbDomainName.length > 0)
1040 printf("\tAvId: MsvAvNbDomainName AvLen: %d\n", av_pairs->NbDomainName.length);
1041 freerdp_hexdump(av_pairs->NbDomainName.value, av_pairs->NbDomainName.length);
1044 if (av_pairs->NbComputerName.length > 0)
1046 printf("\tAvId: MsvAvNbComputerName AvLen: %d\n", av_pairs->NbComputerName.length);
1047 freerdp_hexdump(av_pairs->NbComputerName.value, av_pairs->NbComputerName.length);
1050 if (av_pairs->DnsDomainName.length > 0)
1052 printf("\tAvId: MsvAvDnsDomainName AvLen: %d\n", av_pairs->DnsDomainName.length);
1053 freerdp_hexdump(av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length);
1056 if (av_pairs->DnsComputerName.length > 0)
1058 printf("\tAvId: MsvAvDnsComputerName AvLen: %d\n", av_pairs->DnsComputerName.length);
1059 freerdp_hexdump(av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length);
1062 if (av_pairs->DnsTreeName.length > 0)
1064 printf("\tAvId: MsvAvDnsTreeName AvLen: %d\n", av_pairs->DnsTreeName.length);
1065 freerdp_hexdump(av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length);
1068 if (av_pairs->Timestamp.length > 0)
1070 printf("\tAvId: MsvAvTimestamp AvLen: %d\n", av_pairs->Timestamp.length);
1071 freerdp_hexdump(av_pairs->Timestamp.value, av_pairs->Timestamp.length);
1074 if (av_pairs->Flags > 0)
1076 printf("\tAvId: MsvAvFlags AvLen: %d\n", 4);
1077 printf("0x%08X\n", av_pairs->Flags);
1080 if (av_pairs->Restrictions.length > 0)
1082 printf("\tAvId: MsvAvRestrictions AvLen: %d\n", av_pairs->Restrictions.length);
1083 freerdp_hexdump(av_pairs->Restrictions.value, av_pairs->Restrictions.length);
1086 if (av_pairs->ChannelBindings.length > 0)
1088 printf("\tAvId: MsvChannelBindings AvLen: %d\n", av_pairs->ChannelBindings.length);
1089 freerdp_hexdump(av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length);
1092 if (av_pairs->TargetName.length > 0)
1094 printf("\tAvId: MsvAvTargetName AvLen: %d\n", av_pairs->TargetName.length);
1095 freerdp_hexdump(av_pairs->TargetName.value, av_pairs->TargetName.length);
1102 * Free array of AV_PAIRs.\n
1103 * AV_PAIR @msdn{cc236646}
1107 void ntlmssp_free_av_pairs(NTLMSSP* ntlmssp)
1109 AV_PAIRS *av_pairs = ntlmssp->av_pairs;
1111 if (av_pairs != NULL)
1113 if (av_pairs->NbComputerName.value != NULL)
1114 xfree(av_pairs->NbComputerName.value);
1115 if (av_pairs->NbDomainName.value != NULL)
1116 xfree(av_pairs->NbDomainName.value);
1117 if (av_pairs->DnsComputerName.value != NULL)
1118 xfree(av_pairs->DnsComputerName.value);
1119 if (av_pairs->DnsDomainName.value != NULL)
1120 xfree(av_pairs->DnsDomainName.value);
1121 if (av_pairs->DnsTreeName.value != NULL)
1122 xfree(av_pairs->DnsTreeName.value);
1123 if (av_pairs->Timestamp.value != NULL)
1124 xfree(av_pairs->Timestamp.value);
1125 if (av_pairs->Restrictions.value != NULL)
1126 xfree(av_pairs->Restrictions.value);
1127 if (av_pairs->TargetName.value != NULL)
1128 xfree(av_pairs->TargetName.value);
1129 if (av_pairs->ChannelBindings.value != NULL)
1130 xfree(av_pairs->ChannelBindings.value);
1135 ntlmssp->av_pairs = NULL;
1139 * Output VERSION structure.\n
1140 * VERSION @msdn{cc236654}
1144 static void ntlmssp_output_version(STREAM* s)
1146 /* The following version information was observed with Windows 7 */
1148 stream_write_uint8(s, WINDOWS_MAJOR_VERSION_6); /* ProductMajorVersion (1 byte) */
1149 stream_write_uint8(s, WINDOWS_MINOR_VERSION_1); /* ProductMinorVersion (1 byte) */
1150 stream_write_uint16(s, 7600); /* ProductBuild (2 bytes) */
1151 stream_write_zero(s, 3); /* Reserved (3 bytes) */
1152 stream_write_uint8(s, NTLMSSP_REVISION_W2K3); /* NTLMRevisionCurrent (1 byte) */
1155 void ntlmssp_compute_message_integrity_check(NTLMSSP* ntlmssp)
1160 * Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE,
1161 * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey
1164 HMAC_CTX_init(&hmac_ctx);
1165 HMAC_Init_ex(&hmac_ctx, ntlmssp->exported_session_key, 16, EVP_md5(), NULL);
1166 HMAC_Update(&hmac_ctx, ntlmssp->negotiate_message.data, ntlmssp->negotiate_message.length);
1167 HMAC_Update(&hmac_ctx, ntlmssp->challenge_message.data, ntlmssp->challenge_message.length);
1168 HMAC_Update(&hmac_ctx, ntlmssp->authenticate_message.data, ntlmssp->authenticate_message.length);
1169 HMAC_Final(&hmac_ctx, ntlmssp->message_integrity_check, NULL);
1173 * Encrypt and sign message using NTLMSSP.\n
1174 * GSS_WrapEx() @msdn{cc236718}\n
1175 * EncryptMessage() @msdn{aa375378}
1177 * @param[in] msg message to encrypt
1178 * @param[out] encrypted_msg encrypted message
1179 * @param[out] signature destination signature
1182 void ntlmssp_encrypt_message(NTLMSSP* ntlmssp, rdpBlob* msg, rdpBlob* encrypted_msg, uint8* signature)
1189 /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,msg) using the client signing key */
1190 HMAC_CTX_init(&hmac_ctx);
1191 HMAC_Init_ex(&hmac_ctx, ntlmssp->client_signing_key, 16, EVP_md5(), NULL);
1192 HMAC_Update(&hmac_ctx, (void*) &ntlmssp->send_seq_num, 4);
1193 HMAC_Update(&hmac_ctx, msg->data, msg->length);
1194 HMAC_Final(&hmac_ctx, digest, NULL);
1196 /* Allocate space for encrypted message */
1197 freerdp_blob_alloc(encrypted_msg, msg->length);
1199 /* Encrypt message using with RC4 */
1200 crypto_rc4(ntlmssp->send_rc4_seal, msg->length, msg->data, encrypted_msg->data);
1202 /* RC4-encrypt first 8 bytes of digest */
1203 crypto_rc4(ntlmssp->send_rc4_seal, 8, digest, checksum);
1205 /* Concatenate version, ciphertext and sequence number to build signature */
1206 memcpy(signature, (void*) &version, 4);
1207 memcpy(&signature[4], (void*) checksum, 8);
1208 memcpy(&signature[12], (void*) &(ntlmssp->send_seq_num), 4);
1210 HMAC_CTX_cleanup(&hmac_ctx);
1212 ntlmssp->send_seq_num++;
1216 * Decrypt message and verify signature using NTLMSSP.\n
1217 * GSS_UnwrapEx() @msdn{cc236703}\n
1218 * DecryptMessage() @msdn{aa375211}
1220 * @param[in] encrypted_msg encrypted message
1221 * @param[out] msg decrypted message
1222 * @param[in] signature signature
1226 int ntlmssp_decrypt_message(NTLMSSP* ntlmssp, rdpBlob* encrypted_msg, rdpBlob* msg, uint8* signature)
1232 uint8 expected_signature[16];
1234 /* Allocate space for encrypted message */
1235 freerdp_blob_alloc(msg, encrypted_msg->length);
1237 /* Encrypt message using with RC4 */
1238 crypto_rc4(ntlmssp->recv_rc4_seal, encrypted_msg->length, encrypted_msg->data, msg->data);
1240 /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,msg) using the client signing key */
1241 HMAC_CTX_init(&hmac_ctx);
1242 HMAC_Init_ex(&hmac_ctx, ntlmssp->server_signing_key, 16, EVP_md5(), NULL);
1243 HMAC_Update(&hmac_ctx, (void*) &ntlmssp->recv_seq_num, 4);
1244 HMAC_Update(&hmac_ctx, msg->data, msg->length);
1245 HMAC_Final(&hmac_ctx, digest, NULL);
1247 /* RC4-encrypt first 8 bytes of digest */
1248 crypto_rc4(ntlmssp->recv_rc4_seal, 8, digest, checksum);
1250 /* Concatenate version, ciphertext and sequence number to build signature */
1251 memcpy(expected_signature, (void*) &version, 4);
1252 memcpy(&expected_signature[4], (void*) checksum, 8);
1253 memcpy(&expected_signature[12], (void*) &(ntlmssp->recv_seq_num), 4);
1255 if (memcmp(signature, expected_signature, 16) != 0)
1257 /* signature verification failed! */
1258 printf("signature verification failed, something nasty is going on!\n");
1262 HMAC_CTX_cleanup(&hmac_ctx);
1264 ntlmssp->recv_seq_num++;
1269 * Send NTLMSSP NEGOTIATE_MESSAGE.\n
1270 * NEGOTIATE_MESSAGE @msdn{cc236641}
1275 void ntlmssp_send_negotiate_message(NTLMSSP* ntlmssp, STREAM* s)
1278 uint32 negotiateFlags = 0;
1280 stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
1281 stream_write_uint32(s, 1); /* MessageType */
1283 if (ntlmssp->ntlm_v2)
1285 DEBUG_NLA("Negotiating NTLMv2");
1286 /* observed: B7 82 08 E2 (0xE20882B7) (Dmitrij Jasnov) */
1287 negotiateFlags |= NTLMSSP_NEGOTIATE_56;
1288 negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1289 negotiateFlags |= NTLMSSP_NEGOTIATE_128;
1290 negotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
1291 negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
1292 negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
1293 negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
1294 negotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY;
1295 negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
1296 negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
1297 negotiateFlags |= NTLMSSP_REQUEST_TARGET;
1298 negotiateFlags |= NTLMSSP_NEGOTIATE_OEM;
1299 negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
1303 negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1304 negotiateFlags |= NTLMSSP_NEGOTIATE_128;
1305 negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
1306 negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
1307 negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
1308 negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
1309 negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
1310 negotiateFlags |= NTLMSSP_REQUEST_TARGET;
1311 negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
1314 ntlmssp_output_negotiate_flags(s, negotiateFlags); /* NegotiateFlags (4 bytes) */
1316 #ifdef WITH_DEBUG_NLA
1317 ntlmssp_print_negotiate_flags(negotiateFlags);
1320 /* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
1322 /* DomainNameFields (8 bytes) */
1323 stream_write_uint16(s, 0); /* DomainNameLen */
1324 stream_write_uint16(s, 0); /* DomainNameMaxLen */
1325 stream_write_uint32(s, 0); /* DomainNameBufferOffset */
1327 /* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
1329 /* WorkstationFields (8 bytes) */
1330 stream_write_uint16(s, 0); /* WorkstationLen */
1331 stream_write_uint16(s, 0); /* WorkstationMaxLen */
1332 stream_write_uint32(s, 0); /* WorkstationBufferOffset */
1334 if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
1336 /* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
1337 ntlmssp_output_version(s);
1339 #ifdef WITH_DEBUG_NLA
1340 printf("Version (length = 8)\n");
1341 freerdp_hexdump((s->p - 8), 8);
1346 length = s->p - s->data;
1347 freerdp_blob_alloc(&ntlmssp->negotiate_message, length);
1348 memcpy(ntlmssp->negotiate_message.data, s->data, length);
1350 #ifdef WITH_DEBUG_NLA
1351 printf("NEGOTIATE_MESSAGE (length = %d)\n", length);
1352 freerdp_hexdump(s->data, length);
1356 ntlmssp->state = NTLMSSP_STATE_CHALLENGE;
1360 * Receive NTLMSSP CHALLENGE_MESSAGE.\n
1361 * CHALLENGE_MESSAGE @msdn{cc236642}
1366 void ntlmssp_recv_challenge_message(NTLMSSP* ntlmssp, STREAM* s)
1370 uint8* start_offset;
1371 uint8* payload_offset;
1372 uint16 targetNameLen;
1373 uint16 targetNameMaxLen;
1374 uint32 targetNameBufferOffset;
1375 uint16 targetInfoLen;
1376 uint16 targetInfoMaxLen;
1377 uint32 targetInfoBufferOffset;
1379 start_offset = s->p - 12;
1381 /* TargetNameFields (8 bytes) */
1382 stream_read_uint16(s, targetNameLen); /* TargetNameLen (2 bytes) */
1383 stream_read_uint16(s, targetNameMaxLen); /* TargetNameMaxLen (2 bytes) */
1384 stream_read_uint32(s, targetNameBufferOffset); /* TargetNameBufferOffset (4 bytes) */
1386 ntlmssp_input_negotiate_flags(s, &(ntlmssp->negotiate_flags)); /* NegotiateFlags (4 bytes) */
1388 #ifdef WITH_DEBUG_NLA
1389 ntlmssp_print_negotiate_flags(ntlmssp->negotiate_flags);
1392 stream_read(s, ntlmssp->server_challenge, 8); /* ServerChallenge (8 bytes) */
1393 stream_seek(s, 8); /* Reserved (8 bytes), should be ignored */
1395 /* TargetInfoFields (8 bytes) */
1396 stream_read_uint16(s, targetInfoLen); /* TargetInfoLen (2 bytes) */
1397 stream_read_uint16(s, targetInfoMaxLen); /* TargetInfoMaxLen (2 bytes) */
1398 stream_read_uint32(s, targetInfoBufferOffset); /* TargetInfoBufferOffset (4 bytes) */
1400 /* only present if NTLMSSP_NEGOTIATE_VERSION is set */
1402 if (ntlmssp->negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1404 stream_seek(s, 8); /* Version (8 bytes), can be ignored */
1407 /* Payload (variable) */
1408 payload_offset = s->p;
1410 if (targetNameLen > 0)
1412 p = start_offset + targetNameBufferOffset;
1413 freerdp_blob_alloc(&ntlmssp->target_name, targetNameLen);
1414 memcpy(ntlmssp->target_name.data, p, targetNameLen);
1416 #ifdef WITH_DEBUG_NLA
1417 printf("targetName (length = %d, offset = %d)\n", targetNameLen, targetNameBufferOffset);
1418 freerdp_hexdump(ntlmssp->target_name.data, ntlmssp->target_name.length);
1423 if (targetInfoLen > 0)
1425 p = start_offset + targetInfoBufferOffset;
1426 freerdp_blob_alloc(&ntlmssp->target_info, targetInfoLen);
1427 memcpy(ntlmssp->target_info.data, p, targetInfoLen);
1429 #ifdef WITH_DEBUG_NLA
1430 printf("targetInfo (length = %d, offset = %d)\n", targetInfoLen, targetInfoBufferOffset);
1431 freerdp_hexdump(ntlmssp->target_info.data, ntlmssp->target_info.length);
1435 if (ntlmssp->ntlm_v2)
1438 ntlmssp_input_av_pairs(ntlmssp, s);
1442 length = (payload_offset - start_offset) + targetNameLen + targetInfoLen;
1444 freerdp_blob_alloc(&ntlmssp->challenge_message, length);
1445 memcpy(ntlmssp->challenge_message.data, start_offset, length);
1447 #ifdef WITH_DEBUG_NLA
1448 printf("CHALLENGE_MESSAGE (length = %d)\n", length);
1449 freerdp_hexdump(start_offset, length);
1454 if (ntlmssp->ntlm_v2)
1455 ntlmssp_populate_av_pairs(ntlmssp);
1458 ntlmssp_generate_timestamp(ntlmssp);
1460 /* LmChallengeResponse */
1461 ntlmssp_compute_lm_v2_response(ntlmssp);
1463 if (ntlmssp->ntlm_v2)
1464 memset(ntlmssp->lm_challenge_response.data, '\0', 24);
1466 /* NtChallengeResponse */
1467 ntlmssp_compute_ntlm_v2_response(ntlmssp);
1469 /* KeyExchangeKey */
1470 ntlmssp_generate_key_exchange_key(ntlmssp);
1472 /* EncryptedRandomSessionKey */
1473 ntlmssp_encrypt_random_session_key(ntlmssp);
1475 /* Generate signing keys */
1476 ntlmssp_generate_client_signing_key(ntlmssp);
1477 ntlmssp_generate_server_signing_key(ntlmssp);
1479 /* Generate sealing keys */
1480 ntlmssp_generate_client_sealing_key(ntlmssp);
1481 ntlmssp_generate_server_sealing_key(ntlmssp);
1483 /* Initialize RC4 seal state using client sealing key */
1484 ntlmssp_init_rc4_seal_states(ntlmssp);
1486 #ifdef WITH_DEBUG_NLA
1487 printf("ClientChallenge\n");
1488 freerdp_hexdump(ntlmssp->client_challenge, 8);
1491 printf("ServerChallenge\n");
1492 freerdp_hexdump(ntlmssp->server_challenge, 8);
1495 printf("SessionBaseKey\n");
1496 freerdp_hexdump(ntlmssp->session_base_key, 16);
1499 printf("KeyExchangeKey\n");
1500 freerdp_hexdump(ntlmssp->key_exchange_key, 16);
1503 printf("ExportedSessionKey\n");
1504 freerdp_hexdump(ntlmssp->exported_session_key, 16);
1507 printf("RandomSessionKey\n");
1508 freerdp_hexdump(ntlmssp->random_session_key, 16);
1511 printf("ClientSignKey\n");
1512 freerdp_hexdump(ntlmssp->client_signing_key, 16);
1515 printf("ClientSealingKey\n");
1516 freerdp_hexdump(ntlmssp->client_sealing_key, 16);
1519 printf("Timestamp\n");
1520 freerdp_hexdump(ntlmssp->timestamp, 8);
1524 ntlmssp->state = NTLMSSP_STATE_AUTHENTICATE;
1528 * Send NTLMSSP AUTHENTICATE_MESSAGE.\n
1529 * AUTHENTICATE_MESSAGE @msdn{cc236643}
1534 void ntlmssp_send_authenticate_message(NTLMSSP* ntlmssp, STREAM* s)
1537 uint32 negotiateFlags = 0;
1538 uint8* mic_offset = NULL;
1540 uint16 DomainNameLen;
1542 uint16 WorkstationLen;
1543 uint16 LmChallengeResponseLen;
1544 uint16 NtChallengeResponseLen;
1545 uint16 EncryptedRandomSessionKeyLen;
1547 uint32 PayloadBufferOffset;
1548 uint32 DomainNameBufferOffset;
1549 uint32 UserNameBufferOffset;
1550 uint32 WorkstationBufferOffset;
1551 uint32 LmChallengeResponseBufferOffset;
1552 uint32 NtChallengeResponseBufferOffset;
1553 uint32 EncryptedRandomSessionKeyBufferOffset;
1555 uint8* UserNameBuffer;
1556 uint8* DomainNameBuffer;
1557 uint8* WorkstationBuffer;
1558 uint8* EncryptedRandomSessionKeyBuffer;
1560 WorkstationLen = ntlmssp->workstation.length;
1561 WorkstationBuffer = ntlmssp->workstation.data;
1563 if (ntlmssp->ntlm_v2 < 1)
1566 DomainNameLen = ntlmssp->domain.length;
1567 DomainNameBuffer = ntlmssp->domain.data;
1569 UserNameLen = ntlmssp->username.length;
1570 UserNameBuffer = ntlmssp->username.data;
1572 LmChallengeResponseLen = ntlmssp->lm_challenge_response.length;
1573 NtChallengeResponseLen = ntlmssp->nt_challenge_response.length;
1575 EncryptedRandomSessionKeyLen = 16;
1576 EncryptedRandomSessionKeyBuffer = ntlmssp->encrypted_random_session_key;
1578 if (ntlmssp->ntlm_v2)
1580 /* observed: 35 82 88 e2 (0xE2888235) */
1581 negotiateFlags |= NTLMSSP_NEGOTIATE_56;
1582 negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1583 negotiateFlags |= NTLMSSP_NEGOTIATE_128;
1584 negotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
1585 negotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
1586 negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
1587 negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
1588 negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
1589 negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
1590 negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
1591 negotiateFlags |= NTLMSSP_REQUEST_TARGET;
1592 negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
1596 negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
1597 negotiateFlags |= NTLMSSP_NEGOTIATE_128;
1598 negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
1599 negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
1600 negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
1601 negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
1602 negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
1603 negotiateFlags |= NTLMSSP_REQUEST_TARGET;
1604 negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
1607 if (ntlmssp->ntlm_v2)
1608 PayloadBufferOffset = 80; /* starting buffer offset */
1610 PayloadBufferOffset = 64; /* starting buffer offset */
1612 if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
1613 PayloadBufferOffset += 8;
1615 DomainNameBufferOffset = PayloadBufferOffset;
1616 UserNameBufferOffset = DomainNameBufferOffset + DomainNameLen;
1617 WorkstationBufferOffset = UserNameBufferOffset + UserNameLen;
1618 LmChallengeResponseBufferOffset = WorkstationBufferOffset + WorkstationLen;
1619 NtChallengeResponseBufferOffset = LmChallengeResponseBufferOffset + LmChallengeResponseLen;
1620 EncryptedRandomSessionKeyBufferOffset = NtChallengeResponseBufferOffset + NtChallengeResponseLen;
1622 stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */
1623 stream_write_uint32(s, 3); /* MessageType */
1625 /* LmChallengeResponseFields (8 bytes) */
1626 stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseLen */
1627 stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseMaxLen */
1628 stream_write_uint32(s, LmChallengeResponseBufferOffset); /* LmChallengeResponseBufferOffset */
1630 /* NtChallengeResponseFields (8 bytes) */
1631 stream_write_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseLen */
1632 stream_write_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseMaxLen */
1633 stream_write_uint32(s, NtChallengeResponseBufferOffset); /* NtChallengeResponseBufferOffset */
1635 /* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
1637 /* DomainNameFields (8 bytes) */
1638 stream_write_uint16(s, DomainNameLen); /* DomainNameLen */
1639 stream_write_uint16(s, DomainNameLen); /* DomainNameMaxLen */
1640 stream_write_uint32(s, DomainNameBufferOffset); /* DomainNameBufferOffset */
1642 /* UserNameFields (8 bytes) */
1643 stream_write_uint16(s, UserNameLen); /* UserNameLen */
1644 stream_write_uint16(s, UserNameLen); /* UserNameMaxLen */
1645 stream_write_uint32(s, UserNameBufferOffset); /* UserNameBufferOffset */
1647 /* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
1649 /* WorkstationFields (8 bytes) */
1650 stream_write_uint16(s, WorkstationLen); /* WorkstationLen */
1651 stream_write_uint16(s, WorkstationLen); /* WorkstationMaxLen */
1652 stream_write_uint32(s, WorkstationBufferOffset); /* WorkstationBufferOffset */
1654 /* EncryptedRandomSessionKeyFields (8 bytes) */
1655 stream_write_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyLen */
1656 stream_write_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyMaxLen */
1657 stream_write_uint32(s, EncryptedRandomSessionKeyBufferOffset); /* EncryptedRandomSessionKeyBufferOffset */
1659 ntlmssp_output_negotiate_flags(s, negotiateFlags); /* NegotiateFlags (4 bytes) */
1661 #ifdef WITH_DEBUG_NLA
1662 ntlmssp_print_negotiate_flags(negotiateFlags);
1665 if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
1667 /* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
1668 ntlmssp_output_version(s);
1670 #ifdef WITH_DEBUG_NLA
1671 printf("Version (length = 8)\n");
1672 freerdp_hexdump((s->p - 8), 8);
1677 if (ntlmssp->ntlm_v2)
1679 /* Message Integrity Check */
1681 stream_write_zero(s, 16);
1685 if (DomainNameLen > 0)
1687 stream_write(s, DomainNameBuffer, DomainNameLen);
1688 #ifdef WITH_DEBUG_NLA
1689 printf("DomainName (length = %d, offset = %d)\n", DomainNameLen, DomainNameBufferOffset);
1690 freerdp_hexdump(DomainNameBuffer, DomainNameLen);
1696 stream_write(s, UserNameBuffer, UserNameLen);
1698 #ifdef WITH_DEBUG_NLA
1699 printf("UserName (length = %d, offset = %d)\n", UserNameLen, UserNameBufferOffset);
1700 freerdp_hexdump(UserNameBuffer, UserNameLen);
1705 if (WorkstationLen > 0)
1707 stream_write(s, WorkstationBuffer, WorkstationLen);
1708 #ifdef WITH_DEBUG_NLA
1709 printf("Workstation (length = %d, offset = %d)\n", WorkstationLen, WorkstationBufferOffset);
1710 freerdp_hexdump(WorkstationBuffer, WorkstationLen);
1715 /* LmChallengeResponse */
1716 stream_write(s, ntlmssp->lm_challenge_response.data, LmChallengeResponseLen);
1718 #ifdef WITH_DEBUG_NLA
1719 printf("LmChallengeResponse (length = %d, offset = %d)\n", LmChallengeResponseLen, LmChallengeResponseBufferOffset);
1720 freerdp_hexdump(ntlmssp->lm_challenge_response.data, LmChallengeResponseLen);
1724 /* NtChallengeResponse */
1725 stream_write(s, ntlmssp->nt_challenge_response.data, NtChallengeResponseLen);
1727 #ifdef WITH_DEBUG_NLA
1728 if (ntlmssp->ntlm_v2)
1730 ntlmssp_print_av_pairs(ntlmssp);
1732 printf("targetInfo (length = %d)\n", ntlmssp->target_info.length);
1733 freerdp_hexdump(ntlmssp->target_info.data, ntlmssp->target_info.length);
1738 #ifdef WITH_DEBUG_NLA
1739 printf("NtChallengeResponse (length = %d, offset = %d)\n", NtChallengeResponseLen, NtChallengeResponseBufferOffset);
1740 freerdp_hexdump(ntlmssp->nt_challenge_response.data, NtChallengeResponseLen);
1744 /* EncryptedRandomSessionKey */
1745 stream_write(s, EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen);
1747 #ifdef WITH_DEBUG_NLA
1748 printf("EncryptedRandomSessionKey (length = %d, offset = %d)\n", EncryptedRandomSessionKeyLen, EncryptedRandomSessionKeyBufferOffset);
1749 freerdp_hexdump(EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen);
1753 length = s->p - s->data;
1754 freerdp_blob_alloc(&ntlmssp->authenticate_message, length);
1755 memcpy(ntlmssp->authenticate_message.data, s->data, length);
1757 if (ntlmssp->ntlm_v2)
1759 /* Message Integrity Check */
1760 ntlmssp_compute_message_integrity_check(ntlmssp);
1763 stream_write(s, ntlmssp->message_integrity_check, 16);
1764 s->p = s->data + length;
1766 #ifdef WITH_DEBUG_NLA
1767 printf("MessageIntegrityCheck (length = 16)\n");
1768 freerdp_hexdump(mic_offset, 16);
1773 #ifdef WITH_DEBUG_NLA
1774 printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
1775 freerdp_hexdump(s->data, length);
1779 ntlmssp->state = NTLMSSP_STATE_FINAL;
1783 * Send NTLMSSP message.
1789 int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s)
1791 if (ntlmssp->state == NTLMSSP_STATE_INITIAL)
1792 ntlmssp->state = NTLMSSP_STATE_NEGOTIATE;
1794 if (ntlmssp->state == NTLMSSP_STATE_NEGOTIATE)
1795 ntlmssp_send_negotiate_message(ntlmssp, s);
1796 else if (ntlmssp->state == NTLMSSP_STATE_AUTHENTICATE)
1797 ntlmssp_send_authenticate_message(ntlmssp, s);
1799 return (ntlmssp->state == NTLMSSP_STATE_FINAL) ? 0 : 1;
1803 * Receive NTLMSSP message.
1809 int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s)
1811 char signature[8]; /* Signature, "NTLMSSP" */
1812 uint32 messageType; /* MessageType */
1814 stream_read(s, signature, 8);
1815 stream_read_uint32(s, messageType);
1817 if (messageType == 2 && ntlmssp->state == NTLMSSP_STATE_CHALLENGE)
1818 ntlmssp_recv_challenge_message(ntlmssp, s);
1824 * Create new NTLMSSP state machine instance.
1828 NTLMSSP* ntlmssp_new()
1830 NTLMSSP* ntlmssp = (NTLMSSP*) xmalloc(sizeof(NTLMSSP));
1832 if (ntlmssp != NULL)
1834 memset(ntlmssp, '\0', sizeof(NTLMSSP));
1835 ntlmssp->av_pairs = (AV_PAIRS*) xmalloc(sizeof(AV_PAIRS));
1836 memset(ntlmssp->av_pairs, 0, sizeof(AV_PAIRS));
1837 ntlmssp_init(ntlmssp);
1844 * Initialize NTLMSSP state machine.
1848 void ntlmssp_init(NTLMSSP* ntlmssp)
1850 ntlmssp->state = NTLMSSP_STATE_INITIAL;
1851 ntlmssp->uniconv = freerdp_uniconv_new();
1855 * Finalize NTLMSSP state machine.
1859 void ntlmssp_uninit(NTLMSSP* ntlmssp)
1861 freerdp_blob_free(&ntlmssp->username);
1862 freerdp_blob_free(&ntlmssp->password);
1863 freerdp_blob_free(&ntlmssp->domain);
1865 freerdp_blob_free(&ntlmssp->spn);
1866 freerdp_blob_free(&ntlmssp->workstation);
1867 freerdp_blob_free(&ntlmssp->target_info);
1868 freerdp_blob_free(&ntlmssp->target_name);
1870 freerdp_blob_free(&ntlmssp->negotiate_message);
1871 freerdp_blob_free(&ntlmssp->challenge_message);
1872 freerdp_blob_free(&ntlmssp->authenticate_message);
1874 freerdp_blob_free(&ntlmssp->lm_challenge_response);
1875 freerdp_blob_free(&ntlmssp->nt_challenge_response);
1877 ntlmssp_free_av_pairs(ntlmssp);
1878 freerdp_uniconv_free(ntlmssp->uniconv);
1880 ntlmssp->state = NTLMSSP_STATE_FINAL;
1884 * Free NTLMSSP state machine.
1888 void ntlmssp_free(NTLMSSP* ntlmssp)
1890 ntlmssp_uninit(ntlmssp);
1892 if (ntlmssp->send_rc4_seal)
1893 crypto_rc4_free(ntlmssp->send_rc4_seal);
1894 if (ntlmssp->recv_rc4_seal)
1895 crypto_rc4_free(ntlmssp->recv_rc4_seal);