Source code of Windows XP (NT5)
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.

784 lines
22 KiB

  1. // CryptCtx.cpp -- Cryptographic Context class implementation
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 1999. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #include "stdafx.h"
  8. #include <algorithm>
  9. #include <malloc.h> // for _alloca
  10. #include <scuOsExc.h>
  11. #include <cciPubKey.h>
  12. #include <cciPriKey.h>
  13. #include <cciKeyPair.h>
  14. #include "LoginId.h"
  15. #include "ACntrFinder.h"
  16. #include "Secured.h"
  17. #include "ILoginTask.h"
  18. #include "NILoginTsk.h"
  19. #include "SesKeyCtx.h"
  20. #include "PubKeyCtx.h"
  21. #include "HashCtx.h"
  22. #include "CryptCtx.h"
  23. #include "Uuid.h"
  24. #include "PromptUser.h"
  25. #include "AlignedBlob.h"
  26. #include "scarderr.h" // must be last for now
  27. using namespace std;
  28. using namespace scu;
  29. using namespace cci;
  30. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  31. namespace
  32. {
  33. WORD const dwHandleIdKeyContext = 13;
  34. WORD const dwHandleIdHashContext = 7;
  35. template<class T>
  36. HANDLE_TYPE
  37. AddHandle(auto_ptr<T> &rapObject,
  38. CHandleList &rhl)
  39. {
  40. HANDLE_TYPE handle = rhl.Add(rapObject.get());
  41. rapObject.release();
  42. return handle;
  43. }
  44. CardFinder::DialogDisplayMode
  45. DefaultDialogMode(bool fGuiEnabled)
  46. {
  47. using CardFinder::DialogDisplayMode;
  48. return fGuiEnabled
  49. ? CardFinder::DialogDisplayMode::ddmIfNecessary
  50. : CardFinder::DialogDisplayMode::ddmNever;
  51. }
  52. bool
  53. IsEmpty(CContainer &rcntr)
  54. {
  55. return !rcntr->KeyPairExists(ksExchange) &&
  56. !rcntr->KeyPairExists(ksSignature);
  57. }
  58. bool
  59. IsProtected(CKeyPair const &rhkp)
  60. {
  61. bool fIsProtected = false;
  62. CCard hcard(rhkp->Card());
  63. if (hcard->IsProtectedMode())
  64. fIsProtected = true;
  65. else
  66. {
  67. if (hcard->IsPKCS11Enabled())
  68. {
  69. CPrivateKey hprikey(rhkp->PrivateKey());
  70. if (hprikey && hprikey->Private())
  71. fIsProtected = true;
  72. else
  73. {
  74. CPublicKey hpubkey(rhkp->PublicKey());
  75. if (hpubkey && hpubkey->Private())
  76. fIsProtected = true;
  77. else
  78. {
  79. CCertificate hcert(rhkp->Certificate());
  80. fIsProtected = (hcert && hcert->Private());
  81. }
  82. }
  83. }
  84. }
  85. return fIsProtected;
  86. }
  87. bool
  88. IsProtected(CContainer &rhcntr)
  89. {
  90. return IsProtected(rhcntr->GetKeyPair(ksExchange)) ||
  91. IsProtected(rhcntr->GetKeyPair(ksSignature));
  92. }
  93. } // namespace
  94. /////////////////////////// PUBLIC /////////////////////////////////
  95. // Types
  96. // C'tors/D'tors
  97. CryptContext::CryptContext(CSpec const &rcspec,
  98. PVTableProvStruc const pVTable,
  99. bool fGuiEnabled,
  100. bool fCreateContainer,
  101. bool fEphemeralContainer)
  102. : CHandle(),
  103. m_dwOwnerThreadId(GetCurrentThreadId()),
  104. m_hacntr(),
  105. m_fEphemeralContainer(fEphemeralContainer),
  106. m_fGuiEnabled(fGuiEnabled),
  107. m_hwnd(0),
  108. m_hlKeys(dwHandleIdKeyContext),
  109. m_hlHashes(dwHandleIdHashContext),
  110. m_auxcontext(),
  111. m_ce(),
  112. m_apabCachedAlg()
  113. {
  114. if (pVTable && pVTable->FuncReturnhWnd)
  115. (reinterpret_cast<CRYPT_RETURN_HWND>(pVTable->FuncReturnhWnd))(&m_hwnd);
  116. // An ephemeral container cannot be "created"
  117. if (m_fEphemeralContainer && fCreateContainer)
  118. throw scu::OsException(ERROR_INVALID_PARAMETER);
  119. if (fCreateContainer)
  120. CreateNewContainer(rcspec);
  121. else
  122. OpenExistingContainer(rcspec);
  123. }
  124. CryptContext::~CryptContext()
  125. {
  126. if (m_hacntr)
  127. {
  128. try
  129. {
  130. m_hacntr = 0;
  131. }
  132. catch (...)
  133. {
  134. // don't allow exceptions to propagate out of destructor
  135. }
  136. }
  137. }
  138. // Operators
  139. // Operations
  140. HCRYPTHASH
  141. CryptContext::Add(auto_ptr<CHashContext> &rapHashCtx)
  142. {
  143. return AddHandle(rapHashCtx, m_hlHashes);
  144. }
  145. HCRYPTKEY
  146. CryptContext::Add(auto_ptr<CKeyContext> &rapKeyCtx)
  147. {
  148. return AddHandle(rapKeyCtx, m_hlKeys);
  149. }
  150. HCRYPTKEY
  151. CryptContext::Add(auto_ptr<CPublicKeyContext> &rapPublicKeyCtx)
  152. {
  153. return AddHandle(rapPublicKeyCtx, m_hlKeys);
  154. }
  155. HCRYPTKEY
  156. CryptContext::Add(auto_ptr<CSessionKeyContext> &rapSessionKeyCtx)
  157. {
  158. return AddHandle(rapSessionKeyCtx, m_hlKeys);
  159. }
  160. auto_ptr<CHashContext>
  161. CryptContext::CloseHash(HCRYPTHASH const hHash)
  162. {
  163. return auto_ptr<CHashContext>(reinterpret_cast<CHashContext *>(m_hlHashes.Close(hHash)));
  164. }
  165. auto_ptr<CKeyContext>
  166. CryptContext::CloseKey(HCRYPTKEY const hKey)
  167. {
  168. return auto_ptr<CKeyContext>(reinterpret_cast<CKeyContext *>(m_hlKeys.Close(hKey)));
  169. }
  170. void
  171. CryptContext::CntrEnumerator(ContainerEnumerator const &rce)
  172. {
  173. m_ce = rce;
  174. }
  175. void
  176. CryptContext::EnumAlgorithms(DWORD dwParam,
  177. DWORD dwFlags,
  178. bool fPostAdvanceIterator,
  179. AlignedBlob &rabAlgInfo)
  180. {
  181. bool fFirst = dwFlags & CRYPT_FIRST;
  182. if (fFirst)
  183. m_apabCachedAlg = auto_ptr<AlignedBlob>(0);
  184. if (!m_apabCachedAlg.get())
  185. {
  186. DWORD dwDataLen;
  187. bool bSkip;
  188. do
  189. {
  190. if (CryptGetProvParam(m_auxcontext(),
  191. dwParam,
  192. NULL,
  193. &dwDataLen,
  194. dwFlags) == CRYPT_FAILED)
  195. throw scu::OsException(GetLastError());
  196. BYTE *pbAlgInfo = reinterpret_cast<BYTE *>(_alloca(dwDataLen));
  197. if (CryptGetProvParam(m_auxcontext(),
  198. dwParam,
  199. pbAlgInfo,
  200. &dwDataLen,
  201. dwFlags) == CRYPT_FAILED)
  202. throw scu::OsException(GetLastError());
  203. m_apabCachedAlg =
  204. auto_ptr<AlignedBlob>(new AlignedBlob(pbAlgInfo, dwDataLen));
  205. // Override SIGN and KEYX and algorithms not suported
  206. ALG_ID algid = (PP_ENUMALGS == dwParam)
  207. ? reinterpret_cast<PROV_ENUMALGS *>(m_apabCachedAlg->Data())->aiAlgid
  208. : reinterpret_cast<PROV_ENUMALGS_EX *>(m_apabCachedAlg->Data())->aiAlgid;
  209. switch (GET_ALG_CLASS(algid))
  210. {
  211. case ALG_CLASS_SIGNATURE: // fall-through intentional
  212. case ALG_CLASS_KEY_EXCHANGE:
  213. if (PP_ENUMALGS == dwParam)
  214. {
  215. PROV_ENUMALGS *pAlgEnum =
  216. reinterpret_cast<PROV_ENUMALGS *>(m_apabCachedAlg->Data());
  217. pAlgEnum->dwBitLen = 1024;
  218. }
  219. else
  220. {
  221. PROV_ENUMALGS_EX *pAlgEnum =
  222. reinterpret_cast<PROV_ENUMALGS_EX *>(m_apabCachedAlg->Data());
  223. pAlgEnum->dwDefaultLen =
  224. pAlgEnum->dwMinLen =
  225. pAlgEnum->dwMaxLen = 1024;
  226. }
  227. bSkip = false;
  228. break;
  229. case ALG_CLASS_HASH:
  230. bSkip = (!CHashContext::IsSupported(algid));
  231. break;
  232. case ALG_CLASS_DATA_ENCRYPT:
  233. bSkip = false;
  234. break;
  235. default:
  236. m_apabCachedAlg = auto_ptr<AlignedBlob>(0);
  237. bSkip = true;
  238. break;
  239. }
  240. dwFlags = dwFlags & ~CRYPT_FIRST;
  241. } while (bSkip);
  242. }
  243. rabAlgInfo = m_apabCachedAlg.get()
  244. ? *m_apabCachedAlg
  245. : AlignedBlob();
  246. if (fPostAdvanceIterator)
  247. m_apabCachedAlg = auto_ptr<AlignedBlob>(0);
  248. }
  249. auto_ptr<CPublicKeyContext>
  250. CryptContext::ImportPrivateKey(Blob const &rblbMsPrivateKey,
  251. DWORD dwKeySpec,
  252. bool fExportable,
  253. HCRYPTKEY hEncKey)
  254. {
  255. Secured<HAdaptiveContainer> hsacntr(m_hacntr);
  256. auto_ptr<CPublicKeyContext>
  257. apKeyCtx(ImportPublicKey(rblbMsPrivateKey, dwKeySpec));
  258. BYTE const *pbKeyData = 0;
  259. DWORD dwKeyDataLen = 0;
  260. if (hEncKey || m_fEphemeralContainer)
  261. {
  262. // Export the key in plain text by importing to the aux provider
  263. // and then exporting.
  264. HCRYPTKEY hAuxKey;
  265. AlignedBlob abMsPrivateKey(rblbMsPrivateKey);
  266. if (!CryptImportKey(m_auxcontext(),
  267. abMsPrivateKey.Data(),
  268. abMsPrivateKey.Length(), hEncKey,
  269. CRYPT_EXPORTABLE, &hAuxKey))
  270. throw scu::OsException(GetLastError());
  271. if (!m_fEphemeralContainer)
  272. {
  273. // Export the key in plain text
  274. if (!CryptExportKey(m_auxcontext(), NULL, PRIVATEKEYBLOB, 0, NULL,
  275. &dwKeyDataLen))
  276. throw scu::OsException(GetLastError());
  277. // Define pb to avoid "const" cast problems due to
  278. // rblbMsPrivateKey.data below
  279. BYTE *pb = reinterpret_cast<BYTE *>(_alloca(dwKeyDataLen));
  280. if (!CryptExportKey(m_auxcontext(), NULL, PRIVATEKEYBLOB, 0, pb,
  281. &dwKeyDataLen))
  282. throw scu::OsException(GetLastError());
  283. pbKeyData = pb;
  284. // Scrub the key imported into the aux provider. To do this,
  285. // the auxillary key must be destroyed and another key be put
  286. // (generated) in its place.
  287. if (!CryptDestroyKey(hAuxKey))
  288. throw scu::OsException(GetLastError());
  289. hAuxKey = NULL;
  290. if (!CryptGenKey(m_auxcontext(), dwKeySpec, 0, &hAuxKey))
  291. throw scu::OsException(GetLastError());
  292. if (!CryptDestroyKey(hAuxKey))
  293. throw scu::OsException(GetLastError());
  294. }
  295. }
  296. else
  297. {
  298. pbKeyData = rblbMsPrivateKey.data();
  299. dwKeyDataLen = rblbMsPrivateKey.length();
  300. }
  301. if (!m_fEphemeralContainer)
  302. {
  303. // Now continue importing the key that's now in plain text.
  304. MsRsaPrivateKeyBlob msprikb(pbKeyData, dwKeyDataLen);
  305. apKeyCtx->ImportPrivateKey(msprikb, fExportable);
  306. }
  307. return apKeyCtx;
  308. }
  309. auto_ptr<CPublicKeyContext>
  310. CryptContext::ImportPublicKey(Blob const &rblbMsPublicKey,
  311. DWORD dwKeySpec)
  312. {
  313. Secured<HAdaptiveContainer> hsacntr(m_hacntr);
  314. auto_ptr<CPublicKeyContext>
  315. apKeyCtx(new CPublicKeyContext(m_auxcontext(), *this,
  316. dwKeySpec, false));
  317. if (m_fEphemeralContainer)
  318. apKeyCtx->AuxPublicKey(AlignedBlob(rblbMsPublicKey));
  319. else
  320. {
  321. MsRsaPublicKeyBlob mspubkb(rblbMsPublicKey.data(),
  322. rblbMsPublicKey.length());
  323. apKeyCtx->ImportPublicKey(mspubkb);
  324. }
  325. return apKeyCtx;
  326. }
  327. void
  328. CryptContext::Login(LoginIdentity const &rlid)
  329. {
  330. Secured<HCardContext> hscardctx(AdaptiveContainer()->CardContext());
  331. Login(rlid, hscardctx);
  332. }
  333. void
  334. CryptContext::Pin(LoginIdentity const &rlid,
  335. char const *pszPin)
  336. {
  337. Secured<HCardContext> hscardctx(AdaptiveContainer()->CardContext());
  338. // TO DO: Support Entrust
  339. if (pszPin)
  340. hscardctx->Login(rlid, NonInteractiveLoginTask(string(pszPin)));
  341. else
  342. hscardctx->ClearLogin(rlid);
  343. }
  344. // Remove (destroy) the container from the card
  345. void
  346. CryptContext::RemoveContainer()
  347. {
  348. Secured<HCardContext> hscardctx(AdaptiveContainer()->CardContext());
  349. CContainer hcntr(m_hacntr->TheCContainer());
  350. DeleteContainer(hscardctx, hcntr);
  351. m_hacntr = 0; // disconnect from container
  352. }
  353. // Generate a key, string it in the context
  354. HCRYPTKEY
  355. CryptContext::GenerateKey(ALG_ID algid,
  356. DWORD dwFlags)
  357. {
  358. // TO DO: Revisit this method, implement as a manager/factory?
  359. HCRYPTKEY hKey = 0;
  360. auto_ptr<CKeyContext> apKey;
  361. bool bError = false;
  362. DWORD dwErrorCode = NO_ERROR;
  363. //
  364. // Verify the parameters.
  365. //
  366. switch(algid)
  367. {
  368. case AT_KEYEXCHANGE:
  369. case AT_SIGNATURE:
  370. {
  371. if (dwFlags & (CRYPT_CREATE_SALT | CRYPT_NO_SALT | CRYPT_PREGEN))
  372. throw scu::OsException(NTE_BAD_FLAGS);
  373. Secured<HAdaptiveContainer> hsacntr(m_hacntr);
  374. apKey =
  375. auto_ptr<CKeyContext>(new CPublicKeyContext(m_auxcontext(),
  376. *this,
  377. algid,
  378. false));
  379. apKey->Generate(algid, dwFlags);
  380. }
  381. break;
  382. default:
  383. apKey =
  384. auto_ptr<CKeyContext>(new CSessionKeyContext(m_auxcontext()));
  385. apKey->Generate(algid, dwFlags);
  386. break;
  387. }
  388. hKey = Add(apKey);
  389. return hKey;
  390. }
  391. // Load an external Session Key.
  392. auto_ptr<CSessionKeyContext>
  393. CryptContext::UseSessionKey(BYTE const *pbKeyBlob,
  394. DWORD cbKeyBlobLen,
  395. HCRYPTKEY hAuxImpKey,
  396. DWORD dwFlags)
  397. {
  398. // TO DO: Revisit this method, really necessary??
  399. auto_ptr<CSessionKeyContext>
  400. apKeyCtx(new CSessionKeyContext(m_auxcontext()));
  401. if (!apKeyCtx.get())
  402. throw scu::OsException(NTE_NO_MEMORY);
  403. // Decrypt key blob if encrypted with Key Exchange Key
  404. // otherwise forward blob to Auxiliary CSP directly
  405. ALG_ID const *pAlgId =
  406. reinterpret_cast<ALG_ID const *>(&pbKeyBlob[sizeof(BLOBHEADER)]);
  407. if (CALG_RSA_KEYX == *pAlgId)
  408. {
  409. // Get Key exchange key
  410. // TO DO: Shouldn't this be getting a private key?
  411. auto_ptr<CPublicKeyContext>
  412. apXKey(new CPublicKeyContext(m_auxcontext(), *this,
  413. AT_KEYEXCHANGE));
  414. // Decrypt key blob
  415. // TO DO: Support multiple key sizes
  416. Blob EncryptedKey(pbKeyBlob + sizeof BLOBHEADER + sizeof ALG_ID,
  417. 128);
  418. Blob DecryptedKey(apXKey->Decrypt(EncryptedKey));
  419. // Recreate the blob
  420. Blob DecryptedBlob(pbKeyBlob, sizeof BLOBHEADER + sizeof ALG_ID);
  421. // we must trim out 64 bytes of the random data from the simple
  422. // blob and then terminate it. (Termination occurs by making the
  423. // n-1 byte = 0x02 and the nth byte = 0x00.) This is necessary
  424. // in order to import this blob into the CSP.
  425. DecryptedBlob.append(DecryptedKey.data(),
  426. (DecryptedKey.length() / 2) - 2);
  427. BYTE bTerminationBytes[] = { 0x02, 0x00 };
  428. DecryptedBlob.append(bTerminationBytes, sizeof bTerminationBytes);
  429. // Load Decrypted blob into key context
  430. apKeyCtx->LoadKey(DecryptedBlob.data(),
  431. DecryptedBlob.length(), 0, dwFlags);
  432. }
  433. else
  434. {
  435. // Load Encrypted blob into key context
  436. apKeyCtx->LoadKey(pbKeyBlob, cbKeyBlobLen, hAuxImpKey, dwFlags);
  437. }
  438. // Import decrypted blob into Auxiliary CSP
  439. apKeyCtx->ImportToAuxCSP();
  440. return apKeyCtx;
  441. }
  442. // Access
  443. HAdaptiveContainer
  444. CryptContext::AdaptiveContainer() const
  445. {
  446. if (!m_hacntr)
  447. throw scu::OsException(ERROR_INVALID_PARAMETER);
  448. return m_hacntr;
  449. }
  450. HCRYPTPROV
  451. CryptContext::AuxContext() const
  452. {
  453. return m_auxcontext();
  454. }
  455. HCardContext
  456. CryptContext::CardContext() const
  457. {
  458. return AdaptiveContainer()->CardContext();
  459. }
  460. ContainerEnumerator
  461. CryptContext::CntrEnumerator(bool fReset)
  462. {
  463. if (fReset)
  464. {
  465. if (m_hacntr)
  466. m_ce = ContainerEnumerator(list<HCardContext>(1, m_hacntr->CardContext()));
  467. else
  468. {
  469. CardEnumerator ce;
  470. m_ce = ContainerEnumerator(*(ce.Cards()));
  471. }
  472. }
  473. return m_ce;
  474. }
  475. CHashContext *
  476. CryptContext::LookupHash(HCRYPTHASH hHash)
  477. {
  478. return reinterpret_cast<CHashContext *>(m_hlHashes[hHash]);
  479. }
  480. CKeyContext *
  481. CryptContext::LookupKey(HCRYPTKEY hKey)
  482. {
  483. return reinterpret_cast<CKeyContext *>(m_hlKeys[hKey]);
  484. }
  485. CPublicKeyContext *
  486. CryptContext::LookupPublicKey(HCRYPTKEY hKey)
  487. {
  488. return reinterpret_cast<CPublicKeyContext *>(LookupChecked(hKey, KT_PUBLICKEY));
  489. }
  490. CSessionKeyContext *
  491. CryptContext::LookupSessionKey(HCRYPTKEY hKey)
  492. {
  493. return reinterpret_cast<CSessionKeyContext *>(LookupChecked(hKey, KT_SESSIONKEY));
  494. }
  495. HWND
  496. CryptContext::Window() const
  497. {
  498. HWND hwndActive = m_hwnd;
  499. // Find a window if the designated one isn't valid. If the
  500. // designated one is NULL, don't use the result of GetActiveWindow
  501. // because the mouse is locked when displaying a dialog box using
  502. // that as the parent window from certain applications (IE and
  503. // Outlook Express).
  504. return (m_hwnd && !IsWindow(m_hwnd))
  505. ? GetActiveWindow()
  506. : m_hwnd;
  507. }
  508. // Predicates
  509. bool
  510. CryptContext::GuiEnabled() const
  511. {
  512. return m_fGuiEnabled;
  513. }
  514. bool
  515. CryptContext::IsEphemeral() const
  516. {
  517. return m_fEphemeralContainer;
  518. }
  519. // Static Variables
  520. /////////////////////////// PROTECTED /////////////////////////////////
  521. // C'tors/D'tors
  522. // Operators
  523. // Operations
  524. // Access
  525. // Predicates
  526. // Static Variables
  527. /////////////////////////// PRIVATE /////////////////////////////////
  528. // C'tors/D'tors
  529. // Operators
  530. // Operations
  531. // Create and open a new container (named by rcspec). If the
  532. // container does exist, then it must be empty.
  533. void
  534. CryptContext::CreateNewContainer(CSpec const &rcspec)
  535. {
  536. ASSERT (!m_hacntr);
  537. // Find the card in the reader specified.
  538. CardFinder cardfinder(DefaultDialogMode(GuiEnabled()), Window());
  539. CSpec csReader(rcspec);
  540. csReader.SetReader(rcspec.Reader());
  541. Secured<HCardContext> hscardctx(cardfinder.Find(csReader));
  542. // Default the container name a UUID (GUID) if it wasn't supplied.
  543. string sCntrToCreate(rcspec.CardId());
  544. if (sCntrToCreate.empty())
  545. {
  546. Uuid uuid;
  547. sCntrToCreate = AsString(uuid.AsUString());
  548. }
  549. AdaptiveContainerKey Key(hscardctx, sCntrToCreate);
  550. m_hacntr = AdaptiveContainer::Find(Key); // find the existing one
  551. if (m_hacntr && !IsEmpty(m_hacntr->TheCContainer()))
  552. throw scu::OsException(NTE_TOKEN_KEYSET_STORAGE_FULL);
  553. if (hscardctx->Card()->IsProtectedMode())
  554. Login(User, hscardctx);
  555. if (!m_hacntr)
  556. m_hacntr = HAdaptiveContainer(Key);
  557. }
  558. void
  559. CryptContext::DeleteContainer(Secured<HCardContext> &rhscardctx,
  560. CContainer &rhcntr)
  561. {
  562. if (IsProtected(rhcntr))
  563. Login(User, rhscardctx);
  564. AdaptiveContainer::Discard(AdaptiveContainerKey(rhscardctx,
  565. rhcntr->Name()));
  566. rhcntr->Delete();
  567. }
  568. void
  569. CryptContext::Login(LoginIdentity const &rlid,
  570. Secured<HCardContext> &rhscardctx)
  571. {
  572. // TO DO: Support Entrust
  573. if (m_fGuiEnabled)
  574. rhscardctx->Login(rlid, InteractiveLoginTask(Window()));
  575. else
  576. rhscardctx->Login(rlid, LoginTask());
  577. }
  578. void
  579. CryptContext::OkDeletingCredentials() const
  580. {
  581. if (GuiEnabled())
  582. {
  583. UINT uiResponse = PromptUser(Window(),
  584. IDS_DELETE_CREDENTIALS,
  585. MB_OKCANCEL | MB_ICONWARNING);
  586. switch (uiResponse)
  587. {
  588. case IDCANCEL:
  589. throw scu::OsException(ERROR_CANCELLED);
  590. break;
  591. case IDOK:
  592. break;
  593. default:
  594. throw scu::OsException(ERROR_INTERNAL_ERROR);
  595. break;
  596. };
  597. }
  598. else
  599. throw scu::OsException(NTE_EXISTS);
  600. }
  601. // Access
  602. CKeyContext *
  603. CryptContext::LookupChecked(HCRYPTKEY hKey,
  604. DWORD const dwKeyType)
  605. {
  606. CKeyContext *pKeyCtx = LookupKey(hKey);
  607. if (dwKeyType != pKeyCtx->TypeOfKey())
  608. throw scu::OsException(ERROR_INVALID_PARAMETER);
  609. return pKeyCtx;
  610. }
  611. // Open to an existing container specified by the container
  612. // specification rcspec. If container name is empty, then open the
  613. // default container.
  614. void
  615. CryptContext::OpenExistingContainer(CSpec const &rcspec)
  616. {
  617. if (rcspec.CardId().empty())
  618. {
  619. if (!m_fEphemeralContainer)
  620. {
  621. CardFinder cardfinder(DefaultDialogMode(GuiEnabled()), Window());
  622. Secured<HCardContext> hscardctx(cardfinder.Find(rcspec));
  623. CContainer hcntr(hscardctx->Card()->DefaultContainer());
  624. if (hcntr)
  625. m_hacntr =
  626. HAdaptiveContainer(AdaptiveContainerKey(hscardctx,
  627. hcntr->Name()));
  628. }
  629. }
  630. else
  631. {
  632. AContainerFinder cntrfinder(DefaultDialogMode(GuiEnabled()), Window());
  633. m_hacntr = cntrfinder.Find(rcspec);
  634. }
  635. if (!m_hacntr && (!rcspec.CardId().empty() || !m_fEphemeralContainer))
  636. throw scu::OsException(NTE_BAD_KEYSET);
  637. }
  638. // Predicates
  639. // Static Variables