|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: stubs.c
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 8-01-95 RichardW Created
//
//----------------------------------------------------------------------------
#include "sslp.h"
#include "spsspi.h"
#include <cert509.h>
#include <rsa.h>
CHAR CertTag[ 13 ] = { 0x04, 0x0b, 'c', 'e', 'r', 't', 'i', 'f', 'i', 'c', 'a', 't', 'e' };
SecurityFunctionTableW SPFunctionTable = { SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION, EnumerateSecurityPackagesW, NULL, AcquireCredentialsHandleW, FreeCredentialsHandle, NULL, InitializeSecurityContextW, AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, ApplyControlToken, QueryContextAttributesW, ImpersonateSecurityContext, RevertSecurityContext, MakeSignature, VerifySignature, FreeContextBuffer, QuerySecurityPackageInfoW, SealMessage, UnsealMessage, NULL, /* GrantProxyW */ NULL, /* RevokeProxyW */ NULL, /* InvokeProxyW */ NULL, /* RenewProxyW */ QuerySecurityContextToken, SealMessage, UnsealMessage, SetContextAttributesW };
SecurityFunctionTableA SPFunctionTableA = { SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION, EnumerateSecurityPackagesA, NULL, AcquireCredentialsHandleA, FreeCredentialsHandle, NULL, InitializeSecurityContextA, AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, ApplyControlToken, QueryContextAttributesA, ImpersonateSecurityContext, RevertSecurityContext, MakeSignature, VerifySignature, FreeContextBuffer, QuerySecurityPackageInfoA, SealMessage, UnsealMessage, NULL, /* GrantProxyA */ NULL, /* RevokeProxyA */ NULL, /* InvokeProxyA */ NULL, /* RenewProxyA */ QuerySecurityContextToken, SealMessage, UnsealMessage, SetContextAttributesA };
PSecurityFunctionTableW SEC_ENTRY InitSecurityInterfaceW( VOID ) { return(&SPFunctionTable); }
PSecurityFunctionTableA SEC_ENTRY InitSecurityInterfaceA( VOID ) { return(&SPFunctionTableA); }
SECURITY_STATUS SEC_ENTRY FreeContextBuffer( void SEC_FAR * pvContextBuffer ) { SPExternalFree( pvContextBuffer ); return(SEC_E_OK); }
SECURITY_STATUS SEC_ENTRY SecurityPackageControl( SEC_WCHAR SEC_FAR * pszPackageName, unsigned long dwFunctionCode, unsigned long cbInputBuffer, unsigned char SEC_FAR * pbInputBuffer, unsigned long SEC_FAR * pcbOutputBuffer, unsigned char SEC_FAR * pbOutputBuffer) { return(SEC_E_UNSUPPORTED_FUNCTION); }
SECURITY_STATUS PctTranslateError(SP_STATUS spRet) { if(HRESULT_FACILITY(spRet) == FACILITY_SECURITY) { return (spRet); }
switch(spRet) { case PCT_ERR_OK: return SEC_E_OK; case PCT_ERR_BAD_CERTIFICATE: return SEC_E_INVALID_TOKEN; case PCT_ERR_CLIENT_AUTH_FAILED: return SEC_E_INVALID_TOKEN; case PCT_ERR_ILLEGAL_MESSAGE: return SEC_E_INVALID_TOKEN; case PCT_ERR_INTEGRITY_CHECK_FAILED: return SEC_E_MESSAGE_ALTERED; case PCT_ERR_SERVER_AUTH_FAILED: return SEC_E_INVALID_TOKEN; case PCT_ERR_SPECS_MISMATCH: return SEC_E_ALGORITHM_MISMATCH; case PCT_ERR_SSL_STYLE_MSG: return SEC_E_INVALID_TOKEN; case SEC_I_INCOMPLETE_CREDENTIALS: return SEC_I_INCOMPLETE_CREDENTIALS; case PCT_ERR_RENEGOTIATE: return SEC_I_RENEGOTIATE; case PCT_ERR_UNKNOWN_CREDENTIAL: return SEC_E_UNKNOWN_CREDENTIALS;
case CERT_E_UNTRUSTEDROOT: return SEC_E_UNTRUSTED_ROOT; case CERT_E_EXPIRED: return SEC_E_CERT_EXPIRED; case CERT_E_VALIDITYPERIODNESTING: return SEC_E_CERT_EXPIRED; case CERT_E_REVOKED: return CRYPT_E_REVOKED; case CERT_E_CN_NO_MATCH: return SEC_E_WRONG_PRINCIPAL;
case PCT_INT_BAD_CERT: return SEC_E_INVALID_TOKEN; case PCT_INT_CLI_AUTH: return SEC_E_INVALID_TOKEN; case PCT_INT_ILLEGAL_MSG: return SEC_E_INVALID_TOKEN; case PCT_INT_SPECS_MISMATCH: return SEC_E_ALGORITHM_MISMATCH; case PCT_INT_INCOMPLETE_MSG: return SEC_E_INCOMPLETE_MESSAGE; case PCT_INT_MSG_ALTERED: return SEC_E_MESSAGE_ALTERED; case PCT_INT_INTERNAL_ERROR: return SEC_E_INTERNAL_ERROR; case PCT_INT_DATA_OVERFLOW: return SEC_E_INTERNAL_ERROR; case SEC_E_INCOMPLETE_CREDENTIALS: return SEC_E_INCOMPLETE_CREDENTIALS; case PCT_INT_RENEGOTIATE: return SEC_I_RENEGOTIATE; case PCT_INT_UNKNOWN_CREDENTIAL: return SEC_E_UNKNOWN_CREDENTIALS;
case PCT_INT_BUFF_TOO_SMALL: return SEC_E_BUFFER_TOO_SMALL; case SEC_E_BUFFER_TOO_SMALL: return SEC_E_BUFFER_TOO_SMALL;
default: return SEC_E_INTERNAL_ERROR; } }
//+---------------------------------------------------------------------------
//
// Function: SslGenerateRandomBits
//
// Synopsis: Hook for setup to get a good random stream
//
// Arguments: [pRandomData] --
// [cRandomData] --
//
//
// Notes:
//
//----------------------------------------------------------------------------
VOID WINAPI SslGenerateRandomBits( PUCHAR pRandomData, LONG cRandomData ) { if(!SchannelInit(TRUE)) { return; }
GenerateRandomBits(pRandomData, (ULONG)cRandomData); }
//+---------------------------------------------------------------------------
//
// Function: SslGenerateKeyPair
//
// Synopsis: Generates a public/private key pair, protected by password
//
// Arguments: [pCerts] --
// [pszDN] --
// [pszPassword] --
// [Bits] --
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL WINAPI SslGenerateKeyPair( PSSL_CREDENTIAL_CERTIFICATE pCerts, PSTR pszDN, PSTR pszPassword, DWORD Bits ) { if(!SchannelInit(TRUE)) { return FALSE; }
#ifdef SCHANNEL_EXPORT
if ( Bits > 1024 ) { SetLastError( ERROR_INVALID_PARAMETER ); return( FALSE ); } #endif
return GenerateKeyPair(pCerts, pszDN, pszPassword, Bits); }
//+---------------------------------------------------------------------------
//
// Function: SslGetMaximumKeySize
//
// Synopsis: Returns maximum public key size
//
// Arguments: [Reserved] --
//
// Notes:
//
//----------------------------------------------------------------------------
DWORD WINAPI SslGetMaximumKeySize( DWORD Reserved ) {
#ifdef SCHANNEL_EXPORT
return( 1024 ); #else
return( 2048 ); #endif
}
//+---------------------------------------------------------------------------
//
// Function: SslFreeCertificate
//
// Synopsis: Frees a certificate created from SslCrackCertificate
//
// Arguments: [pCertificate] --
//
// Notes:
//
//----------------------------------------------------------------------------
VOID WINAPI SslFreeCertificate( PX509Certificate pCertificate) { if ( pCertificate ) {
SPExternalFree(pCertificate->pPublicKey); SPExternalFree(pCertificate); } }
//+---------------------------------------------------------------------------
//
// Function: SslCrackCertificate
//
// Synopsis: Cracks a X509 certificate into remotely easy format
//
// Arguments: [pbCertificate] --
// [cbCertificate] --
// [dwFlags] --
// [ppCertificate] --
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL WINAPI SslCrackCertificate( PUCHAR pbCertificate, DWORD cbCertificate, DWORD dwFlags, PX509Certificate * ppCertificate) {
PX509Certificate pResult = NULL; PCCERT_CONTEXT pContext = NULL; DWORD cbIssuer; DWORD cbSubject;
if(!SchannelInit(TRUE)) { return FALSE; }
if (dwFlags & CF_CERT_FROM_FILE) { if (cbCertificate < CERT_HEADER_LEN + 1 ) { goto error; }
//
// Sleazy quick check. Some CAs wrap certs in a cert wrapper.
// Some don't. Some do both, but we won't mention any names.
// Quick check for the wrapper tag. If so, scoot in by enough
// to bypass it (17 bytes. Sheesh).
//
if ( memcmp( pbCertificate + 4, CertTag, sizeof( CertTag ) ) == 0 ) { pbCertificate += CERT_HEADER_LEN; cbCertificate -= CERT_HEADER_LEN; } }
pContext = CertCreateCertificateContext(X509_ASN_ENCODING, pbCertificate, cbCertificate); if(pContext == NULL) { SP_LOG_RESULT(GetLastError()); goto error; }
if(0 >= (cbSubject = CertNameToStrA(pContext->dwCertEncodingType, &pContext->pCertInfo->Subject, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, NULL, 0))) { SP_LOG_RESULT(GetLastError()); goto error; }
if(0 >= (cbIssuer = CertNameToStrA(pContext->dwCertEncodingType, &pContext->pCertInfo->Issuer, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, NULL, 0))) { SP_LOG_RESULT(GetLastError()); goto error; }
pResult = SPExternalAlloc(sizeof(X509Certificate) + cbIssuer + cbSubject + 2); if(pResult == NULL) { goto error; } pResult->pPublicKey = NULL; pResult->pszIssuer = (PUCHAR)(pResult + 1); pResult->pszSubject = pResult->pszIssuer + cbIssuer;
pResult->Version = pContext->pCertInfo->dwVersion; memcpy(pResult->SerialNumber, pContext->pCertInfo->SerialNumber.pbData, min(sizeof(pResult->SerialNumber), pContext->pCertInfo->SerialNumber.cbData)); pResult->ValidFrom = pContext->pCertInfo->NotBefore; pResult->ValidUntil = pContext->pCertInfo->NotAfter;
if(0 >= CertNameToStrA(pContext->dwCertEncodingType, &pContext->pCertInfo->Issuer, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, pResult->pszIssuer, cbIssuer)) { SP_LOG_RESULT(GetLastError()); goto error; }
if(0 >= CertNameToStrA(pContext->dwCertEncodingType, &pContext->pCertInfo->Subject, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, pResult->pszSubject, cbSubject)) { SP_LOG_RESULT(GetLastError()); goto error; }
{ BSAFE_PUB_KEY *pk; PUBLICKEY * pPubKey = NULL; SP_STATUS pctRet; DWORD cbPublicKey;
pResult->pPublicKey = SPExternalAlloc(sizeof(PctPublicKey) + sizeof(BSAFE_PUB_KEY)); if(pResult->pPublicKey == NULL) { goto error; } pResult->pPublicKey->Type = 0; pResult->pPublicKey->cbKey = sizeof(BSAFE_PUB_KEY);
pk = (BSAFE_PUB_KEY *)pResult->pPublicKey->pKey; pk->magic = RSA1;
pctRet = SPPublicKeyFromCert(pContext, &pPubKey, NULL);
if(pctRet == PCT_ERR_OK) { if(pPubKey->pPublic->aiKeyAlg == CALG_RSA_KEYX) { RSAPUBKEY *pRsaKey = (RSAPUBKEY *)(pPubKey->pPublic + 1); pk->keylen = pRsaKey->bitlen/8; pk->bitlen = pRsaKey->bitlen; pk->datalen = pk->bitlen/8 - 1; pk->pubexp = pRsaKey->pubexp; } else { DHPUBKEY *pDHKey = (DHPUBKEY *)(pPubKey->pPublic + 1); pk->keylen = pDHKey->bitlen/8; pk->bitlen = pDHKey->bitlen/8; pk->datalen = pk->bitlen/8 - 1; pk->pubexp = 0;
} SPExternalFree(pPubKey); } else { goto error; }
} CertFreeCertificateContext(pContext);
*ppCertificate = pResult; return TRUE;
error: if(pContext) { CertFreeCertificateContext(pContext); } if(pResult) { if(pResult->pPublicKey) { SPExternalFree(pResult->pPublicKey); } SPExternalFree(pResult); } return FALSE; }
//+---------------------------------------------------------------------------
//
// Function: SslLoadCertificate
//
// Synopsis: Not supported.
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL WINAPI SslLoadCertificate( PUCHAR pbCertificate, DWORD cbCertificate, BOOL AddToWellKnownKeys) { return FALSE; }
BOOL SslGetClientProcess(ULONG *pProcessID) { SECPKG_CALL_INFO CallInfo; SECURITY_STATUS Status;
if(LsaTable == NULL) { *pProcessID = GetCurrentProcessId(); return TRUE; }
if(LsaTable->GetCallInfo(&CallInfo)) { *pProcessID = CallInfo.ProcessId; return TRUE; } else { *pProcessID = -1; return FALSE; } }
BOOL SslGetClientThread(ULONG *pThreadID) { SECPKG_CALL_INFO CallInfo; SECURITY_STATUS Status;
if(LsaTable == NULL) { *pThreadID = GetCurrentThreadId(); return TRUE; }
if(LsaTable->GetCallInfo(&CallInfo)) { *pThreadID = CallInfo.ThreadId; return TRUE; } else { *pThreadID = -1; return FALSE; } }
BOOL SslImpersonateClient(void) { SECPKG_CALL_INFO CallInfo; SECURITY_STATUS Status;
// Don't impersonate if we're in the client process.
if(LsaTable == NULL) { return FALSE; }
// Don't impersonate if the client is running in the lsass process.
if(LsaTable->GetCallInfo(&CallInfo)) { if(CallInfo.ProcessId == GetCurrentProcessId()) { // DebugLog((DEB_WARN, "Running locally, so don't impersonate.\n"));
return FALSE; } }
Status = LsaTable->ImpersonateClient(); if(!NT_SUCCESS(Status)) { SP_LOG_RESULT(Status); return FALSE; }
return TRUE; }
NTSTATUS SslGetClientLogonId(LUID *pLogonId) { SECPKG_CLIENT_INFO ClientInfo; SECURITY_STATUS Status;
memset(pLogonId, 0, sizeof(LUID));
Status = LsaTable->GetClientInfo(&ClientInfo); if(NT_SUCCESS(Status)) { *pLogonId = ClientInfo.LogonId; }
return Status; }
PVOID SPExternalAlloc(DWORD cbLength) { if(LsaTable) { // Lsass process
return LsaTable->AllocateLsaHeap(cbLength); } else { // Application process
return LocalAlloc(LPTR, cbLength); } }
VOID SPExternalFree(PVOID pMemory) { if(LsaTable) { // Lsass process
LsaTable->FreeLsaHeap(pMemory); } else { // Application process
LocalFree(pMemory); } }
|