diff options
author | jmagne <jmagne@fba4d07e-fe0f-4d7f-8147-e0026e666dc0> | 2007-04-30 23:30:58 +0000 |
---|---|---|
committer | jmagne <jmagne@fba4d07e-fe0f-4d7f-8147-e0026e666dc0> | 2007-04-30 23:30:58 +0000 |
commit | 01d09b3fda6e1fc805afd1ef9036462afbe363bb (patch) | |
tree | b7cea7d70d817cd6b332fe7efa46837bedb5d222 /src | |
parent | 1100b847661442110a7b89e98ddacd435c509867 (diff) |
Bring Fedora CSP up to one shipped with CertSystem. Bug #23150, rev. WTC.
git-svn-id: http://svn.fedorahosted.org/svn/coolkey/trunk@61 fba4d07e-fe0f-4d7f-8147-e0026e666dc0
Diffstat (limited to 'src')
-rw-r--r-- | src/windows/csp/RegDll.cpp | 4 | ||||
-rw-r--r-- | src/windows/csp/State.cpp | 50 | ||||
-rw-r--r-- | src/windows/csp/State.h | 4 | ||||
-rw-r--r-- | src/windows/csp/csp.cpp | 5 | ||||
-rw-r--r-- | src/windows/csp/csp.h | 1 | ||||
-rw-r--r-- | src/windows/csp/cspx.cpp | 77 |
6 files changed, 135 insertions, 6 deletions
diff --git a/src/windows/csp/RegDll.cpp b/src/windows/csp/RegDll.cpp index fcc1abd..08ece93 100644 --- a/src/windows/csp/RegDll.cpp +++ b/src/windows/csp/RegDll.cpp @@ -36,7 +36,7 @@ extern HINSTANCE g_hModule; "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider" // Windows key values #define TYPE_KEY "Type" -#define IMAGE_KEY "ImagePath" +#define IMAGE_KEY "Image Path" #define SIG_KEY "Signature" // CSP specific key values @@ -44,7 +44,7 @@ extern HINSTANCE g_hModule; #define KEYGEN_KEY "KeyGenHack" #define PIN_KEY "PIN" #define MODULE_KEY "PKCS11Module" -#define DEFAULT_PKCS11_MODULE "coolkey.dll" +#define DEFAULT_PKCS11_MODULE "coolkeypk11.dll" #define DEFAULT_PIN "1234" diff --git a/src/windows/csp/State.cpp b/src/windows/csp/State.cpp index eba3e9a..54eedbf 100644 --- a/src/windows/csp/State.cpp +++ b/src/windows/csp/State.cpp @@ -26,6 +26,7 @@ ******************************************************************/ #include "csp.h" +#include "cspres.h" #include "State.h" #include <winscard.h> @@ -34,7 +35,8 @@ using namespace std; namespace MCSP { State::State() - : init_(false), logging_(false), logFilename_("C:\\CSPDEBUG.log"), slot_(0), keyGenHack_(false), pkcs11dllname_("PKCS11.dll") + : init_(false), logging_(false), logFilename_("C:\\CSPDEBUG.log"), slot_(0), keyGenHack_(false), pkcs11dllname_("PKCS11.dll"), + p11_(CK_INVALID_HANDLE) { lock_ = ::CreateMutex(NULL, FALSE, NULL); @@ -121,9 +123,6 @@ void State::removeSession(Session* session) lock(); sessions_.erase(session); delete session; - - if (sessions_.empty()) - shutdown(); unlock(); } @@ -160,6 +159,43 @@ Key* State::checkValidKey(HCRYPTKEY hKey) return reinterpret_cast<Key*>(hKey); } +void State::login(Session* session) +{ + + int pin_size; + BinStr userPIN; + userPIN.resize(256); + if (!(pin_size = CSPDisplayPinDialog((char*)&userPIN[0], userPIN.size()))) + ThrowMsg(SCARD_W_CANCELLED_BY_USER, "PIN dialog cancelled"); + + userPIN.resize(pin_size); + + CK_RV ck_rv = g_state.p11->C_Login(session->p11_, CKU_USER, + (CK_UTF8CHAR*)&userPIN[0], (CK_ULONG)userPIN.size()); + + if (ck_rv == CKR_OK) + { + if (p11_ != CK_INVALID_HANDLE) + { + LOG("Existing invalid session must be destroyed. \n"); + + g_state.p11->C_CloseSession(p11_); + p11_ = CK_INVALID_HANDLE; + } + ck_rv = g_state.p11->C_OpenSession(g_state.slot(), CKF_RW_SESSION | CKF_SERIAL_SESSION, 0, 0, &p11_); + } + + if (ck_rv != CKR_OK) + { + DisplayError(session, "Error during PIN verification"); + Throw(NTE_FAIL); + } + else + LOG("PIN Verification Successful\n"); + +} + + bool State::shutdown() { if (init()) @@ -187,6 +223,12 @@ bool State::shutdown() keys_.clear(); } + if (p11_ != CK_INVALID_HANDLE) + { + p11->C_CloseSession(p11_); + p11_ = CK_INVALID_HANDLE; + } + g_state.p11->C_Finalize(0); init(false); diff --git a/src/windows/csp/State.h b/src/windows/csp/State.h index c1535d4..fac9523 100644 --- a/src/windows/csp/State.h +++ b/src/windows/csp/State.h @@ -45,6 +45,7 @@ private: std::set<Session*> sessions_; std::set<Key*> keys_; std::string pkcs11dllname_; + CK_SESSION_HANDLE p11_; public: CK_FUNCTION_LIST_PTR p11; @@ -99,6 +100,9 @@ public: bool keyExists(Key* key); Key* checkValidKey(HCRYPTKEY hKey); + + void login(Session* session); + bool shutdown(); void lock() diff --git a/src/windows/csp/csp.cpp b/src/windows/csp/csp.cpp index 43ac030..1ed32af 100644 --- a/src/windows/csp/csp.cpp +++ b/src/windows/csp/csp.cpp @@ -99,9 +99,11 @@ CPAcquireContext( BinStr container_name, reader_name; Session::parseFQCN(szContainer, &container_name, &reader_name); + // Missing output is only allowed for DELETEKEYSET if (!phProv && !(dwFlags & CRYPT_DELETEKEYSET)) ThrowMsg(NTE_FAIL, "Can't return context, phProv is invalid"); + // Do one-time initialization of state if (g_state.init()) LOG("CSP already initialized\n"); else @@ -177,6 +179,7 @@ CPAcquireContext( } else { +#ifdef LOGIN_FOR_SESSION int pin_size; BinStr userPIN; userPIN.resize(256); @@ -195,6 +198,8 @@ CPAcquireContext( } else LOG("PIN Verification Successful\n"); +#endif /* LOGIN_FOR_SESSION */ + g_state.login(context); } } diff --git a/src/windows/csp/csp.h b/src/windows/csp/csp.h index df00ccb..54c72c2 100644 --- a/src/windows/csp/csp.h +++ b/src/windows/csp/csp.h @@ -87,6 +87,7 @@ bool GetExtKeyUsageFromCert(std::vector<std::string>* ext, const BinStr& cert); bool GetModulusFromCert(Session* context, BinStr* modulus, BinStr* exponent, const BinStr& cert); void HexIfBin(BinStr* str); bool InitP11(); +bool IsCACert(const BinStr& cert); void Reverse(BinStr* buf); void Reverse(LPBYTE buf, size_t len); std::string StringifyAquireFlags(DWORD param); diff --git a/src/windows/csp/cspx.cpp b/src/windows/csp/cspx.cpp index 200f43f..70a9b39 100644 --- a/src/windows/csp/cspx.cpp +++ b/src/windows/csp/cspx.cpp @@ -648,6 +648,8 @@ bool FindDefaultCert(Session* context, CK_OBJECT_HANDLE* phCert, BinStr* contain CK_OBJECT_CLASS objClass = CKO_CERTIFICATE; CK_ATTRIBUTE attrib = { CKA_CLASS, &objClass, sizeof(objClass) }; + LOG("FindDefaultCert. \n"); + // start object search for all certificates if (g_state.p11->C_FindObjectsInit(context->p11_, &attrib, 1) != CKR_OK) { @@ -669,6 +671,8 @@ bool FindDefaultCert(Session* context, CK_OBJECT_HANDLE* phCert, BinStr* contain CK_ULONG ulNumFound = 1; while (ulNumFound > 0) { + LOG("FindDefaultCert. Top of while loop, through certs. \n"); + CK_OBJECT_HANDLE hCert; if (g_state.p11->C_FindObjects(context->p11_, &hCert, 1, &ulNumFound) != CKR_OK) ThrowMsg(0, "C_FindObjects failed\n"); @@ -676,6 +680,7 @@ bool FindDefaultCert(Session* context, CK_OBJECT_HANDLE* phCert, BinStr* contain if (ulNumFound == 0) break; + LOG("FindDefaultCert. Num Certs found %d hcert %d. \n",ulNumFound,hCert); // First we want the CKA_ID and CKA_VALUE lengths attrib[0].pValue = 0; attrib[1].pValue = 0; @@ -691,6 +696,10 @@ bool FindDefaultCert(Session* context, CK_OBJECT_HANDLE* phCert, BinStr* contain if (g_state.p11->C_GetAttributeValue(context->p11_, hCert, attrib, sizeof(attrib)/sizeof(CK_ATTRIBUTE)) != CKR_OK) continue; + + if (IsCACert(cert)) + continue; + vector<string> ext; GetExtKeyUsageFromCert(&ext, cert); @@ -703,6 +712,7 @@ bool FindDefaultCert(Session* context, CK_OBJECT_HANDLE* phCert, BinStr* contain haveLogonCert = true; container->swap(ckaid); *phCert = hCert; + LOG("FindDefaultCert. Setting default cert because proper extension found. \n"); break; } } @@ -710,6 +720,7 @@ bool FindDefaultCert(Session* context, CK_OBJECT_HANDLE* phCert, BinStr* contain if (i >= ext.size() && !haveLogonCert) { container->swap(ckaid); + LOG("FindDefaultCert Setting default cert because not a login cert. %d \n",hCert); *phCert = hCert; } } @@ -1011,6 +1022,72 @@ bool GetExtKeyUsageFromCert(vector<string>* ext, const BinStr& cert) return rv; } +bool IsCACert(const BinStr& cert) +{ + bool rv = false; + DWORD cbInfo= 0; + + PCCERT_CONTEXT certContext = 0; + + LOG("IsCACert cert %p size %d \n", &cert,cert.size()); + + cbInfo = sizeof(CERT_BASIC_CONSTRAINTS2_INFO); + + PCERT_BASIC_CONSTRAINTS2_INFO pInfo = + (PCERT_BASIC_CONSTRAINTS2_INFO) LocalAlloc(LPTR,cbInfo); + + if (!pInfo) + return rv; + + try + { + certContext = + CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + &cert[0], cert.size()); + + if (certContext == 0) + ThrowMsg(0, "CertCreateCertificateContext failed"); + + + PCERT_EXTENSION pBC = CertFindExtension(szOID_BASIC_CONSTRAINTS2, + certContext->pCertInfo->cExtension, certContext->pCertInfo->rgExtension); + + if (!pBC) + ThrowMsg(0,"No BASIC_CONSTRAINT extension."); + + DWORD cbDecoded = cbInfo; + + BOOL dResult = CryptDecodeObject(X509_ASN_ENCODING |PKCS_7_ASN_ENCODING , szOID_BASIC_CONSTRAINTS2, + pBC->Value.pbData, pBC->Value.cbData, 0, pInfo,&cbDecoded); + + if (!dResult) + { + + DWORD error = GetLastError(); + + LOG("IsCACert CryptDecodeObject failed! error 0x%lx \n",error); + + ThrowMsg(0,"CryptDecodeObject failed"); + } + + rv = (bool) pInfo->fCA; + + LOG("IsCACert returning fCA %ld fPathLenConstraint %ld dwPathLenConstraint %lu .\n",pInfo->fCA,pInfo->fPathLenConstraint,pInfo->dwPathLenConstraint); + } + catch (Error&) + { + rv = false; + } + + if (certContext) + CertFreeCertificateContext(certContext); + + if (pInfo) + LocalFree(pInfo); + + return rv; +} + string GetCurrentExecutable() { TCHAR szModulePath[MAX_PATH]; |