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.

1318 lines
35 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. ScLogon2
  5. Abstract:
  6. Author:
  7. reidk
  8. Environment:
  9. Win32, C++ w/ Exceptions
  10. --*/
  11. /////////////////////////////////////////////////////////////////////////////
  12. //
  13. // Includes
  14. #if !defined(_X86_) && !defined(_AMD64_) && !defined(_IA64_)
  15. #define _X86_ 1
  16. #endif
  17. #ifndef _WIN32_WINNT
  18. #define _WIN32_WINNT 0x0400
  19. #ifndef UNICODE
  20. #define UNICODE
  21. #endif
  22. #endif
  23. #ifndef WIN32_LEAN_AND_MEAN
  24. #define WIN32_LEAN_AND_MEAN 1
  25. #endif
  26. extern "C" {
  27. #include <nt.h>
  28. #include <ntrtl.h>
  29. #include <nturtl.h>
  30. #include <ntlsa.h>
  31. }
  32. #include <windows.h>
  33. #include <winscard.h>
  34. #include <wincrypt.h>
  35. #include <softpub.h>
  36. #include <stddef.h>
  37. #include <crtdbg.h>
  38. #include "sclogon.h"
  39. #include "sclogon2.h"
  40. #include "unicodes.h"
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #include <time.h>
  44. #include <tchar.h>
  45. #include "sclgnrpc.h"
  46. //
  47. // from secpkg.h
  48. //
  49. typedef NTSTATUS (NTAPI LSA_IMPERSONATE_CLIENT) (VOID);
  50. typedef LSA_IMPERSONATE_CLIENT * PLSA_IMPERSONATE_CLIENT;
  51. DWORD
  52. GetTSSessionID(void)
  53. {
  54. bool fRet = false;
  55. PLIST_ENTRY Module;
  56. PLDR_DATA_TABLE_ENTRY Entry;
  57. BOOL fRunningInLsa = false;
  58. HMODULE hLsa = NULL;
  59. PLSA_IMPERSONATE_CLIENT pLsaImpersonateClient = NULL;
  60. bool bImpersonating = false;
  61. bool bRunningInLsa = false;
  62. HANDLE hThreadToken = INVALID_HANDLE_VALUE;
  63. DWORD dwTSSessionID = 0;
  64. DWORD dwSize;
  65. //
  66. // Make sure we are running in LSA
  67. //
  68. Module = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
  69. Entry = CONTAINING_RECORD(Module,
  70. LDR_DATA_TABLE_ENTRY,
  71. InLoadOrderLinks);
  72. bRunningInLsa = (0 == _wcsicmp(Entry->BaseDllName.Buffer, L"lsass.exe"));
  73. if (bRunningInLsa)
  74. {
  75. //
  76. // If we running in Lsa, then we need to call the special LssImpersonateClient
  77. //
  78. hLsa = GetModuleHandleW(L"lsasrv.dll");
  79. if (hLsa == NULL)
  80. {
  81. DbgPrint("failed to get lsa module handle\n");
  82. goto Return;
  83. }
  84. pLsaImpersonateClient = (PLSA_IMPERSONATE_CLIENT) GetProcAddress(hLsa, "LsaIImpersonateClient");
  85. if (pLsaImpersonateClient == NULL)
  86. {
  87. DbgPrint("failed to get proc address\n");
  88. goto Return;
  89. }
  90. if (pLsaImpersonateClient() != STATUS_SUCCESS)
  91. {
  92. DbgPrint("failed to impersonate\n");
  93. goto Return;
  94. }
  95. bImpersonating = true;
  96. }
  97. else
  98. {
  99. return (0);
  100. }
  101. //
  102. // see if the calling thread token has a TS session ID...
  103. // if so, then we are being called on behalf of a process in a TS session
  104. //
  105. if (!OpenThreadToken(
  106. GetCurrentThread(),
  107. TOKEN_QUERY,
  108. FALSE,
  109. &hThreadToken))
  110. {
  111. DbgPrint("OpenThreadToken failed\n");
  112. goto Return;
  113. }
  114. if (!GetTokenInformation(
  115. hThreadToken,
  116. TokenSessionId,
  117. &dwTSSessionID,
  118. sizeof(dwTSSessionID),
  119. &dwSize))
  120. {
  121. DbgPrint("GetTokenInformation failed\n");
  122. goto Return;
  123. }
  124. Return:
  125. if (hThreadToken != INVALID_HANDLE_VALUE)
  126. {
  127. CloseHandle(hThreadToken);
  128. }
  129. if (bImpersonating)
  130. {
  131. RevertToSelf();
  132. }
  133. return (dwTSSessionID);
  134. }
  135. void
  136. _TeardownRPCConnection(
  137. RPC_BINDING_HANDLE *phRPCBinding)
  138. {
  139. __try
  140. {
  141. RpcBindingFree(phRPCBinding);
  142. }
  143. __except (EXCEPTION_EXECUTE_HANDLER)
  144. {
  145. DbgPrint("Exception occurred during RpcBindingFree - %lx\n", _exception_code());
  146. }
  147. }
  148. NTSTATUS
  149. _SetupRPCConnection(
  150. RPC_BINDING_HANDLE *phRPCBinding)
  151. {
  152. LPWSTR pStringBinding = NULL;
  153. NTSTATUS status = STATUS_SUCCESS;
  154. RPC_STATUS rpcStatus = RPC_S_OK;
  155. static BOOL fDone = FALSE;
  156. DWORD dwTSSessionID = 0;
  157. WCHAR wszLocalEndpoint[256];
  158. LPWSTR pwszLocalEndpoint = NULL;
  159. RPC_SECURITY_QOS RpcSecurityQOS;
  160. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  161. PSID pSID = NULL;
  162. WCHAR szName[64]; // SYSTEM
  163. DWORD cbName = 64;
  164. WCHAR szDomainName[256]; // max domain is 255
  165. DWORD cbDomainName = 256;
  166. SID_NAME_USE Use;
  167. dwTSSessionID = GetTSSessionID();
  168. if (dwTSSessionID != 0)
  169. {
  170. wsprintfW(
  171. wszLocalEndpoint,
  172. SZ_ENDPOINT_NAME_FORMAT,
  173. SCLOGONRPC_LOCAL_ENDPOINT,
  174. dwTSSessionID);
  175. pwszLocalEndpoint = wszLocalEndpoint;
  176. }
  177. else
  178. {
  179. pwszLocalEndpoint = SCLOGONRPC_LOCAL_ENDPOINT;
  180. }
  181. //
  182. // get a binding handle
  183. //
  184. if (RPC_S_OK != (rpcStatus = RpcStringBindingComposeW(
  185. NULL,
  186. SCLOGONRPC_LOCAL_PROT_SEQ,
  187. NULL, //LPC - no machine name
  188. pwszLocalEndpoint,
  189. 0,
  190. &pStringBinding)))
  191. {
  192. DbgPrint("RpcStringBindingComposeW failed\n");
  193. status = I_RpcMapWin32Status(rpcStatus);
  194. //
  195. // if I_RpcMapWin32Status() can't map the error code it returns
  196. // the same error back, so check for that
  197. //
  198. if (status == rpcStatus)
  199. {
  200. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  201. }
  202. goto Return;
  203. }
  204. if (RPC_S_OK != (rpcStatus = RpcBindingFromStringBindingW(
  205. pStringBinding,
  206. phRPCBinding)))
  207. {
  208. DbgPrint("RpcBindingFromStringBindingW failed\n");
  209. status = I_RpcMapWin32Status(rpcStatus);
  210. //
  211. // if I_RpcMapWin32Status() can't map the error code it returns
  212. // the same error back, so check for that
  213. //
  214. if (status == rpcStatus)
  215. {
  216. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  217. }
  218. goto Return;
  219. }
  220. if (RPC_S_OK != (rpcStatus = RpcEpResolveBinding(
  221. *phRPCBinding,
  222. IRPCSCLogon_v1_0_c_ifspec)))
  223. {
  224. DbgPrint("RpcEpResolveBinding failed\n");
  225. status = I_RpcMapWin32Status(rpcStatus);
  226. //
  227. // if I_RpcMapWin32Status() can't map the error code it returns
  228. // the same error back, so check for that
  229. //
  230. if (status == rpcStatus)
  231. {
  232. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  233. }
  234. _TeardownRPCConnection(phRPCBinding);
  235. goto Return;
  236. }
  237. //
  238. // Set the autorization so that we will only call a Local System process
  239. //
  240. memset(&RpcSecurityQOS, 0, sizeof(RpcSecurityQOS));
  241. RpcSecurityQOS.Version = RPC_C_SECURITY_QOS_VERSION;
  242. RpcSecurityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH;
  243. RpcSecurityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
  244. RpcSecurityQOS.ImpersonationType = RPC_C_IMP_LEVEL_DELEGATE; //RPC_C_IMP_LEVEL_DEFAULT; //RPC_C_IMP_LEVEL_IMPERSONATE
  245. if (AllocateAndInitializeSid(&SIDAuth, 1,
  246. SECURITY_LOCAL_SYSTEM_RID,
  247. 0, 0, 0, 0, 0, 0, 0,
  248. &pSID) == 0)
  249. {
  250. DbgPrint("AllocateAndInitializeSid failed\n");
  251. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  252. goto Return;
  253. }
  254. if (LookupAccountSid(NULL,
  255. pSID,
  256. szName,
  257. &cbName,
  258. szDomainName,
  259. &cbDomainName,
  260. &Use) == 0)
  261. {
  262. DbgPrint("LookupAccountSid failed\n");
  263. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  264. goto Return;
  265. }
  266. if (RPC_S_OK != (rpcStatus = RpcBindingSetAuthInfoEx(
  267. *phRPCBinding,
  268. szName,
  269. RPC_C_AUTHN_LEVEL_PKT_PRIVACY, //RPC_C_AUTHN_LEVEL_CONNECT
  270. RPC_C_AUTHN_WINNT,
  271. NULL,
  272. 0,
  273. &RpcSecurityQOS)))
  274. {
  275. DbgPrint("RpcBindingSetAuthInfoEx failed\n");
  276. status = I_RpcMapWin32Status(rpcStatus);
  277. goto Return;
  278. }
  279. Return:
  280. if (pStringBinding != NULL)
  281. {
  282. RpcStringFreeW(&pStringBinding);
  283. }
  284. if (pSID != NULL)
  285. {
  286. FreeSid( pSID );
  287. }
  288. return (status);
  289. }
  290. typedef struct _SCLOGON_PIPE
  291. {
  292. RPC_BINDING_HANDLE hRPCBinding;
  293. BINDING_CONTEXT BindingContext;
  294. } SCLOGON_PIPE;
  295. ///////////////////////////////////////////////////////////////////////////////
  296. //
  297. // ScLogon APIs
  298. //
  299. //***************************************************************************************
  300. //
  301. // __ScHelperInitializeContext:
  302. //
  303. //***************************************************************************************
  304. NTSTATUS WINAPI
  305. __ScHelperInitializeContext(
  306. IN OUT PBYTE pbLogonInfo,
  307. IN ULONG cbLogonInfo
  308. )
  309. {
  310. SCLOGON_PIPE *pSCLogonPipe;
  311. NTSTATUS status = STATUS_SUCCESS;
  312. BOOL fRPCBindingInitialized = FALSE;
  313. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  314. if ((cbLogonInfo < sizeof(ULONG)) ||
  315. (cbLogonInfo != pLI->dwLogonInfoLen))
  316. {
  317. return(STATUS_INVALID_PARAMETER);
  318. }
  319. pLI->ContextInformation = malloc(sizeof(SCLOGON_PIPE));
  320. if (pLI->ContextInformation == NULL)
  321. {
  322. return(STATUS_INSUFFICIENT_RESOURCES);
  323. }
  324. pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  325. status = _SetupRPCConnection(&(pSCLogonPipe->hRPCBinding));
  326. if (!NT_SUCCESS(status))
  327. {
  328. goto ErrorReturn;
  329. }
  330. fRPCBindingInitialized = TRUE;
  331. pSCLogonPipe->BindingContext = NULL;
  332. __try
  333. {
  334. status = RPC_ScHelperInitializeContext(
  335. pSCLogonPipe->hRPCBinding,
  336. cbLogonInfo,
  337. pbLogonInfo,
  338. &(pSCLogonPipe->BindingContext));
  339. }
  340. __except (EXCEPTION_EXECUTE_HANDLER)
  341. {
  342. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  343. DbgPrint("Exception occurred during RPC_ScHelperInitializeContext - %lx\n", _exception_code());
  344. }
  345. if (!NT_SUCCESS(status))
  346. {
  347. goto ErrorReturn;
  348. }
  349. Return:
  350. return (status);
  351. ErrorReturn:
  352. if (pSCLogonPipe != NULL)
  353. {
  354. if (fRPCBindingInitialized)
  355. {
  356. _TeardownRPCConnection(&(pSCLogonPipe->hRPCBinding));
  357. }
  358. free(pSCLogonPipe);
  359. }
  360. goto Return;
  361. }
  362. //***************************************************************************************
  363. //
  364. // __ScHelperRelease:
  365. //
  366. //***************************************************************************************
  367. VOID WINAPI
  368. __ScHelperRelease(
  369. IN OUT PBYTE pbLogonInfo
  370. )
  371. {
  372. _ASSERTE(NULL != pbLogonInfo);
  373. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  374. SCLOGON_PIPE * pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  375. BOOL fReleaseFailed = TRUE;
  376. if (pSCLogonPipe != NULL)
  377. {
  378. __try
  379. {
  380. RPC_ScHelperRelease(
  381. pSCLogonPipe->hRPCBinding,
  382. &(pSCLogonPipe->BindingContext));
  383. fReleaseFailed = FALSE;
  384. }
  385. __except (EXCEPTION_EXECUTE_HANDLER)
  386. {
  387. DbgPrint("Exception occurred during RPC_ScHelperRelease - %lx\n", _exception_code());
  388. }
  389. //
  390. // RPC_ScHelperRelease will throw an exception if the winlogon process it is trying
  391. // to talk to has gone away. If that is the case, then we need to manually free
  392. // the BINDING_CONTEXT since it won't get free'd by RPC.
  393. //
  394. // NOTE: RPC will free the BINDING_CONTEXT when the server sets it to NULL, which
  395. // does happen if the RPC_ScHelperRelease function executes
  396. //
  397. if (fReleaseFailed)
  398. {
  399. __try
  400. {
  401. RpcSsDestroyClientContext(&(pSCLogonPipe->BindingContext));
  402. }
  403. __except (EXCEPTION_EXECUTE_HANDLER)
  404. {
  405. DbgPrint("Exception occurred during RpcSsDestroyClientContext - %lx\n", _exception_code());
  406. }
  407. }
  408. _TeardownRPCConnection(&(pSCLogonPipe->hRPCBinding));
  409. free(pSCLogonPipe);
  410. pLI->ContextInformation = NULL;
  411. }
  412. }
  413. //***************************************************************************************
  414. //
  415. // __ScHelperGetCertFromLogonInfo:
  416. //
  417. //***************************************************************************************
  418. NTSTATUS WINAPI
  419. __ScHelperGetCertFromLogonInfo(
  420. IN PBYTE pbLogonInfo,
  421. IN PUNICODE_STRING pucPIN,
  422. OUT PCCERT_CONTEXT *CertificateContext
  423. )
  424. {
  425. _ASSERTE(NULL != pbLogonInfo);
  426. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  427. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  428. NTSTATUS status = STATUS_SUCCESS;
  429. PCCERT_CONTEXT pCertCtx = NULL;
  430. OUT_BUFFER1 CertBytes;
  431. CUnicodeString szPIN(pucPIN);
  432. memset(&CertBytes, 0, sizeof(CertBytes));
  433. //
  434. // Make sure pin got initialized correctly in constructor
  435. //
  436. if (NULL != pucPIN)
  437. {
  438. if (!szPIN.Valid())
  439. {
  440. status = STATUS_INSUFFICIENT_RESOURCES;
  441. goto Return;
  442. }
  443. }
  444. //
  445. // Make the call
  446. //
  447. __try
  448. {
  449. status = RPC_ScHelperGetCertFromLogonInfo(
  450. pSCLogonPipe->hRPCBinding,
  451. pSCLogonPipe->BindingContext,
  452. (LPCWSTR)szPIN,
  453. &CertBytes);
  454. }
  455. __except (EXCEPTION_EXECUTE_HANDLER)
  456. {
  457. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  458. DbgPrint("Exception occurred during RPC_ScHelperGetCertFromLogonInfo - %lx\n", _exception_code());
  459. }
  460. if (!NT_SUCCESS(status))
  461. {
  462. goto Return;
  463. }
  464. //
  465. // Create the return CertContext based on the bytes returned
  466. //
  467. pCertCtx = CertCreateCertificateContext(
  468. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  469. CertBytes.pb,
  470. CertBytes.cb);
  471. if (pCertCtx == NULL)
  472. {
  473. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  474. }
  475. Return:
  476. if (CertBytes.pb != NULL)
  477. {
  478. MIDL_user_free(CertBytes.pb);
  479. }
  480. *CertificateContext = pCertCtx;
  481. return (status);
  482. }
  483. //***************************************************************************************
  484. //
  485. // __ScHelperGetProvParam:
  486. //
  487. //***************************************************************************************
  488. NTSTATUS WINAPI
  489. __ScHelperGetProvParam(
  490. IN PUNICODE_STRING pucPIN,
  491. IN PBYTE pbLogonInfo,
  492. DWORD dwParam,
  493. BYTE *pbData,
  494. DWORD *pdwDataLen,
  495. DWORD dwFlags
  496. )
  497. {
  498. _ASSERTE(NULL != pbLogonInfo);
  499. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  500. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  501. NTSTATUS status = STATUS_SUCCESS;
  502. CUnicodeString szPIN(pucPIN);
  503. OUT_BUFFER1 Data;
  504. memset(&Data, 0, sizeof(Data));
  505. //
  506. // Make sure pin got initialized correctly in constructor
  507. //
  508. if (NULL != pucPIN)
  509. {
  510. if (!szPIN.Valid())
  511. {
  512. status = STATUS_INSUFFICIENT_RESOURCES;
  513. goto Return;
  514. }
  515. }
  516. //
  517. // Make the call
  518. //
  519. __try
  520. {
  521. status = RPC_ScHelperGetProvParam(
  522. pSCLogonPipe->hRPCBinding,
  523. pSCLogonPipe->BindingContext,
  524. (LPCWSTR)szPIN,
  525. dwParam,
  526. pdwDataLen,
  527. &Data,
  528. dwFlags);
  529. }
  530. __except (EXCEPTION_EXECUTE_HANDLER)
  531. {
  532. if ((_exception_code() == RPC_S_CALL_FAILED_DNE) ||
  533. (_exception_code() == RPC_S_SERVER_UNAVAILABLE))
  534. {
  535. // Special case to trigger the balloon when the session
  536. // went away (transfer of credentials case)
  537. status = STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED;
  538. }
  539. else
  540. {
  541. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  542. }
  543. DbgPrint("Exception occurred during RPC_ScHelperGetProvParam - %lx\n", _exception_code());
  544. }
  545. if (!NT_SUCCESS(status))
  546. {
  547. goto Return;
  548. }
  549. //
  550. // if Data.cb is not 0, then the called is getting back data
  551. //
  552. if (Data.cb != 0)
  553. {
  554. memcpy(pbData, Data.pb, Data.cb);
  555. }
  556. Return:
  557. if (Data.pb != NULL)
  558. {
  559. MIDL_user_free(Data.pb);
  560. }
  561. return (status);
  562. }
  563. //***************************************************************************************
  564. //
  565. // __ScHelperGenRandBits:
  566. //
  567. //***************************************************************************************
  568. NTSTATUS WINAPI
  569. __ScHelperGenRandBits(
  570. IN PBYTE pbLogonInfo,
  571. IN OUT ScHelper_RandomCredBits* psc_rcb
  572. )
  573. {
  574. _ASSERTE(NULL != pbLogonInfo);
  575. NTSTATUS status = STATUS_SUCCESS;
  576. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  577. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  578. __try
  579. {
  580. status = RPC_ScHelperGenRandBits(
  581. pSCLogonPipe->hRPCBinding,
  582. pSCLogonPipe->BindingContext,
  583. psc_rcb->bR1,
  584. psc_rcb->bR2);
  585. }
  586. __except (EXCEPTION_EXECUTE_HANDLER)
  587. {
  588. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  589. DbgPrint("Exception occurred during RPC_ScHelperGenRandBits - %lx\n", _exception_code());
  590. }
  591. return (status);
  592. }
  593. //***************************************************************************************
  594. //
  595. // __ScHelperVerifyCardAndCreds:
  596. //
  597. //***************************************************************************************
  598. NTSTATUS WINAPI
  599. __ScHelperVerifyCardAndCreds(
  600. IN PUNICODE_STRING pucPIN,
  601. IN PCCERT_CONTEXT CertificateContext,
  602. IN PBYTE pbLogonInfo,
  603. IN PBYTE EncryptedData,
  604. IN ULONG EncryptedDataSize,
  605. OUT OPTIONAL PBYTE CleartextData,
  606. OUT PULONG CleartextDataSize
  607. )
  608. {
  609. _ASSERTE(NULL != pbLogonInfo);
  610. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  611. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  612. NTSTATUS status = STATUS_SUCCESS;
  613. CUnicodeString szPIN(pucPIN);
  614. OUT_BUFFER2 CleartextDataBuffer;
  615. memset(&CleartextDataBuffer, 0, sizeof(CleartextDataBuffer));
  616. //
  617. // Make sure pin got initialized correctly in constructor
  618. //
  619. if (NULL != pucPIN)
  620. {
  621. if (!szPIN.Valid())
  622. {
  623. status = STATUS_INSUFFICIENT_RESOURCES;
  624. goto Return;
  625. }
  626. }
  627. //
  628. // Make the call
  629. //
  630. __try
  631. {
  632. status = RPC_ScHelperVerifyCardAndCreds(
  633. pSCLogonPipe->hRPCBinding,
  634. pSCLogonPipe->BindingContext,
  635. (LPCWSTR)szPIN,
  636. EncryptedDataSize,
  637. EncryptedData,
  638. CleartextDataSize,
  639. &CleartextDataBuffer);
  640. }
  641. __except (EXCEPTION_EXECUTE_HANDLER)
  642. {
  643. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  644. DbgPrint("Exception occurred during RPC_ScHelperVerifyCardAndCreds - %lx\n", _exception_code());
  645. }
  646. if (!NT_SUCCESS(status))
  647. {
  648. goto Return;
  649. }
  650. //
  651. // if CleartextData.cb is not 0, then the called is getting back data
  652. //
  653. if (CleartextDataBuffer.cb != 0)
  654. {
  655. memcpy(CleartextData, CleartextDataBuffer.pb, CleartextDataBuffer.cb);
  656. }
  657. Return:
  658. if (CleartextDataBuffer.pb != NULL)
  659. {
  660. MIDL_user_free(CleartextDataBuffer.pb);
  661. }
  662. return (status);
  663. }
  664. //***************************************************************************************
  665. //
  666. // __ScHelperEncryptCredentials:
  667. //
  668. //***************************************************************************************
  669. NTSTATUS WINAPI
  670. __ScHelperEncryptCredentials(
  671. IN PUNICODE_STRING pucPIN,
  672. IN PCCERT_CONTEXT CertificateContext,
  673. IN ScHelper_RandomCredBits* psch_rcb,
  674. IN PBYTE pbLogonInfo,
  675. IN PBYTE CleartextData,
  676. IN ULONG CleartextDataSize,
  677. OUT OPTIONAL PBYTE EncryptedData,
  678. OUT PULONG EncryptedDataSize)
  679. {
  680. _ASSERTE(NULL != pbLogonInfo);
  681. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  682. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  683. NTSTATUS status = STATUS_SUCCESS;
  684. CUnicodeString szPIN(pucPIN);
  685. OUT_BUFFER2 EncryptedDataBuffer;
  686. memset(&EncryptedDataBuffer, 0, sizeof(EncryptedDataBuffer));
  687. //
  688. // Make sure pin got initialized correctly in constructor
  689. //
  690. if (NULL != pucPIN)
  691. {
  692. if (!szPIN.Valid())
  693. {
  694. status = STATUS_INSUFFICIENT_RESOURCES;
  695. goto Return;
  696. }
  697. }
  698. //
  699. // Make the call
  700. //
  701. __try
  702. {
  703. status = RPC_ScHelperEncryptCredentials(
  704. pSCLogonPipe->hRPCBinding,
  705. pSCLogonPipe->BindingContext,
  706. (LPCWSTR)szPIN,
  707. psch_rcb->bR1,
  708. psch_rcb->bR2,
  709. CleartextDataSize,
  710. CleartextData,
  711. EncryptedDataSize,
  712. &EncryptedDataBuffer);
  713. }
  714. __except (EXCEPTION_EXECUTE_HANDLER)
  715. {
  716. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  717. DbgPrint("Exception occurred during RPC_ScHelperEncryptCredentials - %lx\n", _exception_code());
  718. }
  719. if (!NT_SUCCESS(status))
  720. {
  721. goto Return;
  722. }
  723. //
  724. // if EncryptedDataBuffer.cb is not 0, then the called is getting back data
  725. //
  726. if (EncryptedDataBuffer.cb != 0)
  727. {
  728. memcpy(EncryptedData, EncryptedDataBuffer.pb, EncryptedDataBuffer.cb);
  729. }
  730. Return:
  731. if (EncryptedDataBuffer.pb != NULL)
  732. {
  733. MIDL_user_free(EncryptedDataBuffer.pb);
  734. }
  735. return (status);
  736. }
  737. //***************************************************************************************
  738. //
  739. // __ScHelperSignMessage:
  740. //
  741. //***************************************************************************************
  742. NTSTATUS WINAPI
  743. __ScHelperSignMessage(
  744. IN PUNICODE_STRING pucPIN,
  745. IN OPTIONAL PBYTE pbLogonInfo,
  746. IN OPTIONAL HCRYPTPROV Provider,
  747. IN ULONG Algorithm,
  748. IN PBYTE Buffer,
  749. IN ULONG BufferLength,
  750. OUT PBYTE Signature,
  751. OUT PULONG SignatureLength
  752. )
  753. {
  754. if (Provider != NULL)
  755. {
  756. return (ScHelperSignMessage(
  757. pucPIN,
  758. pbLogonInfo,
  759. Provider,
  760. Algorithm,
  761. Buffer,
  762. BufferLength,
  763. Signature,
  764. SignatureLength));
  765. }
  766. _ASSERTE(NULL != pbLogonInfo);
  767. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  768. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  769. NTSTATUS status = STATUS_SUCCESS;
  770. CUnicodeString szPIN(pucPIN);
  771. OUT_BUFFER2 SignatureBuffer;
  772. memset(&SignatureBuffer, 0, sizeof(SignatureBuffer));
  773. //
  774. // Make sure pin got initialized correctly in constructor
  775. //
  776. if (NULL != pucPIN)
  777. {
  778. if (!szPIN.Valid())
  779. {
  780. status = STATUS_INSUFFICIENT_RESOURCES;
  781. goto Return;
  782. }
  783. }
  784. //
  785. // Make the call
  786. //
  787. __try
  788. {
  789. status = RPC_ScHelperSignMessage(
  790. pSCLogonPipe->hRPCBinding,
  791. pSCLogonPipe->BindingContext,
  792. (LPCWSTR)szPIN,
  793. Algorithm,
  794. BufferLength,
  795. Buffer,
  796. SignatureLength,
  797. &SignatureBuffer);
  798. }
  799. __except (EXCEPTION_EXECUTE_HANDLER)
  800. {
  801. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  802. DbgPrint("Exception occurred during RPC_ScHelperSignMessage - %lx\n", _exception_code());
  803. }
  804. if (!NT_SUCCESS(status))
  805. {
  806. goto Return;
  807. }
  808. //
  809. // if SignatureBuffer.cb is not 0, then the called is getting back data
  810. //
  811. if (SignatureBuffer.cb != 0)
  812. {
  813. memcpy(Signature, SignatureBuffer.pb, SignatureBuffer.cb);
  814. }
  815. Return:
  816. if (SignatureBuffer.pb != NULL)
  817. {
  818. MIDL_user_free(SignatureBuffer.pb);
  819. }
  820. return (status);
  821. }
  822. //***************************************************************************************
  823. //
  824. // __ScHelperVerifyMessage:
  825. //
  826. //***************************************************************************************
  827. NTSTATUS WINAPI
  828. __ScHelperVerifyMessage(
  829. IN OPTIONAL PBYTE pbLogonInfo,
  830. IN PCCERT_CONTEXT CertificateContext,
  831. IN ULONG Algorithm,
  832. IN PBYTE Buffer,
  833. IN ULONG BufferLength,
  834. IN PBYTE Signature,
  835. IN ULONG SignatureLength
  836. )
  837. {
  838. _ASSERTE(NULL != pbLogonInfo);
  839. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  840. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  841. NTSTATUS status = STATUS_SUCCESS;
  842. __try
  843. {
  844. status = RPC_ScHelperVerifyMessage(
  845. pSCLogonPipe->hRPCBinding,
  846. pSCLogonPipe->BindingContext,
  847. Algorithm,
  848. BufferLength,
  849. Buffer,
  850. SignatureLength,
  851. Signature);
  852. }
  853. __except (EXCEPTION_EXECUTE_HANDLER)
  854. {
  855. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  856. DbgPrint("Exception occurred during RPC_ScHelperVerifyMessage - %lx\n", _exception_code());
  857. }
  858. return (status);
  859. }
  860. //***************************************************************************************
  861. //
  862. // __ScHelperSignPkcsMessage:
  863. //
  864. //***************************************************************************************
  865. NTSTATUS WINAPI
  866. __ScHelperSignPkcsMessage(
  867. IN OPTIONAL PUNICODE_STRING pucPIN,
  868. IN OPTIONAL PBYTE pbLogonInfo,
  869. IN OPTIONAL HCRYPTPROV Provider,
  870. IN PCCERT_CONTEXT Certificate,
  871. IN PCRYPT_ALGORITHM_IDENTIFIER Algorithm,
  872. IN DWORD dwSignMessageFlags,
  873. IN PBYTE Buffer,
  874. IN ULONG BufferLength,
  875. OUT OPTIONAL PBYTE SignedBuffer,
  876. OUT OPTIONAL PULONG SignedBufferLength
  877. )
  878. {
  879. if (Provider != NULL)
  880. {
  881. return (ScHelperSignPkcsMessage(
  882. pucPIN,
  883. pbLogonInfo,
  884. Provider,
  885. Certificate,
  886. Algorithm,
  887. dwSignMessageFlags,
  888. Buffer,
  889. BufferLength,
  890. SignedBuffer,
  891. SignedBufferLength));
  892. }
  893. _ASSERTE(NULL != pbLogonInfo);
  894. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  895. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  896. NTSTATUS status = STATUS_SUCCESS;
  897. CUnicodeString szPIN(pucPIN);
  898. OUT_BUFFER2 SignedBufferBuffer;
  899. memset(&SignedBufferBuffer, 0, sizeof(SignedBufferBuffer));
  900. //
  901. // Make sure pin got initialized correctly in constructor
  902. //
  903. if (NULL != pucPIN)
  904. {
  905. if (!szPIN.Valid())
  906. {
  907. status = STATUS_INSUFFICIENT_RESOURCES;
  908. goto Return;
  909. }
  910. }
  911. //
  912. // Make the call
  913. //
  914. __try
  915. {
  916. status = RPC_ScHelperSignPkcsMessage(
  917. pSCLogonPipe->hRPCBinding,
  918. pSCLogonPipe->BindingContext,
  919. (LPCWSTR)szPIN,
  920. Algorithm->pszObjId,
  921. Algorithm->Parameters.cbData,
  922. Algorithm->Parameters.pbData,
  923. dwSignMessageFlags,
  924. BufferLength,
  925. Buffer,
  926. SignedBufferLength,
  927. &SignedBufferBuffer);
  928. }
  929. __except (EXCEPTION_EXECUTE_HANDLER)
  930. {
  931. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  932. DbgPrint("Exception occurred during RPC_ScHelperSignPkcsMessage - %lx\n", _exception_code());
  933. }
  934. if (!NT_SUCCESS(status))
  935. {
  936. goto Return;
  937. }
  938. //
  939. // if SignedBufferBuffer.cb is not 0, then the called is getting back data
  940. //
  941. if (SignedBufferBuffer.cb != 0)
  942. {
  943. memcpy(SignedBuffer, SignedBufferBuffer.pb, SignedBufferBuffer.cb);
  944. }
  945. Return:
  946. if (SignedBufferBuffer.pb != NULL)
  947. {
  948. MIDL_user_free(SignedBufferBuffer.pb);
  949. }
  950. return (status);
  951. }
  952. //***************************************************************************************
  953. //
  954. // __ScHelperVerifyPkcsMessage:
  955. //
  956. //***************************************************************************************
  957. NTSTATUS WINAPI
  958. __ScHelperVerifyPkcsMessage(
  959. IN OPTIONAL PBYTE pbLogonInfo,
  960. IN OPTIONAL HCRYPTPROV Provider,
  961. IN PBYTE Buffer,
  962. IN ULONG BufferLength,
  963. OUT OPTIONAL PBYTE DecodedBuffer,
  964. OUT OPTIONAL PULONG DecodedBufferLength,
  965. OUT OPTIONAL PCCERT_CONTEXT * CertificateContext
  966. )
  967. {
  968. if (Provider != NULL)
  969. {
  970. return (ScHelperVerifyPkcsMessage(
  971. pbLogonInfo,
  972. Provider,
  973. Buffer,
  974. BufferLength,
  975. DecodedBuffer,
  976. DecodedBufferLength,
  977. CertificateContext));
  978. }
  979. _ASSERTE(NULL != pbLogonInfo);
  980. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  981. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  982. NTSTATUS status = STATUS_SUCCESS;
  983. PCCERT_CONTEXT pCertCtx = NULL;
  984. OUT_BUFFER2 DecodedBufferBuffer;
  985. OUT_BUFFER1 CertBytes;
  986. BOOL fCertificateContextRequested = (CertificateContext != NULL);
  987. memset(&DecodedBufferBuffer, 0, sizeof(DecodedBufferBuffer));
  988. memset(&CertBytes, 0, sizeof(CertBytes));
  989. //
  990. // Make the call
  991. //
  992. __try
  993. {
  994. status = RPC_ScHelperVerifyPkcsMessage(
  995. pSCLogonPipe->hRPCBinding,
  996. pSCLogonPipe->BindingContext,
  997. BufferLength,
  998. Buffer,
  999. DecodedBufferLength,
  1000. &DecodedBufferBuffer,
  1001. fCertificateContextRequested,
  1002. &CertBytes);
  1003. }
  1004. __except (EXCEPTION_EXECUTE_HANDLER)
  1005. {
  1006. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  1007. DbgPrint("Exception occurred during RPC_ScHelperVerifyPkcsMessage - %lx\n", _exception_code());
  1008. }
  1009. if (!NT_SUCCESS(status))
  1010. {
  1011. goto Return;
  1012. }
  1013. //
  1014. // Create the return CertContext based on the bytes returned
  1015. //
  1016. if (fCertificateContextRequested)
  1017. {
  1018. pCertCtx = CertCreateCertificateContext(
  1019. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1020. CertBytes.pb,
  1021. CertBytes.cb);
  1022. if (pCertCtx == NULL)
  1023. {
  1024. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  1025. goto Return;
  1026. }
  1027. }
  1028. //
  1029. // if DecodedBufferBuffer.cb is not 0, then the called is getting back data
  1030. //
  1031. if (DecodedBufferBuffer.cb != 0)
  1032. {
  1033. memcpy(DecodedBuffer, DecodedBufferBuffer.pb, DecodedBufferBuffer.cb);
  1034. }
  1035. Return:
  1036. if (fCertificateContextRequested)
  1037. {
  1038. *CertificateContext = pCertCtx;
  1039. }
  1040. if (DecodedBufferBuffer.pb != NULL)
  1041. {
  1042. MIDL_user_free(DecodedBufferBuffer.pb);
  1043. }
  1044. if (CertBytes.pb != NULL)
  1045. {
  1046. MIDL_user_free(CertBytes.pb);
  1047. }
  1048. return (status);
  1049. }
  1050. //***************************************************************************************
  1051. //
  1052. // __ScHelperDecryptMessage:
  1053. //
  1054. //***************************************************************************************
  1055. NTSTATUS WINAPI
  1056. __ScHelperDecryptMessage(
  1057. IN PUNICODE_STRING pucPIN,
  1058. IN OPTIONAL PBYTE pbLogonInfo,
  1059. IN OPTIONAL HCRYPTPROV Provider,
  1060. IN PCCERT_CONTEXT CertificateContext,
  1061. IN PBYTE CipherText, // Supplies formatted CipherText
  1062. IN ULONG CipherLength, // Supplies the length of the CiperText
  1063. OUT PBYTE ClearText, // Receives decrypted message
  1064. IN OUT PULONG pClearLength // Supplies length of buffer, receives actual length
  1065. )
  1066. {
  1067. if (Provider != NULL)
  1068. {
  1069. return (ScHelperDecryptMessage(
  1070. pucPIN,
  1071. pbLogonInfo,
  1072. Provider,
  1073. CertificateContext,
  1074. CipherText,
  1075. CipherLength,
  1076. ClearText,
  1077. pClearLength));
  1078. }
  1079. _ASSERTE(NULL != pbLogonInfo);
  1080. LogonInfo *pLI = (LogonInfo *)pbLogonInfo;
  1081. SCLOGON_PIPE *pSCLogonPipe = (SCLOGON_PIPE *) pLI->ContextInformation;
  1082. NTSTATUS status = STATUS_SUCCESS;
  1083. CUnicodeString szPIN(pucPIN);
  1084. OUT_BUFFER2 ClearTextBuffer;
  1085. memset(&ClearTextBuffer, 0, sizeof(ClearTextBuffer));
  1086. //
  1087. // Make sure pin got initialized correctly in constructor
  1088. //
  1089. if (NULL != pucPIN)
  1090. {
  1091. if (!szPIN.Valid())
  1092. {
  1093. status = STATUS_INSUFFICIENT_RESOURCES;
  1094. goto Return;
  1095. }
  1096. }
  1097. //
  1098. // Make the call
  1099. //
  1100. __try
  1101. {
  1102. status = RPC_ScHelperDecryptMessage(
  1103. pSCLogonPipe->hRPCBinding,
  1104. pSCLogonPipe->BindingContext,
  1105. (LPCWSTR)szPIN,
  1106. CipherLength,
  1107. CipherText,
  1108. pClearLength,
  1109. &ClearTextBuffer);
  1110. }
  1111. __except (EXCEPTION_EXECUTE_HANDLER)
  1112. {
  1113. status = STATUS_SMARTCARD_SUBSYSTEM_FAILURE;
  1114. DbgPrint("Exception occurred during RPC_ScHelperDecryptMessage - %lx\n", _exception_code());
  1115. }
  1116. if (!NT_SUCCESS(status))
  1117. {
  1118. goto Return;
  1119. }
  1120. //
  1121. // if ClearTextBuffer.cb is not 0, then the called is getting back data
  1122. //
  1123. if (ClearTextBuffer.cb != 0)
  1124. {
  1125. memcpy(ClearText, ClearTextBuffer.pb, ClearTextBuffer.cb);
  1126. }
  1127. Return:
  1128. if (ClearTextBuffer.pb != NULL)
  1129. {
  1130. MIDL_user_free(ClearTextBuffer.pb);
  1131. }
  1132. return (status);
  1133. }