Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2369 lines
67 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. NTSTATUS 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 = lstrlenA(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 = lstrlenA(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. PCCERT_CONTEXT pCertContext = NULL;
  620. SecBuffer Input;
  621. SecBuffer Output;
  622. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_LOCAL_CERT_CONTEXT)\n"));
  623. pContext = (PSPContext)ContextHandle;
  624. Size = sizeof( PCCERT_CONTEXT );
  625. //
  626. // Obtain data from Schannel.
  627. //
  628. if(pContext->dwProtocol & SP_PROT_CLIENTS)
  629. {
  630. pCertContext = pContext->RipeZombie->pClientCert;
  631. }
  632. else
  633. {
  634. pCertContext = pContext->RipeZombie->pActiveServerCred->pCert;
  635. }
  636. //
  637. // Copy buffers to client memory.
  638. //
  639. if(pCertContext)
  640. {
  641. // Serialize the certificate context, as well as the associated
  642. // certificate store.
  643. Status = SerializeCertContext(pCertContext,
  644. NULL,
  645. &Input.cbBuffer);
  646. if(FAILED(Status))
  647. {
  648. return SP_LOG_RESULT(Status);
  649. }
  650. SafeAllocaAllocate(Input.pvBuffer, Input.cbBuffer);
  651. if(Input.pvBuffer == NULL)
  652. {
  653. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  654. }
  655. Status = SerializeCertContext(pCertContext,
  656. Input.pvBuffer,
  657. &Input.cbBuffer);
  658. if(FAILED(Status))
  659. {
  660. SafeAllocaFree(Input.pvBuffer);
  661. return SP_LOG_RESULT(Status);
  662. }
  663. // Call back into the user process in order to replicate the
  664. // certificate context and store over there.
  665. Input.BufferType = SECBUFFER_DATA;
  666. Status = PerformApplicationCallback(SCH_DOWNLOAD_CERT_CALLBACK,
  667. 0,
  668. 0,
  669. &Input,
  670. &Output,
  671. TRUE);
  672. SafeAllocaFree(Input.pvBuffer);
  673. if(FAILED(Status))
  674. {
  675. return SP_LOG_RESULT(Status);
  676. }
  677. pCertContext = *(PCCERT_CONTEXT *)(Output.pvBuffer);
  678. SPExternalFree(Output.pvBuffer);
  679. }
  680. //
  681. // Copy structure back to client memory.
  682. //
  683. if(pCertContext)
  684. {
  685. Status = LsaTable->CopyToClientBuffer( NULL,
  686. Size,
  687. Buffer,
  688. (PVOID)&pCertContext );
  689. if(FAILED(Status))
  690. {
  691. return SP_LOG_RESULT(Status);
  692. }
  693. }
  694. else
  695. {
  696. return SP_LOG_RESULT(SEC_E_NO_CREDENTIALS);
  697. }
  698. return SEC_E_OK;
  699. }
  700. //+-------------------------------------------------------------------------
  701. //
  702. // Function: SpQueryRemoteCertContext
  703. //
  704. // Synopsis: Retrieves the SECPKG_ATTR_REMOTE_CERT_CONTEXT
  705. // context attribute.
  706. //
  707. // Arguments:
  708. //
  709. // Returns:
  710. //
  711. // Notes: The buffer returned contains a pointer to a CERT_CONTEXT
  712. // structure.
  713. //
  714. //--------------------------------------------------------------------------
  715. SECURITY_STATUS
  716. SpQueryRemoteCertContext(
  717. PSPContext pContext,
  718. PVOID Buffer)
  719. {
  720. PCCERT_CONTEXT pCertContext;
  721. SP_STATUS pctRet;
  722. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_REMOTE_CERT_CONTEXT)\n"));
  723. if(pContext->RipeZombie->pbServerCertificate)
  724. {
  725. pctRet = DeserializeCertContext(&pCertContext,
  726. pContext->RipeZombie->pbServerCertificate,
  727. pContext->RipeZombie->cbServerCertificate);
  728. if(pctRet != PCT_ERR_OK)
  729. {
  730. return SP_LOG_RESULT(pctRet);
  731. }
  732. *(PCCERT_CONTEXT *)Buffer = pCertContext;
  733. return SEC_E_OK;
  734. }
  735. else
  736. {
  737. return SP_LOG_RESULT(SEC_E_NO_CREDENTIALS);
  738. }
  739. }
  740. //+-------------------------------------------------------------------------
  741. //
  742. // Function: SpQueryLocalCred
  743. //
  744. // Synopsis: Retrieves the SECPKG_ATTR_LOCAL_CRED context attribute.
  745. //
  746. // Arguments:
  747. //
  748. // Returns:
  749. //
  750. // Notes: The buffer returned contains the following structure:
  751. //
  752. // typedef struct _SecPkgContext_LocalCredentialInfo
  753. // {
  754. // DWORD cbCertificateChain;
  755. // PBYTE pbCertificateChain;
  756. // DWORD cCertificates;
  757. // DWORD fFlags;
  758. // DWORD dwBits;
  759. // } SecPkgContext_LocalCredentialInfo;
  760. //
  761. //--------------------------------------------------------------------------
  762. SECURITY_STATUS
  763. SpQueryLocalCred(
  764. LSA_SEC_HANDLE ContextHandle,
  765. PVOID Buffer)
  766. {
  767. SecPkgContext_LocalCredentialInfo CredInfo;
  768. DWORD Size;
  769. PSPContext pContext;
  770. SECURITY_STATUS Status;
  771. PVOID pvClient = NULL;
  772. PCCERT_CONTEXT pCert = NULL;
  773. PUBLICKEY * pKey = NULL;
  774. RSAPUBKEY * pk = NULL;
  775. PSPCredential pCred;
  776. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_LOCAL_CRED)\n"));
  777. pContext = (PSPContext)ContextHandle;
  778. Size = sizeof( SecPkgContext_LocalCredentialInfo );
  779. //
  780. // Obtain data from Schannel.
  781. //
  782. ZeroMemory(&CredInfo, Size);
  783. if(pContext->dwProtocol & SP_PROT_CLIENTS)
  784. {
  785. pCred = pContext->pActiveClientCred;
  786. }
  787. else
  788. {
  789. pCred = pContext->RipeZombie->pActiveServerCred;
  790. }
  791. if(pCred)
  792. {
  793. pCert = pCred->pCert;
  794. pKey = pCred->pPublicKey;
  795. }
  796. if(pCert)
  797. {
  798. CredInfo.fFlags |= LCRED_CRED_EXISTS;
  799. CredInfo.pbCertificateChain = pCert->pbCertEncoded;
  800. CredInfo.cbCertificateChain = pCert->cbCertEncoded;
  801. CredInfo.cCertificates = 1;
  802. // Compute number of bits in the certificate's public key.
  803. CredInfo.dwBits = 0;
  804. pk = (RSAPUBKEY *)((pKey->pPublic) + 1);
  805. if(pk)
  806. {
  807. CredInfo.dwBits = pk->bitlen;
  808. }
  809. }
  810. //
  811. // Copy buffers to client memory.
  812. //
  813. if(CredInfo.pbCertificateChain)
  814. {
  815. Status = LsaTable->AllocateClientBuffer(
  816. NULL,
  817. CredInfo.cbCertificateChain,
  818. &pvClient);
  819. if(FAILED(Status))
  820. {
  821. return SP_LOG_RESULT(Status);
  822. }
  823. Status = LsaTable->CopyToClientBuffer(
  824. NULL,
  825. CredInfo.cbCertificateChain,
  826. pvClient,
  827. CredInfo.pbCertificateChain);
  828. if(FAILED(Status))
  829. {
  830. LsaTable->FreeClientBuffer(NULL, pvClient);
  831. return SP_LOG_RESULT(Status);
  832. }
  833. CredInfo.pbCertificateChain = pvClient;
  834. }
  835. //
  836. // Copy structure back to client memory.
  837. //
  838. Status = LsaTable->CopyToClientBuffer( NULL,
  839. Size,
  840. Buffer,
  841. &CredInfo );
  842. if(FAILED(Status))
  843. {
  844. LsaTable->FreeClientBuffer(NULL, pvClient);
  845. return SP_LOG_RESULT(Status);
  846. }
  847. return SEC_E_OK;
  848. }
  849. //+-------------------------------------------------------------------------
  850. //
  851. // Function: SpQueryRemoteCred
  852. //
  853. // Synopsis: Retrieves the SECPKG_ATTR_REMOTE_CRED context attribute.
  854. //
  855. // Arguments:
  856. //
  857. // Returns:
  858. //
  859. // Notes: The buffer returned contains the following structure:
  860. //
  861. // typedef struct _SecPkgContext_LocalCredentialInfo
  862. // {
  863. // DWORD cbCertificateChain;
  864. // PBYTE pbCertificateChain;
  865. // DWORD cCertificates;
  866. // DWORD fFlags;
  867. // DWORD dwBits;
  868. // } SecPkgContext_LocalCredentialInfo;
  869. //
  870. //--------------------------------------------------------------------------
  871. SECURITY_STATUS
  872. SpQueryRemoteCred(
  873. PSPContext pContext,
  874. PVOID Buffer)
  875. {
  876. SecPkgContext_LocalCredentialInfo *pCredInfo;
  877. PCCERT_CONTEXT pCertContext = NULL;
  878. PUBLICKEY * pKey = NULL;
  879. RSAPUBKEY * pk = NULL;
  880. SP_STATUS pctRet;
  881. PBYTE pbCert;
  882. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_REMOTE_CRED)\n"));
  883. pCredInfo = (SecPkgContext_LocalCredentialInfo *)Buffer;
  884. ZeroMemory(pCredInfo, sizeof(*pCredInfo));
  885. if(pContext->RipeZombie->pbServerCertificate)
  886. {
  887. pctRet = DeserializeCertContext(&pCertContext,
  888. pContext->RipeZombie->pbServerCertificate,
  889. pContext->RipeZombie->cbServerCertificate);
  890. if(pctRet != PCT_ERR_OK)
  891. {
  892. return SP_LOG_RESULT(pctRet);
  893. }
  894. }
  895. if(pCertContext)
  896. {
  897. pbCert = LocalAlloc(LPTR, pCertContext->cbCertEncoded);
  898. if(pbCert == NULL)
  899. {
  900. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  901. }
  902. memcpy(pbCert, pCertContext->pbCertEncoded, pCertContext->cbCertEncoded);
  903. pCredInfo->fFlags |= LCRED_CRED_EXISTS;
  904. pCredInfo->pbCertificateChain = pbCert;
  905. pCredInfo->cbCertificateChain = pCertContext->cbCertEncoded;
  906. pCredInfo->cCertificates = 1;
  907. pCredInfo->dwBits = 0;
  908. // Compute number of bits in the certificate's public key.
  909. pctRet = SPPublicKeyFromCert(pCertContext, &pKey, NULL);
  910. if(pctRet == PCT_ERR_OK)
  911. {
  912. pk = (RSAPUBKEY *)((pKey->pPublic) + 1);
  913. if(pk)
  914. {
  915. pCredInfo->dwBits = pk->bitlen;
  916. }
  917. SPExternalFree(pKey);
  918. }
  919. CertFreeCertificateContext(pCertContext);
  920. }
  921. return SEC_E_OK;
  922. }
  923. //+-------------------------------------------------------------------------
  924. //
  925. // Function: SpQueryNames
  926. //
  927. // Synopsis: Retrieves the SECPKG_ATTR_NAMES context attribute.
  928. //
  929. // Arguments:
  930. //
  931. // Returns:
  932. //
  933. // Notes: The buffer returned contains the following structure:
  934. //
  935. // typedef struct _SecPkgContext_NamesW
  936. // {
  937. // SEC_WCHAR SEC_FAR * sUserName;
  938. // } SecPkgContext_NamesW;
  939. //
  940. //--------------------------------------------------------------------------
  941. SECURITY_STATUS
  942. SpQueryNames(
  943. PSPContext pContext,
  944. SecPkgContext_Names *pNames)
  945. {
  946. SECURITY_STATUS Status;
  947. PCCERT_CONTEXT pCert = NULL;
  948. DWORD cchSubject;
  949. DWORD cbSubject;
  950. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_NAMES)\n"));
  951. //
  952. // Obtain data from Schannel.
  953. //
  954. if(pContext->RipeZombie->pbServerCertificate == NULL)
  955. {
  956. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  957. }
  958. Status = DeserializeCertContext(&pCert,
  959. pContext->RipeZombie->pbServerCertificate,
  960. pContext->RipeZombie->cbServerCertificate);
  961. if(Status != PCT_ERR_OK)
  962. {
  963. return SP_LOG_RESULT(Status);
  964. }
  965. //
  966. // Build name string.
  967. //
  968. if(0 >= (cchSubject = CertNameToStr(pCert->dwCertEncodingType,
  969. &pCert->pCertInfo->Subject,
  970. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  971. NULL,
  972. 0)))
  973. {
  974. CertFreeCertificateContext(pCert);
  975. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  976. }
  977. cbSubject = (cchSubject + 1) * sizeof(TCHAR);
  978. pNames->sUserName = LocalAlloc(LPTR, cbSubject);
  979. if(pNames->sUserName == NULL)
  980. {
  981. CertFreeCertificateContext(pCert);
  982. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  983. }
  984. if(0 >= CertNameToStr(pCert->dwCertEncodingType,
  985. &pCert->pCertInfo->Subject,
  986. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  987. pNames->sUserName,
  988. cchSubject))
  989. {
  990. CertFreeCertificateContext(pCert);
  991. LocalFree(pNames->sUserName);
  992. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  993. }
  994. CertFreeCertificateContext(pCert);
  995. return SEC_E_OK;
  996. }
  997. //+-------------------------------------------------------------------------
  998. //
  999. // Function: SpQueryPackageInfo
  1000. //
  1001. // Synopsis: Retrieves the SECPKG_ATTR_PACKAGE_INFO context attribute.
  1002. //
  1003. // Arguments:
  1004. //
  1005. // Returns:
  1006. //
  1007. // Notes: The buffer returned contains the following structure:
  1008. //
  1009. // typedef struct _SecPkgContext_PackageInfoW
  1010. // {
  1011. // PSecPkgInfoW PackageInfo;
  1012. // } SecPkgContext_PackageInfoW, SEC_FAR * PSecPkgContext_PackageInfoW;
  1013. //
  1014. //--------------------------------------------------------------------------
  1015. SECURITY_STATUS
  1016. SpQueryPackageInfo(
  1017. PSPContext pContext,
  1018. PVOID Buffer)
  1019. {
  1020. PSecPkgContext_PackageInfoW pPackageInfo;
  1021. SecPkgInfoW Info;
  1022. DWORD cbName;
  1023. DWORD cbComment;
  1024. UNREFERENCED_PARAMETER(pContext);
  1025. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_PACKAGE_INFO)\n"));
  1026. SpSslGetInfo(&Info);
  1027. pPackageInfo = (PSecPkgContext_PackageInfoW)Buffer;
  1028. cbName = (lstrlen(Info.Name) + 1) * sizeof(WCHAR);
  1029. cbComment = (lstrlen(Info.Comment) + 1) * sizeof(WCHAR);
  1030. pPackageInfo->PackageInfo = LocalAlloc(LPTR, sizeof(SecPkgInfo) + cbName + cbComment);
  1031. if(pPackageInfo->PackageInfo == NULL)
  1032. {
  1033. return SP_LOG_RESULT(STATUS_INSUFFICIENT_RESOURCES);
  1034. }
  1035. pPackageInfo->PackageInfo->wVersion = Info.wVersion;
  1036. pPackageInfo->PackageInfo->wRPCID = Info.wRPCID;
  1037. pPackageInfo->PackageInfo->fCapabilities = Info.fCapabilities;
  1038. pPackageInfo->PackageInfo->cbMaxToken = Info.cbMaxToken;
  1039. pPackageInfo->PackageInfo->Name = (LPWSTR)(pPackageInfo->PackageInfo + 1);
  1040. pPackageInfo->PackageInfo->Comment = (LPWSTR)((PBYTE)pPackageInfo->PackageInfo->Name + cbName);
  1041. lstrcpy(
  1042. pPackageInfo->PackageInfo->Name,
  1043. Info.Name);
  1044. lstrcpy(
  1045. pPackageInfo->PackageInfo->Comment,
  1046. Info.Comment);
  1047. return SEC_E_OK;
  1048. }
  1049. //+-------------------------------------------------------------------------
  1050. //
  1051. // Function: SpQueryProtoInfo
  1052. //
  1053. // Synopsis: Retrieves the SECPKG_ATTR_PROTO_INFO context attribute.
  1054. //
  1055. // Arguments:
  1056. //
  1057. // Returns:
  1058. //
  1059. // Notes: The buffer returned contains the following structure:
  1060. //
  1061. // typedef struct _SecPkgContext_ProtoInfoW
  1062. // {
  1063. // SEC_WCHAR SEC_FAR * sProtocolName;
  1064. // unsigned long majorVersion;
  1065. // unsigned long minorVersion;
  1066. // } SecPkgContext_ProtoInfoW;
  1067. //
  1068. //--------------------------------------------------------------------------
  1069. SECURITY_STATUS
  1070. SpQueryProtoInfo(
  1071. PSPContext pContext,
  1072. PVOID Buffer)
  1073. {
  1074. SecPkgContext_ProtoInfo *pProtoInfo;
  1075. DWORD index;
  1076. DWORD cbName;
  1077. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_PROTO_INFO)\n"));
  1078. pProtoInfo = (SecPkgContext_ProtoInfo *)Buffer;
  1079. for(index = 0;
  1080. index < sizeof(rgProts) / sizeof(PROTO_ID);
  1081. index += 1)
  1082. {
  1083. if(pContext->RipeZombie->fProtocol == rgProts[index].dwProtoId)
  1084. {
  1085. break;
  1086. }
  1087. }
  1088. if(index >= sizeof(rgProts) / sizeof(PROTO_ID))
  1089. {
  1090. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1091. }
  1092. cbName = (lstrlen(rgProts[index].szProto) + 1) * sizeof(WCHAR);
  1093. pProtoInfo->sProtocolName = LocalAlloc(LPTR, cbName);
  1094. if(pProtoInfo->sProtocolName == NULL)
  1095. {
  1096. return SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1097. }
  1098. lstrcpy(pProtoInfo->sProtocolName, rgProts[index].szProto);
  1099. pProtoInfo->majorVersion = rgProts[index].dwMajor;
  1100. pProtoInfo->minorVersion = rgProts[index].dwMinor;
  1101. return SEC_E_OK;
  1102. }
  1103. //+-------------------------------------------------------------------------
  1104. //
  1105. // Function: SpQuerySizes
  1106. //
  1107. // Synopsis: Retrieves the SECPKG_ATTR_SIZES context attribute.
  1108. //
  1109. // Arguments:
  1110. //
  1111. // Returns:
  1112. //
  1113. // Notes: The buffer returned contains the following structure:
  1114. //
  1115. // typedef struct _SecPkgContext_Sizes
  1116. // {
  1117. // unsigned long cbMaxToken;
  1118. // unsigned long cbMaxSignature;
  1119. // unsigned long cbBlockSize;
  1120. // unsigned long cbSecurityTrailer;
  1121. // } SecPkgContext_Sizes;
  1122. //
  1123. //--------------------------------------------------------------------------
  1124. SECURITY_STATUS
  1125. SpQuerySizes(
  1126. PSPContext pContext,
  1127. SecPkgContext_Sizes *pSizes)
  1128. {
  1129. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_SIZES)\n"));
  1130. if (NULL == pContext->pCipherInfo ||
  1131. NULL == pContext->pHashInfo)
  1132. {
  1133. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1134. }
  1135. switch(pContext->RipeZombie->fProtocol)
  1136. {
  1137. case SP_PROT_SSL2_CLIENT:
  1138. case SP_PROT_SSL2_SERVER:
  1139. pSizes->cbMaxToken = SSL2_MAX_MESSAGE_LENGTH;
  1140. pSizes->cbSecurityTrailer = 2 + pContext->pHashInfo->cbCheckSum;
  1141. if(pContext->pCipherInfo->dwBlockSize > 1)
  1142. {
  1143. pSizes->cbSecurityTrailer += 1 + pContext->pCipherInfo->dwBlockSize; // 3 byte header
  1144. }
  1145. break;
  1146. case SP_PROT_PCT1_CLIENT:
  1147. case SP_PROT_PCT1_SERVER:
  1148. pSizes->cbMaxToken = PCT1_MAX_MESSAGE_LENGTH;
  1149. pSizes->cbSecurityTrailer = 2 + pContext->pHashInfo->cbCheckSum;
  1150. if(pContext->pCipherInfo->dwBlockSize > 1)
  1151. {
  1152. pSizes->cbSecurityTrailer += 1 + pContext->pCipherInfo->dwBlockSize; // 3 byte header
  1153. }
  1154. break;
  1155. case SP_PROT_SSL3_CLIENT:
  1156. case SP_PROT_SSL3_SERVER:
  1157. case SP_PROT_TLS1_CLIENT:
  1158. case SP_PROT_TLS1_SERVER:
  1159. pSizes->cbMaxToken = SSL3_MAX_MESSAGE_LENGTH;
  1160. pSizes->cbSecurityTrailer = 5 + pContext->pHashInfo->cbCheckSum;
  1161. if(pContext->pCipherInfo->dwBlockSize > 1)
  1162. {
  1163. pSizes->cbSecurityTrailer += pContext->pCipherInfo->dwBlockSize;
  1164. }
  1165. break;
  1166. default:
  1167. pSizes->cbMaxToken = SSL3_MAX_MESSAGE_LENGTH;
  1168. pSizes->cbSecurityTrailer = 0;
  1169. }
  1170. pSizes->cbMaxSignature = pContext->pHashInfo->cbCheckSum;
  1171. pSizes->cbBlockSize = pContext->pCipherInfo->dwBlockSize;
  1172. return SEC_E_OK;
  1173. }
  1174. //+-------------------------------------------------------------------------
  1175. //
  1176. // Function: SpQueryStreamSizes
  1177. //
  1178. // Synopsis: Retrieves the SECPKG_ATTR_STREAM_SIZES context attribute.
  1179. //
  1180. // Arguments:
  1181. //
  1182. // Returns:
  1183. //
  1184. // Notes: The buffer returned contains the following structure:
  1185. //
  1186. // typedef struct _SecPkgContext_StreamSizes
  1187. // {
  1188. // unsigned long cbHeader;
  1189. // unsigned long cbTrailer;
  1190. // unsigned long cbMaximumMessage;
  1191. // unsigned long cBuffers;
  1192. // unsigned long cbBlockSize;
  1193. // } SecPkgContext_StreamSizes;
  1194. //
  1195. //--------------------------------------------------------------------------
  1196. SECURITY_STATUS
  1197. SpQueryStreamSizes(
  1198. PSPContext pContext,
  1199. SecPkgContext_StreamSizes *pStreamSizes)
  1200. {
  1201. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_STREAM_SIZES)\n"));
  1202. if (NULL == pContext->pCipherInfo ||
  1203. NULL == pContext->pHashInfo)
  1204. {
  1205. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1206. }
  1207. switch(pContext->RipeZombie->fProtocol)
  1208. {
  1209. case SP_PROT_SSL2_CLIENT:
  1210. case SP_PROT_SSL2_SERVER:
  1211. pStreamSizes->cbMaximumMessage = SSL2_MAX_MESSAGE_LENGTH;
  1212. pStreamSizes->cbHeader = 2 + pContext->pHashInfo->cbCheckSum;
  1213. pStreamSizes->cbTrailer = 0;
  1214. if(pContext->pCipherInfo->dwBlockSize > 1)
  1215. {
  1216. pStreamSizes->cbHeader += 1; // 3 byte header
  1217. pStreamSizes->cbTrailer += pContext->pCipherInfo->dwBlockSize;
  1218. }
  1219. break;
  1220. case SP_PROT_PCT1_CLIENT:
  1221. case SP_PROT_PCT1_SERVER:
  1222. pStreamSizes->cbMaximumMessage = PCT1_MAX_MESSAGE_LENGTH;
  1223. pStreamSizes->cbHeader = 2;
  1224. pStreamSizes->cbTrailer = pContext->pHashInfo->cbCheckSum;
  1225. if(pContext->pCipherInfo->dwBlockSize > 1)
  1226. {
  1227. pStreamSizes->cbHeader += 1; // 3 byte header
  1228. pStreamSizes->cbTrailer += pContext->pCipherInfo->dwBlockSize;
  1229. }
  1230. break;
  1231. case SP_PROT_TLS1_CLIENT:
  1232. case SP_PROT_TLS1_SERVER:
  1233. case SP_PROT_SSL3_CLIENT:
  1234. case SP_PROT_SSL3_SERVER:
  1235. pStreamSizes->cbMaximumMessage = SSL3_MAX_MESSAGE_LENGTH;
  1236. pStreamSizes->cbHeader = 5;
  1237. pStreamSizes->cbTrailer = pContext->pHashInfo->cbCheckSum;
  1238. if(pContext->pCipherInfo->dwBlockSize > 1)
  1239. {
  1240. pStreamSizes->cbTrailer += pContext->pCipherInfo->dwBlockSize;
  1241. }
  1242. break;
  1243. default:
  1244. pStreamSizes->cbMaximumMessage = SSL3_MAX_MESSAGE_LENGTH;
  1245. pStreamSizes->cbHeader = 0;
  1246. pStreamSizes->cbTrailer = 0;
  1247. }
  1248. pStreamSizes->cbBlockSize = pContext->pCipherInfo->dwBlockSize;
  1249. pStreamSizes->cBuffers = 4;
  1250. return SEC_E_OK;
  1251. }
  1252. //+-------------------------------------------------------------------------
  1253. //
  1254. // Function: SpQueryEapKeyBlock
  1255. //
  1256. // Synopsis: Retrieves the SECPKG_ATTR_EAP_KEY_BLOCK context attribute.
  1257. //
  1258. // Arguments:
  1259. //
  1260. // Returns:
  1261. //
  1262. // Notes: The buffer returned contains the following structure:
  1263. //
  1264. // typedef struct _SecPkgContext_EapKeyBlock
  1265. // {
  1266. // BYTE rgbKeys[128];
  1267. // BYTE rgbIVs[64];
  1268. // } SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock;
  1269. //
  1270. //--------------------------------------------------------------------------
  1271. SECURITY_STATUS
  1272. SpQueryEapKeyBlock(
  1273. LSA_SEC_HANDLE ContextHandle,
  1274. PVOID Buffer)
  1275. {
  1276. SecPkgContext_EapKeyBlock KeyBlock;
  1277. DWORD Size;
  1278. PSPContext pContext;
  1279. SECURITY_STATUS Status;
  1280. HCRYPTHASH hHash;
  1281. CRYPT_DATA_BLOB Data;
  1282. UCHAR rgbRandom[CB_SSL3_RANDOM + CB_SSL3_RANDOM];
  1283. DWORD cbRandom;
  1284. DWORD cbData;
  1285. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_EAP_KEY_BLOCK)\n"));
  1286. pContext = (PSPContext)ContextHandle;
  1287. Size = sizeof( SecPkgContext_EapKeyBlock );
  1288. //
  1289. // Obtain data from Schannel.
  1290. //
  1291. if(!(pContext->RipeZombie->fProtocol & SP_PROT_TLS1))
  1292. {
  1293. // This attribute is defined for TLS only.
  1294. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1295. }
  1296. if(!pContext->RipeZombie->hMasterKey)
  1297. {
  1298. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1299. }
  1300. // Build random buffer.
  1301. CopyMemory(rgbRandom, pContext->rgbS3CRandom, CB_SSL3_RANDOM);
  1302. CopyMemory(rgbRandom + CB_SSL3_RANDOM, pContext->rgbS3SRandom, CB_SSL3_RANDOM);
  1303. cbRandom = CB_SSL3_RANDOM + CB_SSL3_RANDOM;
  1304. // rgbKeys = PRF(master_secret, "client EAP encryption", client_random + server_random);
  1305. // Compute the PRF
  1306. if(!CryptCreateHash(pContext->RipeZombie->hMasterProv,
  1307. CALG_TLS1PRF,
  1308. pContext->RipeZombie->hMasterKey,
  1309. 0,
  1310. &hHash))
  1311. {
  1312. SP_LOG_RESULT(GetLastError());
  1313. return SEC_E_INTERNAL_ERROR;
  1314. }
  1315. Data.pbData = (PBYTE)TLS1_LABEL_EAP_KEYS;
  1316. Data.cbData = CB_TLS1_LABEL_EAP_KEYS;
  1317. if(!CryptSetHashParam(hHash,
  1318. HP_TLS1PRF_LABEL,
  1319. (PBYTE)&Data,
  1320. 0))
  1321. {
  1322. SP_LOG_RESULT(GetLastError());
  1323. CryptDestroyHash(hHash);
  1324. return SEC_E_INTERNAL_ERROR;
  1325. }
  1326. Data.pbData = rgbRandom;
  1327. Data.cbData = cbRandom;
  1328. if(!CryptSetHashParam(hHash,
  1329. HP_TLS1PRF_SEED,
  1330. (PBYTE)&Data,
  1331. 0))
  1332. {
  1333. SP_LOG_RESULT(GetLastError());
  1334. CryptDestroyHash(hHash);
  1335. return SEC_E_INTERNAL_ERROR;
  1336. }
  1337. cbData = sizeof(KeyBlock.rgbKeys);
  1338. if(!CryptGetHashParam(hHash,
  1339. HP_HASHVAL,
  1340. KeyBlock.rgbKeys,
  1341. &cbData,
  1342. 0))
  1343. {
  1344. SP_LOG_RESULT(GetLastError());
  1345. CryptDestroyHash(hHash);
  1346. return SEC_E_INTERNAL_ERROR;
  1347. }
  1348. SP_ASSERT(cbData == sizeof(KeyBlock.rgbKeys));
  1349. CryptDestroyHash(hHash);
  1350. // IVs = PRF("", "client EAP encryption", client_random + server_random)
  1351. if(!PRF(NULL, 0,
  1352. (PBYTE)TLS1_LABEL_EAP_KEYS, CB_TLS1_LABEL_EAP_KEYS,
  1353. rgbRandom, sizeof(rgbRandom),
  1354. KeyBlock.rgbIVs, sizeof(KeyBlock.rgbIVs)))
  1355. {
  1356. return SP_LOG_RESULT(SEC_E_INTERNAL_ERROR);
  1357. }
  1358. //
  1359. // Copy structure back to client memory.
  1360. //
  1361. Status = LsaTable->CopyToClientBuffer( NULL,
  1362. Size,
  1363. Buffer,
  1364. &KeyBlock );
  1365. if(FAILED(Status))
  1366. {
  1367. return SP_LOG_RESULT(Status);
  1368. }
  1369. return SEC_E_OK;
  1370. }
  1371. //+-------------------------------------------------------------------------
  1372. //
  1373. // Function: SpQueryApplicationData
  1374. //
  1375. // Synopsis: Retrieves the SECPKG_ATTR_APP_DATA context attribute.
  1376. //
  1377. // Arguments:
  1378. //
  1379. // Returns:
  1380. //
  1381. // Notes: The buffer returned contains the following structure:
  1382. //
  1383. // typedef struct _SecPkgContext_SessionAppData
  1384. // {
  1385. // DWORD dwFlags;
  1386. // DWORD cbAppData;
  1387. // PBYTE pbAppData;
  1388. // } SecPkgContext_SessionAppData, *PSecPkgContext_SessionAppData;
  1389. //
  1390. //--------------------------------------------------------------------------
  1391. SECURITY_STATUS
  1392. SpQueryApplicationData(
  1393. LSA_SEC_HANDLE ContextHandle,
  1394. PVOID Buffer)
  1395. {
  1396. SecPkgContext_SessionAppData AppData;
  1397. PBYTE pbAppData = NULL;
  1398. DWORD cbAppData = 0;
  1399. PSPContext pContext;
  1400. SECURITY_STATUS Status;
  1401. PVOID pvClient = NULL;
  1402. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_APP_DATA)\n"));
  1403. pContext = (PSPContext)ContextHandle;
  1404. if(pContext == NULL || pContext->RipeZombie == NULL)
  1405. {
  1406. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1407. }
  1408. //
  1409. // Get application data from cache.
  1410. //
  1411. Status = GetCacheAppData(pContext->RipeZombie, &pbAppData, &cbAppData);
  1412. if(FAILED(Status))
  1413. {
  1414. SP_LOG_RESULT(Status);
  1415. goto cleanup;
  1416. }
  1417. //
  1418. // Allocate memory for application data in application process.
  1419. //
  1420. if(pbAppData != NULL)
  1421. {
  1422. Status = LsaTable->AllocateClientBuffer(
  1423. NULL,
  1424. cbAppData,
  1425. &pvClient);
  1426. if(FAILED(Status))
  1427. {
  1428. SP_LOG_RESULT(Status);
  1429. goto cleanup;
  1430. }
  1431. Status = LsaTable->CopyToClientBuffer(
  1432. NULL,
  1433. cbAppData,
  1434. pvClient,
  1435. pbAppData);
  1436. if(FAILED(Status))
  1437. {
  1438. SP_LOG_RESULT(Status);
  1439. goto cleanup;
  1440. }
  1441. }
  1442. //
  1443. // Build output structure.
  1444. //
  1445. ZeroMemory(&AppData, sizeof(AppData));
  1446. AppData.cbAppData = cbAppData;
  1447. AppData.pbAppData = pvClient;
  1448. //
  1449. // Copy output structure back to client memory.
  1450. //
  1451. Status = LsaTable->CopyToClientBuffer( NULL,
  1452. sizeof(SecPkgContext_SessionAppData),
  1453. Buffer,
  1454. &AppData);
  1455. if(FAILED(Status))
  1456. {
  1457. SP_LOG_RESULT(Status);
  1458. goto cleanup;
  1459. }
  1460. // Operation has succeeded, so consume this buffer.
  1461. pvClient = NULL;
  1462. cleanup:
  1463. if(pvClient)
  1464. {
  1465. LsaTable->FreeClientBuffer(NULL, pvClient);
  1466. }
  1467. if(pbAppData)
  1468. {
  1469. SPExternalFree(pbAppData);
  1470. }
  1471. return Status;
  1472. }
  1473. //+-------------------------------------------------------------------------
  1474. //
  1475. // Function: SpQuerySessionInfo
  1476. //
  1477. // Synopsis: Retrieves the SECPKG_ATTR_SESSION_INFO context attribute.
  1478. //
  1479. // Arguments:
  1480. //
  1481. // Returns:
  1482. //
  1483. // Notes: The buffer returned contains the following structure:
  1484. //
  1485. // typedef struct _SecPkgContext_SessionInfo
  1486. // {
  1487. // DWORD dwFlags;
  1488. // DWORD cbSessionId;
  1489. // BYTE rgbSessionId[32];
  1490. // } SecPkgContext_SessionInfo, *PSecPkgContext_SessionInfo;
  1491. //
  1492. //--------------------------------------------------------------------------
  1493. SECURITY_STATUS
  1494. SpQuerySessionInfo(
  1495. PSPContext pContext,
  1496. SecPkgContext_SessionInfo *pSessionInfo)
  1497. {
  1498. DebugLog((DEB_TRACE, "QueryContextAttributes(SECPKG_ATTR_SESSION_INFO)\n"));
  1499. if (NULL == pContext->RipeZombie)
  1500. {
  1501. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1502. }
  1503. ZeroMemory(pSessionInfo, sizeof(SecPkgContext_SessionInfo));
  1504. if(!(pContext->Flags & CONTEXT_FLAG_FULL_HANDSHAKE))
  1505. {
  1506. pSessionInfo->dwFlags = SSL_SESSION_RECONNECT;
  1507. }
  1508. pSessionInfo->cbSessionId = pContext->RipeZombie->cbSessionID;
  1509. memcpy(pSessionInfo->rgbSessionId, pContext->RipeZombie->SessionID, pContext->RipeZombie->cbSessionID);
  1510. return SEC_E_OK;
  1511. }
  1512. //+-------------------------------------------------------------------------
  1513. //
  1514. // Function: SpQueryContextAttributes
  1515. //
  1516. // Synopsis: Querys attributes of the specified context
  1517. //
  1518. // Effects:
  1519. //
  1520. // Arguments:
  1521. //
  1522. // Requires:
  1523. //
  1524. // Returns:
  1525. //
  1526. // Notes: The following attributes are supported by the Schannel
  1527. // package:
  1528. //
  1529. // SECPKG_ATTR_AUTHORITY
  1530. // SECPKG_ATTR_CONNECTION_INFO
  1531. // SECPKG_ATTR_ISSUER_LIST
  1532. // SECPKG_ATTR_ISSUER_LIST_EX
  1533. // SECPKG_ATTR_KEY_INFO
  1534. // SECPKG_ATTR_LIFESPAN
  1535. // SECPKG_ATTR_LOCAL_CERT_CONTEXT
  1536. // SECPKG_ATTR_LOCAL_CRED
  1537. // SECPKG_ATTR_NAMES
  1538. // SECPKG_ATTR_PROTO_INFO
  1539. // SECPKG_ATTR_REMOTE_CERT_CONTEXT
  1540. // SECPKG_ATTR_REMOTE_CRED
  1541. // SECPKG_ATTR_SIZES
  1542. // SECPKG_ATTR_STREAM_SIZES
  1543. //
  1544. //--------------------------------------------------------------------------
  1545. SECURITY_STATUS
  1546. SEC_ENTRY
  1547. SpLsaQueryContextAttributes(
  1548. LSA_SEC_HANDLE Context,
  1549. ULONG Attribute,
  1550. PVOID Buffer)
  1551. {
  1552. SECURITY_STATUS Status;
  1553. PSPContext pContext;
  1554. pContext = (PSPContext)Context;
  1555. switch(Attribute)
  1556. {
  1557. case SECPKG_ATTR_AUTHORITY :
  1558. Status = SpQueryAuthority(Context, Buffer);
  1559. break;
  1560. case SECPKG_ATTR_ISSUER_LIST :
  1561. Status = SpQueryIssuerList(Context, Buffer);
  1562. break;
  1563. case SECPKG_ATTR_ISSUER_LIST_EX:
  1564. Status = SpQueryIssuerListEx(Context, Buffer);
  1565. break;
  1566. // case SECPKG_ATTR_KEY_INFO :
  1567. // Status = SpQueryKeyInfo(Context, Buffer);
  1568. // break;
  1569. // case SECPKG_ATTR_LIFESPAN :
  1570. // Status = SpQueryLifespan(Context, Buffer);
  1571. // break;
  1572. case SECPKG_ATTR_LOCAL_CERT_CONTEXT:
  1573. Status = SpQueryLocalCertContext(Context, Buffer);
  1574. break;
  1575. case SECPKG_ATTR_LOCAL_CRED:
  1576. Status = SpQueryLocalCred(Context, Buffer);
  1577. break;
  1578. // case SECPKG_ATTR_NAMES :
  1579. // Status = SpQueryNames(Context, Buffer);
  1580. // break;
  1581. // case SECPKG_ATTR_PROTO_INFO:
  1582. // Status = SpQueryProtoInfo(Context, Buffer);
  1583. // break;
  1584. // case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
  1585. // Status = SpQueryCertContext(Context, Buffer, FALSE);
  1586. // break;
  1587. // case SECPKG_ATTR_REMOTE_CRED:
  1588. // Status = SpQueryRemoteCred(Context, Buffer);
  1589. // break;
  1590. // case SECPKG_ATTR_SIZES:
  1591. // Status = SpQuerySizes(Context, Buffer);
  1592. // break;
  1593. // case SECPKG_ATTR_STREAM_SIZES:
  1594. // Status = SpQueryStreamSizes(Context, Buffer);
  1595. // break;
  1596. case SECPKG_ATTR_EAP_KEY_BLOCK:
  1597. Status = SpQueryEapKeyBlock(Context, Buffer);
  1598. break;
  1599. // case SECPKG_ATTR_MAPPED_CRED_ATTR:
  1600. // Status = SpQueryMappedCredAttr(Context, Buffer);
  1601. // break;
  1602. case SECPKG_ATTR_APP_DATA:
  1603. Status = SpQueryApplicationData(Context, Buffer);
  1604. break;
  1605. default:
  1606. DebugLog((DEB_ERROR, "QueryContextAttributes(unsupported function %d)\n", Attribute));
  1607. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1608. }
  1609. return Status;
  1610. }
  1611. //+-------------------------------------------------------------------------
  1612. //
  1613. // Function: SpUserQueryContextAttributes
  1614. //
  1615. // Synopsis: User mode QueryContextAttribute.
  1616. //
  1617. // Effects:
  1618. //
  1619. // Arguments:
  1620. //
  1621. // Requires:
  1622. //
  1623. // Returns:
  1624. //
  1625. // Notes:
  1626. //
  1627. //--------------------------------------------------------------------------
  1628. NTSTATUS NTAPI
  1629. SpUserQueryContextAttributes(
  1630. IN LSA_SEC_HANDLE ContextHandle,
  1631. IN ULONG ContextAttribute,
  1632. IN OUT PVOID pBuffer
  1633. )
  1634. {
  1635. PSSL_USER_CONTEXT Context;
  1636. PSPContext pContext;
  1637. SECURITY_STATUS Status;
  1638. Context = SslFindUserContext( ContextHandle );
  1639. if(Context == NULL)
  1640. {
  1641. return(SEC_E_INVALID_HANDLE);
  1642. }
  1643. pContext = Context->pContext;
  1644. if(!pContext)
  1645. {
  1646. return(SEC_E_INVALID_HANDLE);
  1647. }
  1648. switch(ContextAttribute)
  1649. {
  1650. case SECPKG_ATTR_CONNECTION_INFO:
  1651. Status = SpQueryConnectionInfo(pContext, pBuffer);
  1652. break;
  1653. case SECPKG_ATTR_KEY_INFO:
  1654. Status = SpQueryKeyInfo(pContext, pBuffer);
  1655. break;
  1656. case SECPKG_ATTR_LIFESPAN:
  1657. Status = SpQueryLifespan(pContext, pBuffer);
  1658. break;
  1659. case SECPKG_ATTR_NAMES :
  1660. Status = SpQueryNames(pContext, pBuffer);
  1661. break;
  1662. case SECPKG_ATTR_PACKAGE_INFO:
  1663. Status = SpQueryPackageInfo(pContext, pBuffer);
  1664. break;
  1665. case SECPKG_ATTR_PROTO_INFO:
  1666. Status = SpQueryProtoInfo(pContext, pBuffer);
  1667. break;
  1668. case SECPKG_ATTR_REMOTE_CERT_CONTEXT:
  1669. Status = SpQueryRemoteCertContext(pContext, pBuffer);
  1670. break;
  1671. case SECPKG_ATTR_REMOTE_CRED:
  1672. Status = SpQueryRemoteCred(pContext, pBuffer);
  1673. break;
  1674. case SECPKG_ATTR_SIZES:
  1675. Status = SpQuerySizes(pContext, pBuffer);
  1676. break;
  1677. case SECPKG_ATTR_STREAM_SIZES:
  1678. Status = SpQueryStreamSizes(pContext, pBuffer);
  1679. break;
  1680. case SECPKG_ATTR_ACCESS_TOKEN:
  1681. Status = SpQueryAccessToken(pContext, pBuffer);
  1682. break;
  1683. case SECPKG_ATTR_SESSION_INFO:
  1684. Status = SpQuerySessionInfo(pContext, pBuffer);
  1685. break;
  1686. default:
  1687. DebugLog((DEB_ERROR, "QueryContextAttributes(unsupported function %d)\n", ContextAttribute));
  1688. return SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1689. }
  1690. return Status;
  1691. }
  1692. //+-------------------------------------------------------------------------
  1693. //
  1694. // Function: SpSetUseValidatedProp
  1695. //
  1696. // Synopsis: Sets the SECPKG_ATTR_USE_VALIDATED context attribute.
  1697. //
  1698. // Arguments:
  1699. //
  1700. // Returns:
  1701. //
  1702. // Notes: The buffer must contain a DWORD indicating whether the
  1703. // credential currently associated with the context has been
  1704. // validated for use.
  1705. //
  1706. //--------------------------------------------------------------------------
  1707. NTSTATUS
  1708. SpSetUseValidatedProp(
  1709. IN PSPContext pContext,
  1710. IN PVOID Buffer,
  1711. IN ULONG BufferSize)
  1712. {
  1713. DWORD dwUseValidated;
  1714. NTSTATUS Status;
  1715. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_USE_VALIDATED)\n"));
  1716. if(BufferSize < sizeof(DWORD))
  1717. {
  1718. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1719. goto cleanup;
  1720. }
  1721. Status = LsaTable->CopyFromClientBuffer( NULL,
  1722. sizeof(DWORD),
  1723. &dwUseValidated,
  1724. Buffer );
  1725. if(FAILED(Status))
  1726. {
  1727. SP_LOG_RESULT(Status);
  1728. goto cleanup;
  1729. }
  1730. DebugLog((DEB_TRACE, "Use validated:%d\n", dwUseValidated));
  1731. if(pContext->RipeZombie == NULL)
  1732. {
  1733. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1734. goto cleanup;
  1735. }
  1736. if(dwUseValidated)
  1737. {
  1738. pContext->RipeZombie->dwFlags |= SP_CACHE_FLAG_USE_VALIDATED;
  1739. }
  1740. else
  1741. {
  1742. pContext->RipeZombie->dwFlags &= ~SP_CACHE_FLAG_USE_VALIDATED;
  1743. }
  1744. cleanup:
  1745. return Status;
  1746. }
  1747. //+-------------------------------------------------------------------------
  1748. //
  1749. // Function: SpSetCredentialNameProp
  1750. //
  1751. // Synopsis: Sets the SECPKG_ATTR_CREDENTIAL_NAME context attribute.
  1752. //
  1753. // Arguments:
  1754. //
  1755. // Returns:
  1756. //
  1757. // Notes: The buffer must contain the following structure:
  1758. //
  1759. // typedef struct _SecPkgContext_CredentialNameW
  1760. // {
  1761. // unsigned long CredentialType;
  1762. // SEC_WCHAR SEC_FAR *sCredentialName;
  1763. // } SecPkgContext_CredentialNameW, SEC_FAR * PSecPkgContext_CredentialNameW;
  1764. //
  1765. //--------------------------------------------------------------------------
  1766. NTSTATUS
  1767. SpSetCredentialNameProp(
  1768. IN PSPContext pContext,
  1769. IN PVOID Buffer,
  1770. IN ULONG BufferSize)
  1771. {
  1772. PSecPkgContext_CredentialNameW pCredentialStruct = NULL;
  1773. SEC_WCHAR *pClientCredName = NULL;
  1774. SEC_WCHAR *pCredName = NULL;
  1775. DWORD_PTR Offset;
  1776. NTSTATUS Status;
  1777. ULONG i;
  1778. BOOL fTerminated = FALSE;
  1779. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_CREDENTIAL_NAME)\n"));
  1780. //
  1781. // Marshal over the credential name from the client address space.
  1782. //
  1783. if(BufferSize < sizeof(SecPkgContext_CredentialNameW))
  1784. {
  1785. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1786. goto cleanup;
  1787. }
  1788. if(BufferSize > sizeof(SecPkgContext_CredentialNameW) +
  1789. CRED_MAX_DOMAIN_TARGET_NAME_LENGTH * sizeof(WCHAR))
  1790. {
  1791. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1792. goto cleanup;
  1793. }
  1794. pCredentialStruct = SPExternalAlloc(BufferSize + sizeof(WCHAR));
  1795. if(pCredentialStruct == NULL)
  1796. {
  1797. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1798. goto cleanup;
  1799. }
  1800. Status = LsaTable->CopyFromClientBuffer( NULL,
  1801. BufferSize,
  1802. pCredentialStruct,
  1803. Buffer );
  1804. if(FAILED(Status))
  1805. {
  1806. SP_LOG_RESULT(Status);
  1807. goto cleanup;
  1808. }
  1809. if(pCredentialStruct->CredentialType != CRED_TYPE_DOMAIN_CERTIFICATE)
  1810. {
  1811. DebugLog((DEB_ERROR, "Unexpected credential type %d\n", pCredentialStruct->CredentialType));
  1812. Status = SEC_E_UNKNOWN_CREDENTIALS;
  1813. goto cleanup;
  1814. }
  1815. // Get pointer to credential name in the client's address space.
  1816. pClientCredName = pCredentialStruct->sCredentialName;
  1817. if(!POINTER_IS_ALIGNED(pClientCredName, sizeof(WCHAR)))
  1818. {
  1819. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1820. goto cleanup;
  1821. }
  1822. if((PBYTE)pClientCredName < (PBYTE)Buffer + sizeof(SecPkgContext_CredentialNameW) ||
  1823. (PBYTE)pClientCredName >= (PBYTE)Buffer + BufferSize)
  1824. {
  1825. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1826. goto cleanup;
  1827. }
  1828. // Compute offset of credential name within the input buffer.
  1829. Offset = (PBYTE)pClientCredName - (PBYTE)Buffer;
  1830. // Build pointer to credential name in the local process.
  1831. pCredName = (SEC_WCHAR *)((PBYTE)pCredentialStruct + Offset);
  1832. // Ensure that the credential name is zero terminated.
  1833. for(i = 0; i < (BufferSize - Offset) / sizeof(WCHAR); i++)
  1834. {
  1835. if(pCredName[i] == L'\0')
  1836. {
  1837. fTerminated = TRUE;
  1838. break;
  1839. }
  1840. }
  1841. if(!fTerminated)
  1842. {
  1843. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1844. goto cleanup;
  1845. }
  1846. DebugLog((DEB_TRACE, "Set client credential to '%ls'.\n", pCredName));
  1847. //
  1848. // Associate the specified credential with the current context.
  1849. //
  1850. pContext->pszCredentialName = SPExternalAlloc((lstrlenW(pCredName) + 1) * sizeof(WCHAR));
  1851. if(pContext->pszCredentialName == NULL)
  1852. {
  1853. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1854. goto cleanup;
  1855. }
  1856. lstrcpyW(pContext->pszCredentialName, pCredName);
  1857. Status = QueryCredentialManagerForCert(pContext, pCredName);
  1858. if(FAILED(Status))
  1859. {
  1860. SP_LOG_RESULT(Status);
  1861. goto cleanup;
  1862. }
  1863. DebugLog((DEB_TRACE, "Credential assigned to context successfully.\n"));
  1864. cleanup:
  1865. if(pCredentialStruct)
  1866. {
  1867. SPExternalFree(pCredentialStruct);
  1868. }
  1869. return Status;
  1870. }
  1871. //+-------------------------------------------------------------------------
  1872. //
  1873. // Function: SpSetApplicationData
  1874. //
  1875. // Synopsis: Sets the SECPKG_ATTR_APP_DATA context attribute.
  1876. //
  1877. // Arguments:
  1878. //
  1879. // Returns:
  1880. //
  1881. // Notes: The buffer must contain the following structure:
  1882. //
  1883. // typedef struct _SecPkgContext_SessionAppData
  1884. // {
  1885. // DWORD dwFlags;
  1886. // DWORD cbAppData;
  1887. // PBYTE pbAppData;
  1888. // } SecPkgContext_SessionAppData, *PSecPkgContext_SessionAppData;
  1889. //
  1890. //--------------------------------------------------------------------------
  1891. NTSTATUS
  1892. SpSetApplicationData(
  1893. IN PSPContext pContext,
  1894. IN PVOID Buffer,
  1895. IN ULONG BufferSize)
  1896. {
  1897. SecPkgContext_SessionAppData AppData;
  1898. PBYTE pbAppData = NULL;
  1899. NTSTATUS Status;
  1900. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_APP_DATA)\n"));
  1901. if(pContext->RipeZombie == NULL)
  1902. {
  1903. return SP_LOG_RESULT(SEC_E_INVALID_HANDLE);
  1904. }
  1905. //
  1906. // Marshal over the input structure from the client address space.
  1907. //
  1908. if(BufferSize < sizeof(SecPkgContext_SessionAppData))
  1909. {
  1910. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1911. goto cleanup;
  1912. }
  1913. Status = LsaTable->CopyFromClientBuffer( NULL,
  1914. sizeof(SecPkgContext_SessionAppData),
  1915. &AppData,
  1916. Buffer );
  1917. if(FAILED(Status))
  1918. {
  1919. SP_LOG_RESULT(Status);
  1920. goto cleanup;
  1921. }
  1922. //
  1923. // Marshal over the application data from the client address space.
  1924. //
  1925. // Limit application data size to 64k.
  1926. if(AppData.cbAppData > 0x10000)
  1927. {
  1928. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1929. goto cleanup;
  1930. }
  1931. if(AppData.cbAppData == 0 || AppData.pbAppData == NULL)
  1932. {
  1933. Status = SP_LOG_RESULT(STATUS_INVALID_PARAMETER);
  1934. goto cleanup;
  1935. }
  1936. pbAppData = SPExternalAlloc(AppData.cbAppData);
  1937. if(pbAppData == NULL)
  1938. {
  1939. Status = SP_LOG_RESULT(SEC_E_INSUFFICIENT_MEMORY);
  1940. goto cleanup;
  1941. }
  1942. Status = LsaTable->CopyFromClientBuffer( NULL,
  1943. AppData.cbAppData,
  1944. pbAppData,
  1945. AppData.pbAppData );
  1946. if(FAILED(Status))
  1947. {
  1948. SP_LOG_RESULT(Status);
  1949. goto cleanup;
  1950. }
  1951. //
  1952. // Assign application data to cache entry.
  1953. //
  1954. Status = SetCacheAppData(pContext->RipeZombie,
  1955. pbAppData,
  1956. AppData.cbAppData);
  1957. if(!FAILED(Status))
  1958. {
  1959. // The operation succeeded, so consume the application data.
  1960. pbAppData = NULL;
  1961. }
  1962. cleanup:
  1963. if(pbAppData)
  1964. {
  1965. SPExternalFree(pbAppData);
  1966. }
  1967. return Status;
  1968. }
  1969. NTSTATUS
  1970. NTAPI
  1971. SpSetContextAttributes(
  1972. IN LSA_SEC_HANDLE ContextHandle,
  1973. IN ULONG ContextAttribute,
  1974. IN PVOID Buffer,
  1975. IN ULONG BufferSize)
  1976. {
  1977. NTSTATUS Status;
  1978. PSPContext pContext;
  1979. pContext = (PSPContext)ContextHandle;
  1980. switch(ContextAttribute)
  1981. {
  1982. case SECPKG_ATTR_USE_VALIDATED:
  1983. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_USE_VALIDATED)\n"));
  1984. Status = STATUS_SUCCESS;
  1985. break;
  1986. case SECPKG_ATTR_CREDENTIAL_NAME:
  1987. Status = SpSetCredentialNameProp(pContext, Buffer, BufferSize);
  1988. break;
  1989. case SECPKG_ATTR_TARGET_INFORMATION:
  1990. DebugLog((DEB_TRACE, "SetContextAttributes(SECPKG_ATTR_TARGET_INFORMATION)\n"));
  1991. Status = STATUS_SUCCESS;
  1992. break;
  1993. case SECPKG_ATTR_APP_DATA:
  1994. Status = SpSetApplicationData(pContext, Buffer, BufferSize);
  1995. break;
  1996. default:
  1997. DebugLog((DEB_ERROR, "SetContextAttributes(unsupported function %d)\n", ContextAttribute));
  1998. Status = SP_LOG_RESULT(SEC_E_UNSUPPORTED_FUNCTION);
  1999. }
  2000. return Status;
  2001. }