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.

785 lines
23 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 <scuOsExc.h>
  10. #include <scuArrayP.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. AutoArrayPtr<BYTE> apbAlgInfo (new BYTE[dwDataLen]);
  197. if (CryptGetProvParam(m_auxcontext(),
  198. dwParam,
  199. apbAlgInfo.Get(),
  200. &dwDataLen,
  201. dwFlags) == CRYPT_FAILED)
  202. throw scu::OsException(GetLastError());
  203. m_apabCachedAlg =
  204. auto_ptr<AlignedBlob>(new AlignedBlob(apbAlgInfo.Get(), 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(SecureArray<BYTE> 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. SecureArray<BYTE> apb(0);
  259. BYTE const *pbKeyData = 0;
  260. DWORD dwKeyDataLen = 0;
  261. if (hEncKey || m_fEphemeralContainer)
  262. {
  263. // Export the key in plain text by importing to the aux provider
  264. // and then exporting.
  265. HCRYPTKEY hAuxKey;
  266. if (!CryptImportKey(m_auxcontext(),
  267. rblbMsPrivateKey.data(),
  268. rblbMsPrivateKey.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. apb = SecureArray<BYTE>(dwKeyDataLen);
  278. if (!CryptExportKey(m_auxcontext(), NULL, PRIVATEKEYBLOB, 0, apb.data(),
  279. &dwKeyDataLen))
  280. throw scu::OsException(GetLastError());
  281. pbKeyData = apb.data();
  282. // Scrub the key imported into the aux provider. To do this,
  283. // the auxillary key must be destroyed and another key be put
  284. // (generated) in its place.
  285. if (!CryptDestroyKey(hAuxKey))
  286. throw scu::OsException(GetLastError());
  287. hAuxKey = NULL;
  288. if (!CryptGenKey(m_auxcontext(), dwKeySpec, 0, &hAuxKey))
  289. throw scu::OsException(GetLastError());
  290. if (!CryptDestroyKey(hAuxKey))
  291. throw scu::OsException(GetLastError());
  292. }
  293. }
  294. else
  295. {
  296. pbKeyData = rblbMsPrivateKey.data();
  297. dwKeyDataLen = rblbMsPrivateKey.length();
  298. }
  299. if (!m_fEphemeralContainer)
  300. {
  301. // Now continue importing the key that's now in plain text.
  302. MsRsaPrivateKeyBlob msprikb(pbKeyData, dwKeyDataLen);
  303. apKeyCtx->ImportPrivateKey(msprikb, fExportable);
  304. }
  305. return apKeyCtx;
  306. }
  307. auto_ptr<CPublicKeyContext>
  308. CryptContext::ImportPublicKey(SecureArray<BYTE> const &rblbMsPublicKey,
  309. DWORD dwKeySpec)
  310. {
  311. Secured<HAdaptiveContainer> hsacntr(m_hacntr);
  312. auto_ptr<CPublicKeyContext>
  313. apKeyCtx(new CPublicKeyContext(m_auxcontext(), *this,
  314. dwKeySpec, false));
  315. if (m_fEphemeralContainer)
  316. apKeyCtx->AuxPublicKey(rblbMsPublicKey);
  317. else
  318. {
  319. MsRsaPublicKeyBlob mspubkb(rblbMsPublicKey.data(),
  320. rblbMsPublicKey.length());
  321. apKeyCtx->ImportPublicKey(mspubkb);
  322. }
  323. return apKeyCtx;
  324. }
  325. void
  326. CryptContext::Login(LoginIdentity const &rlid)
  327. {
  328. Secured<HCardContext> hscardctx(AdaptiveContainer()->CardContext());
  329. Login(rlid, hscardctx);
  330. }
  331. void
  332. CryptContext::Pin(LoginIdentity const &rlid,
  333. char const *pszPin)
  334. {
  335. Secured<HCardContext> hscardctx(AdaptiveContainer()->CardContext());
  336. // TO DO: Support Entrust
  337. if (pszPin)
  338. hscardctx->Login(rlid, NonInteractiveLoginTask(pszPin));
  339. else
  340. hscardctx->ClearLogin(rlid);
  341. }
  342. // Remove (destroy) the container from the card
  343. void
  344. CryptContext::RemoveContainer()
  345. {
  346. Secured<HCardContext> hscardctx(AdaptiveContainer()->CardContext());
  347. CContainer hcntr(m_hacntr->TheCContainer());
  348. DeleteContainer(hscardctx, hcntr);
  349. m_hacntr = 0; // disconnect from container
  350. }
  351. // Generate a key, string it in the context
  352. HCRYPTKEY
  353. CryptContext::GenerateKey(ALG_ID algid,
  354. DWORD dwFlags)
  355. {
  356. // TO DO: Revisit this method, implement as a manager/factory?
  357. HCRYPTKEY hKey = 0;
  358. auto_ptr<CKeyContext> apKey;
  359. bool bError = false;
  360. DWORD dwErrorCode = NO_ERROR;
  361. //
  362. // Verify the parameters.
  363. //
  364. switch(algid)
  365. {
  366. case AT_KEYEXCHANGE:
  367. case AT_SIGNATURE:
  368. {
  369. if (dwFlags & (CRYPT_CREATE_SALT | CRYPT_NO_SALT | CRYPT_PREGEN))
  370. throw scu::OsException(NTE_BAD_FLAGS);
  371. Secured<HAdaptiveContainer> hsacntr(m_hacntr);
  372. apKey =
  373. auto_ptr<CKeyContext>(new CPublicKeyContext(m_auxcontext(),
  374. *this,
  375. algid,
  376. false));
  377. apKey->Generate(algid, dwFlags);
  378. }
  379. break;
  380. default:
  381. apKey =
  382. auto_ptr<CKeyContext>(new CSessionKeyContext(m_auxcontext()));
  383. apKey->Generate(algid, dwFlags);
  384. break;
  385. }
  386. hKey = Add(apKey);
  387. return hKey;
  388. }
  389. // Load an external Session Key.
  390. auto_ptr<CSessionKeyContext>
  391. CryptContext::UseSessionKey(BYTE const *pbKeyBlob,
  392. DWORD cbKeyBlobLen,
  393. HCRYPTKEY hAuxImpKey,
  394. DWORD dwFlags)
  395. {
  396. // TO DO: Revisit this method, really necessary??
  397. auto_ptr<CSessionKeyContext>
  398. apKeyCtx(new CSessionKeyContext(m_auxcontext()));
  399. if (!apKeyCtx.get())
  400. throw scu::OsException(NTE_NO_MEMORY);
  401. // Decrypt key blob if encrypted with Key Exchange Key
  402. // otherwise forward blob to Auxiliary CSP directly
  403. ALG_ID const *pAlgId =
  404. reinterpret_cast<ALG_ID const *>(&pbKeyBlob[sizeof(BLOBHEADER)]);
  405. if (CALG_RSA_KEYX == *pAlgId)
  406. {
  407. // Get Key exchange key
  408. // TO DO: Shouldn't this be getting a private key?
  409. auto_ptr<CPublicKeyContext>
  410. apXKey(new CPublicKeyContext(m_auxcontext(), *this,
  411. AT_KEYEXCHANGE));
  412. // Decrypt key blob
  413. // TO DO: Support multiple key sizes
  414. Blob EncryptedKey(pbKeyBlob + sizeof BLOBHEADER + sizeof ALG_ID,
  415. 128);
  416. Blob DecryptedKey(apXKey->Decrypt(EncryptedKey));
  417. // Recreate the blob
  418. Blob DecryptedBlob(pbKeyBlob, sizeof BLOBHEADER + sizeof ALG_ID);
  419. // we must trim out 64 bytes of the random data from the simple
  420. // blob and then terminate it. (Termination occurs by making the
  421. // n-1 byte = 0x02 and the nth byte = 0x00.) This is necessary
  422. // in order to import this blob into the CSP.
  423. DecryptedBlob.append(DecryptedKey.data(),
  424. (DecryptedKey.length() / 2) - 2);
  425. BYTE bTerminationBytes[] = { 0x02, 0x00 };
  426. DecryptedBlob.append(bTerminationBytes, sizeof bTerminationBytes);
  427. // Load Decrypted blob into key context
  428. apKeyCtx->LoadKey(DecryptedBlob.data(),
  429. DecryptedBlob.length(), 0, dwFlags);
  430. }
  431. else
  432. {
  433. // Load Encrypted blob into key context
  434. apKeyCtx->LoadKey(pbKeyBlob, cbKeyBlobLen, hAuxImpKey, dwFlags);
  435. }
  436. // Import decrypted blob into Auxiliary CSP
  437. apKeyCtx->ImportToAuxCSP();
  438. return apKeyCtx;
  439. }
  440. // Access
  441. HAdaptiveContainer
  442. CryptContext::AdaptiveContainer() const
  443. {
  444. if (!m_hacntr)
  445. throw scu::OsException(ERROR_INVALID_PARAMETER);
  446. return m_hacntr;
  447. }
  448. HCRYPTPROV
  449. CryptContext::AuxContext() const
  450. {
  451. return m_auxcontext();
  452. }
  453. HCardContext
  454. CryptContext::CardContext() const
  455. {
  456. return AdaptiveContainer()->CardContext();
  457. }
  458. ContainerEnumerator
  459. CryptContext::CntrEnumerator(bool fReset)
  460. {
  461. if (fReset)
  462. {
  463. if (m_hacntr)
  464. m_ce = ContainerEnumerator(list<HCardContext>(1, m_hacntr->CardContext()));
  465. else
  466. {
  467. CardEnumerator ce;
  468. m_ce = ContainerEnumerator(*(ce.Cards()));
  469. }
  470. }
  471. return m_ce;
  472. }
  473. CHashContext *
  474. CryptContext::LookupHash(HCRYPTHASH hHash)
  475. {
  476. return reinterpret_cast<CHashContext *>(m_hlHashes[hHash]);
  477. }
  478. CKeyContext *
  479. CryptContext::LookupKey(HCRYPTKEY hKey)
  480. {
  481. return reinterpret_cast<CKeyContext *>(m_hlKeys[hKey]);
  482. }
  483. CPublicKeyContext *
  484. CryptContext::LookupPublicKey(HCRYPTKEY hKey)
  485. {
  486. return reinterpret_cast<CPublicKeyContext *>(LookupChecked(hKey, KT_PUBLICKEY));
  487. }
  488. CSessionKeyContext *
  489. CryptContext::LookupSessionKey(HCRYPTKEY hKey)
  490. {
  491. return reinterpret_cast<CSessionKeyContext *>(LookupChecked(hKey, KT_SESSIONKEY));
  492. }
  493. HWND
  494. CryptContext::Window() const
  495. {
  496. HWND hwndActive = m_hwnd;
  497. // Find a window if the designated one isn't valid. If the
  498. // designated one is NULL, don't use the result of GetActiveWindow
  499. // because the mouse is locked when displaying a dialog box using
  500. // that as the parent window from certain applications (IE and
  501. // Outlook Express).
  502. return (m_hwnd && !IsWindow(m_hwnd))
  503. ? GetActiveWindow()
  504. : m_hwnd;
  505. }
  506. // Predicates
  507. bool
  508. CryptContext::GuiEnabled() const
  509. {
  510. return m_fGuiEnabled;
  511. }
  512. bool
  513. CryptContext::IsEphemeral() const
  514. {
  515. return m_fEphemeralContainer;
  516. }
  517. // Static Variables
  518. /////////////////////////// PROTECTED /////////////////////////////////
  519. // C'tors/D'tors
  520. // Operators
  521. // Operations
  522. // Access
  523. // Predicates
  524. // Static Variables
  525. /////////////////////////// PRIVATE /////////////////////////////////
  526. // C'tors/D'tors
  527. // Operators
  528. // Operations
  529. // Create and open a new container (named by rcspec). If the
  530. // container does exist, then it must be empty.
  531. void
  532. CryptContext::CreateNewContainer(CSpec const &rcspec)
  533. {
  534. ASSERT (!m_hacntr);
  535. // Find the card in the reader specified.
  536. CardFinder cardfinder(DefaultDialogMode(GuiEnabled()), Window());
  537. CSpec csReader(rcspec);
  538. csReader.SetReader(rcspec.Reader());
  539. Secured<HCardContext> hscardctx(cardfinder.Find(csReader));
  540. // Default the container name a UUID (GUID) if it wasn't supplied.
  541. string sCntrToCreate(rcspec.CardId());
  542. if (sCntrToCreate.empty())
  543. {
  544. Uuid uuid;
  545. sCntrToCreate = AsString(uuid.AsUString());
  546. }
  547. AdaptiveContainerKey Key(hscardctx, sCntrToCreate);
  548. m_hacntr = AdaptiveContainer::Find(Key); // find the existing one
  549. if(m_hacntr)
  550. {
  551. //according to spec, a new container cannot have the
  552. //same name as an old one.
  553. throw scu::OsException(NTE_EXISTS);
  554. }
  555. if (hscardctx->Card()->IsProtectedMode())
  556. Login(User, hscardctx);
  557. m_hacntr = HAdaptiveContainer(Key);
  558. }
  559. void
  560. CryptContext::DeleteContainer(Secured<HCardContext> &rhscardctx,
  561. CContainer &rhcntr)
  562. {
  563. if (IsProtected(rhcntr))
  564. Login(User, rhscardctx);
  565. AdaptiveContainer::Discard(AdaptiveContainerKey(rhscardctx,
  566. rhcntr->Name()));
  567. rhcntr->Delete();
  568. }
  569. void
  570. CryptContext::Login(LoginIdentity const &rlid,
  571. Secured<HCardContext> &rhscardctx)
  572. {
  573. // TO DO: Support Entrust
  574. if (m_fGuiEnabled)
  575. rhscardctx->Login(rlid, InteractiveLoginTask(Window()));
  576. else
  577. rhscardctx->Login(rlid, LoginTask());
  578. }
  579. void
  580. CryptContext::OkDeletingCredentials() const
  581. {
  582. if (GuiEnabled())
  583. {
  584. UINT uiResponse = PromptUser(Window(),
  585. IDS_DELETE_CREDENTIALS,
  586. MB_OKCANCEL | MB_ICONWARNING);
  587. switch (uiResponse)
  588. {
  589. case IDCANCEL:
  590. throw scu::OsException(ERROR_CANCELLED);
  591. break;
  592. case IDOK:
  593. break;
  594. default:
  595. throw scu::OsException(ERROR_INTERNAL_ERROR);
  596. break;
  597. };
  598. }
  599. else
  600. throw scu::OsException(NTE_EXISTS);
  601. }
  602. // Access
  603. CKeyContext *
  604. CryptContext::LookupChecked(HCRYPTKEY hKey,
  605. DWORD const dwKeyType)
  606. {
  607. CKeyContext *pKeyCtx = LookupKey(hKey);
  608. if (dwKeyType != pKeyCtx->TypeOfKey())
  609. throw scu::OsException(ERROR_INVALID_PARAMETER);
  610. return pKeyCtx;
  611. }
  612. // Open to an existing container specified by the container
  613. // specification rcspec. If container name is empty, then open the
  614. // default container.
  615. void
  616. CryptContext::OpenExistingContainer(CSpec const &rcspec)
  617. {
  618. if (rcspec.CardId().empty())
  619. {
  620. if (!m_fEphemeralContainer)
  621. {
  622. CardFinder cardfinder(DefaultDialogMode(GuiEnabled()), Window());
  623. Secured<HCardContext> hscardctx(cardfinder.Find(rcspec));
  624. CContainer hcntr(hscardctx->Card()->DefaultContainer());
  625. if (hcntr)
  626. m_hacntr =
  627. HAdaptiveContainer(AdaptiveContainerKey(hscardctx,
  628. hcntr->Name()));
  629. }
  630. }
  631. else
  632. {
  633. AContainerFinder cntrfinder(DefaultDialogMode(GuiEnabled()), Window());
  634. m_hacntr = cntrfinder.Find(rcspec);
  635. }
  636. if (!m_hacntr && (!rcspec.CardId().empty() || !m_fEphemeralContainer))
  637. throw scu::OsException(NTE_BAD_KEYSET);
  638. }
  639. // Predicates
  640. // Static Variables