summaryrefslogtreecommitdiffstats
path: root/src/ntlm_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ntlm_crypto.c')
-rw-r--r--src/ntlm_crypto.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/ntlm_crypto.c b/src/ntlm_crypto.c
index fbfdc41..5bccb39 100644
--- a/src/ntlm_crypto.c
+++ b/src/ntlm_crypto.c
@@ -830,3 +830,41 @@ int ntlm_mic(struct ntlm_key *exported_session_key,
return HMAC_MD5_IOV(&key, &iov, mic);
}
+
+int ntlm_verify_mic(struct ntlm_key *key,
+ struct ntlm_buffer *negotiate_message,
+ struct ntlm_buffer *challenge_message,
+ struct ntlm_buffer *authenticate_message,
+ struct ntlm_buffer *mic)
+{
+ uint8_t micbuf[16];
+ struct ntlm_buffer check_mic = { micbuf, 16 };
+ struct wire_auth_msg *msg;
+ size_t payload_offs;
+ uint32_t flags;
+ int ret;
+
+ msg = (struct wire_auth_msg *)authenticate_message->data;
+ payload_offs = offsetof(struct wire_auth_msg, payload);
+
+ /* flags must be checked as they may push the payload further down */
+ flags = le32toh(msg->neg_flags);
+ if (flags & NTLMSSP_NEGOTIATE_VERSION) {
+ /* skip version for now */
+ payload_offs += sizeof(struct wire_version);
+ }
+
+ if (payload_offs + 16 > authenticate_message->length) return EINVAL;
+
+ /* payload_offs now points at the MIC buffer, clear it off in order
+ * to be able to calculate the original chcksum */
+ memset(&authenticate_message->data[payload_offs], 0, 16);
+
+ ret = ntlm_mic(key, negotiate_message, challenge_message,
+ authenticate_message, &check_mic);
+ if (ret) return ret;
+
+ if (memcmp(mic->data, check_mic.data, 16) != 0) return EACCES;
+
+ return 0;
+}