Leaked source code of windows server 2003
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.

508 lines
18 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. #if SECURITY_KERNEL
  19. extern "C"
  20. {
  21. // #include <rc4.h> // How to use RC4 routine
  22. #include <md5.h> // For md5init(), md5update(), md5final()
  23. // #include <hmac.h>
  24. }
  25. #endif // SECURITY_KERNEL
  26. #define MD5_HASH_BYTESIZE 16 // MD5 hash size
  27. #define MD5_HASH_HEX_SIZE (2*MD5_HASH_BYTESIZE) // BYTES needed to store a Hash as hex Encoded
  28. // Contains all of the pointers and lengths for directives used in
  29. // calculating the digest access values. Usually the
  30. // parameters point to an external buffer, pHTTPBuffer
  31. enum DIGEST_TYPE
  32. {
  33. DIGEST_UNDEFINED, // Initial state
  34. NO_DIGEST_SPECIFIED,
  35. DIGEST_CLIENT,
  36. DIGEST_SERVER,
  37. SASL_SERVER,
  38. SASL_CLIENT
  39. };
  40. enum QOP_TYPE
  41. {
  42. QOP_UNDEFINED, // Initial state
  43. NO_QOP_SPECIFIED,
  44. AUTH,
  45. AUTH_INT,
  46. AUTH_CONF
  47. };
  48. typedef QOP_TYPE *PQOP_TYPE;
  49. enum ALGORITHM_TYPE
  50. {
  51. ALGORITHM_UNDEFINED, // Initial state
  52. NO_ALGORITHM_SPECIFIED,
  53. MD5,
  54. MD5_SESS
  55. };
  56. enum CHARSET_TYPE
  57. {
  58. CHARSET_UNDEFINED, // Initial state
  59. ISO_8859_1,
  60. UTF_8, // UTF-8 encoding
  61. UTF_8_SUBSET // ISO_8859_1 subset in UTF-8
  62. };
  63. enum CIPHER_TYPE
  64. {
  65. CIPHER_UNDEFINED,
  66. CIPHER_3DES,
  67. CIPHER_DES, // 56bit key
  68. CIPHER_RC4_40,
  69. CIPHER_RC4, // 128bit key
  70. CIPHER_RC4_56
  71. };
  72. enum DIGESTMODE_TYPE
  73. {
  74. DIGESTMODE_UNDEFINED,
  75. DIGESTMODE_HTTP,
  76. DIGESTMODE_SASL
  77. };
  78. enum NAMEFORMAT_TYPE
  79. {
  80. NAMEFORMAT_UNKNOWN,
  81. NAMEFORMAT_ACCOUNTNAME,
  82. NAMEFORMAT_UPN,
  83. NAMEFORMAT_NETBIOS
  84. };
  85. // For list of supported protocols
  86. // Pack supported cyphers into a WORD (2 bytes)
  87. #define SUPPORT_3DES 0x0001
  88. #define SUPPORT_DES 0x0002
  89. #define SUPPORT_RC4_40 0x0004
  90. #define SUPPORT_RC4 0x0008
  91. #define SUPPORT_RC4_56 0x0010
  92. // Strings for the challenge and challengeResponse
  93. #define STR_CIPHER_3DES "3des"
  94. #define STR_CIPHER_DES "des"
  95. #define STR_CIPHER_RC4_40 "rc4-40"
  96. #define STR_CIPHER_RC4 "rc4"
  97. #define STR_CIPHER_RC4_56 "rc4-56"
  98. #define WSTR_CIPHER_HMAC_MD5 L"HMAC_MD5"
  99. #define WSTR_CIPHER_RC4 L"RC4"
  100. #define WSTR_CIPHER_DES L"DES"
  101. #define WSTR_CIPHER_3DES L"3DES"
  102. #define WSTR_CIPHER_MD5 L"MD5"
  103. // Default string for realm directives in challenges
  104. #define STR_DIGEST_DOMAIN "Digest"
  105. #define WSTR_DIGEST_DOMAIN L"Digest"
  106. typedef enum _eSignSealOp {
  107. eSign, // MakeSignature is calling
  108. eVerify, // VerifySignature is calling
  109. eSeal, // SealMessage is calling
  110. eUnseal // UnsealMessage is calling
  111. } eSignSealOp;
  112. // Supplimental credentals stored in the DC (pre-calculated Digest Hashes
  113. #define SUPPCREDS_VERSION 1
  114. #define NUMPRECALC_HEADERS 29
  115. #define TOTALPRECALC_HEADERS (NUMPRECALC_HEADERS + 1)
  116. // Supp Creds format '1' 0 version numhashes 0 0 0 0 0 0 0 0 0 0 0 0
  117. #define SUPPCREDS_VERSIONLOC 2
  118. #define SUPPCREDS_CNTLOC 3
  119. // Format in supplimental credentials U UPPER() D LOWER() n normal passed in value
  120. #define NAME_HEADER 0
  121. #define NAME_ACCT 1
  122. #define NAME_ACCT_DOWNCASE 2
  123. #define NAME_ACCT_UPCASE 3
  124. #define NAME_ACCT_DUCASE 4
  125. #define NAME_ACCT_UDCASE 5
  126. #define NAME_ACCT_NUCASE 6
  127. #define NAME_ACCT_NDCASE 7
  128. #define NAME_ACCTDNS 8
  129. #define NAME_ACCTDNS_DOWNCASE 9
  130. #define NAME_ACCTDNS_UPCASE 10
  131. #define NAME_ACCTDNS_DUCASE 11
  132. #define NAME_ACCTDNS_UDCASE 12
  133. #define NAME_ACCTDNS_NUCASE 13
  134. #define NAME_ACCTDNS_NDCASE 14
  135. #define NAME_UPN 15
  136. #define NAME_UPN_DOWNCASE 16
  137. #define NAME_UPN_UPCASE 17
  138. #define NAME_NT4 18
  139. #define NAME_NT4_DOWNCASE 19
  140. #define NAME_NT4_UPCASE 20
  141. // Fixed realm to STR_DIGEST_DOMAIN
  142. #define NAME_ACCT_FREALM 21
  143. #define NAME_ACCT_FREALM_DOWNCASE 22
  144. #define NAME_ACCT_FREALM_UPCASE 23
  145. #define NAME_UPN_FREALM 24
  146. #define NAME_UPN_FREALM_DOWNCASE 25
  147. #define NAME_UPN_FREALM_UPCASE 26
  148. #define NAME_NT4_FREALM 27
  149. #define NAME_NT4_FREALM_DOWNCASE 28
  150. #define NAME_NT4_FREALM_UPCASE 29
  151. //
  152. // value names used by MD5 authentication.
  153. //
  154. enum MD5_AUTH_NAME
  155. {
  156. MD5_AUTH_USERNAME = 0,
  157. MD5_AUTH_REALM,
  158. MD5_AUTH_NONCE,
  159. MD5_AUTH_CNONCE,
  160. MD5_AUTH_NC,
  161. MD5_AUTH_ALGORITHM,
  162. MD5_AUTH_QOP,
  163. MD5_AUTH_METHOD,
  164. MD5_AUTH_URI,
  165. MD5_AUTH_RESPONSE,
  166. MD5_AUTH_HENTITY,
  167. MD5_AUTH_AUTHZID, // for SASL
  168. // Above this list are Marshalled to DC as BlobData
  169. MD5_AUTH_DOMAIN,
  170. MD5_AUTH_STALE,
  171. MD5_AUTH_OPAQUE,
  172. MD5_AUTH_MAXBUF,
  173. MD5_AUTH_CHARSET,
  174. MD5_AUTH_CIPHER,
  175. MD5_AUTH_DIGESTURI, // for SASL mapped to MD5_AUTH_URI
  176. MD5_AUTH_RSPAUTH, // verify server has auth data
  177. MD5_AUTH_NEXTNONCE,
  178. MD5_AUTH_LAST
  179. };
  180. // Structure to pass around that contains the parameters for the Digest Calculation
  181. typedef struct _DIGEST_PARAMETER
  182. {
  183. DIGEST_TYPE typeDigest;
  184. USHORT usFlags; // Flags defined in DIGEST_BLOB_REQUEST
  185. ALGORITHM_TYPE typeAlgorithm;
  186. QOP_TYPE typeQOP;
  187. CIPHER_TYPE typeCipher;
  188. CHARSET_TYPE typeCharset;
  189. STRING refstrParam[MD5_AUTH_LAST]; // referenced - points to non-owned memory- do not free up these Strings
  190. USHORT usDirectiveCnt[MD5_AUTH_LAST]; // count of the number of times directive is utilized
  191. UNICODE_STRING ustrRealm; // extracted from the digest auth directive values
  192. UNICODE_STRING ustrUsername; // extracted from the digest auth directive values
  193. // Info extracted from Username & Realm - used for auditing and open SAM useraccount
  194. NAMEFORMAT_TYPE typeName;
  195. UNICODE_STRING ustrCrackedAccountName; // SAMAccount name from extracted from ustrUsername & ustrRealm
  196. UNICODE_STRING ustrCrackedDomain; // Domain from ustrUsername & ustrRealm
  197. UNICODE_STRING ustrWorkstation; // Name of workstation/server making Digest request
  198. STRING strUsernameEncoded; // contains a copy of the encoded string used in challengeresponse
  199. STRING strRealmEncoded; // contains a copy of the realm
  200. STRING strDirective[MD5_AUTH_LAST]; // NULL terminated strings that contain directive values
  201. STRING strSessionKey; // String for Sessionkey (points to chSessionKey)
  202. // STRINGS Alloced by DigestInit and Freed by DigestFree
  203. STRING strResponse; // String for the BinHex Hashed Response
  204. // Trust information for this request
  205. ULONG ulTrustDirection;
  206. ULONG ulTrustType;
  207. ULONG ulTrustAttributes;
  208. PSID pTrustSid;
  209. UNICODE_STRING ustrTrustedForest;
  210. } DIGEST_PARAMETER, *PDIGEST_PARAMETER;
  211. // Structure to extract MD5 hashes and passwords for user accounts
  212. typedef struct _USER_CREDENTIALS
  213. {
  214. UNICODE_STRING ustrUsername; // username value to use in H(Username:realm:password) calc
  215. UNICODE_STRING ustrRealm; // realm value to use in H(username:realm:password)
  216. // The following fields might be filled in
  217. // Will check any precalculated hashes first and then try the password if available
  218. BOOL fIsValidPasswd; // set true if password is valid
  219. BOOL fIsValidDigestHash; // set true if hash is valid
  220. BOOL fIsEncryptedPasswd; // set to TRUE is passwd encrypted
  221. SHORT wHashSelected; // if hash valid, index to process
  222. SHORT sHashTags[TOTALPRECALC_HEADERS]; // indicate which hashes match username format
  223. UNICODE_STRING ustrPasswd;
  224. STRING strDigestHash;
  225. USHORT usDigestHashCnt; // number of pre-calc hashes in credential
  226. } USER_CREDENTIALS, *PUSER_CREDENTIALS;
  227. // Data to use GenericPassthrough to send to the DC for processing
  228. // The server will create the data, BlobData, and it will be wraped for
  229. // transport over GenericPassthrough to the DC. The DC will be presented
  230. // with only the BlobData to process
  231. // ALL directive-values have a NULL terminator attached to each directive
  232. // ALL directive-values are UNQUOTED unq("X") -> X
  233. // cbBlobSize has number of bytes to hold header and the string data
  234. // cbCharValues has number of bytes to hold string data
  235. // This way future revs can Version++, increase cbBlobSize, and append to message
  236. //
  237. // Data Format
  238. //
  239. // USHORT Version
  240. // USHORT cbBlobSize
  241. // USHORT DIGEST_TYPE
  242. // USHORT cbCharValues
  243. //
  244. // CHAR[cbUserName+1] unq(username-value)
  245. // CHAR[cbRealm+1] unq(realm-value)
  246. // CHAR[cbNonce+1] unq(nonce-value)
  247. // CHAR[cbCnonce+1] unq(cnonce-value)
  248. // CHAR[cbNC+1] unq(nc-value)
  249. // CHAR[cbAlgorithm+1] unq(algorithm-value)
  250. // CHAR[cbQOP+1] unq(qop-value)
  251. // CHAR[cbMethod+1] Method
  252. // CHAR[cbURI+1] unq(digest-uri-value)
  253. // CHAR[cbReqDigest+1] unq(request-digest)
  254. // CHAR[cbHEntity+1] unq(H(entity-body)) * maybe NULL only for qop="auth"
  255. // CHAR[cbAuthzId+1] unq(AuthzId-value)
  256. //
  257. //
  258. #define DIGEST_BLOB_VERSION 1
  259. #define DIGEST_BLOB_VALUES 12 // How many field-values are sent over
  260. // Values for separators detweent field-values
  261. #define COLONSTR ":"
  262. #define COLONSTR_LEN 1
  263. #define AUTHSTR "auth"
  264. #define AUTHSTR_LEN 4
  265. #define AUTHINTSTR "auth-int"
  266. #define AUTHINTSTR_LEN 8
  267. #define AUTHCONFSTR "auth-conf"
  268. #define AUTHCONFSTR_LEN 9
  269. #define MAX_AUTH_LENGTH AUTHCONFSTR_LEN
  270. #define MD5STR "MD5"
  271. #define MD5_SESSSTR "MD5-sess"
  272. #define MD5_SESS_SASLSTR "md5-sess"
  273. #define MD5_UTF8STR "utf-8"
  274. #define URI_STR "uri"
  275. #define DIGESTURI_STR "digest-uri"
  276. // SASL paramters
  277. #define AUTHENTICATESTR "AUTHENTICATE"
  278. #define ZERO32STR "00000000000000000000000000000000"
  279. #define SASL_C2S_SIGN_KEY "Digest session key to client-to-server signing key magic constant"
  280. #define SASL_S2C_SIGN_KEY "Digest session key to server-to-client signing key magic constant"
  281. #define SASL_C2S_SEAL_KEY "Digest H(A1) to client-to-server sealing key magic constant"
  282. #define SASL_S2C_SEAL_KEY "Digest H(A1) to server-to-client sealing key magic constant"
  283. // number of bytes to hold ChallengeResponse directives and symbols (actual count is 107) round up for padding
  284. // 14 for charset
  285. #define CB_CHALRESP 375
  286. #define CB_CHAL 400
  287. // Number of characters in the NonceCount (hex digits)
  288. #define NCNUM 8
  289. #define NCFIRST "00000001"
  290. // Flags used in DIGEST_PARAMETER usFlags and in Digest_blob_request
  291. #define FLAG_CRACKNAME_ON_DC 0x00000001 // Name in Username & Realm needs to be processed on DC
  292. #define FLAG_AUTHZID_PROVIDED 0x00000002
  293. #define FLAG_SERVERS_DOMAIN 0x00000004 // Indicate on Server's DC (first hop from server) so expand group membership
  294. #define FLAG_NOBS_DECODE 0x00000008 // if set to one, the wire communication is done without backslash encoding
  295. #define FLAG_BS_ENCODE_CLIENT_BROKEN 0x00000010 // set to TRUE if backslash encoding is possibly boken on client
  296. #define FLAG_QUOTE_QOP 0x00000020 // set according to the context if quote the QOP - client side only
  297. // For Context Flags
  298. #define FLAG_CONTEXT_AUTHZID_PROVIDED 0x00000002
  299. #define FLAG_CONTEXT_QUOTE_QOP 0x00000004 // for compat quote the QOP directive on ChallengeResponse
  300. #define FLAG_CONTEXT_NOBS_DECODE 0x00000008 // if set to one, the wire communication is done without backslash encoding
  301. #define FLAG_CONTEXT_PARTIAL 0x00000010 // set if context is only partial - not valid for auth processing
  302. #define FLAG_CONTEXT_REFCOUNT 0x00000020 // a securitycontext handle was issued by ASC/ISC - ref count app count
  303. #define FLAG_CONTEXT_SERVER 0x00000040 // context was created in ASC server side if set, otherwise in ISC client
  304. // Overlay header for getting values in Generic Passthrough request
  305. typedef struct _DIGEST_BLOB_REQUEST
  306. {
  307. ULONG MessageType;
  308. USHORT version;
  309. USHORT cbBlobSize;
  310. USHORT digest_type;
  311. USHORT qop_type;
  312. USHORT alg_type;
  313. USHORT charset_type;
  314. USHORT cbCharValues;
  315. USHORT name_format;
  316. USHORT usFlags;
  317. USHORT cbAccountName;
  318. USHORT cbCrackedDomain;
  319. USHORT cbWorkstation;
  320. USHORT ulReserved3;
  321. ULONG64 pad1;
  322. char cCharValues; // dummy char to mark start of field-values
  323. } DIGEST_BLOB_REQUEST, *PDIGEST_BLOB_REQUEST;
  324. // Supported MesageTypes
  325. #define VERIFY_DIGEST_MESSAGE 0x1a // No specific value is needed
  326. #define VERIFY_DIGEST_MESSAGE_RESPONSE 0x0a // No specific value is needed
  327. // The response for the GenericPassthrough call is the status of the Digest Authentication
  328. // Note: This is a fixed length response header - Authdata length not static
  329. // Format for data sent back
  330. // DIGEST_BLOB_RESPONSE AuthData UnicodeStringAccountName
  331. typedef struct _DIGEST_BLOB_RESPONSE
  332. {
  333. ULONG MessageType;
  334. USHORT version;
  335. NTSTATUS Status; // Information on Success of Digest Auth
  336. USHORT SessionKeyMaxLength;
  337. ULONG ulAuthDataSize;
  338. USHORT usAcctNameSize; // size of the NetBIOS name (after AuthData)
  339. USHORT ulReserved1;
  340. ULONG ulBlobSize; // size of entire blob sent as response
  341. ULONG ulReserved3;
  342. char SessionKey[MD5_HASH_HEX_SIZE + 1];
  343. ULONG64 pad1;
  344. char cAuthData; // Start of AuthData opaque data
  345. // Place group info here for LogonUser
  346. } DIGEST_BLOB_RESPONSE, *PDIGEST_BLOB_RESPONSE;
  347. // SASL MAC block
  348. // Total of 16 bytes per rfc2831 sect 2.3
  349. // first 10 bytes of HMAC-MD5 [ RFC 2104]
  350. // 2-byte message type number fixed to value 1 (0x0001)
  351. // 4-byte sequence number
  352. // NOTE: This is using WORD as a 2 byte value and DWORD as a 4 byte value!
  353. #define HMAC_MD5_HASH_BYTESIZE 16 // MHAC-MD5 hash size per RFC 2104
  354. #define SASL_MAC_HMAC_SIZE 10
  355. #define SASL_MAC_MSG_SIZE 2
  356. #define SASL_MAC_SEQ_SIZE 4
  357. typedef struct _SASL_MAC_BLOCK
  358. {
  359. UCHAR hmacMD5[SASL_MAC_HMAC_SIZE];
  360. WORD wMsgType;
  361. DWORD dwSeqNumber;
  362. } SASL_MAC_BLOCK, *PSASL_MAC_BLOCK;
  363. // The SASL MAC Block is 16 bytes: RFC 2831 sect 2.4
  364. #define MAC_BLOCK_SIZE sizeof(SASL_MAC_BLOCK)
  365. #define MAX_PADDING 8 // max padding is currently 8 for DES
  366. // Perform Digest Access Calculation
  367. NTSTATUS NTAPI DigestCalculation(IN PDIGEST_PARAMETER pDigest, IN PUSER_CREDENTIALS pUserCreds);
  368. // Simple checks for enough data for Digest calculation
  369. NTSTATUS NTAPI DigestIsValid(IN PDIGEST_PARAMETER pDigest);
  370. // Initialize the DIGEST_PARAMETER structure
  371. NTSTATUS NTAPI DigestInit(IN PDIGEST_PARAMETER pDigest);
  372. // Clear out the digest & free memory from Digest struct
  373. NTSTATUS NTAPI DigestFree(IN PDIGEST_PARAMETER pDigest);
  374. // Perform Digest Access Calculation for ChallengeResponse
  375. NTSTATUS NTAPI DigestCalcChalRsp(IN PDIGEST_PARAMETER pDigest,
  376. IN PUSER_CREDENTIALS pUserCreds,
  377. BOOL bIsChallenge);
  378. NTSTATUS PrecalcDigestHash(
  379. IN PUNICODE_STRING pustrUsername,
  380. IN PUNICODE_STRING pustrRealm,
  381. IN PUNICODE_STRING pustrPassword,
  382. OUT PCHAR pHexHash,
  383. IN OUT PUSHORT piHashSize);
  384. NTSTATUS PrecalcForms(
  385. IN PUNICODE_STRING pustrUsername,
  386. IN PUNICODE_STRING pustrRealm,
  387. IN PUNICODE_STRING pustrPassword,
  388. IN BOOL fFixedRealm,
  389. OUT PCHAR pHexHash,
  390. IN OUT PUSHORT piHashSize);
  391. // Creates the Output SecBuffer for the Challenge Response
  392. NTSTATUS NTAPI DigestCreateChalResp(IN PDIGEST_PARAMETER pDigest,
  393. IN PUSER_CREDENTIALS pUserCreds,
  394. OUT PSecBuffer OutBuffer);
  395. // Parse input string into Parameter section of Digest
  396. NTSTATUS DigestParser2(PSecBuffer pInputBuf, PSTR *pNameTable,UINT cNameTable, PDIGEST_PARAMETER pDigest);
  397. // Hash and Encode upto 7 STRINGS SOut = Hex(H(S1 ":" S2 ... ":" S7))
  398. NTSTATUS NTAPI DigestHash7(IN PSTRING pS1, IN PSTRING pS2, IN PSTRING pS3,
  399. IN PSTRING pS4, IN PSTRING pS5, IN PSTRING pS6, IN PSTRING pS7,
  400. IN BOOL fHexOut,
  401. OUT PSTRING pSOut);
  402. // Formatted printout of Digest Parameters
  403. NTSTATUS DigestPrint(PDIGEST_PARAMETER pDigest);
  404. #ifndef SECURITY_KERNEL
  405. // Processed parsed digest auth message and fill in string values
  406. NTSTATUS NTAPI DigestDecodeDirectiveStrings(IN OUT PDIGEST_PARAMETER pDigest);
  407. // Determine H(A1) for Digest Access
  408. NTSTATUS NTAPI DigestCalcHA1(IN PDIGEST_PARAMETER pDigest, PUSER_CREDENTIALS pUserCreds);
  409. // Encode the Digest Access Parameters fields into a BYTE Buffer
  410. NTSTATUS NTAPI BlobEncodeRequest(IN PDIGEST_PARAMETER pDigest, OUT BYTE **ppBuffer, OUT USHORT *cbBuffer);
  411. // Decode the Digest Access Parameters fields from a BYTE Buffer
  412. NTSTATUS NTAPI BlobDecodeRequest(IN USHORT cbMessageRequest,
  413. IN BYTE *pBuffer,
  414. PDIGEST_PARAMETER pDigest);
  415. // Free BYTE Buffer from BlobEncodeRequest
  416. VOID NTAPI BlobFreeRequest(BYTE *pBuffer);
  417. #endif // SECURITY_KERNEL
  418. #endif // NTDIGEST_AUTH_H