107
110
#define CHECK(f, e) \
108
do { ret = f ; if (ret != (e)) { ret = EINVAL; goto out; } } while(0)
112
ret = f ; if (ret != (e)) { ret = HNTLM_ERR_DECODE; goto out; } } \
115
static struct units ntlm_flag_units[] = {
116
#define ntlm_flag(x) { #x, NTLM_##x }
118
ntlm_flag(NEG_KEYEX),
123
ntlm_flag(NEG_VERSION),
125
ntlm_flag(NEG_TARGET_INFO),
126
ntlm_flag(NON_NT_SESSION_KEY),
128
ntlm_flag(NEG_IDENTIFY),
129
ntlm_flag(NEG_NTLM2),
130
ntlm_flag(TARGET_SHARE),
131
ntlm_flag(TARGET_SERVER),
132
ntlm_flag(TARGET_DOMAIN),
133
ntlm_flag(NEG_ALWAYS_SIGN),
135
ntlm_flag(OEM_SUPPLIED_WORKSTATION),
136
ntlm_flag(OEM_SUPPLIED_DOMAIN),
137
ntlm_flag(NEG_ANONYMOUS),
138
ntlm_flag(NEG_NT_ONLY),
141
ntlm_flag(NEG_LM_KEY),
142
ntlm_flag(NEG_DATAGRAM),
146
ntlm_flag(NEG_TARGET),
148
ntlm_flag(NEG_UNICODE),
154
heim_ntlm_unparse_flags(uint32_t flags, char *s, size_t len)
156
return unparse_flags(flags, ntlm_flag_units, s, len);
111
161
* heim_ntlm_free_buf frees the ntlm buffer
200
254
static krb5_error_code
201
ret_string(krb5_storage *sp, int ucs2, struct sec_buffer *desc, char **s)
255
ret_string(krb5_storage *sp, int ucs2, size_t len, char **s)
203
257
krb5_error_code ret;
205
*s = malloc(desc->length + 1);
206
CHECK(krb5_storage_seek(sp, desc->offset, SEEK_SET), desc->offset);
207
CHECK(krb5_storage_read(sp, *s, desc->length), desc->length);
208
(*s)[desc->length] = '\0';
259
*s = malloc(len + 1);
262
CHECK(krb5_storage_read(sp, *s, len), len);
212
for (i = 0; i < desc->length / 2; i++) {
268
for (i = 0; i < len / 2; i++) {
213
269
(*s)[i] = (*s)[i * 2];
214
270
if ((*s)[i * 2 + 1]) {
405
krb5_storage_set_byteorder(out, KRB5_STORAGE_BYTEORDER_LE);
338
407
if (ti->servername)
339
CHECK(encode_ti_blob(out, 1, ucs2, ti->servername), 0);
408
CHECK(encode_ti_string(out, 1, ucs2, ti->servername), 0);
340
409
if (ti->domainname)
341
CHECK(encode_ti_blob(out, 2, ucs2, ti->domainname), 0);
410
CHECK(encode_ti_string(out, 2, ucs2, ti->domainname), 0);
342
411
if (ti->dnsservername)
343
CHECK(encode_ti_blob(out, 3, ucs2, ti->dnsservername), 0);
412
CHECK(encode_ti_string(out, 3, ucs2, ti->dnsservername), 0);
344
413
if (ti->dnsdomainname)
345
CHECK(encode_ti_blob(out, 4, ucs2, ti->dnsdomainname), 0);
414
CHECK(encode_ti_string(out, 4, ucs2, ti->dnsdomainname), 0);
416
CHECK(encode_ti_string(out, 5, ucs2, ti->dnstreename), 0);
418
CHECK(krb5_store_uint16(out, 6), 0);
419
CHECK(krb5_store_uint16(out, 4), 0);
420
CHECK(krb5_store_uint32(out, ti->avflags), 0);
348
424
CHECK(krb5_store_int16(out, 0), 0);
378
454
struct ntlm_targetinfo *ti)
458
int ret = 0, done = 0;
380
460
memset(ti, 0, sizeof(*ti));
462
if (data->length == 0)
465
in = krb5_storage_from_readonly_mem(data->data, data->length);
468
krb5_storage_set_byteorder(in, KRB5_STORAGE_BYTEORDER_LE);
471
CHECK(krb5_ret_uint16(in, &type), 0);
472
CHECK(krb5_ret_uint16(in, &len), 0);
479
CHECK(ret_string(in, ucs2, len, &ti->servername), 0);
482
CHECK(ret_string(in, ucs2, len, &ti->domainname), 0);
485
CHECK(ret_string(in, ucs2, len, &ti->dnsservername), 0);
488
CHECK(ret_string(in, ucs2, len, &ti->dnsdomainname), 0);
491
CHECK(ret_string(in, ucs2, len, &ti->dnstreename), 0);
494
CHECK(krb5_ret_uint32(in, &ti->avflags), 0);
497
krb5_storage_seek(in, len, SEEK_CUR);
503
krb5_storage_free(in);
422
545
CHECK(krb5_ret_uint32(in, &type), 0);
424
547
CHECK(krb5_ret_uint32(in, &data->flags), 0);
425
if (data->flags & NTLM_SUPPLIED_DOMAIN)
548
if (data->flags & NTLM_OEM_SUPPLIED_DOMAIN)
426
549
CHECK(ret_sec_buffer(in, &domain), 0);
427
if (data->flags & NTLM_SUPPLIED_WORKSTAION)
550
if (data->flags & NTLM_OEM_SUPPLIED_WORKSTATION)
428
551
CHECK(ret_sec_buffer(in, &hostname), 0);
430
553
if (domain.offset > 32) {
432
555
CHECK(krb5_ret_uint32(in, &data->os[1]), 0);
435
if (data->flags & NTLM_SUPPLIED_DOMAIN)
436
CHECK(ret_string(in, 0, &domain, &data->domain), 0);
437
if (data->flags & NTLM_SUPPLIED_WORKSTAION)
438
CHECK(ret_string(in, 0, &hostname, &data->hostname), 0);
558
if (data->flags & NTLM_OEM_SUPPLIED_DOMAIN)
559
CHECK(ret_sec_string(in, 0, &domain, &data->domain), 0);
560
if (data->flags & NTLM_OEM_SUPPLIED_WORKSTATION)
561
CHECK(ret_sec_string(in, 0, &hostname, &data->hostname), 0);
473
596
if (type1->domain) {
475
flags |= NTLM_SUPPLIED_DOMAIN;
598
flags |= NTLM_OEM_SUPPLIED_DOMAIN;
477
600
if (type1->hostname) {
479
flags |= NTLM_SUPPLIED_WORKSTAION;
602
flags |= NTLM_OEM_SUPPLIED_WORKSTATION;
481
604
if (type1->os[0])
607
domain.offset = base;
484
608
if (type1->domain) {
485
domain.offset = base;
486
609
domain.length = len_string(0, type1->domain);
487
610
domain.allocated = domain.length;
613
domain.allocated = 0;
616
hostname.offset = domain.allocated + domain.offset;
489
617
if (type1->hostname) {
490
hostname.offset = domain.allocated + domain.offset;
491
618
hostname.length = len_string(0, type1->hostname);
492
619
hostname.allocated = hostname.length;
622
hostname.allocated = 0;
495
625
out = krb5_storage_emem();
502
632
CHECK(krb5_store_uint32(out, 1), 0);
503
633
CHECK(krb5_store_uint32(out, flags), 0);
506
CHECK(store_sec_buffer(out, &domain), 0);
508
CHECK(store_sec_buffer(out, &hostname), 0);
635
CHECK(store_sec_buffer(out, &domain), 0);
636
CHECK(store_sec_buffer(out, &hostname), 0);
510
638
CHECK(krb5_store_uint32(out, type1->os[0]), 0);
511
639
CHECK(krb5_store_uint32(out, type1->os[1]), 0);
513
641
if (type1->domain)
514
642
CHECK(put_string(out, 0, type1->domain), 0);
515
643
if (type1->hostname)
572
700
CHECK(krb5_ret_uint32(in, &type2->flags), 0);
573
701
if (type2->flags & NTLM_NEG_UNICODE)
575
CHECK(krb5_storage_read(in, type2->challange, sizeof(type2->challange)),
576
sizeof(type2->challange));
703
CHECK(krb5_storage_read(in, type2->challenge, sizeof(type2->challenge)),
704
sizeof(type2->challenge));
577
705
CHECK(krb5_ret_uint32(in, &ctx[0]), 0); /* context */
578
706
CHECK(krb5_ret_uint32(in, &ctx[1]), 0);
579
707
CHECK(ret_sec_buffer(in, &targetinfo), 0);
582
CHECK(krb5_ret_uint32(in, &type2->os[0]), 0);
583
CHECK(krb5_ret_uint32(in, &type2->os[1]), 0);
709
if (type2->flags & NTLM_NEG_VERSION) {
710
CHECK(krb5_ret_uint32(in, &type2->os[0]), 0);
711
CHECK(krb5_ret_uint32(in, &type2->os[1]), 0);
586
CHECK(ret_string(in, ucs2, &targetname, &type2->targetname), 0);
714
CHECK(ret_sec_string(in, ucs2, &targetname, &type2->targetname), 0);
587
715
CHECK(ret_buf(in, &targetinfo, &type2->targetinfo), 0);
644
772
CHECK(krb5_store_uint32(out, 2), 0);
645
773
CHECK(store_sec_buffer(out, &targetname), 0);
646
774
CHECK(krb5_store_uint32(out, type2->flags), 0);
647
CHECK(krb5_storage_write(out, type2->challange, sizeof(type2->challange)),
648
sizeof(type2->challange));
775
CHECK(krb5_storage_write(out, type2->challenge, sizeof(type2->challenge)),
776
sizeof(type2->challenge));
649
777
CHECK(krb5_store_uint32(out, 0), 0); /* context */
650
778
CHECK(krb5_store_uint32(out, 0), 0);
651
779
CHECK(store_sec_buffer(out, &targetinfo), 0);
781
if (type2->flags & NTLM_NEG_VERSION) {
654
782
CHECK(krb5_store_uint32(out, type2->os[0]), 0);
655
783
CHECK(krb5_store_uint32(out, type2->os[1]), 0);
725
854
CHECK(krb5_ret_uint32(in, &type), 0);
727
856
CHECK(ret_sec_buffer(in, &lm), 0);
858
min_offset = min(min_offset, lm.offset);
728
859
CHECK(ret_sec_buffer(in, &ntlm), 0);
861
min_offset = min(min_offset, ntlm.offset);
729
862
CHECK(ret_sec_buffer(in, &target), 0);
863
if (target.allocated)
864
min_offset = min(min_offset, target.offset);
730
865
CHECK(ret_sec_buffer(in, &username), 0);
866
if (username.allocated)
867
min_offset = min(min_offset, username.offset);
731
868
CHECK(ret_sec_buffer(in, &ws), 0);
732
if (lm.offset >= 60) {
870
min_offset = min(min_offset, ws.offset);
872
if (min_offset > 52) {
733
873
CHECK(ret_sec_buffer(in, &sessionkey), 0);
735
if (lm.offset >= 64) {
874
min_offset = max(min_offset, sessionkey.offset);
736
875
CHECK(krb5_ret_uint32(in, &type3->flags), 0);
738
if (lm.offset >= 72) {
877
if (min_offset > 52 + 8 + 4 + 8) {
739
878
CHECK(krb5_ret_uint32(in, &type3->os[0]), 0);
740
879
CHECK(krb5_ret_uint32(in, &type3->os[1]), 0);
742
881
CHECK(ret_buf(in, &lm, &type3->lm), 0);
743
882
CHECK(ret_buf(in, &ntlm, &type3->ntlm), 0);
744
CHECK(ret_string(in, ucs2, &target, &type3->targetname), 0);
745
CHECK(ret_string(in, ucs2, &username, &type3->username), 0);
746
CHECK(ret_string(in, ucs2, &ws, &type3->ws), 0);
883
CHECK(ret_sec_string(in, ucs2, &target, &type3->targetname), 0);
884
CHECK(ret_sec_string(in, ucs2, &username, &type3->username), 0);
885
CHECK(ret_sec_string(in, ucs2, &ws, &type3->ws), 0);
747
886
if (sessionkey.offset)
748
887
CHECK(ret_buf(in, &sessionkey, &type3->sessionkey), 0);
817
948
ws.length = len_string(ucs2, type3->ws);
818
949
ws.allocated = ws.length;
820
sessionkey.offset = ws.offset + ws.allocated;
951
lm.offset = ws.offset + ws.allocated;
952
lm.length = type3->lm.length;
953
lm.allocated = type3->lm.length;
955
ntlm.offset = lm.offset + lm.allocated;
956
ntlm.length = type3->ntlm.length;
957
ntlm.allocated = ntlm.length;
959
sessionkey.offset = ntlm.offset + ntlm.allocated;
821
960
sessionkey.length = type3->sessionkey.length;
822
961
sessionkey.allocated = type3->sessionkey.length;
835
974
CHECK(store_sec_buffer(out, &target), 0);
836
975
CHECK(store_sec_buffer(out, &username), 0);
837
976
CHECK(store_sec_buffer(out, &ws), 0);
839
if (type3->sessionkey.length) {
840
CHECK(store_sec_buffer(out, &sessionkey), 0);
841
CHECK(krb5_store_uint32(out, type3->flags), 0);
977
CHECK(store_sec_buffer(out, &sessionkey), 0);
978
CHECK(krb5_store_uint32(out, type3->flags), 0);
844
981
CHECK(krb5_store_uint32(out, 0), 0); /* os0 */
845
982
CHECK(krb5_store_uint32(out, 0), 0); /* os1 */
848
CHECK(put_buf(out, &type3->lm), 0);
849
CHECK(put_buf(out, &type3->ntlm), 0);
850
985
CHECK(put_string(out, ucs2, type3->targetname), 0);
851
986
CHECK(put_string(out, ucs2, type3->username), 0);
852
987
CHECK(put_string(out, ucs2, type3->ws), 0);
988
CHECK(put_buf(out, &type3->lm), 0);
989
CHECK(put_buf(out, &type3->ntlm), 0);
853
990
CHECK(put_buf(out, &type3->sessionkey), 0);
874
1011
splitandenc(unsigned char *hash,
875
unsigned char *challange,
1012
unsigned char *challenge,
876
1013
unsigned char *answer)
879
DES_key_schedule sched;
881
((unsigned char*)key)[0] = hash[0];
882
((unsigned char*)key)[1] = (hash[0] << 7) | (hash[1] >> 1);
883
((unsigned char*)key)[2] = (hash[1] << 6) | (hash[2] >> 2);
884
((unsigned char*)key)[3] = (hash[2] << 5) | (hash[3] >> 3);
885
((unsigned char*)key)[4] = (hash[3] << 4) | (hash[4] >> 4);
886
((unsigned char*)key)[5] = (hash[4] << 3) | (hash[5] >> 5);
887
((unsigned char*)key)[6] = (hash[5] << 2) | (hash[6] >> 6);
888
((unsigned char*)key)[7] = (hash[6] << 1);
890
DES_set_odd_parity(&key);
891
DES_set_key_unchecked(&key, &sched);
892
DES_ecb_encrypt((DES_cblock *)challange, (DES_cblock *)answer, &sched, 1);
893
memset(&sched, 0, sizeof(sched));
1016
unsigned char key[8];
1019
key[1] = (hash[0] << 7) | (hash[1] >> 1);
1020
key[2] = (hash[1] << 6) | (hash[2] >> 2);
1021
key[3] = (hash[2] << 5) | (hash[3] >> 3);
1022
key[4] = (hash[3] << 4) | (hash[4] >> 4);
1023
key[5] = (hash[4] << 3) | (hash[5] >> 5);
1024
key[6] = (hash[5] << 2) | (hash[6] >> 6);
1025
key[7] = (hash[6] << 1);
1027
EVP_CIPHER_CTX_init(&ctx);
1029
EVP_CipherInit_ex(&ctx, EVP_des_cbc(), NULL, key, NULL, 1);
1030
EVP_Cipher(&ctx, answer, challenge, 8);
1031
EVP_CIPHER_CTX_cleanup(&ctx);
894
1032
memset(key, 0, sizeof(key));
963
1111
answer->length = 24;
965
splitandenc(&res[0], challange, ((unsigned char *)answer->data) + 0);
966
splitandenc(&res[7], challange, ((unsigned char *)answer->data) + 8);
967
splitandenc(&res[14], challange, ((unsigned char *)answer->data) + 16);
1113
splitandenc(&res[0], challenge, ((unsigned char *)answer->data) + 0);
1114
splitandenc(&res[7], challenge, ((unsigned char *)answer->data) + 8);
1115
splitandenc(&res[14], challenge, ((unsigned char *)answer->data) + 16);
1121
heim_ntlm_v1_base_session(void *key, size_t len,
1122
struct ntlm_buf *session)
1126
session->length = MD4_DIGEST_LENGTH;
1127
session->data = malloc(session->length);
1128
if (session->data == NULL) {
1129
session->length = 0;
1133
m = EVP_MD_CTX_create();
1135
heim_ntlm_free_buf(session);
1138
EVP_DigestInit_ex(m, EVP_md4(), NULL);
1139
EVP_DigestUpdate(m, key, len);
1140
EVP_DigestFinal_ex(m, session->data, NULL);
1141
EVP_MD_CTX_destroy(m);
1147
heim_ntlm_v2_base_session(void *key, size_t len,
1148
struct ntlm_buf *ntlmResponse,
1149
struct ntlm_buf *session)
1151
unsigned int hmaclen;
1154
if (ntlmResponse->length <= 16)
1155
return HNTLM_ERR_INVALID_LENGTH;
1157
session->data = malloc(16);
1158
if (session->data == NULL)
1160
session->length = 16;
1162
/* Note: key is the NTLMv2 key */
1164
HMAC_Init_ex(&c, key, len, EVP_md5(), NULL);
1165
HMAC_Update(&c, ntlmResponse->data, 16);
1166
HMAC_Final(&c, session->data, &hmaclen);
1167
HMAC_CTX_cleanup(&c);
1174
heim_ntlm_keyex_wrap(struct ntlm_buf *base_session,
1175
struct ntlm_buf *session,
1176
struct ntlm_buf *encryptedSession)
1181
session->length = MD4_DIGEST_LENGTH;
1182
session->data = malloc(session->length);
1183
if (session->data == NULL) {
1184
session->length = 0;
1187
encryptedSession->length = MD4_DIGEST_LENGTH;
1188
encryptedSession->data = malloc(encryptedSession->length);
1189
if (encryptedSession->data == NULL) {
1190
heim_ntlm_free_buf(session);
1191
encryptedSession->length = 0;
1195
EVP_CIPHER_CTX_init(&c);
1197
ret = EVP_CipherInit_ex(&c, EVP_rc4(), NULL, base_session->data, NULL, 1);
1199
EVP_CIPHER_CTX_cleanup(&c);
1200
heim_ntlm_free_buf(encryptedSession);
1201
heim_ntlm_free_buf(session);
1202
return HNTLM_ERR_CRYPTO;
1205
if (RAND_bytes(session->data, session->length) != 1) {
1206
EVP_CIPHER_CTX_cleanup(&c);
1207
heim_ntlm_free_buf(encryptedSession);
1208
heim_ntlm_free_buf(session);
1209
return HNTLM_ERR_RAND;
1212
EVP_Cipher(&c, encryptedSession->data, session->data, encryptedSession->length);
1213
EVP_CIPHER_CTX_cleanup(&c);
973
1224
* Generates an NTLMv1 session random with assosited session master key.
988
1239
struct ntlm_buf *session,
989
1240
struct ntlm_buf *master)
993
memset(master, 0, sizeof(*master));
1242
struct ntlm_buf sess;
1245
ret = heim_ntlm_v1_base_session(key, len, &sess);
1249
ret = heim_ntlm_keyex_wrap(&sess, session, master);
1250
heim_ntlm_free_buf(&sess);
1256
* Generates an NTLMv2 session random with associated session master key.
1258
* @param key the NTLMv2 key
1259
* @param len length of key
1260
* @param blob the NTLMv2 "blob"
1261
* @param session generated session nonce, should be freed with heim_ntlm_free_buf().
1262
* @param master calculated session master key, should be freed with heim_ntlm_free_buf().
1264
* @return In case of success 0 is return, an errors, a errno in what
1267
* @ingroup ntlm_core
1272
heim_ntlm_build_ntlm2_master(void *key, size_t len,
1273
struct ntlm_buf *blob,
1274
struct ntlm_buf *session,
1275
struct ntlm_buf *master)
1277
struct ntlm_buf sess;
1280
ret = heim_ntlm_v2_base_session(key, len, blob, &sess);
1284
ret = heim_ntlm_keyex_wrap(&sess, session, master);
1285
heim_ntlm_free_buf(&sess);
1291
* Given a key and encrypted session, unwrap the session key
1293
* @param baseKey the sessionBaseKey
1294
* @param encryptedSession encrypted session, type3.session field.
1295
* @param session generated session nonce, should be freed with heim_ntlm_free_buf().
1297
* @return In case of success 0 is return, an errors, a errno in what
1300
* @ingroup ntlm_core
1304
heim_ntlm_keyex_unwrap(struct ntlm_buf *baseKey,
1305
struct ntlm_buf *encryptedSession,
1306
struct ntlm_buf *session)
994
1310
memset(session, 0, sizeof(*session));
996
if (len != MD4_DIGEST_LENGTH)
1312
if (baseKey->length != MD4_DIGEST_LENGTH)
1313
return HNTLM_ERR_INVALID_LENGTH;
999
1315
session->length = MD4_DIGEST_LENGTH;
1000
1316
session->data = malloc(session->length);
1001
1317
if (session->data == NULL) {
1002
1318
session->length = 0;
1005
master->length = MD4_DIGEST_LENGTH;
1006
master->data = malloc(master->length);
1007
if (master->data == NULL) {
1008
heim_ntlm_free_buf(master);
1009
heim_ntlm_free_buf(session);
1014
unsigned char sessionkey[MD4_DIGEST_LENGTH];
1018
MD4_Update(&ctx, key, len);
1019
MD4_Final(sessionkey, &ctx);
1021
RC4_set_key(&rc4, sizeof(sessionkey), sessionkey);
1024
if (RAND_bytes(session->data, session->length) != 1) {
1025
heim_ntlm_free_buf(master);
1026
heim_ntlm_free_buf(session);
1030
RC4(&rc4, master->length, session->data, master->data);
1031
memset(&rc4, 0, sizeof(rc4));
1321
EVP_CIPHER_CTX_init(&c);
1323
if (EVP_CipherInit_ex(&c, EVP_rc4(), NULL, baseKey->data, NULL, 0) != 1) {
1324
EVP_CIPHER_CTX_cleanup(&c);
1325
heim_ntlm_free_buf(session);
1326
return HNTLM_ERR_CRYPTO;
1329
EVP_Cipher(&c, session->data, encryptedSession->data, session->length);
1330
EVP_CIPHER_CTX_cleanup(&c);
1037
1337
* Generates an NTLMv2 session key.
1104
1404
return (time_t)t;
1408
* Calculate LMv2 response
1410
* @param key the ntlm key
1411
* @param len length of key
1412
* @param username name of the user, as sent in the message, assumed to be in UTF8.
1413
* @param target the name of the target, assumed to be in UTF8.
1414
* @param serverchallenge challenge as sent by the server in the type2 message.
1415
* @param ntlmv2 calculated session key
1416
* @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
1418
* @return In case of success 0 is return, an errors, a errno in what
1421
* @ingroup ntlm_core
1425
heim_ntlm_calculate_lm2(const void *key, size_t len,
1426
const char *username,
1428
const unsigned char serverchallenge[8],
1429
unsigned char ntlmv2[16],
1430
struct ntlm_buf *answer)
1432
unsigned char clientchallenge[8];
1434
if (RAND_bytes(clientchallenge, sizeof(clientchallenge)) != 1)
1435
return HNTLM_ERR_RAND;
1437
/* calculate ntlmv2 key */
1439
heim_ntlm_ntlmv2_key(key, len, username, target, ntlmv2);
1441
answer->data = malloc(24);
1442
if (answer->data == NULL)
1444
answer->length = 24;
1446
heim_ntlm_derive_ntlm2_sess(ntlmv2, clientchallenge, 8,
1447
serverchallenge, answer->data);
1449
memcpy(((uint8_t *)answer->data) + 16, clientchallenge, 8);
1109
1456
* Calculate NTLMv2 response
1127
1474
heim_ntlm_calculate_ntlm2(const void *key, size_t len,
1128
1475
const char *username,
1129
1476
const char *target,
1130
const unsigned char serverchallange[8],
1477
const unsigned char serverchallenge[8],
1131
1478
const struct ntlm_buf *infotarget,
1132
1479
unsigned char ntlmv2[16],
1133
1480
struct ntlm_buf *answer)
1135
1482
krb5_error_code ret;
1136
1483
krb5_data data;
1137
unsigned int hmaclen;
1138
1484
unsigned char ntlmv2answer[16];
1139
1485
krb5_storage *sp;
1140
unsigned char clientchallange[8];
1486
unsigned char clientchallenge[8];
1144
1489
t = unix2nttime(time(NULL));
1146
if (RAND_bytes(clientchallange, sizeof(clientchallange)) != 1)
1491
if (RAND_bytes(clientchallenge, sizeof(clientchallenge)) != 1)
1492
return HNTLM_ERR_RAND;
1149
1494
/* calculate ntlmv2 key */
1163
1508
CHECK(krb5_store_uint32(sp, t & 0xffffffff), 0);
1164
1509
CHECK(krb5_store_uint32(sp, t >> 32), 0);
1166
CHECK(krb5_storage_write(sp, clientchallange, 8), 8);
1511
CHECK(krb5_storage_write(sp, clientchallenge, 8), 8);
1168
1513
CHECK(krb5_store_uint32(sp, 0), 0); /* unknown but zero will work */
1169
1514
CHECK(krb5_storage_write(sp, infotarget->data, infotarget->length),
1174
1519
krb5_storage_free(sp);
1178
HMAC_Init_ex(&c, ntlmv2, 16, EVP_md5(), NULL);
1179
HMAC_Update(&c, serverchallange, 8);
1180
HMAC_Update(&c, data.data, data.length);
1181
HMAC_Final(&c, ntlmv2answer, &hmaclen);
1182
HMAC_CTX_cleanup(&c);
1522
heim_ntlm_derive_ntlm2_sess(ntlmv2, data.data, data.length, serverchallenge, ntlmv2answer);
1184
1524
sp = krb5_storage_emem();
1185
1525
if (sp == NULL) {
1304
1642
krb5_storage_free(sp);
1308
HMAC_Init_ex(&c, ntlmv2, 16, EVP_md5(), NULL);
1309
HMAC_Update(&c, serverchallange, 8);
1310
HMAC_Update(&c, ((unsigned char *)answer->data) + 16, answer->length - 16);
1311
HMAC_Final(&c, serveranswer, &hmaclen);
1312
HMAC_CTX_cleanup(&c);
1645
if (answer->length < 16) {
1646
ret = HNTLM_ERR_INVALID_LENGTH;
1650
heim_ntlm_derive_ntlm2_sess(ntlmv2,
1651
((unsigned char *)answer->data) + 16, answer->length - 16,
1314
1655
if (memcmp(serveranswer, clientanswer, 16) != 0) {
1315
1656
heim_ntlm_free_buf(infotarget);
1657
return HNTLM_ERR_AUTH;
1732
* Calculate the NTLM2 Session "Verifier"
1734
* @param clnt_nonce client nonce
1735
* @param svr_chal server challage
1736
* @param hash The NTLM session verifier
1738
* @return In case of success 0 is return, an errors, a errno in what
1741
* @ingroup ntlm_core
1745
heim_ntlm_calculate_ntlm2_sess_hash(const unsigned char clnt_nonce[8],
1746
const unsigned char svr_chal[8],
1747
unsigned char verifier[8])
1749
unsigned char ntlm2_sess_hash[MD5_DIGEST_LENGTH];
1752
m = EVP_MD_CTX_create();
1756
EVP_DigestInit_ex(m, EVP_md5(), NULL);
1757
EVP_DigestUpdate(m, svr_chal, 8); /* session nonce part 1 */
1758
EVP_DigestUpdate(m, clnt_nonce, 8); /* session nonce part 2 */
1759
EVP_DigestFinal_ex(m, ntlm2_sess_hash, NULL); /* will only use first 8 bytes */
1760
EVP_MD_CTX_destroy(m);
1762
memcpy(verifier, ntlm2_sess_hash, 8);
1769
* Derive a NTLM2 session key
1771
* @param sessionkey session key from domain controller
1772
* @param clnt_nonce client nonce
1773
* @param svr_chal server challenge
1774
* @param derivedkey salted session key
1776
* @return In case of success 0 is return, an errors, a errno in what
1779
* @ingroup ntlm_core
1783
heim_ntlm_derive_ntlm2_sess(const unsigned char sessionkey[16],
1784
const unsigned char *clnt_nonce, size_t clnt_nonce_length,
1785
const unsigned char svr_chal[8],
1786
unsigned char derivedkey[16])
1788
unsigned int hmaclen;
1791
/* HMAC(Ksession, serverchallenge || clientchallenge) */
1793
HMAC_Init_ex(&c, sessionkey, 16, EVP_md5(), NULL);
1794
HMAC_Update(&c, svr_chal, 8);
1795
HMAC_Update(&c, clnt_nonce, clnt_nonce_length);
1796
HMAC_Final(&c, derivedkey, &hmaclen);
1797
HMAC_CTX_cleanup(&c);