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

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
certcach.hxx
Abstract:
Contains class definition for certificate cache object.
The class acts a container for common certificates.
Contents:
SECURITY_CACHE_LIST
SECURITY_CACHE_LIST_ENTRY
Author:
Arthur L Bierer (arthurbi) 20-Apr-1996
Revision History:
20-Apr-1996 arthurbi
Created
--*/
typedef struct _SEC_PROVIDER
{
CHAR *pszName; // security pkg name
CredHandle hCreds; // credential handle
DWORD dwFlags; // encryption capabilities
BOOL fEnabled; // enable flag indicator
DWORD dwProtocolFlags; // protocol flags that this provider supports.
PCCERT_CONTEXT pCertCtxt; // cert context to use when getting default credentials.
} SEC_PROVIDER, *PSEC_PROVIDER;
// Default list of security packages to enumerate
#define MAX_SEC_PROVIDERS 3
extern const SEC_PROVIDER g_cSecProviders[MAX_SEC_PROVIDERS];
enum SSL_IMPERSONATION_LEVEL
{
SSL_IMPERSONATION_DISABLED = 0,
SSL_IMPERSONATION_ENABLED = 1,
SSL_IMPERSONATION_UNINITIALIZED = 2
};
//
// SECURITY_INFO_LIST_ENTRY - contains all security info
// pertaining to all connections to a server.
//
class SECURITY_CACHE_LIST_ENTRY {
friend class SECURITY_CACHE_LIST;
private:
//
// _List - Generic List entry structure.
//
LIST_ENTRY _List;
//
// _cRef - Reference count for this element.
//
LONG _cRef;
//
// _CertInfo - Certificate and other security
// attributes for the connection to
// this machine.
//
INTERNET_SECURITY_INFO _CertInfo;
//
// _dwSecurityFlags - Overrides for warnings.
//
DWORD _dwSecurityFlags;
//
// _dwStatusFlags - Tracker for all secure connection failure flags.
//
DWORD _dwStatusFlags;
//
// _ServerName - The name of the server
//
ICSTRING _ServerName;
INTERNET_PORT _ServerPort;
//
// _pCertChainList - If there is Client Authentication do be done with this server,
// then we'll cache it and remeber it later.
//
CERT_CONTEXT_ARRAY *_pCertContextArray;
//
// _fInCache - indicates this element is held by the cache
//
BOOL _fInCache;
//
// _fNoRevert - indicates whether or not any potential impersonation
// should be reverted during SSL handling.
//
BOOL _fNoRevert;
#if INET_DEBUG
DWORD m_Signature;
#endif
public:
LONG AddRef(VOID);
LONG Release(VOID);
//
// Cleans up object, so it can be reused
//
BOOL InCache() { return _fInCache; }
const INTERNET_SECURITY_INFO& GetSecInfo() const { return _CertInfo; }
VOID
Clear();
SECURITY_CACHE_LIST_ENTRY(
IN BOOL fNoRevert,
IN LPSTR lpszHostName,
IN INTERNET_PORT ServerPort
);
~SECURITY_CACHE_LIST_ENTRY();
//
// Copy CERT_INFO IN Method -
// copies a structure into our object.
//
SECURITY_CACHE_LIST_ENTRY& operator=(LPINTERNET_SECURITY_INFO Cert)
{
if(_CertInfo.pCertificate)
{
WRAP_REVERT_USER_VOID((*g_pfnCertFreeCertificateContext),
_fNoRevert,
(_CertInfo.pCertificate));
}
_CertInfo.dwSize = sizeof(_CertInfo);
WRAP_REVERT_USER((*g_pfnCertDuplicateCertificateContext),
_fNoRevert,
(Cert->pCertificate),
_CertInfo.pCertificate);
_CertInfo.dwProtocol = Cert->dwProtocol;
_CertInfo.aiCipher = Cert->aiCipher;
_CertInfo.dwCipherStrength = Cert->dwCipherStrength;
_CertInfo.aiHash = Cert->aiHash;
_CertInfo.dwHashStrength = Cert->dwHashStrength;
_CertInfo.aiExch = Cert->aiExch;
_CertInfo.dwExchStrength = Cert->dwExchStrength;
return *this;
}
//
// Copy CERT_INFO OUT Method -
// need to copy ourselves out.
//
VOID
CopyOut(INTERNET_SECURITY_INFO &Cert)
{
Cert.dwSize = sizeof(Cert);
WRAP_REVERT_USER((*g_pfnCertDuplicateCertificateContext),
_fNoRevert,
(_CertInfo.pCertificate),
Cert.pCertificate);
Cert.dwProtocol = _CertInfo.dwProtocol;
Cert.aiCipher = _CertInfo.aiCipher;
Cert.dwCipherStrength = _CertInfo.dwCipherStrength;
Cert.aiHash = _CertInfo.aiHash;
Cert.dwHashStrength = _CertInfo.dwHashStrength;
Cert.aiExch = _CertInfo.aiExch;
Cert.dwExchStrength = _CertInfo.dwExchStrength;
}
//
// Sets and Gets the Client Authentication CertChain -
// we piggy back this pointer into the cache so we can cache
// previously generated and selected client auth certs.
//
VOID SetCertContextArray(CERT_CONTEXT_ARRAY *pCertContextArray) {
if (_pCertContextArray) {
delete _pCertContextArray;
}
_pCertContextArray = pCertContextArray;
}
CERT_CONTEXT_ARRAY * GetCertContextArray() {
return _pCertContextArray;
}
DWORD GetSecureFlags() {
return _dwSecurityFlags;
}
VOID SetSecureFlags(DWORD dwFlags) {
_dwSecurityFlags |= dwFlags;
}
VOID ClearSecureFlags(DWORD dwFlags) {
_dwSecurityFlags &= (~dwFlags);
}
DWORD GetStatusFlags(VOID)
{
return _dwStatusFlags;
}
VOID SetStatusFlags(DWORD dwFlags)
{
_dwStatusFlags |= dwFlags;
}
VOID ClearStatusFlags(DWORD dwFlags)
{
_dwStatusFlags &= (~dwFlags);
}
LPSTR GetHostName(VOID) {
return _ServerName.StringAddress();
}
BOOL IsImpersonationEnabled() {
return _fNoRevert;
}
};
class SECURITY_CACHE_LIST {
private:
//
// _List - serialized list of SECURITY_CACHE_LIST_ENTRY objects
//
SERIALIZED_LIST _List;
#if INET_DEBUG
DWORD m_Signature;
#endif
//
// Array of encryption providers
//
SEC_PROVIDER _SecProviders[MAX_SEC_PROVIDERS];
//
// EncProvider flag
//
DWORD _dwEncFlags;
// Enabled SSL protocols for the session
DWORD _dwSecureProtocols;
SSL_IMPERSONATION_LEVEL _eImpersonationLevel;
LONG _cRefs;
public:
SECURITY_CACHE_LIST()
{
_cRefs = 1;
_eImpersonationLevel = SSL_IMPERSONATION_UNINITIALIZED;
}
LONG AddRef(VOID)
{
return (InterlockedIncrement(&_cRefs));
}
LONG Release(VOID)
{
// We can get away with interlocked increment/decrement
// because we're guaranteed to always have a live WHO
// reference anytime this is addref'ed.
LONG cRefs = InterlockedDecrement(&_cRefs);
if (cRefs == 0)
{
Terminate();
delete this;
}
return cRefs;
}
SECURITY_CACHE_LIST_ENTRY *
Find(
IN LPSTR lpszHostname,
IN INTERNET_PORT HostPort
);
BOOL Initialize(
VOID
);
VOID Terminate(
VOID
);
VOID
ClearList(
VOID
);
DWORD
Add(
IN SECURITY_CACHE_LIST_ENTRY * entry
);
#if 0
BOOL
IsCertInCache(
IN LPSTR lpszHostname
)
{
SECURITY_CACHE_LIST_ENTRY *entry =
Find(lpszHostname);
if ( entry )
return TRUE;
return FALSE;
}
#endif
VOID SetSecureProtocols(DWORD dwSecureProtocols)
{
_dwSecureProtocols = dwSecureProtocols;
}
DWORD GetSecureProtocols()
{
return _dwSecureProtocols;
}
VOID SetEncFlags(DWORD dwEncFlags)
{
_dwEncFlags = dwEncFlags;
}
DWORD GetEncFlags()
{
return _dwEncFlags;
}
SEC_PROVIDER *GetSecProviders()
{
return _SecProviders;
}
DWORD SetImpersonationLevel(BOOL fLeaveImpersonation)
{
if (_eImpersonationLevel == SSL_IMPERSONATION_UNINITIALIZED)
{
_eImpersonationLevel = (fLeaveImpersonation ?
SSL_IMPERSONATION_ENABLED : SSL_IMPERSONATION_DISABLED);
return ERROR_SUCCESS;
}
else
{
// Can only be set once. This must also be initialized
// upon creation of the first request handle if the
// client doesn't set prior the first send request.
return ERROR_WINHTTP_INCORRECT_HANDLE_STATE;
}
}
BOOL IsImpersonationLevelInitialized()
{
return (_eImpersonationLevel == SSL_IMPERSONATION_UNINITIALIZED);
}
BOOL IsImpersonationEnabled()
{
return (_eImpersonationLevel == SSL_IMPERSONATION_ENABLED);
}
};