summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-04-05 15:20:06 -0400
committerSimo Sorce <simo@redhat.com>2014-05-04 17:21:06 -0400
commit6c31661097c7aac2729ed2a5a6e3a8856b5ae15c (patch)
tree4c242ae9c091db40d60581148cf70ca66cf3597b /src
parentc867bc34147832923360c5b6ca6cc35200dfdbe8 (diff)
downloadgss-ntlmssp-6c31661097c7aac2729ed2a5a6e3a8856b5ae15c.tar.gz
gss-ntlmssp-6c31661097c7aac2729ed2a5a6e3a8856b5ae15c.tar.xz
gss-ntlmssp-6c31661097c7aac2729ed2a5a6e3a8856b5ae15c.zip
Add function to verify MICs
Diffstat (limited to 'src')
-rw-r--r--src/ntlm.c46
-rw-r--r--src/ntlm.h20
-rw-r--r--src/ntlm_common.h46
-rw-r--r--src/ntlm_crypto.c38
4 files changed, 104 insertions, 46 deletions
diff --git a/src/ntlm.c b/src/ntlm.c
index 9cb3814..41b21f6 100644
--- a/src/ntlm.c
+++ b/src/ntlm.c
@@ -36,25 +36,6 @@
#include "ntlm.h"
#pragma pack(push, 1)
-struct wire_msg_hdr {
- uint8_t signature[8];
- uint32_t msg_type;
-};
-#pragma pack(pop)
-
-/* A wire string, the offset is relative to the mesage and must fall into the
- * payload section.
- * max_len should be set equal to len and ignored by servers.
- */
-#pragma pack(push, 1)
-struct wire_field_hdr {
- uint16_t len;
- uint16_t max_len;
- uint32_t offset;
-};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
struct wire_neg_msg {
struct wire_msg_hdr header;
uint32_t neg_flags;
@@ -77,20 +58,6 @@ struct wire_chal_msg {
#pragma pack(pop)
#pragma pack(push, 1)
-struct wire_auth_msg {
- struct wire_msg_hdr header;
- struct wire_field_hdr lm_chalresp;
- struct wire_field_hdr nt_chalresp;
- struct wire_field_hdr domain_name;
- struct wire_field_hdr user_name;
- struct wire_field_hdr workstation;
- struct wire_field_hdr enc_sess_key;
- uint32_t neg_flags;
- uint8_t payload[]; /* variable */
-};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
struct wire_av_pair {
uint16_t av_id;
uint16_t av_len;
@@ -142,19 +109,6 @@ struct wire_ntlm_cli_chal {
};
#pragma pack(pop)
-/* Version information.
- * Used only for debugging and usually placed as the head of the payload when
- * used */
-#pragma pack(push, 1)
-struct wire_version {
- uint8_t major;
- uint8_t minor;
- uint16_t build;
- uint8_t reserved[3];
- uint8_t revision;
-};
-#pragma pack(pop)
-
struct ntlm_ctx {
iconv_t from_oem;
iconv_t to_oem;
diff --git a/src/ntlm.h b/src/ntlm.h
index 40508e4..72d62c8 100644
--- a/src/ntlm.h
+++ b/src/ntlm.h
@@ -430,6 +430,26 @@ int ntlm_mic(struct ntlm_key *exported_session_key,
struct ntlm_buffer *authenticate_message,
struct ntlm_buffer *mic);
+/**
+ * @brief Verifies a MIC
+ *
+ * @param key The keys used to generate the original MIC
+ * @param negotiate_message The NTLM Negotiate Message (or empty)
+ * @param challenge_message The NTLM Challenge Message
+ * @param authenticate_message The NTLM Authenticate Message
+ * @param mic The original MIC
+ *
+ * NOTE: This function zeros the area of memory where the MIC is held in the
+ * Authenticate Message
+ *
+ * @return 0 on success, EACCES if the MIC fails to verify, or an error
+ */
+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);
+
/* ############## ENCODING / DECODING ############## */
/**
diff --git a/src/ntlm_common.h b/src/ntlm_common.h
index 264afe1..01d6b16 100644
--- a/src/ntlm_common.h
+++ b/src/ntlm_common.h
@@ -57,4 +57,50 @@ enum ntlm_cipher_mode {
NTLM_CIPHER_DECRYPT,
};
+#pragma pack(push, 1)
+struct wire_msg_hdr {
+ uint8_t signature[8];
+ uint32_t msg_type;
+};
+#pragma pack(pop)
+
+/* A wire string, the offset is relative to the mesage and must fall into the
+ * payload section.
+ * max_len should be set equal to len and ignored by servers.
+ */
+#pragma pack(push, 1)
+struct wire_field_hdr {
+ uint16_t len;
+ uint16_t max_len;
+ uint32_t offset;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct wire_auth_msg {
+ struct wire_msg_hdr header;
+ struct wire_field_hdr lm_chalresp;
+ struct wire_field_hdr nt_chalresp;
+ struct wire_field_hdr domain_name;
+ struct wire_field_hdr user_name;
+ struct wire_field_hdr workstation;
+ struct wire_field_hdr enc_sess_key;
+ uint32_t neg_flags;
+ uint8_t payload[]; /* variable */
+};
+#pragma pack(pop)
+
+/* Version information.
+ * Used only for debugging and usually placed as the head of the payload when
+ * used */
+#pragma pack(push, 1)
+struct wire_version {
+ uint8_t major;
+ uint8_t minor;
+ uint16_t build;
+ uint8_t reserved[3];
+ uint8_t revision;
+};
+#pragma pack(pop)
+
#endif /* _NTLM_COMMON_H_ */
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;
+}