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.

621 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: stubs.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 8-01-95 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "sslp.h"
  18. #include "spsspi.h"
  19. #include <cert509.h>
  20. #include <rsa.h>
  21. CHAR CertTag[ 13 ] = { 0x04, 0x0b, 'c', 'e', 'r', 't', 'i', 'f', 'i', 'c', 'a', 't', 'e' };
  22. SecurityFunctionTableW SPFunctionTable = {
  23. SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
  24. EnumerateSecurityPackagesW,
  25. NULL,
  26. AcquireCredentialsHandleW,
  27. FreeCredentialsHandle,
  28. NULL,
  29. InitializeSecurityContextW,
  30. AcceptSecurityContext,
  31. CompleteAuthToken,
  32. DeleteSecurityContext,
  33. ApplyControlToken,
  34. QueryContextAttributesW,
  35. ImpersonateSecurityContext,
  36. RevertSecurityContext,
  37. MakeSignature,
  38. VerifySignature,
  39. FreeContextBuffer,
  40. QuerySecurityPackageInfoW,
  41. SealMessage,
  42. UnsealMessage,
  43. NULL, /* GrantProxyW */
  44. NULL, /* RevokeProxyW */
  45. NULL, /* InvokeProxyW */
  46. NULL, /* RenewProxyW */
  47. QuerySecurityContextToken,
  48. SealMessage,
  49. UnsealMessage,
  50. SetContextAttributesW
  51. };
  52. SecurityFunctionTableA SPFunctionTableA = {
  53. SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
  54. EnumerateSecurityPackagesA,
  55. NULL,
  56. AcquireCredentialsHandleA,
  57. FreeCredentialsHandle,
  58. NULL,
  59. InitializeSecurityContextA,
  60. AcceptSecurityContext,
  61. CompleteAuthToken,
  62. DeleteSecurityContext,
  63. ApplyControlToken,
  64. QueryContextAttributesA,
  65. ImpersonateSecurityContext,
  66. RevertSecurityContext,
  67. MakeSignature,
  68. VerifySignature,
  69. FreeContextBuffer,
  70. QuerySecurityPackageInfoA,
  71. SealMessage,
  72. UnsealMessage,
  73. NULL, /* GrantProxyA */
  74. NULL, /* RevokeProxyA */
  75. NULL, /* InvokeProxyA */
  76. NULL, /* RenewProxyA */
  77. QuerySecurityContextToken,
  78. SealMessage,
  79. UnsealMessage,
  80. SetContextAttributesA
  81. };
  82. PSecurityFunctionTableW SEC_ENTRY
  83. InitSecurityInterfaceW(
  84. VOID )
  85. {
  86. return(&SPFunctionTable);
  87. }
  88. PSecurityFunctionTableA SEC_ENTRY
  89. InitSecurityInterfaceA(
  90. VOID )
  91. {
  92. return(&SPFunctionTableA);
  93. }
  94. SECURITY_STATUS SEC_ENTRY
  95. FreeContextBuffer(
  96. void SEC_FAR * pvContextBuffer
  97. )
  98. {
  99. SPExternalFree( pvContextBuffer );
  100. return(SEC_E_OK);
  101. }
  102. SECURITY_STATUS SEC_ENTRY
  103. SecurityPackageControl(
  104. SEC_WCHAR SEC_FAR * pszPackageName,
  105. unsigned long dwFunctionCode,
  106. unsigned long cbInputBuffer,
  107. unsigned char SEC_FAR * pbInputBuffer,
  108. unsigned long SEC_FAR * pcbOutputBuffer,
  109. unsigned char SEC_FAR * pbOutputBuffer)
  110. {
  111. return(SEC_E_UNSUPPORTED_FUNCTION);
  112. }
  113. SECURITY_STATUS PctTranslateError(SP_STATUS spRet)
  114. {
  115. if(HRESULT_FACILITY(spRet) == FACILITY_SECURITY)
  116. {
  117. return (spRet);
  118. }
  119. switch(spRet) {
  120. case PCT_ERR_OK: return SEC_E_OK;
  121. case PCT_ERR_BAD_CERTIFICATE: return SEC_E_INVALID_TOKEN;
  122. case PCT_ERR_CLIENT_AUTH_FAILED: return SEC_E_INVALID_TOKEN;
  123. case PCT_ERR_ILLEGAL_MESSAGE: return SEC_E_INVALID_TOKEN;
  124. case PCT_ERR_INTEGRITY_CHECK_FAILED: return SEC_E_MESSAGE_ALTERED;
  125. case PCT_ERR_SERVER_AUTH_FAILED: return SEC_E_INVALID_TOKEN;
  126. case PCT_ERR_SPECS_MISMATCH: return SEC_E_ALGORITHM_MISMATCH;
  127. case PCT_ERR_SSL_STYLE_MSG: return SEC_E_INVALID_TOKEN;
  128. case SEC_I_INCOMPLETE_CREDENTIALS: return SEC_I_INCOMPLETE_CREDENTIALS;
  129. case PCT_ERR_RENEGOTIATE: return SEC_I_RENEGOTIATE;
  130. case PCT_ERR_UNKNOWN_CREDENTIAL: return SEC_E_UNKNOWN_CREDENTIALS;
  131. case CERT_E_UNTRUSTEDROOT: return SEC_E_UNTRUSTED_ROOT;
  132. case CERT_E_EXPIRED: return SEC_E_CERT_EXPIRED;
  133. case CERT_E_VALIDITYPERIODNESTING: return SEC_E_CERT_EXPIRED;
  134. case CERT_E_REVOKED: return CRYPT_E_REVOKED;
  135. case CERT_E_CN_NO_MATCH: return SEC_E_WRONG_PRINCIPAL;
  136. case PCT_INT_BAD_CERT: return SEC_E_INVALID_TOKEN;
  137. case PCT_INT_CLI_AUTH: return SEC_E_INVALID_TOKEN;
  138. case PCT_INT_ILLEGAL_MSG: return SEC_E_INVALID_TOKEN;
  139. case PCT_INT_SPECS_MISMATCH: return SEC_E_ALGORITHM_MISMATCH;
  140. case PCT_INT_INCOMPLETE_MSG: return SEC_E_INCOMPLETE_MESSAGE;
  141. case PCT_INT_MSG_ALTERED: return SEC_E_MESSAGE_ALTERED;
  142. case PCT_INT_INTERNAL_ERROR: return SEC_E_INTERNAL_ERROR;
  143. case PCT_INT_DATA_OVERFLOW: return SEC_E_INTERNAL_ERROR;
  144. case SEC_E_INCOMPLETE_CREDENTIALS: return SEC_E_INCOMPLETE_CREDENTIALS;
  145. case PCT_INT_RENEGOTIATE: return SEC_I_RENEGOTIATE;
  146. case PCT_INT_UNKNOWN_CREDENTIAL: return SEC_E_UNKNOWN_CREDENTIALS;
  147. case PCT_INT_BUFF_TOO_SMALL: return SEC_E_BUFFER_TOO_SMALL;
  148. case SEC_E_BUFFER_TOO_SMALL: return SEC_E_BUFFER_TOO_SMALL;
  149. default: return SEC_E_INTERNAL_ERROR;
  150. }
  151. }
  152. //+---------------------------------------------------------------------------
  153. //
  154. // Function: SslGenerateRandomBits
  155. //
  156. // Synopsis: Hook for setup to get a good random stream
  157. //
  158. // Arguments: [pRandomData] --
  159. // [cRandomData] --
  160. //
  161. //
  162. // Notes:
  163. //
  164. //----------------------------------------------------------------------------
  165. VOID
  166. WINAPI
  167. SslGenerateRandomBits(
  168. PUCHAR pRandomData,
  169. LONG cRandomData
  170. )
  171. {
  172. if(!SchannelInit(TRUE))
  173. {
  174. return;
  175. }
  176. GenerateRandomBits(pRandomData, (ULONG)cRandomData);
  177. }
  178. //+---------------------------------------------------------------------------
  179. //
  180. // Function: SslGenerateKeyPair
  181. //
  182. // Synopsis: Generates a public/private key pair, protected by password
  183. //
  184. // Arguments: [pCerts] --
  185. // [pszDN] --
  186. // [pszPassword] --
  187. // [Bits] --
  188. //
  189. // Notes:
  190. //
  191. //----------------------------------------------------------------------------
  192. BOOL
  193. WINAPI
  194. SslGenerateKeyPair(
  195. PSSL_CREDENTIAL_CERTIFICATE pCerts,
  196. PSTR pszDN,
  197. PSTR pszPassword,
  198. DWORD Bits )
  199. {
  200. if(!SchannelInit(TRUE))
  201. {
  202. return FALSE;
  203. }
  204. #ifdef SCHANNEL_EXPORT
  205. if ( Bits > 1024 )
  206. {
  207. SetLastError( ERROR_INVALID_PARAMETER );
  208. return( FALSE );
  209. }
  210. #endif
  211. return GenerateKeyPair(pCerts, pszDN, pszPassword, Bits);
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Function: SslGetMaximumKeySize
  216. //
  217. // Synopsis: Returns maximum public key size
  218. //
  219. // Arguments: [Reserved] --
  220. //
  221. // Notes:
  222. //
  223. //----------------------------------------------------------------------------
  224. DWORD
  225. WINAPI
  226. SslGetMaximumKeySize(
  227. DWORD Reserved )
  228. {
  229. #ifdef SCHANNEL_EXPORT
  230. return( 1024 );
  231. #else
  232. return( 2048 );
  233. #endif
  234. }
  235. //+---------------------------------------------------------------------------
  236. //
  237. // Function: SslFreeCertificate
  238. //
  239. // Synopsis: Frees a certificate created from SslCrackCertificate
  240. //
  241. // Arguments: [pCertificate] --
  242. //
  243. // Notes:
  244. //
  245. //----------------------------------------------------------------------------
  246. VOID
  247. WINAPI
  248. SslFreeCertificate(
  249. PX509Certificate pCertificate)
  250. {
  251. if ( pCertificate )
  252. {
  253. SPExternalFree(pCertificate->pPublicKey);
  254. SPExternalFree(pCertificate);
  255. }
  256. }
  257. //+---------------------------------------------------------------------------
  258. //
  259. // Function: SslCrackCertificate
  260. //
  261. // Synopsis: Cracks a X509 certificate into remotely easy format
  262. //
  263. // Arguments: [pbCertificate] --
  264. // [cbCertificate] --
  265. // [dwFlags] --
  266. // [ppCertificate] --
  267. //
  268. // Notes:
  269. //
  270. //----------------------------------------------------------------------------
  271. BOOL
  272. WINAPI
  273. SslCrackCertificate(
  274. PUCHAR pbCertificate,
  275. DWORD cbCertificate,
  276. DWORD dwFlags,
  277. PX509Certificate * ppCertificate)
  278. {
  279. PX509Certificate pResult = NULL;
  280. PCCERT_CONTEXT pContext = NULL;
  281. DWORD cbIssuer;
  282. DWORD cbSubject;
  283. if(!SchannelInit(TRUE))
  284. {
  285. return FALSE;
  286. }
  287. if (dwFlags & CF_CERT_FROM_FILE)
  288. {
  289. if (cbCertificate < CERT_HEADER_LEN + 1 )
  290. {
  291. goto error;
  292. }
  293. //
  294. // Sleazy quick check. Some CAs wrap certs in a cert wrapper.
  295. // Some don't. Some do both, but we won't mention any names.
  296. // Quick check for the wrapper tag. If so, scoot in by enough
  297. // to bypass it (17 bytes. Sheesh).
  298. //
  299. if ( memcmp( pbCertificate + 4, CertTag, sizeof( CertTag ) ) == 0 )
  300. {
  301. pbCertificate += CERT_HEADER_LEN;
  302. cbCertificate -= CERT_HEADER_LEN;
  303. }
  304. }
  305. pContext = CertCreateCertificateContext(X509_ASN_ENCODING, pbCertificate, cbCertificate);
  306. if(pContext == NULL)
  307. {
  308. SP_LOG_RESULT(GetLastError());
  309. goto error;
  310. }
  311. if(0 >= (cbSubject = CertNameToStrA(pContext->dwCertEncodingType,
  312. &pContext->pCertInfo->Subject,
  313. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  314. NULL, 0)))
  315. {
  316. SP_LOG_RESULT(GetLastError());
  317. goto error;
  318. }
  319. if(0 >= (cbIssuer = CertNameToStrA(pContext->dwCertEncodingType,
  320. &pContext->pCertInfo->Issuer,
  321. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  322. NULL, 0)))
  323. {
  324. SP_LOG_RESULT(GetLastError());
  325. goto error;
  326. }
  327. pResult = SPExternalAlloc(sizeof(X509Certificate) + cbIssuer + cbSubject + 2);
  328. if(pResult == NULL)
  329. {
  330. goto error;
  331. }
  332. pResult->pPublicKey = NULL;
  333. pResult->pszIssuer = (PUCHAR)(pResult + 1);
  334. pResult->pszSubject = pResult->pszIssuer + cbIssuer;
  335. pResult->Version = pContext->pCertInfo->dwVersion;
  336. memcpy(pResult->SerialNumber,
  337. pContext->pCertInfo->SerialNumber.pbData,
  338. min(sizeof(pResult->SerialNumber), pContext->pCertInfo->SerialNumber.cbData));
  339. pResult->ValidFrom = pContext->pCertInfo->NotBefore;
  340. pResult->ValidUntil = pContext->pCertInfo->NotAfter;
  341. if(0 >= CertNameToStrA(pContext->dwCertEncodingType,
  342. &pContext->pCertInfo->Issuer,
  343. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  344. pResult->pszIssuer, cbIssuer))
  345. {
  346. SP_LOG_RESULT(GetLastError());
  347. goto error;
  348. }
  349. if(0 >= CertNameToStrA(pContext->dwCertEncodingType,
  350. &pContext->pCertInfo->Subject,
  351. CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
  352. pResult->pszSubject, cbSubject))
  353. {
  354. SP_LOG_RESULT(GetLastError());
  355. goto error;
  356. }
  357. {
  358. BSAFE_PUB_KEY *pk;
  359. PUBLICKEY * pPubKey = NULL;
  360. SP_STATUS pctRet;
  361. DWORD cbPublicKey;
  362. pResult->pPublicKey = SPExternalAlloc(sizeof(PctPublicKey) + sizeof(BSAFE_PUB_KEY));
  363. if(pResult->pPublicKey == NULL)
  364. {
  365. goto error;
  366. }
  367. pResult->pPublicKey->Type = 0;
  368. pResult->pPublicKey->cbKey = sizeof(BSAFE_PUB_KEY);
  369. pk = (BSAFE_PUB_KEY *)pResult->pPublicKey->pKey;
  370. pk->magic = RSA1;
  371. pctRet = SPPublicKeyFromCert(pContext, &pPubKey, NULL);
  372. if(pctRet == PCT_ERR_OK)
  373. {
  374. if(pPubKey->pPublic->aiKeyAlg == CALG_RSA_KEYX)
  375. {
  376. RSAPUBKEY *pRsaKey = (RSAPUBKEY *)(pPubKey->pPublic + 1);
  377. pk->keylen = pRsaKey->bitlen/8;
  378. pk->bitlen = pRsaKey->bitlen;
  379. pk->datalen = pk->bitlen/8 - 1;
  380. pk->pubexp = pRsaKey->pubexp;
  381. }
  382. else
  383. {
  384. DHPUBKEY *pDHKey = (DHPUBKEY *)(pPubKey->pPublic + 1);
  385. pk->keylen = pDHKey->bitlen/8;
  386. pk->bitlen = pDHKey->bitlen/8;
  387. pk->datalen = pk->bitlen/8 - 1;
  388. pk->pubexp = 0;
  389. }
  390. SPExternalFree(pPubKey);
  391. }
  392. else
  393. {
  394. goto error;
  395. }
  396. }
  397. CertFreeCertificateContext(pContext);
  398. *ppCertificate = pResult;
  399. return TRUE;
  400. error:
  401. if(pContext)
  402. {
  403. CertFreeCertificateContext(pContext);
  404. }
  405. if(pResult)
  406. {
  407. if(pResult->pPublicKey)
  408. {
  409. SPExternalFree(pResult->pPublicKey);
  410. }
  411. SPExternalFree(pResult);
  412. }
  413. return FALSE;
  414. }
  415. //+---------------------------------------------------------------------------
  416. //
  417. // Function: SslLoadCertificate
  418. //
  419. // Synopsis: Not supported.
  420. //
  421. // Notes:
  422. //
  423. //----------------------------------------------------------------------------
  424. BOOL
  425. WINAPI
  426. SslLoadCertificate(
  427. PUCHAR pbCertificate,
  428. DWORD cbCertificate,
  429. BOOL AddToWellKnownKeys)
  430. {
  431. return FALSE;
  432. }
  433. BOOL
  434. SslGetClientProcess(ULONG *pProcessID)
  435. {
  436. SECPKG_CALL_INFO CallInfo;
  437. SECURITY_STATUS Status;
  438. if(LsaTable == NULL)
  439. {
  440. *pProcessID = GetCurrentProcessId();
  441. return TRUE;
  442. }
  443. if(LsaTable->GetCallInfo(&CallInfo))
  444. {
  445. *pProcessID = CallInfo.ProcessId;
  446. return TRUE;
  447. }
  448. else
  449. {
  450. *pProcessID = -1;
  451. return FALSE;
  452. }
  453. }
  454. BOOL
  455. SslGetClientThread(ULONG *pThreadID)
  456. {
  457. SECPKG_CALL_INFO CallInfo;
  458. SECURITY_STATUS Status;
  459. if(LsaTable == NULL)
  460. {
  461. *pThreadID = GetCurrentThreadId();
  462. return TRUE;
  463. }
  464. if(LsaTable->GetCallInfo(&CallInfo))
  465. {
  466. *pThreadID = CallInfo.ThreadId;
  467. return TRUE;
  468. }
  469. else
  470. {
  471. *pThreadID = -1;
  472. return FALSE;
  473. }
  474. }
  475. BOOL
  476. SslImpersonateClient(void)
  477. {
  478. SECPKG_CALL_INFO CallInfo;
  479. SECURITY_STATUS Status;
  480. // Don't impersonate if we're in the client process.
  481. if(LsaTable == NULL)
  482. {
  483. return FALSE;
  484. }
  485. // Don't impersonate if the client is running in the lsass process.
  486. if(LsaTable->GetCallInfo(&CallInfo))
  487. {
  488. if(CallInfo.ProcessId == GetCurrentProcessId())
  489. {
  490. // DebugLog((DEB_WARN, "Running locally, so don't impersonate.\n"));
  491. return FALSE;
  492. }
  493. }
  494. Status = LsaTable->ImpersonateClient();
  495. if(!NT_SUCCESS(Status))
  496. {
  497. SP_LOG_RESULT(Status);
  498. return FALSE;
  499. }
  500. return TRUE;
  501. }
  502. NTSTATUS
  503. SslGetClientLogonId(LUID *pLogonId)
  504. {
  505. SECPKG_CLIENT_INFO ClientInfo;
  506. SECURITY_STATUS Status;
  507. memset(pLogonId, 0, sizeof(LUID));
  508. Status = LsaTable->GetClientInfo(&ClientInfo);
  509. if(NT_SUCCESS(Status))
  510. {
  511. *pLogonId = ClientInfo.LogonId;
  512. }
  513. return Status;
  514. }
  515. PVOID SPExternalAlloc(DWORD cbLength)
  516. {
  517. if(LsaTable)
  518. {
  519. // Lsass process
  520. return LsaTable->AllocateLsaHeap(cbLength);
  521. }
  522. else
  523. {
  524. // Application process
  525. return LocalAlloc(LPTR, cbLength);
  526. }
  527. }
  528. VOID SPExternalFree(PVOID pMemory)
  529. {
  530. if(LsaTable)
  531. {
  532. // Lsass process
  533. LsaTable->FreeLsaHeap(pMemory);
  534. }
  535. else
  536. {
  537. // Application process
  538. LocalFree(pMemory);
  539. }
  540. }