#ifndef SSLCERTSTOREMANAGER_H
#define SSLCERTSTOREMANAGER_H
#include "Noncopyable.h"
#include <WinCrypt.h>
namespace WebCore
{
class SSLCertStoreManager :public Noncopyable
{
public:
static SSLCertStoreManager& getInstance();
bool findCertInStore(bool& inAcceptingStore, PCCERT_CONTEXT cert);
bool saveCertInStore(bool inAcceptingStore, PCCERT_CONTEXT cert);
~SSLCertStoreManager();
private:
SSLCertStoreManager();
bool init();
bool isStoreReady();
bool find(PCCERT_CONTEXT cert, HCERTSTORE store);
bool save(bool inAcceptingStore, PCCERT_CONTEXT cert);
void flush();
void open();
void close();
HCERTSTORE m_trustedStore;
HCERTSTORE m_untrustedStore;
bool m_ready;
};
}
#endif //SSLCERTSTOREMANAGER_H
#include "config.h"
#include "SSLCertStoreManager.h"
#include "WTFString.h"
#define ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
const LPCTSTR WebkitRegistryRoot = L"Software\\WebKit\\";
const LPCTSTR TrustedStorePosition = L"TrustedStoreKey";
const LPCTSTR UntrustedStorePosition = L"UntrustedStoreKey";
const LPCTSTR TrustedStoreFileName = L"\\SD\\BROWSER\\TrustedStore.sto";
const LPCTSTR UntrustedStoreFileName = L"\\SD\\BROWSER\\UntrustedStore.sto";
namespace WebCore
{
SSLCertStoreManager& SSLCertStoreManager::getInstance()
{
static SSLCertStoreManager instance;
return instance;
}
static HKEY getKey(LPCTSTR subKey)
{
String strKey(WebkitRegistryRoot);
strKey += subKey;
HKEY hKey;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER,
strKey.charactersWithNullTermination(), 0, KEY_ALL_ACCESS, &hKey))
{
DWORD dwDisp = 0;
int succ = RegCreateKeyEx(HKEY_CURRENT_USER,
strKey.charactersWithNullTermination(), 0, NULL, 0, 0, NULL, &hKey, &dwDisp);
if (succ != ERROR_SUCCESS)
return NULL;
RegCloseKey(hKey);
return getKey(subKey);
}
return hKey;
}
static HANDLE getFileHandle(LPCTSTR storeFileName)
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
// Obtain a file handle.
return CreateFile(
storeFileName,
GENERIC_READ|GENERIC_WRITE,
0,
&sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
}
static HCERTSTORE openStore(LPCTSTR storeFileName)
{
HANDLE hFile = getFileHandle(storeFileName);
if (!hFile)
return NULL;
HCERTSTORE store = CertOpenStore(
CERT_STORE_PROV_FILE, // load certificates from a file
ENCODING_TYPE,
NULL, // use the default HCRYPTPROV
0,
hFile
);
CloseHandle(hFile);
return store;
}
bool SSLCertStoreManager::init()
{
m_trustedStore = openStore(TrustedStoreFileName);
m_untrustedStore = openStore(UntrustedStoreFileName);
m_ready = m_trustedStore && m_untrustedStore;
return m_ready;
}
SSLCertStoreManager::SSLCertStoreManager()
{
init();
}
SSLCertStoreManager::~SSLCertStoreManager()
{
if (m_trustedStore)
CertCloseStore(m_trustedStore, CERT_CLOSE_STORE_FORCE_FLAG);
if (m_untrustedStore)
CertCloseStore(m_untrustedStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
bool SSLCertStoreManager::isStoreReady()
{
return m_ready;
}
bool SSLCertStoreManager::find(PCCERT_CONTEXT cert, HCERTSTORE store)
{
PCCERT_CONTEXT temp = CertFindCertificateInStore(
store,
ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // No dwFlags needed
CERT_FIND_EXISTING,
cert,
NULL);
bool succ = (temp != NULL);
if (temp != NULL)
CertFreeCertificateContext(temp);
return succ;
}
bool SSLCertStoreManager::findCertInStore(bool& inAcceptingStore, PCCERT_CONTEXT cert)
{
if (!isStoreReady())
return false;
if (find(cert, m_trustedStore))
{
inAcceptingStore = true;
return true;
}
if (find(cert, m_untrustedStore))
{
inAcceptingStore = false;
return true;
}
return false;
}
bool SSLCertStoreManager::save(bool inAcceptingStore, PCCERT_CONTEXT cert)
{
HCERTSTORE hStore = inAcceptingStore? m_trustedStore:m_untrustedStore;
BOOL succ = CertAddCertificateContextToStore(hStore, cert, CERT_STORE_ADD_NEW, 0);
if (!succ)
return false;
LPCTSTR storeName = inAcceptingStore? TrustedStoreFileName:UntrustedStoreFileName;
HANDLE hFile = getFileHandle(storeName);
if (!hFile)
return false;
succ = CertSaveStore(
hStore,
ENCODING_TYPE,
CERT_STORE_SAVE_AS_STORE,
CERT_STORE_SAVE_TO_FILE,
hFile,
0);
CloseHandle(hFile);
return succ && succ;
}
bool SSLCertStoreManager::saveCertInStore(bool inAcceptingStore, PCCERT_CONTEXT cert)
{
if (!isStoreReady())
return false;
return save(inAcceptingStore, cert);
}
}
沒有留言:
張貼留言