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.

414 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. certcach.hxx
  5. Abstract:
  6. Contains class definition for certificate cache object.
  7. The class acts a container for common certificates.
  8. Contents:
  9. SECURITY_CACHE_LIST
  10. SECURITY_CACHE_LIST_ENTRY
  11. Author:
  12. Arthur L Bierer (arthurbi) 20-Apr-1996
  13. Revision History:
  14. 20-Apr-1996 arthurbi
  15. Created
  16. --*/
  17. typedef struct _SEC_PROVIDER
  18. {
  19. CHAR *pszName; // security pkg name
  20. CredHandle hCreds; // credential handle
  21. DWORD dwFlags; // encryption capabilities
  22. BOOL fEnabled; // enable flag indicator
  23. DWORD dwProtocolFlags; // protocol flags that this provider supports.
  24. PCCERT_CONTEXT pCertCtxt; // cert context to use when getting default credentials.
  25. } SEC_PROVIDER, *PSEC_PROVIDER;
  26. // Default list of security packages to enumerate
  27. #define MAX_SEC_PROVIDERS 3
  28. extern const SEC_PROVIDER g_cSecProviders[MAX_SEC_PROVIDERS];
  29. enum SSL_IMPERSONATION_LEVEL
  30. {
  31. SSL_IMPERSONATION_DISABLED = 0,
  32. SSL_IMPERSONATION_ENABLED = 1,
  33. SSL_IMPERSONATION_UNINITIALIZED = 2
  34. };
  35. //
  36. // SECURITY_INFO_LIST_ENTRY - contains all security info
  37. // pertaining to all connections to a server.
  38. //
  39. class SECURITY_CACHE_LIST_ENTRY {
  40. friend class SECURITY_CACHE_LIST;
  41. private:
  42. //
  43. // _List - Generic List entry structure.
  44. //
  45. LIST_ENTRY _List;
  46. //
  47. // _cRef - Reference count for this element.
  48. //
  49. LONG _cRef;
  50. //
  51. // _CertInfo - Certificate and other security
  52. // attributes for the connection to
  53. // this machine.
  54. //
  55. INTERNET_SECURITY_INFO _CertInfo;
  56. //
  57. // _dwSecurityFlags - Overrides for warnings.
  58. //
  59. DWORD _dwSecurityFlags;
  60. //
  61. // _dwStatusFlags - Tracker for all secure connection failure flags.
  62. //
  63. DWORD _dwStatusFlags;
  64. //
  65. // _ServerName - The name of the server
  66. //
  67. ICSTRING _ServerName;
  68. INTERNET_PORT _ServerPort;
  69. //
  70. // _pCertChainList - If there is Client Authentication do be done with this server,
  71. // then we'll cache it and remeber it later.
  72. //
  73. CERT_CONTEXT_ARRAY *_pCertContextArray;
  74. //
  75. // _fInCache - indicates this element is held by the cache
  76. //
  77. BOOL _fInCache;
  78. //
  79. // _fNoRevert - indicates whether or not any potential impersonation
  80. // should be reverted during SSL handling.
  81. //
  82. BOOL _fNoRevert;
  83. #if INET_DEBUG
  84. DWORD m_Signature;
  85. #endif
  86. public:
  87. LONG AddRef(VOID);
  88. LONG Release(VOID);
  89. //
  90. // Cleans up object, so it can be reused
  91. //
  92. BOOL InCache() { return _fInCache; }
  93. const INTERNET_SECURITY_INFO& GetSecInfo() const { return _CertInfo; }
  94. VOID
  95. Clear();
  96. SECURITY_CACHE_LIST_ENTRY(
  97. IN BOOL fNoRevert,
  98. IN LPSTR lpszHostName,
  99. IN INTERNET_PORT ServerPort
  100. );
  101. ~SECURITY_CACHE_LIST_ENTRY();
  102. //
  103. // Copy CERT_INFO IN Method -
  104. // copies a structure into our object.
  105. //
  106. SECURITY_CACHE_LIST_ENTRY& operator=(LPINTERNET_SECURITY_INFO Cert)
  107. {
  108. if(_CertInfo.pCertificate)
  109. {
  110. WRAP_REVERT_USER_VOID((*g_pfnCertFreeCertificateContext),
  111. _fNoRevert,
  112. (_CertInfo.pCertificate));
  113. }
  114. _CertInfo.dwSize = sizeof(_CertInfo);
  115. WRAP_REVERT_USER((*g_pfnCertDuplicateCertificateContext),
  116. _fNoRevert,
  117. (Cert->pCertificate),
  118. _CertInfo.pCertificate);
  119. _CertInfo.dwProtocol = Cert->dwProtocol;
  120. _CertInfo.aiCipher = Cert->aiCipher;
  121. _CertInfo.dwCipherStrength = Cert->dwCipherStrength;
  122. _CertInfo.aiHash = Cert->aiHash;
  123. _CertInfo.dwHashStrength = Cert->dwHashStrength;
  124. _CertInfo.aiExch = Cert->aiExch;
  125. _CertInfo.dwExchStrength = Cert->dwExchStrength;
  126. return *this;
  127. }
  128. //
  129. // Copy CERT_INFO OUT Method -
  130. // need to copy ourselves out.
  131. //
  132. VOID
  133. CopyOut(INTERNET_SECURITY_INFO &Cert)
  134. {
  135. Cert.dwSize = sizeof(Cert);
  136. WRAP_REVERT_USER((*g_pfnCertDuplicateCertificateContext),
  137. _fNoRevert,
  138. (_CertInfo.pCertificate),
  139. Cert.pCertificate);
  140. Cert.dwProtocol = _CertInfo.dwProtocol;
  141. Cert.aiCipher = _CertInfo.aiCipher;
  142. Cert.dwCipherStrength = _CertInfo.dwCipherStrength;
  143. Cert.aiHash = _CertInfo.aiHash;
  144. Cert.dwHashStrength = _CertInfo.dwHashStrength;
  145. Cert.aiExch = _CertInfo.aiExch;
  146. Cert.dwExchStrength = _CertInfo.dwExchStrength;
  147. }
  148. //
  149. // Sets and Gets the Client Authentication CertChain -
  150. // we piggy back this pointer into the cache so we can cache
  151. // previously generated and selected client auth certs.
  152. //
  153. VOID SetCertContextArray(CERT_CONTEXT_ARRAY *pCertContextArray) {
  154. if (_pCertContextArray) {
  155. delete _pCertContextArray;
  156. }
  157. _pCertContextArray = pCertContextArray;
  158. }
  159. CERT_CONTEXT_ARRAY * GetCertContextArray() {
  160. return _pCertContextArray;
  161. }
  162. DWORD GetSecureFlags() {
  163. return _dwSecurityFlags;
  164. }
  165. VOID SetSecureFlags(DWORD dwFlags) {
  166. _dwSecurityFlags |= dwFlags;
  167. }
  168. VOID ClearSecureFlags(DWORD dwFlags) {
  169. _dwSecurityFlags &= (~dwFlags);
  170. }
  171. DWORD GetStatusFlags(VOID)
  172. {
  173. return _dwStatusFlags;
  174. }
  175. VOID SetStatusFlags(DWORD dwFlags)
  176. {
  177. _dwStatusFlags |= dwFlags;
  178. }
  179. VOID ClearStatusFlags(DWORD dwFlags)
  180. {
  181. _dwStatusFlags &= (~dwFlags);
  182. }
  183. LPSTR GetHostName(VOID) {
  184. return _ServerName.StringAddress();
  185. }
  186. BOOL IsImpersonationEnabled() {
  187. return _fNoRevert;
  188. }
  189. };
  190. class SECURITY_CACHE_LIST {
  191. private:
  192. //
  193. // _List - serialized list of SECURITY_CACHE_LIST_ENTRY objects
  194. //
  195. SERIALIZED_LIST _List;
  196. #if INET_DEBUG
  197. DWORD m_Signature;
  198. #endif
  199. //
  200. // Array of encryption providers
  201. //
  202. SEC_PROVIDER _SecProviders[MAX_SEC_PROVIDERS];
  203. //
  204. // EncProvider flag
  205. //
  206. DWORD _dwEncFlags;
  207. // Enabled SSL protocols for the session
  208. DWORD _dwSecureProtocols;
  209. SSL_IMPERSONATION_LEVEL _eImpersonationLevel;
  210. LONG _cRefs;
  211. public:
  212. SECURITY_CACHE_LIST()
  213. {
  214. _cRefs = 1;
  215. _eImpersonationLevel = SSL_IMPERSONATION_UNINITIALIZED;
  216. }
  217. LONG AddRef(VOID)
  218. {
  219. return (InterlockedIncrement(&_cRefs));
  220. }
  221. LONG Release(VOID)
  222. {
  223. // We can get away with interlocked increment/decrement
  224. // because we're guaranteed to always have a live WHO
  225. // reference anytime this is addref'ed.
  226. LONG cRefs = InterlockedDecrement(&_cRefs);
  227. if (cRefs == 0)
  228. {
  229. Terminate();
  230. delete this;
  231. }
  232. return cRefs;
  233. }
  234. SECURITY_CACHE_LIST_ENTRY *
  235. Find(
  236. IN LPSTR lpszHostname,
  237. IN INTERNET_PORT HostPort
  238. );
  239. BOOL Initialize(
  240. VOID
  241. );
  242. VOID Terminate(
  243. VOID
  244. );
  245. VOID
  246. ClearList(
  247. VOID
  248. );
  249. DWORD
  250. Add(
  251. IN SECURITY_CACHE_LIST_ENTRY * entry
  252. );
  253. #if 0
  254. BOOL
  255. IsCertInCache(
  256. IN LPSTR lpszHostname
  257. )
  258. {
  259. SECURITY_CACHE_LIST_ENTRY *entry =
  260. Find(lpszHostname);
  261. if ( entry )
  262. return TRUE;
  263. return FALSE;
  264. }
  265. #endif
  266. VOID SetSecureProtocols(DWORD dwSecureProtocols)
  267. {
  268. _dwSecureProtocols = dwSecureProtocols;
  269. }
  270. DWORD GetSecureProtocols()
  271. {
  272. return _dwSecureProtocols;
  273. }
  274. VOID SetEncFlags(DWORD dwEncFlags)
  275. {
  276. _dwEncFlags = dwEncFlags;
  277. }
  278. DWORD GetEncFlags()
  279. {
  280. return _dwEncFlags;
  281. }
  282. SEC_PROVIDER *GetSecProviders()
  283. {
  284. return _SecProviders;
  285. }
  286. DWORD SetImpersonationLevel(BOOL fLeaveImpersonation)
  287. {
  288. if (_eImpersonationLevel == SSL_IMPERSONATION_UNINITIALIZED)
  289. {
  290. _eImpersonationLevel = (fLeaveImpersonation ?
  291. SSL_IMPERSONATION_ENABLED : SSL_IMPERSONATION_DISABLED);
  292. return ERROR_SUCCESS;
  293. }
  294. else
  295. {
  296. // Can only be set once. This must also be initialized
  297. // upon creation of the first request handle if the
  298. // client doesn't set prior the first send request.
  299. return ERROR_WINHTTP_INCORRECT_HANDLE_STATE;
  300. }
  301. }
  302. BOOL IsImpersonationLevelInitialized()
  303. {
  304. return (_eImpersonationLevel == SSL_IMPERSONATION_UNINITIALIZED);
  305. }
  306. BOOL IsImpersonationEnabled()
  307. {
  308. return (_eImpersonationLevel == SSL_IMPERSONATION_ENABLED);
  309. }
  310. };