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.

2422 lines
66 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: ctxtattr.c
  7. //
  8. // Contents: QueryContextAttribute and related functions.
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 09-30-97 jbanes Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "sslp.h"
  18. #include <ssl2msg.h>
  19. #include <ssl3msg.h>
  20. #include <pct1msg.h>
  21. #include <tls1key.h>
  22. #include <mapper.h>
  23. #include <lsasecpk.h>
  24. typedef struct {
  25. DWORD dwProtoId;
  26. LPCTSTR szProto;
  27. DWORD dwMajor;
  28. DWORD dwMinor;
  29. } PROTO_ID;
  30. const PROTO_ID rgProts[] = {
  31. { SP_PROT_SSL2_CLIENT, TEXT("SSL"), 2, 0 },
  32. { SP_PROT_SSL2_SERVER, TEXT("SSL"), 2, 0 },
  33. { SP_PROT_PCT1_CLIENT, TEXT("PCT"), 1, 0 },
  34. { SP_PROT_PCT1_SERVER, TEXT("PCT"), 1, 0 },
  35. { SP_PROT_SSL3_CLIENT, TEXT("SSL"), 3, 0 },
  36. { SP_PROT_SSL3_SERVER, TEXT("SSL"), 3, 0 },
  37. { SP_PROT_TLS1_CLIENT, TEXT("TLS"), 1, 0 },
  38. { SP_PROT_TLS1_SERVER, TEXT("TLS"), 1, 0 }
  39. };
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Function: SpQueryAccessToken
  43. //
  44. // Synopsis: Retrieves the SECPKG_ATTR_ACCESS_TOKEN context attribute.
  45. //
  46. // Arguments:
  47. //
  48. // Returns:
  49. //
  50. // Notes: The buffer returned contains the following structure:
  51. //
  52. // typedef struct _SecPkgContext_AccessToken
  53. // {
  54. // void SEC_FAR * AccessToken;
  55. // } SecPkgContext_AccessToken, SEC_FAR * PSecPkgContext_AccessToken;
  56. //
  57. //--------------------------------------------------------------------------
  58. SECURITY_STATUS
  59. SpQueryAccessToken(
  60. PSPContext pContext,
  61. PSecPkgContext_AccessToken pAccessToken)
  62. {
  63. PSessCacheItem pZombie;
  64. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_ACCESS_TOKEN)\n"));
  65. pZombie = pContext->RipeZombie;
  66. if(pZombie == NULL ||
  67. pZombie->hLocator == 0)
  68. {
  69. if(pZombie->LocatorStatus)
  70. {
  71. return(SP_LOG_RESULT(pZombie->LocatorStatus));
  72. }
  73. else
  74. {
  75. return(SP_LOG_RESULT(SEC_E_NO_IMPERSONATION));
  76. }
  77. }
  78. pAccessToken->AccessToken = (VOID *)pZombie->hLocator;
  79. return SEC_E_OK;
  80. }
  81. //+-------------------------------------------------------------------------
  82. //
  83. // Function: SpQueryAuthority
  84. //
  85. // Synopsis: Retrieves the SECPKG_ATTR_AUTHORITY context attribute.
  86. //
  87. // Arguments:
  88. //
  89. // Returns:
  90. //
  91. // Notes: The buffer returned contains the following structure:
  92. //
  93. // typedef struct _SecPkgContext_AuthorityW
  94. // {
  95. // SEC_WCHAR SEC_FAR * sAuthorityName;
  96. // } SecPkgContext_AuthorityW, * PSecPkgContext_AuthorityW;
  97. //
  98. //--------------------------------------------------------------------------
  99. SECURITY_STATUS
  100. SpQueryAuthority(
  101. LSA_SEC_HANDLE ContextHandle,
  102. PVOID Buffer)
  103. {
  104. SecPkgContext_Authority Authority;
  105. DWORD Size;
  106. PSPContext pContext;
  107. SECURITY_STATUS Status;
  108. PVOID pvClient = NULL;
  109. CERT_CONTEXT * pCert;
  110. DWORD cchIssuer;
  111. DWORD cbIssuer;
  112. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_AUTHORITY)\n"));
  113. pContext = (PSPContext)ContextHandle;
  114. Size = sizeof( SecPkgContext_Authority );
  115. //
  116. // Obtain data from Schannel.
  117. //
  118. pCert = pContext->RipeZombie->pRemoteCert;
  119. if(NULL == pCert)
  120. {
  121. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  122. }
  123. if(pCert->pCertInfo->Issuer.cbData == 0 ||
  124. pCert->pCertInfo->Issuer.pbData == NULL)
  125. {
  126. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  127. }
  128. if(0 >= (cchIssuer = CertNameToStr(pCert->dwCertEncodingType,
  129. &pCert->pCertInfo->Issuer,
  130. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  131. NULL,
  132. 0)))
  133. {
  134. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  135. }
  136. cbIssuer = (cchIssuer + 1) * sizeof(TCHAR);
  137. Authority.sAuthorityName = SPExternalAlloc(cbIssuer);
  138. if(Authority.sAuthorityName == NULL)
  139. {
  140. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  141. }
  142. if(0 >= CertNameToStr(pCert->dwCertEncodingType,
  143. &pCert->pCertInfo->Issuer,
  144. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  145. Authority.sAuthorityName,
  146. cchIssuer))
  147. {
  148. SPExternalFree(Authority.sAuthorityName);
  149. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  150. }
  151. //
  152. // Copy buffers to client memory.
  153. //
  154. Status = LsaTable->AllocateClientBuffer(
  155. NULL,
  156. cbIssuer,
  157. &pvClient);
  158. if(FAILED(Status))
  159. {
  160. SPExternalFree(Authority.sAuthorityName);
  161. return SP_LOG_RESULT(Status);
  162. }
  163. Status = LsaTable->CopyToClientBuffer(
  164. NULL,
  165. cbIssuer,
  166. pvClient,
  167. Authority.sAuthorityName);
  168. if(FAILED(Status))
  169. {
  170. SPExternalFree(Authority.sAuthorityName);
  171. LsaTable->FreeClientBuffer(NULL, pvClient);
  172. return SP_LOG_RESULT(Status);
  173. }
  174. SPExternalFree(Authority.sAuthorityName);
  175. Authority.sAuthorityName = pvClient;
  176. //
  177. // Copy structure back to client memory.
  178. //
  179. Status = LsaTable->CopyToClientBuffer( NULL,
  180. Size,
  181. Buffer,
  182. &Authority );
  183. if(FAILED(Status))
  184. {
  185. LsaTable->FreeClientBuffer(NULL, pvClient);
  186. return SP_LOG_RESULT(Status);
  187. }
  188. return SEC_E_OK;
  189. }
  190. //+-------------------------------------------------------------------------
  191. //
  192. // Function: SpQueryConnectionInfo
  193. //
  194. // Synopsis: Retrieves the SECPKG_ATTR_CONNECTION_INFO context attribute.
  195. //
  196. // Arguments:
  197. //
  198. // Returns:
  199. //
  200. // Notes: The buffer returned contains the following structure:
  201. //
  202. // typedef struct _SecPkgContext_ConnectionInfo
  203. // {
  204. // DWORD dwProtocol;
  205. // ALG_ID aiCipher;
  206. // DWORD dwCipherStrength;
  207. // ALG_ID aiHash;
  208. // DWORD dwHashStrength;
  209. // ALG_ID aiExch;
  210. // DWORD dwExchStrength;
  211. // } SecPkgContext_ConnectionInfo;
  212. //
  213. //--------------------------------------------------------------------------
  214. SECURITY_STATUS
  215. SpQueryConnectionInfo(
  216. PSPContext pContext,
  217. SecPkgContext_ConnectionInfo *pConnectionInfo)
  218. {
  219. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_CONNECTION_INFO)\n"));
  220. if (NULL == pContext->pCipherInfo ||
  221. NULL == pContext->pHashInfo ||
  222. NULL == pContext->pKeyExchInfo)
  223. {
  224. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  225. }
  226. ZeroMemory(pConnectionInfo, sizeof(SecPkgContext_ConnectionInfo));
  227. pConnectionInfo->dwProtocol = pContext->RipeZombie->fProtocol;
  228. if(pContext->pCipherInfo->aiCipher != CALG_NULLCIPHER)
  229. {
  230. pConnectionInfo->aiCipher = pContext->pCipherInfo->aiCipher;
  231. pConnectionInfo->dwCipherStrength = pContext->pCipherInfo->dwStrength;
  232. }
  233. pConnectionInfo->aiHash = pContext->pHashInfo->aiHash;
  234. pConnectionInfo->dwHashStrength = pContext->pHashInfo->cbCheckSum * 8;
  235. pConnectionInfo->aiExch = pContext->pKeyExchInfo->aiExch;
  236. pConnectionInfo->dwExchStrength = pContext->RipeZombie->dwExchStrength;
  237. return SEC_E_OK;
  238. }
  239. //+-------------------------------------------------------------------------
  240. //
  241. // Function: SpQueryIssuerList
  242. //
  243. // Synopsis: Retrieves the SECPKG_ATTR_ISSUER_LIST context attribute.
  244. //
  245. // Arguments:
  246. //
  247. // Returns:
  248. //
  249. // Notes: The buffer returned contains the following structure:
  250. //
  251. // typedef struct _SecPkgContext_IssuerListInfo
  252. // {
  253. // DWORD cbIssuerList;
  254. // PBYTE pIssuerList;
  255. // } SecPkgContext_IssuerListInfo;
  256. //
  257. //--------------------------------------------------------------------------
  258. SECURITY_STATUS
  259. SpQueryIssuerList(
  260. LSA_SEC_HANDLE ContextHandle,
  261. PVOID Buffer)
  262. {
  263. SecPkgContext_IssuerListInfo IssuerList;
  264. DWORD Size;
  265. PSPContext pContext;
  266. SECURITY_STATUS Status;
  267. PVOID pvClient = NULL;
  268. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_ISSUER_LIST)\n"));
  269. pContext = (PSPContext)ContextHandle;
  270. Size = sizeof( SecPkgContext_IssuerListInfo );
  271. //
  272. // Obtain data from Schannel.
  273. //
  274. // The issuer list is returned in the SSL3 wire format, which
  275. // consists of a bunch of issuer names, each prepended
  276. // with a two byte size (in big endian). Additionally, the list
  277. // is also prepended with a two byte list size (also in big
  278. // endian).
  279. IssuerList.cbIssuerList = pContext->cbIssuerList;
  280. IssuerList.pIssuerList = pContext->pbIssuerList;
  281. //
  282. // Copy buffers to client memory.
  283. //
  284. if(IssuerList.cbIssuerList && IssuerList.pIssuerList)
  285. {
  286. Status = LsaTable->AllocateClientBuffer(
  287. NULL,
  288. IssuerList.cbIssuerList,
  289. &pvClient);
  290. if(FAILED(Status))
  291. {
  292. return SP_LOG_RESULT(Status);
  293. }
  294. Status = LsaTable->CopyToClientBuffer(
  295. NULL,
  296. IssuerList.cbIssuerList,
  297. pvClient,
  298. IssuerList.pIssuerList);
  299. if(FAILED(Status))
  300. {
  301. LsaTable->FreeClientBuffer(NULL, pvClient);
  302. return SP_LOG_RESULT(Status);
  303. }
  304. IssuerList.pIssuerList = pvClient;
  305. }
  306. //
  307. // Copy structure back to client memory.
  308. //
  309. Status = LsaTable->CopyToClientBuffer( NULL,
  310. Size,
  311. Buffer,
  312. &IssuerList );
  313. if(FAILED(Status))
  314. {
  315. LsaTable->FreeClientBuffer(NULL, pvClient);
  316. return SP_LOG_RESULT(Status);
  317. }
  318. return SEC_E_OK;
  319. }
  320. //+-------------------------------------------------------------------------
  321. //
  322. // Function: SpQueryIssuerListEx
  323. //
  324. // Synopsis: Retrieves the SECPKG_ATTR_ISSUER_LIST_EX context attribute.
  325. //
  326. // Arguments:
  327. //
  328. // Returns:
  329. //
  330. // Notes: The buffer returned contains the following structure:
  331. //
  332. // typedef struct _SecPkgContext_IssuerListInfoEx
  333. // {
  334. // PCERT_NAME_BLOB aIssuers;
  335. // DWORD cIssuers;
  336. // } SecPkgContext_IssuerListInfoEx;
  337. //
  338. //--------------------------------------------------------------------------
  339. SECURITY_STATUS
  340. SpQueryIssuerListEx(
  341. LSA_SEC_HANDLE ContextHandle,
  342. PVOID Buffer)
  343. {
  344. SecPkgContext_IssuerListInfoEx IssuerListEx;
  345. DWORD Size;
  346. PSPContext pContext;
  347. SECURITY_STATUS Status;
  348. PVOID pvClient = NULL;
  349. DWORD cIssuers;
  350. PBYTE pbIssuerList;
  351. DWORD cbIssuerList;
  352. PBYTE pbIssuer;
  353. DWORD cbIssuer;
  354. PBYTE pbClientIssuer;
  355. PCERT_NAME_BLOB paIssuerBlobs;
  356. DWORD cbIssuerBlobs;
  357. DWORD i;
  358. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_ISSUER_LIST_EX)\n"));
  359. pContext = (PSPContext)ContextHandle;
  360. Size = sizeof( SecPkgContext_IssuerListInfoEx );
  361. //
  362. // Obtain data from Schannel.
  363. //
  364. IssuerListEx.cIssuers = 0;
  365. IssuerListEx.aIssuers = NULL;
  366. if(pContext->pbIssuerList && pContext->cbIssuerList > 2)
  367. {
  368. pbIssuerList = pContext->pbIssuerList + 2;
  369. cbIssuerList = pContext->cbIssuerList - 2;
  370. // Count issuers.
  371. cIssuers = 0;
  372. pbIssuer = pbIssuerList;
  373. while(pbIssuer + 1 < pbIssuerList + cbIssuerList)
  374. {
  375. cbIssuer = COMBINEBYTES(pbIssuer[0], pbIssuer[1]);
  376. pbIssuer += 2 + cbIssuer;
  377. cIssuers++;
  378. }
  379. // Allocate memory for list of blobs.
  380. cbIssuerBlobs = cIssuers * sizeof(CERT_NAME_BLOB);
  381. paIssuerBlobs = SPExternalAlloc(cbIssuerBlobs);
  382. if(paIssuerBlobs == NULL)
  383. {
  384. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  385. }
  386. // Allocate memory for issuer list.
  387. Status = LsaTable->AllocateClientBuffer(
  388. NULL,
  389. cbIssuerBlobs + cbIssuerList,
  390. &pvClient);
  391. if(FAILED(Status))
  392. {
  393. SPExternalFree(paIssuerBlobs);
  394. return SP_LOG_RESULT(Status);
  395. }
  396. // Copy the raw issuer list into client memory.
  397. Status = LsaTable->CopyToClientBuffer(
  398. NULL,
  399. cbIssuerList,
  400. (PBYTE)pvClient + cbIssuerBlobs,
  401. pbIssuerList );
  402. if(FAILED(Status))
  403. {
  404. SPExternalFree(paIssuerBlobs);
  405. LsaTable->FreeClientBuffer(NULL, pvClient);
  406. return SP_LOG_RESULT(Status);
  407. }
  408. // Build the issuer blob list.
  409. pbIssuer = pbIssuerList;
  410. pbClientIssuer = (PBYTE)pvClient + cbIssuerBlobs;
  411. for(i = 0; i < cIssuers; i++)
  412. {
  413. paIssuerBlobs[i].pbData = pbClientIssuer + 2;
  414. paIssuerBlobs[i].cbData = COMBINEBYTES(pbIssuer[0], pbIssuer[1]);
  415. pbIssuer += 2 + paIssuerBlobs[i].cbData;
  416. pbClientIssuer += 2 + paIssuerBlobs[i].cbData;
  417. }
  418. // Copy the blob list into client memory.
  419. Status = LsaTable->CopyToClientBuffer(
  420. NULL,
  421. cbIssuerBlobs,
  422. pvClient,
  423. paIssuerBlobs );
  424. if(FAILED(Status))
  425. {
  426. SPExternalFree(paIssuerBlobs);
  427. LsaTable->FreeClientBuffer(NULL, pvClient);
  428. return SP_LOG_RESULT(Status);
  429. }
  430. SPExternalFree(paIssuerBlobs);
  431. IssuerListEx.cIssuers = cIssuers;
  432. IssuerListEx.aIssuers = pvClient;
  433. }
  434. //
  435. // Copy structure back to client memory.
  436. //
  437. Status = LsaTable->CopyToClientBuffer( NULL,
  438. Size,
  439. Buffer,
  440. &IssuerListEx );
  441. if(FAILED(Status))
  442. {
  443. if(pvClient) LsaTable->FreeClientBuffer(NULL, pvClient);
  444. return SP_LOG_RESULT(Status);
  445. }
  446. return SEC_E_OK;
  447. }
  448. //+-------------------------------------------------------------------------
  449. //
  450. // Function: SpQueryKeyInfo
  451. //
  452. // Synopsis: Retrieves the SECPKG_ATTR_KEY_INFO context attribute.
  453. //
  454. // Arguments:
  455. //
  456. // Returns:
  457. //
  458. // Notes: The buffer returned contains the following structure:
  459. //
  460. // typedef struct _SecPkgContext_KeyInfoW
  461. // {
  462. // SEC_WCHAR SEC_FAR * sSignatureAlgorithmName;
  463. // SEC_WCHAR SEC_FAR * sEncryptAlgorithmName;
  464. // unsigned long KeySize;
  465. // unsigned long SignatureAlgorithm;
  466. // unsigned long EncryptAlgorithm;
  467. // } SecPkgContext_KeyInfoW;
  468. //
  469. //--------------------------------------------------------------------------
  470. SECURITY_STATUS
  471. SpQueryKeyInfo(
  472. PSPContext pContext,
  473. PVOID Buffer)
  474. {
  475. SecPkgContext_KeyInfo *pKeyInfo;
  476. DWORD cchSigName;
  477. DWORD cbSigName;
  478. DWORD cchCipherName;
  479. DWORD cbCipherName;
  480. UNICODE_STRING UniString;
  481. ANSI_STRING AnsiString;
  482. DWORD Status;
  483. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_KEY_INFO)\n"));
  484. if (NULL == pContext->pCipherInfo ||
  485. NULL == pContext->pHashInfo ||
  486. NULL == pContext->pKeyExchInfo)
  487. {
  488. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  489. }
  490. if (NULL == pContext->pCipherInfo->szName)
  491. {
  492. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  493. }
  494. pKeyInfo = (SecPkgContext_KeyInfo *)Buffer;
  495. ZeroMemory(pKeyInfo, sizeof(*pKeyInfo));
  496. pKeyInfo->KeySize = pContext->pCipherInfo->dwStrength;
  497. pKeyInfo->EncryptAlgorithm = pContext->pCipherInfo->aiCipher;
  498. pKeyInfo->SignatureAlgorithm = 0;
  499. cchSigName = strlen(pContext->pKeyExchInfo->szName);
  500. cbSigName = (cchSigName + 1) * sizeof(WCHAR);
  501. pKeyInfo->sSignatureAlgorithmName = LocalAlloc(LPTR, cbSigName);
  502. if(pKeyInfo->sSignatureAlgorithmName == NULL)
  503. {
  504. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  505. goto done;
  506. }
  507. RtlInitAnsiString(&AnsiString,
  508. pContext->pKeyExchInfo->szName);
  509. UniString.Length = 0;
  510. UniString.MaximumLength = (USHORT)cbSigName;
  511. UniString.Buffer = pKeyInfo->sSignatureAlgorithmName;
  512. RtlAnsiStringToUnicodeString(&UniString,
  513. &AnsiString,
  514. FALSE);
  515. cchCipherName = strlen(pContext->pCipherInfo->szName);
  516. cbCipherName = (cchCipherName + 1) * sizeof(WCHAR);
  517. pKeyInfo->sEncryptAlgorithmName = LocalAlloc(LPTR, cbCipherName);
  518. if(pKeyInfo->sEncryptAlgorithmName == NULL)
  519. {
  520. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  521. goto done;
  522. }
  523. RtlInitAnsiString(&AnsiString,
  524. pContext->pCipherInfo->szName);
  525. UniString.Length = 0;
  526. UniString.MaximumLength = (USHORT)cbCipherName;
  527. UniString.Buffer = pKeyInfo->sEncryptAlgorithmName;
  528. RtlAnsiStringToUnicodeString(&UniString,
  529. &AnsiString,
  530. FALSE);
  531. Status = PCT_ERR_OK;
  532. done:
  533. if(Status != PCT_ERR_OK)
  534. {
  535. if(pKeyInfo->sSignatureAlgorithmName)
  536. {
  537. LocalFree(pKeyInfo->sSignatureAlgorithmName);
  538. pKeyInfo->sSignatureAlgorithmName = NULL;
  539. }
  540. if(pKeyInfo->sEncryptAlgorithmName)
  541. {
  542. LocalFree(pKeyInfo->sEncryptAlgorithmName);
  543. pKeyInfo->sEncryptAlgorithmName = NULL;
  544. }
  545. }
  546. return Status;
  547. }
  548. //+-------------------------------------------------------------------------
  549. //
  550. // Function: SpQueryLifespan
  551. //
  552. // Synopsis: Retrieves the SECPKG_ATTR_LIFESPAN context attribute.
  553. //
  554. // Arguments:
  555. //
  556. // Returns:
  557. //
  558. // Notes: The buffer returned contains the following structure:
  559. //
  560. // typedef struct _SecPkgContext_Lifespan
  561. // {
  562. // TimeStamp tsStart;
  563. // TimeStamp tsExpiry;
  564. // } SecPkgContext_Lifespan;
  565. //
  566. //--------------------------------------------------------------------------
  567. SECURITY_STATUS
  568. SpQueryLifespan(
  569. PSPContext pContext,
  570. SecPkgContext_Lifespan *pLifespan)
  571. {
  572. PCCERT_CONTEXT pCertContext;
  573. NTSTATUS Status;
  574. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_LIFESPAN)\n"));
  575. if(pContext->RipeZombie->pbServerCertificate)
  576. {
  577. Status = DeserializeCertContext(&pCertContext,
  578. pContext->RipeZombie->pbServerCertificate,
  579. pContext->RipeZombie->cbServerCertificate);
  580. if(Status != PCT_ERR_OK)
  581. {
  582. SP_LOG_RESULT(Status);
  583. return SEC_E_INSUFFICIENT_MEMORY;
  584. }
  585. pLifespan->tsStart.QuadPart = *((LONGLONG *)&pCertContext->pCertInfo->NotBefore);
  586. pLifespan->tsExpiry.QuadPart = *((LONGLONG *)&pCertContext->pCertInfo->NotAfter);
  587. CertFreeCertificateContext(pCertContext);
  588. }
  589. else
  590. {
  591. pLifespan->tsStart.QuadPart = 0;
  592. pLifespan->tsExpiry.QuadPart = MAXTIMEQUADPART;
  593. }
  594. return SEC_E_OK;
  595. }
  596. //+-------------------------------------------------------------------------
  597. //
  598. // Function: SpQueryLocalCertContext
  599. //
  600. // Synopsis: Retrieves the SECPKG_ATTR_LOCAL_CERT_CONTEXT
  601. // context attribute.
  602. //
  603. // Arguments:
  604. //
  605. // Returns:
  606. //
  607. // Notes: The buffer returned contains a pointer to a CERT_CONTEXT
  608. // structure.
  609. //
  610. //--------------------------------------------------------------------------
  611. SECURITY_STATUS
  612. SpQueryLocalCertContext(
  613. LSA_SEC_HANDLE ContextHandle,
  614. PVOID Buffer)
  615. {
  616. DWORD Size;
  617. PSPContext pContext;
  618. SECURITY_STATUS Status;
  619. PVOID pvClient = NULL;
  620. PCCERT_CONTEXT pCertContext = NULL;
  621. SecBuffer Input;
  622. SecBuffer Output;
  623. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_LOCAL_CERT_CONTEXT)\n"));
  624. pContext = (PSPContext)ContextHandle;
  625. Size = sizeof( PCCERT_CONTEXT );
  626. //
  627. // Obtain data from Schannel.
  628. //
  629. if(pContext->dwProtocol & SP_PROT_CLIENTS)
  630. {
  631. pCertContext = pContext->RipeZombie->pClientCert;
  632. }
  633. else
  634. {
  635. pCertContext = pContext->RipeZombie->pActiveServerCred->pCert;
  636. }
  637. //
  638. // Copy buffers to client memory.
  639. //
  640. if(pCertContext)
  641. {
  642. // Serialize the certificate context, as well as the associated
  643. // certificate store.
  644. Status = SerializeCertContext(pCertContext,
  645. NULL,
  646. &Input.cbBuffer);
  647. if(FAILED(Status))
  648. {
  649. return SP_LOG_RESULT(Status);
  650. }
  651. Input.pvBuffer = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, Input.cbBuffer);
  652. if(Input.pvBuffer == NULL)
  653. {
  654. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  655. }
  656. Status = SerializeCertContext(pCertContext,
  657. Input.pvBuffer,
  658. &Input.cbBuffer);
  659. if(FAILED(Status))
  660. {
  661. LocalFree(Input.pvBuffer);
  662. return SP_LOG_RESULT(Status);
  663. }
  664. // Call back into the user process in order to replicate the
  665. // certificate context and store over there.
  666. Input.BufferType = SECBUFFER_DATA;
  667. Status = PerformApplicationCallback(SCH_DOWNLOAD_CERT_CALLBACK,
  668. 0,
  669. 0,
  670. &Input,
  671. &Output,
  672. TRUE);
  673. LocalFree(Input.pvBuffer);
  674. if(FAILED(Status))
  675. {
  676. return SP_LOG_RESULT(Status);
  677. }
  678. pCertContext = *(PCCERT_CONTEXT *)(Output.pvBuffer);
  679. SPExternalFree(Output.pvBuffer);
  680. }
  681. //
  682. // Copy structure back to client memory.
  683. //
  684. if(pCertContext)
  685. {
  686. Status = LsaTable->CopyToClientBuffer( NULL,
  687. Size,
  688. Buffer,
  689. (PVOID)&pCertContext );
  690. if(FAILED(Status))
  691. {
  692. return SP_LOG_RESULT(Status);
  693. }
  694. }
  695. else
  696. {
  697. return SP_LOG_RESULT(SEC_E_NO_CREDENTIALS);
  698. }
  699. return SEC_E_OK;
  700. }
  701. //+-------------------------------------------------------------------------
  702. //
  703. // Function: SpQueryRemoteCertContext
  704. //
  705. // Synopsis: Retrieves the SECPKG_ATTR_REMOTE_CERT_CONTEXT
  706. // context attribute.
  707. //
  708. // Arguments:
  709. //
  710. // Returns:
  711. //
  712. // Notes: The buffer returned contains a pointer to a CERT_CONTEXT
  713. // structure.
  714. //
  715. //--------------------------------------------------------------------------
  716. SECURITY_STATUS
  717. SpQueryRemoteCertContext(
  718. PSPContext pContext,
  719. PVOID Buffer)
  720. {
  721. PCCERT_CONTEXT pCertContext;
  722. SP_STATUS pctRet;
  723. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_REMOTE_CERT_CONTEXT)\n"));
  724. if(pContext->RipeZombie->pbServerCertificate)
  725. {
  726. pctRet = DeserializeCertContext(&pCertContext,
  727. pContext->RipeZombie->pbServerCertificate,
  728. pContext->RipeZombie->cbServerCertificate);
  729. if(pctRet != PCT_ERR_OK)
  730. {
  731. return SP_LOG_RESULT(pctRet);
  732. }
  733. *(PCCERT_CONTEXT *)Buffer = pCertContext;
  734. return SEC_E_OK;
  735. }
  736. else
  737. {
  738. return SP_LOG_RESULT(SEC_E_NO_CREDENTIALS);
  739. }
  740. }
  741. //+-------------------------------------------------------------------------
  742. //
  743. // Function: SpQueryLocalCred
  744. //
  745. // Synopsis: Retrieves the SECPKG_ATTR_LOCAL_CRED context attribute.
  746. //
  747. // Arguments:
  748. //
  749. // Returns:
  750. //
  751. // Notes: The buffer returned contains the following structure:
  752. //
  753. // typedef struct _SecPkgContext_LocalCredentialInfo
  754. // {
  755. // DWORD cbCertificateChain;
  756. // PBYTE pbCertificateChain;
  757. // DWORD cCertificates;
  758. // DWORD fFlags;
  759. // DWORD dwBits;
  760. // } SecPkgContext_LocalCredentialInfo;
  761. //
  762. //--------------------------------------------------------------------------
  763. SECURITY_STATUS
  764. SpQueryLocalCred(
  765. LSA_SEC_HANDLE ContextHandle,
  766. PVOID Buffer)
  767. {
  768. SecPkgContext_LocalCredentialInfo CredInfo;
  769. DWORD Size;
  770. PSPContext pContext;
  771. SECURITY_STATUS Status;
  772. PVOID pvClient = NULL;
  773. SP_STATUS pctRet;
  774. PCCERT_CONTEXT pCert = NULL;
  775. PUBLICKEY * pKey = NULL;
  776. DWORD fVerified = FALSE;
  777. RSAPUBKEY * pk = NULL;
  778. PSPCredential pCred;
  779. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_LOCAL_CRED)\n"));
  780. pContext = (PSPContext)ContextHandle;
  781. Size = sizeof( SecPkgContext_LocalCredentialInfo );
  782. //
  783. // Obtain data from Schannel.
  784. //
  785. ZeroMemory(&CredInfo, Size);
  786. if(pContext->dwProtocol & SP_PROT_CLIENTS)
  787. {
  788. pCred = pContext->pActiveClientCred;
  789. }
  790. else
  791. {
  792. pCred = pContext->RipeZombie->pActiveServerCred;
  793. }
  794. if(pCred)
  795. {
  796. pCert = pCred->pCert;
  797. pKey = pCred->pPublicKey;
  798. }
  799. if(pCert)
  800. {
  801. CredInfo.fFlags |= LCRED_CRED_EXISTS;
  802. CredInfo.pbCertificateChain = pCert->pbCertEncoded;
  803. CredInfo.cbCertificateChain = pCert->cbCertEncoded;
  804. CredInfo.cCertificates = 1;
  805. // Compute number of bits in the certificate's public key.
  806. CredInfo.dwBits = 0;
  807. pk = (RSAPUBKEY *)((pKey->pPublic) + 1);
  808. if(pk)
  809. {
  810. CredInfo.dwBits = pk->bitlen;
  811. }
  812. }
  813. //
  814. // Copy buffers to client memory.
  815. //
  816. if(CredInfo.pbCertificateChain)
  817. {
  818. Status = LsaTable->AllocateClientBuffer(
  819. NULL,
  820. CredInfo.cbCertificateChain,
  821. &pvClient);
  822. if(FAILED(Status))
  823. {
  824. return SP_LOG_RESULT(Status);
  825. }
  826. Status = LsaTable->CopyToClientBuffer(
  827. NULL,
  828. CredInfo.cbCertificateChain,
  829. pvClient,
  830. CredInfo.pbCertificateChain);
  831. if(FAILED(Status))
  832. {
  833. LsaTable->FreeClientBuffer(NULL, pvClient);
  834. return SP_LOG_RESULT(Status);
  835. }
  836. CredInfo.pbCertificateChain = pvClient;
  837. }
  838. //
  839. // Copy structure back to client memory.
  840. //
  841. Status = LsaTable->CopyToClientBuffer( NULL,
  842. Size,
  843. Buffer,
  844. &CredInfo );
  845. if(FAILED(Status))
  846. {
  847. LsaTable->FreeClientBuffer(NULL, pvClient);
  848. return SP_LOG_RESULT(Status);
  849. }
  850. return SEC_E_OK;
  851. }
  852. //+-------------------------------------------------------------------------
  853. //
  854. // Function: SpQueryRemoteCred
  855. //
  856. // Synopsis: Retrieves the SECPKG_ATTR_REMOTE_CRED context attribute.
  857. //
  858. // Arguments:
  859. //
  860. // Returns:
  861. //
  862. // Notes: The buffer returned contains the following structure:
  863. //
  864. // typedef struct _SecPkgContext_LocalCredentialInfo
  865. // {
  866. // DWORD cbCertificateChain;
  867. // PBYTE pbCertificateChain;
  868. // DWORD cCertificates;
  869. // DWORD fFlags;
  870. // DWORD dwBits;
  871. // } SecPkgContext_LocalCredentialInfo;
  872. //
  873. //--------------------------------------------------------------------------
  874. SECURITY_STATUS
  875. SpQueryRemoteCred(
  876. PSPContext pContext,
  877. PVOID Buffer)
  878. {
  879. SecPkgContext_LocalCredentialInfo *pCredInfo;
  880. PCCERT_CONTEXT pCertContext = NULL;
  881. PUBLICKEY * pKey = NULL;
  882. RSAPUBKEY * pk = NULL;
  883. SP_STATUS pctRet;
  884. PBYTE pbCert;
  885. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_REMOTE_CRED)\n"));
  886. pCredInfo = (SecPkgContext_LocalCredentialInfo *)Buffer;
  887. ZeroMemory(pCredInfo, sizeof(*pCredInfo));
  888. if(pContext->RipeZombie->pbServerCertificate)
  889. {
  890. pctRet = DeserializeCertContext(&pCertContext,
  891. pContext->RipeZombie->pbServerCertificate,
  892. pContext->RipeZombie->cbServerCertificate);
  893. if(pctRet != PCT_ERR_OK)
  894. {
  895. return SP_LOG_RESULT(pctRet);
  896. }
  897. }
  898. if(pCertContext)
  899. {
  900. pbCert = LocalAlloc(LPTR, pCertContext->cbCertEncoded);
  901. if(pbCert == NULL)
  902. {
  903. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  904. }
  905. memcpy(pbCert, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded);
  906. pCredInfo->fFlags |= LCRED_CRED_EXISTS;
  907. pCredInfo->pbCertificateChain = pbCert;
  908. pCredInfo->cbCertificateChain = pCertContext->cbCertEncoded;
  909. pCredInfo->cCertificates = 1;
  910. pCredInfo->dwBits = 0;
  911. // Compute number of bits in the certificate's public key.
  912. pctRet = SPPublicKeyFromCert(pCertContext, &pKey, NULL);
  913. if(pctRet == PCT_ERR_OK)
  914. {
  915. pk = (RSAPUBKEY *)((pKey->pPublic) + 1);
  916. if(pk)
  917. {
  918. pCredInfo->dwBits = pk->bitlen;
  919. }
  920. SPExternalFree(pKey);
  921. }
  922. CertFreeCertificateContext(pCertContext);
  923. }
  924. return SEC_E_OK;
  925. }
  926. //+-------------------------------------------------------------------------
  927. //
  928. // Function: SpQueryNames
  929. //
  930. // Synopsis: Retrieves the SECPKG_ATTR_NAMES context attribute.
  931. //
  932. // Arguments:
  933. //
  934. // Returns:
  935. //
  936. // Notes: The buffer returned contains the following structure:
  937. //
  938. // typedef struct _SecPkgContext_NamesW
  939. // {
  940. // SEC_WCHAR SEC_FAR * sUserName;
  941. // } SecPkgContext_NamesW;
  942. //
  943. //--------------------------------------------------------------------------
  944. SECURITY_STATUS
  945. SpQueryNames(
  946. PSPContext pContext,
  947. SecPkgContext_Names *pNames)
  948. {
  949. SECURITY_STATUS Status;
  950. PCCERT_CONTEXT pCert = NULL;
  951. DWORD cchSubject;
  952. DWORD cbSubject;
  953. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_NAMES)\n"));
  954. //
  955. // Obtain data from Schannel.
  956. //
  957. if(pContext->RipeZombie->pbServerCertificate == NULL)
  958. {
  959. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  960. }
  961. Status = DeserializeCertContext(&pCert,
  962. pContext->RipeZombie->pbServerCertificate,
  963. pContext->RipeZombie->cbServerCertificate);
  964. if(Status != PCT_ERR_OK)
  965. {
  966. return SP_LOG_RESULT(Status);
  967. }
  968. //
  969. // Build name string.
  970. //
  971. if(0 >= (cchSubject = CertNameToStr(pCert->dwCertEncodingType,
  972. &pCert->pCertInfo->Subject,
  973. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  974. NULL,
  975. 0)))
  976. {
  977. CertFreeCertificateContext(pCert);
  978. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  979. }
  980. cbSubject = (cchSubject + 1) * sizeof(TCHAR);
  981. pNames->sUserName = LocalAlloc(LPTR, cbSubject);
  982. if(pNames->sUserName == NULL)
  983. {
  984. CertFreeCertificateContext(pCert);
  985. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  986. }
  987. if(0 >= CertNameToStr(pCert->dwCertEncodingType,
  988. &pCert->pCertInfo->Subject,
  989. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  990. pNames->sUserName,
  991. cchSubject))
  992. {
  993. CertFreeCertificateContext(pCert);
  994. LocalFree(pNames->sUserName);
  995. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  996. }
  997. CertFreeCertificateContext(pCert);
  998. return SEC_E_OK;
  999. }
  1000. //+-------------------------------------------------------------------------
  1001. //
  1002. // Function: SpQueryPackageInfo
  1003. //
  1004. // Synopsis: Retrieves the SECPKG_ATTR_PACKAGE_INFO context attribute.
  1005. //
  1006. // Arguments:
  1007. //
  1008. // Returns:
  1009. //
  1010. // Notes: The buffer returned contains the following structure:
  1011. //
  1012. // typedef struct _SecPkgContext_PackageInfoW
  1013. // {
  1014. // PSecPkgInfoW PackageInfo;
  1015. // } SecPkgContext_PackageInfoW, SEC_FAR * PSecPkgContext_PackageInfoW;
  1016. //
  1017. //--------------------------------------------------------------------------
  1018. SECURITY_STATUS
  1019. SpQueryPackageInfo(
  1020. PSPContext pContext,
  1021. PVOID Buffer)
  1022. {
  1023. PSecPkgContext_PackageInfoW pPackageInfo;
  1024. SecPkgInfoW Info;
  1025. DWORD cbName;
  1026. DWORD cbComment;
  1027. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_PACKAGE_INFO)\n"));
  1028. SpSslGetInfo(&Info);
  1029. pPackageInfo = (PSecPkgContext_PackageInfoW)Buffer;
  1030. cbName = (lstrlen(Info.Name) + 1) * sizeof(WCHAR);
  1031. cbComment = (lstrlen(Info.Comment) + 1) * sizeof(WCHAR);
  1032. pPackageInfo->PackageInfo = LocalAlloc(LPTR, sizeof(SecPkgInfo) + cbName + cbComment);
  1033. if(pPackageInfo->PackageInfo == NULL)
  1034. {
  1035. return SP_LOG_RESULT(STATUS_INSUFFICIENT_RESOURCES);
  1036. }
  1037. pPackageInfo->PackageInfo->wVersion = Info.wVersion;
  1038. pPackageInfo->PackageInfo->wRPCID = Info.wRPCID;
  1039. pPackageInfo->PackageInfo->fCapabilities = Info.fCapabilities;
  1040. pPackageInfo->PackageInfo->cbMaxToken = Info.cbMaxToken;
  1041. pPackageInfo->PackageInfo->Name = (LPWSTR)(pPackageInfo->PackageInfo + 1);
  1042. pPackageInfo->PackageInfo->Comment = (LPWSTR)((PBYTE)pPackageInfo->PackageInfo->Name + cbName);
  1043. lstrcpy(
  1044. pPackageInfo->PackageInfo->Name,
  1045. Info.Name);
  1046. lstrcpy(
  1047. pPackageInfo->PackageInfo->Comment,
  1048. Info.Comment);
  1049. return SEC_E_OK;
  1050. }
  1051. //+-------------------------------------------------------------------------
  1052. //
  1053. // Function: SpQueryProtoInfo
  1054. //
  1055. // Synopsis: Retrieves the SECPKG_ATTR_PROTO_INFO context attribute.
  1056. //
  1057. // Arguments:
  1058. //
  1059. // Returns:
  1060. //
  1061. // Notes: The buffer returned contains the following structure:
  1062. //
  1063. // typedef struct _SecPkgContext_ProtoInfoW
  1064. // {
  1065. // SEC_WCHAR SEC_FAR * sProtocolName;
  1066. // unsigned long majorVersion;
  1067. // unsigned long minorVersion;
  1068. // } SecPkgContext_ProtoInfoW;
  1069. //
  1070. //--------------------------------------------------------------------------
  1071. SECURITY_STATUS
  1072. SpQueryProtoInfo(
  1073. PSPContext pContext,
  1074. PVOID Buffer)
  1075. {
  1076. SecPkgContext_ProtoInfo *pProtoInfo;
  1077. DWORD index;
  1078. DWORD cbName;
  1079. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_PROTO_INFO)\n"));
  1080. pProtoInfo = (SecPkgContext_ProtoInfo *)Buffer;
  1081. for(index = 0;
  1082. index < sizeof(rgProts) / sizeof(PROTO_ID);
  1083. index += 1)
  1084. {
  1085. if(pContext->RipeZombie->fProtocol == rgProts[index].dwProtoId)
  1086. {
  1087. break;
  1088. }
  1089. }
  1090. if(index >= sizeof(rgProts) / sizeof(PROTO_ID))
  1091. {
  1092. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1093. }
  1094. cbName = (lstrlen(rgProts[index].szProto) + 1) * sizeof(WCHAR);
  1095. pProtoInfo->sProtocolName = LocalAlloc(LPTR, cbName);
  1096. if(pProtoInfo->sProtocolName == NULL)
  1097. {
  1098. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1099. }
  1100. lstrcpy(pProtoInfo->sProtocolName, rgProts[index].szProto);
  1101. pProtoInfo->majorVersion = rgProts[index].dwMajor;
  1102. pProtoInfo->minorVersion = rgProts[index].dwMinor;
  1103. return SEC_E_OK;
  1104. }
  1105. //+-------------------------------------------------------------------------
  1106. //
  1107. // Function: SpQuerySizes
  1108. //
  1109. // Synopsis: Retrieves the SECPKG_ATTR_SIZES context attribute.
  1110. //
  1111. // Arguments:
  1112. //
  1113. // Returns:
  1114. //
  1115. // Notes: The buffer returned contains the following structure:
  1116. //
  1117. // typedef struct _SecPkgContext_Sizes
  1118. // {
  1119. // unsigned long cbMaxToken;
  1120. // unsigned long cbMaxSignature;
  1121. // unsigned long cbBlockSize;
  1122. // unsigned long cbSecurityTrailer;
  1123. // } SecPkgContext_Sizes;
  1124. //
  1125. //--------------------------------------------------------------------------
  1126. SECURITY_STATUS
  1127. SpQuerySizes(
  1128. PSPContext pContext,
  1129. SecPkgContext_Sizes *pSizes)
  1130. {
  1131. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_SIZES)\n"));
  1132. if (NULL == pContext->pCipherInfo ||
  1133. NULL == pContext->pHashInfo)
  1134. {
  1135. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1136. }
  1137. switch(pContext->RipeZombie->fProtocol)
  1138. {
  1139. case SP_PROT_SSL2_CLIENT:
  1140. case SP_PROT_SSL2_SERVER:
  1141. pSizes->cbMaxToken = SSL2_MAX_MESSAGE_LENGTH;
  1142. pSizes->cbSecurityTrailer = 2 + pContext->pHashInfo->cbCheckSum;
  1143. if(pContext->pCipherInfo->dwBlockSize > 1)
  1144. {
  1145. pSizes->cbSecurityTrailer += 1 + pContext->pCipherInfo->dwBlockSize; // 3 byte header
  1146. }
  1147. break;
  1148. case SP_PROT_PCT1_CLIENT:
  1149. case SP_PROT_PCT1_SERVER:
  1150. pSizes->cbMaxToken = PCT1_MAX_MESSAGE_LENGTH;
  1151. pSizes->cbSecurityTrailer = 2 + pContext->pHashInfo->cbCheckSum;
  1152. if(pContext->pCipherInfo->dwBlockSize > 1)
  1153. {
  1154. pSizes->cbSecurityTrailer += 1 + pContext->pCipherInfo->dwBlockSize; // 3 byte header
  1155. }
  1156. break;
  1157. case SP_PROT_SSL3_CLIENT:
  1158. case SP_PROT_SSL3_SERVER:
  1159. case SP_PROT_TLS1_CLIENT:
  1160. case SP_PROT_TLS1_SERVER:
  1161. pSizes->cbMaxToken = SSL3_MAX_MESSAGE_LENGTH;
  1162. pSizes->cbSecurityTrailer = 5 + pContext->pHashInfo->cbCheckSum;
  1163. if(pContext->pCipherInfo->dwBlockSize > 1)
  1164. {
  1165. pSizes->cbSecurityTrailer += pContext->pCipherInfo->dwBlockSize;
  1166. }
  1167. break;
  1168. default:
  1169. pSizes->cbMaxToken = SSL3_MAX_MESSAGE_LENGTH;
  1170. pSizes->cbSecurityTrailer = 0;
  1171. }
  1172. pSizes->cbMaxSignature = pContext->pHashInfo->cbCheckSum;
  1173. pSizes->cbBlockSize = pContext->pCipherInfo->dwBlockSize;
  1174. return SEC_E_OK;
  1175. }
  1176. //+-------------------------------------------------------------------------
  1177. //
  1178. // Function: SpQueryStreamSizes
  1179. //
  1180. // Synopsis: Retrieves the SECPKG_ATTR_STREAM_SIZES context attribute.
  1181. //
  1182. // Arguments:
  1183. //
  1184. // Returns:
  1185. //
  1186. // Notes: The buffer returned contains the following structure:
  1187. //
  1188. // typedef struct _SecPkgContext_StreamSizes
  1189. // {
  1190. // unsigned long cbHeader;
  1191. // unsigned long cbTrailer;
  1192. // unsigned long cbMaximumMessage;
  1193. // unsigned long cBuffers;
  1194. // unsigned long cbBlockSize;
  1195. // } SecPkgContext_StreamSizes;
  1196. //
  1197. //--------------------------------------------------------------------------
  1198. SECURITY_STATUS
  1199. SpQueryStreamSizes(
  1200. PSPContext pContext,
  1201. SecPkgContext_StreamSizes *pStreamSizes)
  1202. {
  1203. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_STREAM_SIZES)\n"));
  1204. if (NULL == pContext->pCipherInfo ||
  1205. NULL == pContext->pHashInfo)
  1206. {
  1207. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1208. }
  1209. switch(pContext->RipeZombie->fProtocol)
  1210. {
  1211. case SP_PROT_SSL2_CLIENT:
  1212. case SP_PROT_SSL2_SERVER:
  1213. pStreamSizes->cbMaximumMessage = SSL2_MAX_MESSAGE_LENGTH;
  1214. pStreamSizes->cbHeader = 2 + pContext->pHashInfo->cbCheckSum;
  1215. pStreamSizes->cbTrailer = 0;
  1216. if(pContext->pCipherInfo->dwBlockSize > 1)
  1217. {
  1218. pStreamSizes->cbHeader += 1; // 3 byte header
  1219. pStreamSizes->cbTrailer += pContext->pCipherInfo->dwBlockSize;
  1220. }
  1221. break;
  1222. case SP_PROT_PCT1_CLIENT:
  1223. case SP_PROT_PCT1_SERVER:
  1224. pStreamSizes->cbMaximumMessage = PCT1_MAX_MESSAGE_LENGTH;
  1225. pStreamSizes->cbHeader = 2;
  1226. pStreamSizes->cbTrailer = pContext->pHashInfo->cbCheckSum;
  1227. if(pContext->pCipherInfo->dwBlockSize > 1)
  1228. {
  1229. pStreamSizes->cbHeader += 1; // 3 byte header
  1230. pStreamSizes->cbTrailer += pContext->pCipherInfo->dwBlockSize;
  1231. }
  1232. break;
  1233. case SP_PROT_TLS1_CLIENT:
  1234. case SP_PROT_TLS1_SERVER:
  1235. case SP_PROT_SSL3_CLIENT:
  1236. case SP_PROT_SSL3_SERVER:
  1237. pStreamSizes->cbMaximumMessage = SSL3_MAX_MESSAGE_LENGTH;
  1238. pStreamSizes->cbHeader = 5;
  1239. pStreamSizes->cbTrailer = pContext->pHashInfo->cbCheckSum;
  1240. if(pContext->pCipherInfo->dwBlockSize > 1)
  1241. {
  1242. pStreamSizes->cbTrailer += pContext->pCipherInfo->dwBlockSize;
  1243. }
  1244. break;
  1245. default:
  1246. pStreamSizes->cbMaximumMessage = SSL3_MAX_MESSAGE_LENGTH;
  1247. pStreamSizes->cbHeader = 0;
  1248. pStreamSizes->cbTrailer = 0;
  1249. }
  1250. pStreamSizes->cbBlockSize = pContext->pCipherInfo->dwBlockSize;
  1251. pStreamSizes->cBuffers = 4;
  1252. return SEC_E_OK;
  1253. }
  1254. //+-------------------------------------------------------------------------
  1255. //
  1256. // Function: SpQueryEapKeyBlock
  1257. //
  1258. // Synopsis: Retrieves the SECPKG_ATTR_EAP_KEY_BLOCK context attribute.
  1259. //
  1260. // Arguments:
  1261. //
  1262. // Returns:
  1263. //
  1264. // Notes: The buffer returned contains the following structure:
  1265. //
  1266. // typedef struct _SecPkgContext_EapKeyBlock
  1267. // {
  1268. // BYTE rgbKeys[128];
  1269. // BYTE rgbIVs[64];
  1270. // } SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock;
  1271. //
  1272. //--------------------------------------------------------------------------
  1273. SECURITY_STATUS
  1274. SpQueryEapKeyBlock(
  1275. LSA_SEC_HANDLE ContextHandle,
  1276. PVOID Buffer)
  1277. {
  1278. SecPkgContext_EapKeyBlock KeyBlock;
  1279. DWORD Size;
  1280. PSPContext pContext;
  1281. SECURITY_STATUS Status;
  1282. HCRYPTHASH hHash;
  1283. CRYPT_DATA_BLOB Data;
  1284. UCHAR rgbRandom[CB_SSL3_RANDOM + CB_SSL3_RANDOM];
  1285. DWORD cbRandom;
  1286. DWORD cbData;
  1287. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_EAP_KEY_BLOCK)\n"));
  1288. pContext = (PSPContext)ContextHandle;
  1289. Size = sizeof( SecPkgContext_EapKeyBlock );
  1290. //
  1291. // Obtain data from Schannel.
  1292. //
  1293. if(!(pContext->RipeZombie->fProtocol & SP_PROT_TLS1))
  1294. {
  1295. // This attribute is defined for TLS only.
  1296. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1297. }
  1298. if(!pContext->RipeZombie->hMasterKey)
  1299. {
  1300. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1301. }
  1302. // Build random buffer.
  1303. CopyMemory(rgbRandom, pContext->rgbS3CRandom, CB_SSL3_RANDOM);
  1304. CopyMemory(rgbRandom + CB_SSL3_RANDOM, pContext->rgbS3SRandom, CB_SSL3_RANDOM);
  1305. cbRandom = CB_SSL3_RANDOM + CB_SSL3_RANDOM;
  1306. // rgbKeys = PRF(master_secret, "client EAP encryption", client_random + server_random);
  1307. // Compute the PRF
  1308. if(!CryptCreateHash(pContext->RipeZombie->hMasterProv,
  1309. CALG_TLS1PRF,
  1310. pContext->RipeZombie->hMasterKey,
  1311. 0,
  1312. &hHash))
  1313. {
  1314. SP_LOG_RESULT(GetLastError());
  1315. return SEC_E_INTERNAL_ERROR;
  1316. }
  1317. Data.pbData = TLS1_LABEL_EAP_KEYS;
  1318. Data.cbData = CB_TLS1_LABEL_EAP_KEYS;
  1319. if(!CryptSetHashParam(hHash,
  1320. HP_TLS1PRF_LABEL,
  1321. (PBYTE)&Data,
  1322. 0))
  1323. {
  1324. SP_LOG_RESULT(GetLastError());
  1325. CryptDestroyHash(hHash);
  1326. return SEC_E_INTERNAL_ERROR;
  1327. }
  1328. Data.pbData = rgbRandom;
  1329. Data.cbData = cbRandom;
  1330. if(!CryptSetHashParam(hHash,
  1331. HP_TLS1PRF_SEED,
  1332. (PBYTE)&Data,
  1333. 0))
  1334. {
  1335. SP_LOG_RESULT(GetLastError());
  1336. CryptDestroyHash(hHash);
  1337. return SEC_E_INTERNAL_ERROR;
  1338. }
  1339. cbData = sizeof(KeyBlock.rgbKeys);
  1340. if(!CryptGetHashParam(hHash,
  1341. HP_HASHVAL,
  1342. KeyBlock.rgbKeys,
  1343. &cbData,
  1344. 0))
  1345. {
  1346. SP_LOG_RESULT(GetLastError());
  1347. CryptDestroyHash(hHash);
  1348. return SEC_E_INTERNAL_ERROR;
  1349. }
  1350. SP_ASSERT(cbData == sizeof(KeyBlock.rgbKeys));
  1351. CryptDestroyHash(hHash);
  1352. // IVs = PRF("", "client EAP encryption", client_random + server_random)
  1353. if(!PRF(NULL, 0,
  1354. TLS1_LABEL_EAP_KEYS, CB_TLS1_LABEL_EAP_KEYS,
  1355. rgbRandom, sizeof(rgbRandom),
  1356. KeyBlock.rgbIVs, sizeof(KeyBlock.rgbIVs)))
  1357. {
  1358. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  1359. }
  1360. //
  1361. // Copy structure back to client memory.
  1362. //
  1363. Status = LsaTable->CopyToClientBuffer( NULL,
  1364. Size,
  1365. Buffer,
  1366. &KeyBlock );
  1367. if(FAILED(Status))
  1368. {
  1369. return SP_LOG_RESULT(Status);
  1370. }
  1371. return SEC_E_OK;
  1372. }
  1373. //+-------------------------------------------------------------------------
  1374. //
  1375. // Function: SpQueryMappedCredProp
  1376. //
  1377. // Synopsis: Retrieves the SECPKG_ATTR_MAPPED_CRED_PROP context
  1378. // attribute.
  1379. //
  1380. // Arguments:
  1381. //
  1382. // Returns:
  1383. //
  1384. // Notes: The buffer returned contains the following structure:
  1385. //
  1386. // typedef struct _SecPkgContext_MappedCredProp
  1387. // {
  1388. // DWORD dwProperty;
  1389. // PBYTE pbBuffer;
  1390. // } SecPkgContext_MappedCredProp;
  1391. //
  1392. //--------------------------------------------------------------------------
  1393. SECURITY_STATUS
  1394. SpQueryMappedCredAttr(
  1395. PSPContext pContext,
  1396. PVOID Buffer)
  1397. {
  1398. SecPkgContext_MappedCredAttr *pMappedCredAttr;
  1399. HMAPPER *phMapper;
  1400. DWORD cbBuffer;
  1401. SECURITY_STATUS Status;
  1402. pMappedCredAttr = (SecPkgContext_MappedCredAttr *)Buffer;
  1403. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_MAPPED_CRED_ATTR %d)\n", pMappedCredAttr->dwAttribute));
  1404. if(pContext->RipeZombie == NULL)
  1405. {
  1406. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1407. }
  1408. phMapper = pContext->RipeZombie->phMapper;
  1409. if(phMapper == NULL)
  1410. {
  1411. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1412. }
  1413. if(phMapper->m_dwFlags & SCH_FLAG_SYSTEM_MAPPER)
  1414. {
  1415. // System mapper.
  1416. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1417. }
  1418. else
  1419. {
  1420. // Application mapper.
  1421. Status = phMapper->m_vtable->QueryMappedCredentialAttributes(
  1422. phMapper,
  1423. pContext->RipeZombie->hLocator,
  1424. pMappedCredAttr->dwAttribute,
  1425. NULL,
  1426. &cbBuffer);
  1427. if(FAILED(Status))
  1428. {
  1429. return SP_LOG_RESULT(Status);
  1430. }
  1431. pMappedCredAttr->pvBuffer = LocalAlloc(LPTR, cbBuffer);
  1432. if(pMappedCredAttr->pvBuffer == NULL)
  1433. {
  1434. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1435. }
  1436. Status = phMapper->m_vtable->QueryMappedCredentialAttributes(
  1437. phMapper,
  1438. pContext->RipeZombie->hLocator,
  1439. pMappedCredAttr->dwAttribute,
  1440. pMappedCredAttr->pvBuffer,
  1441. &cbBuffer);
  1442. if(FAILED(Status))
  1443. {
  1444. LocalFree(pMappedCredAttr->pvBuffer);
  1445. return SP_LOG_RESULT(Status);
  1446. }
  1447. }
  1448. return SEC_E_OK;
  1449. }
  1450. //+-------------------------------------------------------------------------
  1451. //
  1452. // Function: SpQueryApplicationData
  1453. //
  1454. // Synopsis: Retrieves the SECPKG_ATTR_APP_DATA context attribute.
  1455. //
  1456. // Arguments:
  1457. //
  1458. // Returns:
  1459. //
  1460. // Notes: The buffer returned contains the following structure:
  1461. //
  1462. // typedef struct _SecPkgContext_SessionAppData
  1463. // {
  1464. // DWORD dwFlags;
  1465. // DWORD cbAppData;
  1466. // PBYTE pbAppData;
  1467. // } SecPkgContext_SessionAppData, *PSecPkgContext_SessionAppData;
  1468. //
  1469. //--------------------------------------------------------------------------
  1470. SECURITY_STATUS
  1471. SpQueryApplicationData(
  1472. LSA_SEC_HANDLE ContextHandle,
  1473. PVOID Buffer)
  1474. {
  1475. SecPkgContext_SessionAppData AppData;
  1476. PBYTE pbAppData = NULL;
  1477. DWORD cbAppData = 0;
  1478. PSPContext pContext;
  1479. SECURITY_STATUS Status;
  1480. PVOID pvClient = NULL;
  1481. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_APP_DATA)\n"));
  1482. pContext = (PSPContext)ContextHandle;
  1483. if(pContext == NULL || pContext->RipeZombie == NULL)
  1484. {
  1485. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1486. }
  1487. //
  1488. // Get application data from cache.
  1489. //
  1490. Status = GetCacheAppData(pContext->RipeZombie, &pbAppData, &cbAppData);
  1491. if(FAILED(Status))
  1492. {
  1493. SP_LOG_RESULT(Status);
  1494. goto cleanup;
  1495. }
  1496. //
  1497. // Allocate memory for application data in application process.
  1498. //
  1499. if(pbAppData != NULL)
  1500. {
  1501. Status = LsaTable->AllocateClientBuffer(
  1502. NULL,
  1503. cbAppData,
  1504. &pvClient);
  1505. if(FAILED(Status))
  1506. {
  1507. SP_LOG_RESULT(Status);
  1508. goto cleanup;
  1509. }
  1510. Status = LsaTable->CopyToClientBuffer(
  1511. NULL,
  1512. cbAppData,
  1513. pvClient,
  1514. pbAppData);
  1515. if(FAILED(Status))
  1516. {
  1517. SP_LOG_RESULT(Status);
  1518. goto cleanup;
  1519. }
  1520. }
  1521. //
  1522. // Build output structure.
  1523. //
  1524. ZeroMemory(&AppData, sizeof(AppData));
  1525. AppData.cbAppData = cbAppData;
  1526. AppData.pbAppData = pvClient;
  1527. //
  1528. // Copy output structure back to client memory.
  1529. //
  1530. Status = LsaTable->CopyToClientBuffer( NULL,
  1531. sizeof(SecPkgContext_SessionAppData),
  1532. Buffer,
  1533. &AppData);
  1534. if(FAILED(Status))
  1535. {
  1536. SP_LOG_RESULT(Status);
  1537. goto cleanup;
  1538. }
  1539. // Operation has succeeded, so consume this buffer.
  1540. pvClient = NULL;
  1541. cleanup:
  1542. if(pvClient)
  1543. {
  1544. LsaTable->FreeClientBuffer(NULL, pvClient);
  1545. }
  1546. if(pbAppData)
  1547. {
  1548. SPExternalFree(pbAppData);
  1549. }
  1550. return Status;
  1551. }
  1552. //+-------------------------------------------------------------------------
  1553. //
  1554. // Function: SpQuerySessionInfo
  1555. //
  1556. // Synopsis: Retrieves the SECPKG_ATTR_SESSION_INFO context attribute.
  1557. //
  1558. // Arguments:
  1559. //
  1560. // Returns:
  1561. //
  1562. // Notes: The buffer returned contains the following structure:
  1563. //
  1564. // typedef struct _SecPkgContext_SessionInfo
  1565. // {
  1566. // DWORD dwFlags;
  1567. // DWORD cbSessionId;
  1568. // BYTE rgbSessionId[32];
  1569. // } SecPkgContext_SessionInfo, *PSecPkgContext_SessionInfo;
  1570. //
  1571. //--------------------------------------------------------------------------
  1572. SECURITY_STATUS
  1573. SpQuerySessionInfo(
  1574. PSPContext pContext,
  1575. SecPkgContext_SessionInfo *pSessionInfo)
  1576. {
  1577. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_SESSION_INFO)\n"));
  1578. if (NULL == pContext->RipeZombie)
  1579. {
  1580. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1581. }
  1582. ZeroMemory(pSessionInfo, sizeof(SecPkgContext_SessionInfo));
  1583. if(!(pContext->Flags & CONTEXT_FLAG_FULL_HANDSHAKE))
  1584. {
  1585. pSessionInfo->dwFlags = SSL_SESSION_RECONNECT;
  1586. }
  1587. pSessionInfo->cbSessionId = pContext->RipeZombie->cbSessionID;
  1588. memcpy(pSessionInfo->rgbSessionId, pContext->RipeZombie->SessionID, pContext->RipeZombie->cbSessionID);
  1589. return SEC_E_OK;
  1590. }
  1591. //+-------------------------------------------------------------------------
  1592. //
  1593. // Function: SpQueryContextAttributes
  1594. //
  1595. // Synopsis: Querys attributes of the specified context
  1596. //
  1597. // Effects:
  1598. //
  1599. // Arguments:
  1600. //
  1601. // Requires:
  1602. //
  1603. // Returns:
  1604. //
  1605. // Notes: The following attributes are supported by the Schannel
  1606. // package:
  1607. //
  1608. // SECPKG_ATTR_AUTHORITY
  1609. // SECPKG_ATTR_CONNECTION_INFO
  1610. // SECPKG_ATTR_ISSUER_LIST
  1611. // SECPKG_ATTR_ISSUER_LIST_EX
  1612. // SECPKG_ATTR_KEY_INFO
  1613. // SECPKG_ATTR_LIFESPAN
  1614. // SECPKG_ATTR_LOCAL_CERT_CONTEXT
  1615. // SECPKG_ATTR_LOCAL_CRED
  1616. // SECPKG_ATTR_NAMES
  1617. // SECPKG_ATTR_PROTO_INFO
  1618. // SECPKG_ATTR_REMOTE_CERT_CONTEXT
  1619. // SECPKG_ATTR_REMOTE_CRED
  1620. // SECPKG_ATTR_SIZES
  1621. // SECPKG_ATTR_STREAM_SIZES
  1622. //
  1623. //--------------------------------------------------------------------------
  1624. SECURITY_STATUS
  1625. SEC_ENTRY
  1626. SpLsaQueryContextAttributes(
  1627. LSA_SEC_HANDLE Context,
  1628. ULONG Attribute,
  1629. PVOID Buffer)
  1630. {
  1631. SECURITY_STATUS Status;
  1632. PSPContext pContext;
  1633. pContext = (PSPContext)Context;
  1634. switch(Attribute)
  1635. {
  1636. case SECPKG_ATTR_AUTHORITY :
  1637. Status = SpQueryAuthority(Context, Buffer);
  1638. break;
  1639. case SECPKG_ATTR_ISSUER_LIST :
  1640. Status = SpQueryIssuerList(Context, Buffer);
  1641. break;
  1642. case SECPKG_ATTR_ISSUER_LIST_EX:
  1643. Status = SpQueryIssuerListEx(Context, Buffer);
  1644. break;
  1645. // case SECPKG_ATTR_KEY_INFO :
  1646. // Status = SpQueryKeyInfo(Context, Buffer);
  1647. // break;
  1648. // case SECPKG_ATTR_LIFESPAN :
  1649. // Status = SpQueryLifespan(Context, Buffer);
  1650. // break;
  1651. case SECPKG_ATTR_LOCAL_CERT_CONTEXT:
  1652. Status = SpQueryLocalCertContext(Context, Buffer);
  1653. break;
  1654. case SECPKG_ATTR_LOCAL_CRED:
  1655. Status = SpQueryLocalCred(Context, Buffer);
  1656. break;
  1657. // case SECPKG_ATTR_NAMES :
  1658. // Status = SpQueryNames(Context, Buffer);
  1659. // break;
  1660. // case SECPKG_ATTR_PROTO_INFO:
  1661. // Status = SpQueryProtoInfo(Context, Buffer);
  1662. // break;
  1663. // case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
  1664. // Status = SpQueryCertContext(Context, Buffer, FALSE);
  1665. // break;
  1666. // case SECPKG_ATTR_REMOTE_CRED:
  1667. // Status = SpQueryRemoteCred(Context, Buffer);
  1668. // break;
  1669. // case SECPKG_ATTR_SIZES:
  1670. // Status = SpQuerySizes(Context, Buffer);
  1671. // break;
  1672. // case SECPKG_ATTR_STREAM_SIZES:
  1673. // Status = SpQueryStreamSizes(Context, Buffer);
  1674. // break;
  1675. case SECPKG_ATTR_EAP_KEY_BLOCK:
  1676. Status = SpQueryEapKeyBlock(Context, Buffer);
  1677. break;
  1678. // case SECPKG_ATTR_MAPPED_CRED_ATTR:
  1679. // Status = SpQueryMappedCredAttr(Context, Buffer);
  1680. // break;
  1681. case SECPKG_ATTR_APP_DATA:
  1682. Status = SpQueryApplicationData(Context, Buffer);
  1683. break;
  1684. default:
  1685. DebugLog((DEB_ERROR, "QueryContextAttributes(unsupported function %d)\n", Attribute));
  1686. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1687. }
  1688. return Status;
  1689. }
  1690. //+-------------------------------------------------------------------------
  1691. //
  1692. // Function: SpUserQueryContextAttributes
  1693. //
  1694. // Synopsis: User mode QueryContextAttribute.
  1695. //
  1696. // Effects:
  1697. //
  1698. // Arguments:
  1699. //
  1700. // Requires:
  1701. //
  1702. // Returns:
  1703. //
  1704. // Notes:
  1705. //
  1706. //--------------------------------------------------------------------------
  1707. NTSTATUS NTAPI
  1708. SpUserQueryContextAttributes(
  1709. IN LSA_SEC_HANDLE ContextHandle,
  1710. IN ULONG ContextAttribute,
  1711. IN OUT PVOID pBuffer
  1712. )
  1713. {
  1714. PSSL_USER_CONTEXT Context;
  1715. PSPContext pContext;
  1716. SECURITY_STATUS Status;
  1717. Context = SslFindUserContext( ContextHandle );
  1718. if(Context == NULL)
  1719. {
  1720. return(SEC_E_INVALID_HANDLE);
  1721. }
  1722. pContext = Context->pContext;
  1723. if(!pContext)
  1724. {
  1725. return(SEC_E_INVALID_HANDLE);
  1726. }
  1727. switch(ContextAttribute)
  1728. {
  1729. case SECPKG_ATTR_CONNECTION_INFO:
  1730. Status = SpQueryConnectionInfo(pContext, pBuffer);
  1731. break;
  1732. case SECPKG_ATTR_KEY_INFO:
  1733. Status = SpQueryKeyInfo(pContext, pBuffer);
  1734. break;
  1735. case SECPKG_ATTR_LIFESPAN:
  1736. Status = SpQueryLifespan(pContext, pBuffer);
  1737. break;
  1738. case SECPKG_ATTR_NAMES :
  1739. Status = SpQueryNames(pContext, pBuffer);
  1740. break;
  1741. case SECPKG_ATTR_PACKAGE_INFO:
  1742. Status = SpQueryPackageInfo(pContext, pBuffer);
  1743. break;
  1744. case SECPKG_ATTR_PROTO_INFO:
  1745. Status = SpQueryProtoInfo(pContext, pBuffer);
  1746. break;
  1747. case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
  1748. Status = SpQueryRemoteCertContext(pContext, pBuffer);
  1749. break;
  1750. case SECPKG_ATTR_REMOTE_CRED:
  1751. Status = SpQueryRemoteCred(pContext, pBuffer);
  1752. break;
  1753. case SECPKG_ATTR_SIZES:
  1754. Status = SpQuerySizes(pContext, pBuffer);
  1755. break;
  1756. case SECPKG_ATTR_STREAM_SIZES:
  1757. Status = SpQueryStreamSizes(pContext, pBuffer);
  1758. break;
  1759. case SECPKG_ATTR_MAPPED_CRED_ATTR:
  1760. Status = SpQueryMappedCredAttr(pContext, pBuffer);
  1761. break;
  1762. case SECPKG_ATTR_ACCESS_TOKEN:
  1763. Status = SpQueryAccessToken(pContext, pBuffer);
  1764. break;
  1765. case SECPKG_ATTR_SESSION_INFO:
  1766. Status = SpQuerySessionInfo(pContext, pBuffer);
  1767. break;
  1768. default:
  1769. DebugLog((DEB_ERROR, "QueryContextAttributes(unsupported function %d)\n", ContextAttribute));
  1770. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1771. }
  1772. return Status;
  1773. }
  1774. //+-------------------------------------------------------------------------
  1775. //
  1776. // Function: SpSetUseValidatedProp
  1777. //
  1778. // Synopsis: Sets the SECPKG_ATTR_USE_VALIDATED context attribute.
  1779. //
  1780. // Arguments:
  1781. //
  1782. // Returns:
  1783. //
  1784. // Notes: The buffer must contain a DWORD indicating whether the
  1785. // credential currently associated with the context has been
  1786. // validated for use.
  1787. //
  1788. //--------------------------------------------------------------------------
  1789. NTSTATUS
  1790. SpSetUseValidatedProp(
  1791. IN PSPContext pContext,
  1792. IN PVOID Buffer,
  1793. IN ULONG BufferSize)
  1794. {
  1795. DWORD dwUseValidated;
  1796. NTSTATUS Status;
  1797. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_USE_VALIDATED)\n"));
  1798. if(BufferSize < sizeof(DWORD))
  1799. {
  1800. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1801. goto cleanup;
  1802. }
  1803. Status = LsaTable->CopyFromClientBuffer( NULL,
  1804. sizeof(DWORD),
  1805. &dwUseValidated,
  1806. Buffer );
  1807. if(FAILED(Status))
  1808. {
  1809. SP_LOG_RESULT(Status);
  1810. goto cleanup;
  1811. }
  1812. DebugLog((DEB_TRACE, "Use validated:%d\n", dwUseValidated));
  1813. if(pContext->RipeZombie == NULL)
  1814. {
  1815. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1816. goto cleanup;
  1817. }
  1818. if(dwUseValidated)
  1819. {
  1820. pContext->RipeZombie->dwFlags |= SP_CACHE_FLAG_USE_VALIDATED;
  1821. }
  1822. else
  1823. {
  1824. pContext->RipeZombie->dwFlags &= ~SP_CACHE_FLAG_USE_VALIDATED;
  1825. }
  1826. cleanup:
  1827. return Status;
  1828. }
  1829. //+-------------------------------------------------------------------------
  1830. //
  1831. // Function: SpSetCredentialNameProp
  1832. //
  1833. // Synopsis: Sets the SECPKG_ATTR_CREDENTIAL_NAME context attribute.
  1834. //
  1835. // Arguments:
  1836. //
  1837. // Returns:
  1838. //
  1839. // Notes: The buffer must contain the following structure:
  1840. //
  1841. // typedef struct _SecPkgContext_CredentialNameW
  1842. // {
  1843. // unsigned long CredentialType;
  1844. // SEC_WCHAR SEC_FAR *sCredentialName;
  1845. // } SecPkgContext_CredentialNameW, SEC_FAR * PSecPkgContext_CredentialNameW;
  1846. //
  1847. //--------------------------------------------------------------------------
  1848. NTSTATUS
  1849. SpSetCredentialNameProp(
  1850. IN PSPContext pContext,
  1851. IN PVOID Buffer,
  1852. IN ULONG BufferSize)
  1853. {
  1854. PSecPkgContext_CredentialNameW pCredentialName = NULL;
  1855. DWORD_PTR Offset;
  1856. NTSTATUS Status;
  1857. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_CREDENTIAL_NAME)\n"));
  1858. //
  1859. // Marshal over the credential name from the client address space.
  1860. //
  1861. if(BufferSize < sizeof(SecPkgContext_CredentialNameW))
  1862. {
  1863. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1864. goto cleanup;
  1865. }
  1866. pCredentialName = SPExternalAlloc(BufferSize + sizeof(WCHAR));
  1867. if(pCredentialName == NULL)
  1868. {
  1869. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1870. goto cleanup;
  1871. }
  1872. Status = LsaTable->CopyFromClientBuffer( NULL,
  1873. BufferSize,
  1874. pCredentialName,
  1875. Buffer );
  1876. if(FAILED(Status))
  1877. {
  1878. SP_LOG_RESULT(Status);
  1879. goto cleanup;
  1880. }
  1881. if(pCredentialName->CredentialType != CRED_TYPE_DOMAIN_CERTIFICATE)
  1882. {
  1883. DebugLog((DEB_ERROR, "Unexpected credential type %d\n", pCredentialName->CredentialType));
  1884. Status = SEC_E_UNKNOWN_CREDENTIALS;
  1885. }
  1886. if((PVOID)pCredentialName->sCredentialName < Buffer ||
  1887. (PBYTE)pCredentialName->sCredentialName >= (PBYTE)Buffer + BufferSize)
  1888. {
  1889. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1890. goto cleanup;
  1891. }
  1892. Offset = (PBYTE)pCredentialName->sCredentialName - (PBYTE)Buffer;
  1893. pCredentialName->sCredentialName = (LPWSTR)((PBYTE)pCredentialName + Offset);
  1894. DebugLog((DEB_TRACE, "Set client credential to '%ls'.\n", pCredentialName->sCredentialName));
  1895. //
  1896. // Associate the specified credential with the current context.
  1897. //
  1898. pContext->pszCredentialName = SPExternalAlloc((lstrlenW(pCredentialName->sCredentialName) + 1) * sizeof(WCHAR));
  1899. if(pContext->pszCredentialName == NULL)
  1900. {
  1901. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1902. goto cleanup;
  1903. }
  1904. lstrcpyW(pContext->pszCredentialName, pCredentialName->sCredentialName);
  1905. Status = QueryCredentialManagerForCert(pContext,
  1906. pCredentialName->sCredentialName);
  1907. if(FAILED(Status))
  1908. {
  1909. SP_LOG_RESULT(Status);
  1910. goto cleanup;
  1911. }
  1912. DebugLog((DEB_TRACE, "Credential assigned to context successfully.\n"));
  1913. cleanup:
  1914. if(pCredentialName)
  1915. {
  1916. SPExternalFree(pCredentialName);
  1917. }
  1918. return Status;
  1919. }
  1920. //+-------------------------------------------------------------------------
  1921. //
  1922. // Function: SpSetApplicationData
  1923. //
  1924. // Synopsis: Sets the SECPKG_ATTR_APP_DATA context attribute.
  1925. //
  1926. // Arguments:
  1927. //
  1928. // Returns:
  1929. //
  1930. // Notes: The buffer must contain the following structure:
  1931. //
  1932. // typedef struct _SecPkgContext_SessionAppData
  1933. // {
  1934. // DWORD dwFlags;
  1935. // DWORD cbAppData;
  1936. // PBYTE pbAppData;
  1937. // } SecPkgContext_SessionAppData, *PSecPkgContext_SessionAppData;
  1938. //
  1939. //--------------------------------------------------------------------------
  1940. NTSTATUS
  1941. SpSetApplicationData(
  1942. IN PSPContext pContext,
  1943. IN PVOID Buffer,
  1944. IN ULONG BufferSize)
  1945. {
  1946. SecPkgContext_SessionAppData AppData;
  1947. PBYTE pbAppData = NULL;
  1948. NTSTATUS Status;
  1949. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_APP_DATA)\n"));
  1950. if(pContext->RipeZombie == NULL)
  1951. {
  1952. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1953. }
  1954. //
  1955. // Marshal over the input structure from the client address space.
  1956. //
  1957. if(BufferSize < sizeof(SecPkgContext_SessionAppData))
  1958. {
  1959. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1960. goto cleanup;
  1961. }
  1962. Status = LsaTable->CopyFromClientBuffer( NULL,
  1963. sizeof(SecPkgContext_SessionAppData),
  1964. &AppData,
  1965. Buffer );
  1966. if(FAILED(Status))
  1967. {
  1968. SP_LOG_RESULT(Status);
  1969. goto cleanup;
  1970. }
  1971. //
  1972. // Marshal over the application data from the client address space.
  1973. //
  1974. // Limit application data size to 64k.
  1975. if(AppData.cbAppData > 0x10000)
  1976. {
  1977. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1978. goto cleanup;
  1979. }
  1980. if(AppData.cbAppData == 0 || AppData.pbAppData == NULL)
  1981. {
  1982. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1983. goto cleanup;
  1984. }
  1985. pbAppData = SPExternalAlloc(AppData.cbAppData);
  1986. if(pbAppData == NULL)
  1987. {
  1988. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1989. goto cleanup;
  1990. }
  1991. Status = LsaTable->CopyFromClientBuffer( NULL,
  1992. AppData.cbAppData,
  1993. pbAppData,
  1994. AppData.pbAppData );
  1995. if(FAILED(Status))
  1996. {
  1997. SP_LOG_RESULT(Status);
  1998. goto cleanup;
  1999. }
  2000. //
  2001. // Assign application data to cache entry.
  2002. //
  2003. Status = SetCacheAppData(pContext->RipeZombie,
  2004. pbAppData,
  2005. AppData.cbAppData);
  2006. if(!FAILED(Status))
  2007. {
  2008. // The operation succeeded, so consume the application data.
  2009. pbAppData = NULL;
  2010. }
  2011. cleanup:
  2012. if(pbAppData)
  2013. {
  2014. SPExternalFree(pbAppData);
  2015. }
  2016. return Status;
  2017. }
  2018. NTSTATUS
  2019. NTAPI
  2020. SpSetContextAttributes(
  2021. IN LSA_SEC_HANDLE ContextHandle,
  2022. IN ULONG ContextAttribute,
  2023. IN PVOID Buffer,
  2024. IN ULONG BufferSize)
  2025. {
  2026. NTSTATUS Status;
  2027. PSPContext pContext;
  2028. pContext = (PSPContext)ContextHandle;
  2029. switch(ContextAttribute)
  2030. {
  2031. case SECPKG_ATTR_USE_VALIDATED:
  2032. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_USE_VALIDATED)\n"));
  2033. Status = STATUS_SUCCESS;
  2034. break;
  2035. case SECPKG_ATTR_CREDENTIAL_NAME:
  2036. Status = SpSetCredentialNameProp(pContext, Buffer, BufferSize);
  2037. break;
  2038. case SECPKG_ATTR_TARGET_INFORMATION:
  2039. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_TARGET_INFORMATION)\n"));
  2040. Status = STATUS_SUCCESS;
  2041. break;
  2042. case SECPKG_ATTR_APP_DATA:
  2043. Status = SpSetApplicationData(pContext, Buffer, BufferSize);
  2044. break;
  2045. default:
  2046. DebugLog((DEB_ERROR, "SetContextAttributes(unsupported function %d)\n", ContextAttribute));
  2047. Status = SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  2048. }
  2049. return Status;
  2050. }