Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
13 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1992 - 1996
  6. //
  7. // File: auth.h
  8. //
  9. // Contents: include file for auth.cxx for NTDigest
  10. //
  11. //
  12. // History: KDamour 15Mar00 Stolen from msv_sspi\global.h
  13. //
  14. //------------------------------------------------------------------------
  15. #ifndef NTDIGEST_AUTH_H
  16. #define NTDIGEST_AUTH_H
  17. #include "nonce.h"
  18. // Contains all of the pointers and lengths for directives used in
  19. // calculating the digest access values. Usually the
  20. // parameters point to an external buffer, pHTTPBuffer
  21. enum DIGEST_TYPE
  22. {
  23. DIGEST_UNDEFINED, // Initial state
  24. NO_DIGEST_SPECIFIED,
  25. DIGEST_CLIENT,
  26. DIGEST_SERVER,
  27. SASL_SERVER,
  28. SASL_CLIENT
  29. };
  30. enum QOP_TYPE
  31. {
  32. QOP_UNDEFINED, // Initial state
  33. NO_QOP_SPECIFIED,
  34. AUTH,
  35. AUTH_INT,
  36. AUTH_CONF
  37. };
  38. typedef QOP_TYPE *PQOP_TYPE;
  39. enum ALGORITHM_TYPE
  40. {
  41. ALGORITHM_UNDEFINED, // Initial state
  42. NO_ALGORITHM_SPECIFIED,
  43. MD5,
  44. MD5_SESS
  45. };
  46. enum CHARSET_TYPE
  47. {
  48. CHARSET_UNDEFINED, // Initial state
  49. ISO_8859_1,
  50. UTF_8, // UTF-8 encoding
  51. UTF_8_SUBSET // ISO_8859_1 subset in UTF-8
  52. };
  53. enum CIPHER_TYPE
  54. {
  55. CIPHER_UNDEFINED,
  56. CIPHER_3DES,
  57. CIPHER_DES, // 56bit key
  58. CIPHER_RC4_40,
  59. CIPHER_RC4, // 128bit key
  60. CIPHER_RC4_56
  61. };
  62. enum DIGESTMODE_TYPE
  63. {
  64. DIGESTMODE_UNDEFINED,
  65. DIGESTMODE_HTTP,
  66. DIGESTMODE_SASL
  67. };
  68. enum NAMEFORMAT_TYPE
  69. {
  70. NAMEFORMAT_UNKNOWN,
  71. NAMEFORMAT_ACCOUNTNAME,
  72. NAMEFORMAT_UPN,
  73. NAMEFORMAT_NETBIOS
  74. };
  75. // For list of supported protocols
  76. // Pack supported cyphers into a WORD (2 bytes)
  77. #define SUPPORT_3DES 0x0001
  78. #define SUPPORT_DES 0x0002
  79. #define SUPPORT_RC4_40 0x0004
  80. #define SUPPORT_RC4 0x0008
  81. #define SUPPORT_RC4_56 0x0010
  82. // Strings for the challenge and challengeResponse
  83. #define STR_CIPHER_3DES "3des"
  84. #define STR_CIPHER_DES "des"
  85. #define STR_CIPHER_RC4_40 "rc4-40"
  86. #define STR_CIPHER_RC4 "rc4"
  87. #define STR_CIPHER_RC4_56 "rc4-56"
  88. #define WSTR_CIPHER_HMAC_MD5 L"HMAC_MD5"
  89. #define WSTR_CIPHER_RC4 L"RC4"
  90. #define WSTR_CIPHER_DES L"DES"
  91. #define WSTR_CIPHER_3DES L"3DES"
  92. typedef enum _eSignSealOp {
  93. eSign, // MakeSignature is calling
  94. eVerify, // VerifySignature is calling
  95. eSeal, // SealMessage is calling
  96. eUnseal // UnsealMessage is calling
  97. } eSignSealOp;
  98. // Supplimental credentals stored in the DC (pre-calculated Digest Hashes
  99. #define SUPPCREDS_VERSION 1
  100. #define NUMPRECALC_HEADERS 9
  101. #define TOTALPRECALC_HEADERS (NUMPRECALC_HEADERS + 1)
  102. // Format in supplimental credentials
  103. #define NAME_HEADER 0
  104. #define NAME_ACCT 1
  105. #define NAME_ACCT_DOWNCASE 2
  106. #define NAME_ACCT_UPCASE 3
  107. #define NAME_UPN 4
  108. #define NAME_UPN_DOWNCASE 5
  109. #define NAME_UPN_UPCASE 6
  110. #define NAME_NT4 7
  111. #define NAME_NT4_DOWNCASE 8
  112. #define NAME_NT4_UPCASE 9
  113. // Bit flags for Packed UserContext
  114. #define USERCONTEXT_UPDATE 0x00000001
  115. //
  116. // value names used by MD5 authentication.
  117. //
  118. enum MD5_AUTH_NAME
  119. {
  120. MD5_AUTH_USERNAME = 0,
  121. MD5_AUTH_REALM,
  122. MD5_AUTH_NONCE,
  123. MD5_AUTH_CNONCE,
  124. MD5_AUTH_NC,
  125. MD5_AUTH_ALGORITHM,
  126. MD5_AUTH_QOP,
  127. MD5_AUTH_METHOD,
  128. MD5_AUTH_URI,
  129. MD5_AUTH_RESPONSE,
  130. MD5_AUTH_HENTITY,
  131. MD5_AUTH_AUTHZID, // for SASL
  132. // Above this list are Marshalled to DC as BlobData
  133. MD5_AUTH_DOMAIN,
  134. MD5_AUTH_STALE,
  135. MD5_AUTH_OPAQUE,
  136. MD5_AUTH_MAXBUF,
  137. MD5_AUTH_CHARSET,
  138. MD5_AUTH_CIPHER,
  139. MD5_AUTH_DIGESTURI, // for SASL mapped to MD5_AUTH_URI
  140. MD5_AUTH_RSPAUTH, // verify server has auth data
  141. MD5_AUTH_LAST
  142. };
  143. // Structure to pass around that contains the parameters for the Digest Calculation
  144. typedef struct _DIGEST_PARAMETER
  145. {
  146. DIGEST_TYPE typeDigest;
  147. ALGORITHM_TYPE typeAlgorithm;
  148. QOP_TYPE typeQOP;
  149. CIPHER_TYPE typeCipher;
  150. CHARSET_TYPE typeCharset;
  151. STRING refstrParam[MD5_AUTH_LAST]; // referenced - points to non-owned memory- do not free up these Strings
  152. UNICODE_STRING ustrRealm; // extracted from the digest auth directive values
  153. UNICODE_STRING ustrUsername; // extracted from the digest auth directive values
  154. UNICODE_STRING ustrUri; // extracted from the digest auth directive values
  155. // Results from DSCrackName
  156. NAMEFORMAT_TYPE typeName;
  157. UNICODE_STRING ustrCrackedAccountName; // SAMAccount name from DSCrackName
  158. UNICODE_STRING ustrCrackedDomain; // Domain from DSCrackName
  159. STRING strUsernameEncoded; // contains a copy of the encoded string used in challengeresponse
  160. STRING strRealmEncoded; // contains a copy of the realm
  161. STRING strDirective[MD5_AUTH_LAST]; // NULL terminated strings that contain directive values
  162. STRING strSessionKey; // String for Sessionkey (points to chSessionKey)
  163. // STRINGS Alloced by DigestInit and Freed by DigestFree
  164. STRING strResponse; // String for the BinHex Hashed Response
  165. } DIGEST_PARAMETER, *PDIGEST_PARAMETER;
  166. // Structure to extract MD5 hashes and passwords for user accounts
  167. typedef struct _USER_CREDENTIALS
  168. {
  169. UNICODE_STRING ustrUsername;
  170. UNICODE_STRING ustrDomain;
  171. NAMEFORMAT_TYPE typeName;
  172. // The following fields might be filled in
  173. // Will check any precalculated hashes first and then try the password if available
  174. BOOL fIsValidPasswd; // set true if password is valid
  175. BOOL fIsValidDigestHash; // set true if hash is valid
  176. BOOL fIsEncryptedPasswd; // set to TRUE is passwd encrypted
  177. SHORT wHashSelected; // if hash valid, index to process
  178. SHORT sHashTags[TOTALPRECALC_HEADERS]; // indicate which hashes match username format
  179. UNICODE_STRING ustrPasswd;
  180. STRING strDigestHash;
  181. } USER_CREDENTIALS, *PUSER_CREDENTIALS;
  182. // Data to use GenericPassthrough to send to the DC for processing
  183. // The server will create the data, BlobData, and it will be wraped for
  184. // transport over GenericPassthrough to the DC. The DC will be presented
  185. // with only the BlobData to process
  186. // ALL directive-values have a NULL terminator attached to each directive
  187. // ALL directive-values are UNQUOTED unq("X") -> X
  188. // cbBlobSize has number of bytes to hold header and the string data
  189. // cbCharValues has number of bytes to hold string data
  190. // This way future revs can Version++, increase cbBlobSize, and append to message
  191. //
  192. // Data Format
  193. //
  194. // USHORT Version
  195. // USHORT cbBlobSize
  196. // USHORT DIGEST_TYPE
  197. // USHORT cbCharValues
  198. //
  199. // CHAR[cbUserName+1] unq(username-value)
  200. // CHAR[cbRealm+1] unq(realm-value)
  201. // CHAR[cbNonce+1] unq(nonce-value)
  202. // CHAR[cbCnonce+1] unq(cnonce-value)
  203. // CHAR[cbNC+1] unq(nc-value)
  204. // CHAR[cbAlgorithm+1] unq(algorithm-value)
  205. // CHAR[cbQOP+1] unq(qop-value)
  206. // CHAR[cbMethod+1] Method
  207. // CHAR[cbURI+1] unq(digest-uri-value)
  208. // CHAR[cbReqDigest+1] unq(request-digest)
  209. // CHAR[cbHEntity+1] unq(H(entity-body)) * maybe NULL only for qop="auth"
  210. // CHAR[cbAuthzId+1] unq(AuthzId-value)
  211. //
  212. //
  213. #define DIGEST_BLOB_VERSION 1
  214. #define DIGEST_BLOB_VALUES 12 // How many field-values are sent over
  215. // Values for separators detweent field-values
  216. #define COLONSTR ":"
  217. #define COLONSTR_LEN 1
  218. #define AUTHSTR "auth"
  219. #define AUTHSTR_LEN 4
  220. #define AUTHINTSTR "auth-int"
  221. #define AUTHINTSTR_LEN 8
  222. #define AUTHCONFSTR "auth-conf"
  223. #define AUTHCONFSTR_LEN 9
  224. #define MAX_AUTH_LENGTH AUTHCONFSTR_LEN
  225. #define MD5STR "MD5"
  226. #define MD5_SESSSTR "MD5-sess"
  227. #define MD5_SESS_SASLSTR "md5-sess"
  228. #define MD5_UTF8STR "utf-8"
  229. #define URI_STR "uri"
  230. #define DIGESTURI_STR "digest-uri"
  231. // SASL paramters
  232. #define AUTHENTICATESTR "AUTHENTICATE"
  233. #define ZERO32STR "00000000000000000000000000000000"
  234. #define SASL_C2S_SIGN_KEY "Digest session key to client-to-server signing key magic constant"
  235. #define SASL_S2C_SIGN_KEY "Digest session key to server-to-client signing key magic constant"
  236. #define SASL_C2S_SEAL_KEY "Digest H(A1) to client-to-server sealing key magic constant"
  237. #define SASL_S2C_SEAL_KEY "Digest H(A1) to server-to-client sealing key magic constant"
  238. // Number of characters in the NonceCount (hex digits)
  239. #define NCNUM 8
  240. #define NCFIRST "00000001"
  241. // Overlay header for getting values in Generic Passthrough request
  242. typedef struct _DIGEST_BLOB_REQUEST
  243. {
  244. ULONG MessageType;
  245. USHORT version;
  246. USHORT cbBlobSize;
  247. USHORT digest_type;
  248. USHORT qop_type;
  249. USHORT alg_type;
  250. USHORT charset_type;
  251. USHORT cbCharValues;
  252. USHORT name_format;
  253. USHORT usReserved1;
  254. ULONG ulReserved2;
  255. ULONG ulReserved3;
  256. ULONG64 pad1;
  257. char cCharValues; // dummy char to mark start of field-values
  258. } DIGEST_BLOB_REQUEST, *PDIGEST_BLOB_REQUEST;
  259. // Supported MesageTypes
  260. #define VERIFY_DIGEST_MESSAGE 0x1a // No specific value is needed
  261. #define VERIFY_DIGEST_MESSAGE_RESPONSE 0x0a // No specific value is needed
  262. // The response for the GenericPassthrough call is the status of the Digest Authentication
  263. // Note: This is a fixed length response header - Authdata length not static
  264. typedef struct _DIGEST_BLOB_RESPONSE
  265. {
  266. ULONG MessageType;
  267. USHORT version;
  268. NTSTATUS Status; // Information on Success of Digest Auth
  269. USHORT SessionKeyMaxLength;
  270. ULONG ulAuthDataSize;
  271. ULONG ulReserved1;
  272. ULONG ulReserved2;
  273. ULONG ulReserved3;
  274. char SessionKey[MD5_HASH_HEX_SIZE + 1];
  275. ULONG64 pad1;
  276. char cAuthData; // Start of AuthData opaque data
  277. // Place group info here for LogonUser
  278. } DIGEST_BLOB_RESPONSE, *PDIGEST_BLOB_RESPONSE;
  279. // SASL MAC block
  280. // Total of 16 bytes per rfc2831 sect 2.3
  281. // first 10 bytes of HMAC-MD5 [ RFC 2104]
  282. // 2-byte message type number fixed to value 1 (0x0001)
  283. // 4-byte sequence number
  284. // NOTE: This is using WORD as a 2 byte value and DWORD as a 4 byte value!
  285. #define HMAC_MD5_HASH_BYTESIZE 16 // MHAC-MD5 hash size per RFC 2104
  286. #define SASL_MAC_HMAC_SIZE 10
  287. #define SASL_MAC_MSG_SIZE 2
  288. #define SASL_MAC_SEQ_SIZE 4
  289. typedef struct _SASL_MAC_BLOCK
  290. {
  291. UCHAR hmacMD5[SASL_MAC_HMAC_SIZE];
  292. WORD wMsgType;
  293. DWORD dwSeqNumber;
  294. } SASL_MAC_BLOCK, *PSASL_MAC_BLOCK;
  295. // The SASL MAC Block is 16 bytes: RFC 2831 sect 2.4
  296. #define MAC_BLOCK_SIZE sizeof(SASL_MAC_BLOCK)
  297. #define MAX_PADDING 8 // max padding is currently 8 for DES
  298. // Encode the Digest Access Parameters fields into a BYTE Buffer
  299. NTSTATUS NTAPI BlobEncodeRequest(IN PDIGEST_PARAMETER pDigest, OUT BYTE **ppBuffer, OUT USHORT *cbBuffer);
  300. // Decode the Digest Access Parameters fields from a BYTE Buffer
  301. NTSTATUS NTAPI BlobDecodeRequest(IN BYTE *pBuffer, PDIGEST_PARAMETER pDigest);
  302. // Free BYTE Buffer from BlobEncodeRequest
  303. VOID NTAPI BlobFreeRequest(BYTE *pBuffer);
  304. // Hash and Encode upto 7 STRINGS SOut = Hex(H(S1 ":" S2 ... ":" S7))
  305. NTSTATUS NTAPI DigestHash7(IN PSTRING pS1, IN PSTRING pS2, IN PSTRING pS3,
  306. IN PSTRING pS4, IN PSTRING pS5, IN PSTRING pS6, IN PSTRING pS7,
  307. IN BOOL fHexOut,
  308. OUT PSTRING pSOut);
  309. // Perform Digest Access Calculation
  310. NTSTATUS NTAPI DigestCalculation(IN PDIGEST_PARAMETER pDigest, IN PUSER_CREDENTIALS pUserCreds);
  311. // Simple checks for enough data for Digest calculation
  312. NTSTATUS NTAPI DigestIsValid(IN PDIGEST_PARAMETER pDigest);
  313. // Initialize the DIGEST_PARAMETER structure
  314. NTSTATUS NTAPI DigestInit(IN PDIGEST_PARAMETER pDigest);
  315. // Clear out the digest & free memory from Digest struct
  316. NTSTATUS NTAPI DigestFree(IN PDIGEST_PARAMETER pDigest);
  317. // Determine H(A1) for Digest Access
  318. NTSTATUS NTAPI DigestCalcHA1(IN PDIGEST_PARAMETER pDigest, PUSER_CREDENTIALS pUserCreds);
  319. // Perform Digest Access Calculation for ChallengeResponse
  320. NTSTATUS NTAPI DigestCalcChalRsp(IN PDIGEST_PARAMETER pDigest,
  321. IN PUSER_CREDENTIALS pUserCreds,
  322. BOOL bIsChallenge);
  323. // Processed parsed digest auth message and fill in string values
  324. NTSTATUS NTAPI DigestDecodeDirectiveStrings(IN OUT PDIGEST_PARAMETER pDigest);
  325. NTSTATUS PrecalcDigestHash(
  326. IN PUNICODE_STRING pustrUsername,
  327. IN PUNICODE_STRING pustrRealm,
  328. IN PUNICODE_STRING pustrPassword,
  329. OUT PCHAR pHexHash,
  330. IN OUT PUSHORT piHashSize);
  331. NTSTATUS PrecalcForms(
  332. IN PUNICODE_STRING pustrUsername,
  333. IN PUNICODE_STRING pustrRealm,
  334. IN PUNICODE_STRING pustrPassword,
  335. OUT PCHAR pHexHash,
  336. IN OUT PUSHORT piHashSize);
  337. #endif // NTDIGEST_AUTH_H