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.
 
 
 
 
 
 

1034 lines
26 KiB

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
digesta.cxx
Abstract:
sspi ansi interface for digest package.
Author:
Adriaan Canter (adriaanc) 01-Aug-1998
--*/
#include "include.hxx"
static SecurityFunctionTableA
SecTableA =
{
SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
EnumerateSecurityPackagesA,
NULL, // QueryCredentialsAttributesA
AcquireCredentialsHandleA,
FreeCredentialsHandle,
NULL, // SspiLogonUserA
InitializeSecurityContextA,
AcceptSecurityContext,
CompleteAuthToken,
DeleteSecurityContext,
ApplyControlToken,
QueryContextAttributesA,
ImpersonateSecurityContext,
RevertSecurityContext,
MakeSignature,
VerifySignature,
FreeContextBuffer,
QuerySecurityPackageInfoA,
NULL, // Reserved3
NULL, // Reserved4
NULL, // ExportSecurityContext
NULL, // ImportSecurityContextA
NULL, // Reserved7
NULL, // Reserved8
NULL, // QuerySecurityContextToken
NULL, // EncryptMessage
NULL // DecryptMessage
};
//--------------------------------------------------------------------------
//
// Function: InitSecurityInterfaceA
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" PSecurityFunctionTableA SEC_ENTRY
InitSecurityInterfaceA(VOID)
{
PSecurityFunctionTableA pSecTableA = &SecTableA;
return pSecTableA;
}
//--------------------------------------------------------------------------
//
// Function: AcquireCredentialsHandleA
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
// HEINOUS SSPI HACK here: AcquireCredentialsHandle is called with the package
// name ("Digest") as the package identifier. When AcquireCredentialsHandle returns
// to the caller PCredHandle->dwLower is set by security.dll to be the index of
// the package returned. EnumerateSecurityPackages. This is how SSPI resolves the
// correct provider dll when subsequent calls are made through the dispatch table
// (PSecurityFunctionTale). Any credential *or* context handle handed out by the
// package must have the dwLower member set to this index so that subsequent calls
// can resolve the dll from the handle.
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
AcquireCredentialsHandleA(
LPSTR pszPrincipal, // Name of principal
LPSTR pszPackageName, // Name of package
DWORD dwCredentialUse, // Flags indicating use
VOID SEC_FAR * pvLogonId, // Pointer to logon ID
VOID SEC_FAR * pAuthData, // Package specific data
SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func
VOID SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey()
PCredHandle phCredential, // (out) Cred Handle
PTimeStamp ptsExpiry // (out) Lifetime (optional)
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
SECURITY_STATUS ssResult;
// Outbound credentials only.
if (!(dwCredentialUse & SECPKG_CRED_OUTBOUND)
|| (dwCredentialUse & SECPKG_CRED_INBOUND))
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_UNKNOWN_CREDENTIALS;
goto exit;
}
// Logon to cache.
// Logon to the cache and get the session context.
CSess *pSess;
PSEC_WINNT_AUTH_IDENTITY_EXA pSecIdExA;
PSEC_WINNT_AUTH_IDENTITY pSecId;
// HTTP clients will pass in this structure.
pSecIdExA = (PSEC_WINNT_AUTH_IDENTITY_EXA) pAuthData;
// Non-HTTP clients (OE4, OE5) will pass in this structure.
pSecId = (PSEC_WINNT_AUTH_IDENTITY) pAuthData;
// Check for HTTP client application logon.
if (pAuthData
&& (pSecIdExA->Version == sizeof(SEC_WINNT_AUTH_IDENTITY_EXA))
&& pSecIdExA->User
&& pSecIdExA->UserLength == sizeof(DIGEST_PKG_DATA))
{
DIGEST_PKG_DATA *pPkgData;
pPkgData = (DIGEST_PKG_DATA*) pSecIdExA->User;
pSess = g_pCache->LogOnToCache(pPkgData->szAppCtx,
pPkgData->szUserCtx, TRUE);
}
// Check for non-HTTP client application logon.
else
{
// Find or create the single non-HTTP session.
pSess = g_pCache->LogOnToCache(NULL, NULL, FALSE);
// If user+pass+realm (domain) is passed in, create and
// attach a matching credential to this session.
if (pAuthData
&& pSecId->User
&& pSecId->UserLength
&& pSecId->Domain
&& pSecId->DomainLength
&& pSecId->Password
&& pSecId->PasswordLength)
{
// Create a credential with the information passed in.
CCred *pCred;
CCredInfo *pInfo;
pInfo = new CCredInfo(NULL, (LPSTR) pSecId->Domain,
(LPSTR) pSecId->User, (LPSTR) pSecId->Password, NULL, NULL);
if (pInfo)
{
pCred = g_pCache->CreateCred(pSess, pInfo);
delete pInfo;
}
}
}
// BUGBUG - return better error codes.
if (!pSess)
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_INTERNAL_ERROR;
goto exit;
}
// Hand out the session handle.
phCredential->dwUpper = g_pCache->MapSessionToHandle(pSess);
// ***** phCredential->dwLower will be set by security.dll *****
ssResult = SEC_E_OK;
exit:
return ssResult;
}
//--------------------------------------------------------------------------
//
// Function: FreeCredentialsHandle
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
FreeCredentialsHandle(PCredHandle phCredential)
{
// bugbug - asserted.
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
SECURITY_STATUS ssResult;
// Get the session context from the handle.
CSess *pSess;
pSess = g_pCache->MapHandleToSession(phCredential->dwUpper);
if (!pSess)
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_UNKNOWN_CREDENTIALS;
goto exit;
}
// Logoff from the cache.
if (g_pCache->LogOffFromCache(pSess) != ERROR_SUCCESS)
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_INTERNAL_ERROR;
goto exit;
}
ssResult = SEC_E_OK;
exit:
return ssResult;
}
//--------------------------------------------------------------------------
//
// Function: InitializeSecurityContextA
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
InitializeSecurityContextA(
PCredHandle phCredential, // Cred to base context
PCtxtHandle phContext, // Existing context (OPT)
LPSTR pszTargetName, // Name of target
DWORD fContextReq, // Context Requirements
DWORD Reserved1, // Reserved, MBZ
DWORD TargetDataRep, // Data rep of target
PSecBufferDesc pInput, // Input Buffers
DWORD Reserved2, // Reserved, MBZ
PCtxtHandle phNewContext, // (out) New Context handle
PSecBufferDesc pOutput, // (inout) Output Buffers
DWORD SEC_FAR * pfContextAttr, // (out) Context attrs
PTimeStamp ptsExpiry // (out) Life span (OPT)
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
LPSTR szHost, szRealm, szUser, szPass, szNonce;
DWORD cbHost, cbRealm, cbUser, cbPass, cbNonce;
LPSTR szCtx = NULL;
SECURITY_STATUS ssResult = SEC_E_OK;
// Client nonce NULL except for md5-sess.
LPSTR szCNonce = NULL;
CSess *pSess;
CCred *pCred;
CParams *pParams = NULL;
CCredInfo *pInfo = NULL;
// Rude credential flush for all apps.
if (!phCredential && (fContextReq & ISC_REQ_NULL_SESSION))
{
g_pCache->FlushCreds(NULL, NULL);
ssResult = SEC_E_OK;
goto exit;
}
// Get the session pointer from the handle.
pSess = g_pCache->MapHandleToSession(phCredential->dwUpper);
if (!pSess)
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_UNKNOWN_CREDENTIALS;
goto exit;
}
// Legacy conn. oriented client may require a continue
// message on null buffer input.
if (!pSess->fHTTP && !pInput && pOutput)
{
*((LPDWORD) (pOutput->pBuffers[0].pvBuffer)) = 0;
pOutput->pBuffers[0].cbBuffer = sizeof(DWORD);
ssResult = SEC_I_CONTINUE_NEEDED;
goto exit;
}
// Flush creds for indicated session.
if (fContextReq & ISC_REQ_NULL_SESSION)
{
g_pCache->FlushCreds(pSess, NULL);
ssResult = SEC_E_OK;
goto exit;
}
DIGEST_ASSERT(phCredential && pInput && pOutput);
// Parse the challenge to a params object.
if (CDigest::ParseChallenge(pSess, pInput,
&pParams, fContextReq) != ERROR_SUCCESS)
{
// DIGEST_ASSERT(FALSE);
ssResult = SEC_E_INVALID_TOKEN;
goto exit;
}
// Get host, realm (required) and any nonce, user & pass.
pParams->GetParam(CParams::HOST, &szHost, &cbHost);
pParams->GetParam(CParams::REALM, &szRealm, &cbRealm);
pParams->GetParam(CParams::NONCE, &szNonce, &cbNonce);
pParams->GetParam(CParams::USER, &szUser, &cbUser);
pParams->GetParam(CParams::PASS, &szPass, &cbPass);
// If prompting UI is indicated.
if (fContextReq & ISC_REQ_PROMPT_FOR_CREDS)
{
CCredInfo *pInfoIn, *pInfoOut;
// Attempt to get one or more cred infos
pInfoIn = g_pCache->FindCred(pSess, szHost, szRealm,
szUser, NULL, NULL, FIND_CRED_UI);
// Get the persistence key from pSess
szCtx = CSess::GetCtx(pSess);
DIGEST_ASSERT(szCtx);
// If this is prompting for UI specifying md5-sess,
// create a client nonce to associate with cred.
if (pParams->IsMd5Sess())
szCNonce = CDigest::MakeCNonce();
pParams->GetParam(CParams::HOST, &szHost, &cbHost);
// Prompt with authentication dialog.
if (DigestErrorDlg(szCtx, szHost, szRealm,
szUser, szNonce, szCNonce,
pInfoIn, &pInfoOut, pParams->GetHwnd()) == ERROR_SUCCESS)
{
DIGEST_ASSERT(pInfoOut);
// Create the credential.
pCred = g_pCache->CreateCred(pSess, pInfoOut);
// Record that the host is trusted.
if (pSess->fHTTP)
CCredCache::SetTrustedHostInfo(szCtx, pParams);
}
else
{
ssResult = SEC_E_NO_CREDENTIALS;
goto exit;
}
// Retrieve the credentials just created.
pInfo = g_pCache->FindCred(pSess, szHost, szRealm,
pInfoOut->szUser, szNonce, szCNonce, FIND_CRED_AUTH);
// Clean up one or more cred infos.
// BUGBUG - null out pointers after freeing.
while (pInfoIn)
{
CCredInfo *pNext;
pNext = pInfoIn->pNext;
delete pInfoIn;
pInfoIn = pNext;
}
if (pInfoOut)
delete pInfoOut;
if (szCNonce)
delete szCNonce;
if (!pInfo)
{
ssResult = SEC_E_NO_CREDENTIALS;
goto exit;
}
}
// Otherwise we are attempting to authenticate. We may be either
// authenticating in response to a challenge or pre-authenticating.
else
{
// Get the persistence key from pSess
szCtx = CSess::GetCtx(pSess);
DIGEST_ASSERT(szCtx);
// For HTTP sessions we check the trusted host list unless
// 1) credentials are supplied, or 2) a context has been passed
// in which specifically instructs to ignore the host list.
if (pSess->fHTTP && !pParams->IsPreAuth() && !pParams->AreCredsSupplied())
{
if (!phContext || !(phContext->dwUpper & DIGEST_PKG_FLAGS_IGNORE_TRUSTED_HOST_LIST))
{
if (!CCredCache::IsTrustedHost(szCtx, szHost))
{
ssResult = SEC_E_NO_CREDENTIALS;
goto exit;
}
}
}
// If preauthenticating.
if (pParams->IsPreAuth())
{
// If using supplied credentials.
if (pParams->AreCredsSupplied())
{
// Create a cred info using supplied values. Include passed-in NC.
pInfo = new CCredInfo(szHost, szRealm, szUser, szPass, szNonce, szCNonce);
pInfo->cCount = pParams->GetNC();
if (!(pInfo && pInfo->dwStatus == ERROR_SUCCESS))
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_INTERNAL_ERROR;
goto exit;
}
}
// Otherwise attempt to find cred info in cache.
else
{
// Attempt to find the credentials from realm and any user.
pInfo = g_pCache->FindCred(pSess, szHost, szRealm,
szUser, NULL, NULL, FIND_CRED_PREAUTH);
}
// Return if no credentials exist.
if (!pInfo)
{
ssResult = SEC_E_NO_CREDENTIALS;
goto exit;
}
}
// Otherwise auth in response to challenge.
else
{
// Check if logoff is requested.
CHAR* szLogoff;
szLogoff = pParams->GetParam(CParams::LOGOFF);
if (szLogoff && !lstrcmpi(szLogoff, "TRUE"))
{
g_pCache->FlushCreds(NULL, szRealm);
ssResult = SEC_E_CONTEXT_EXPIRED;
goto exit;
}
// If a context is passed in examine the stale header unless specifically
// directed not to.
if (pSess->fHTTP
&& phContext
&& !pParams->AreCredsSupplied()
&& !(phContext->dwUpper & DIGEST_PKG_FLAGS_IGNORE_STALE_HEADER))
{
CHAR* szStale;
DWORD cbStale;
pParams->GetParam(CParams::STALE, &szStale, &cbStale);
if (!szStale || !lstrcmpi(szStale, "FALSE"))
{
ssResult = SEC_E_NO_CREDENTIALS;
goto exit;
}
}
// If this is authenticating specifying md5-sess,
// create a client nonce to associate with cred.
if (pParams->IsMd5Sess())
szCNonce = CDigest::MakeCNonce();
// If credentials are supplied, create an entry in
// the credential cache. We search as usual subsequently.
if (pParams->AreCredsSupplied())
{
// Create a cred info using supplied values.
pInfo = new CCredInfo(szHost, szRealm, szUser, szPass, szNonce, szCNonce);
if (!(pInfo && pInfo->dwStatus == ERROR_SUCCESS))
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_INTERNAL_ERROR;
goto exit;
}
pCred = g_pCache->CreateCred(pSess, pInfo);
delete pInfo;
}
// Attempt to find the credentials from realm and any user.
pInfo = g_pCache->FindCred(pSess, szHost, szRealm,
szUser, szNonce, szCNonce, FIND_CRED_AUTH);
// Return if no credentials exist.
if (!pInfo)
{
ssResult = SEC_E_NO_CREDENTIALS;
goto exit;
}
}
}
// We should now have the appropriate cred info. Generate the response.
DIGEST_ASSERT(pInfo);
if (CDigest::GenerateResponse(pSess, pParams,
pInfo, pOutput) != ERROR_SUCCESS)
{
DIGEST_ASSERT(FALSE);
ssResult = SEC_E_INTERNAL_ERROR;
goto exit;
}
// Delete cred info if allocated.
// bugbug - move further down.
if (pInfo)
delete pInfo;
ssResult = SEC_E_OK;
exit:
if ((ssResult != SEC_E_OK) &&
(ssResult != SEC_I_CONTINUE_NEEDED))
pOutput->pBuffers[0].cbBuffer = 0;
// BUGBUG - delete pInfo if not NULL.
// Delete persistence key if allocated.
if (szCtx)
delete szCtx;
// Identify the new context.
if (phNewContext && phCredential)
phNewContext->dwLower = phCredential->dwLower;
// Delete the params object.
if (pParams)
delete pParams;
return ssResult;
}
//--------------------------------------------------------------------------
//
// Function: AcceptSecurityContext
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
AcceptSecurityContext(
PCredHandle phCredential, // Cred to base context
PCtxtHandle phContext, // Existing context (OPT)
PSecBufferDesc pInput, // Input buffer
unsigned long fContextReq, // Context Requirements
unsigned long TargetDataRep, // Target Data Rep
PCtxtHandle phNewContext, // (out) New context handle
PSecBufferDesc pOutput, // (inout) Output buffers
unsigned long SEC_FAR * pfContextAttr, // (out) Context attributes
PTimeStamp ptsExpiry // (out) Life span (OPT)
)
{
// BUGBUG - don't need initglobals.
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return(SEC_E_UNSUPPORTED_FUNCTION);
}
//--------------------------------------------------------------------------
//
// Function: DeleteSecurityContext
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
DeleteSecurityContext(
PCtxtHandle phContext // Context to delete
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}
//--------------------------------------------------------------------------
//
// Function: ApplyControlToken
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
ApplyControlToken(
PCtxtHandle phContext, // Context to modify
PSecBufferDesc pInput // Input token to apply
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
SECURITY_STATUS ssResult;
// Current flags used are
// DIGEST_PKG_FLAG_IGNORE_TRUSTED_HOST_LIST
// DIGEST_PKG_FLAG_IGNORE_STALE_HEADER
phContext->dwUpper |= *((LPDWORD) (pInput->pBuffers[0].pvBuffer));
ssResult = SEC_E_OK;
return ssResult;
}
//--------------------------------------------------------------------------
//
// Function: EnumerateSecurityPackagesA
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
SECURITY_STATUS SEC_ENTRY
EnumerateSecurityPackagesA(DWORD SEC_FAR *pcPackages,
PSecPkgInfoA SEC_FAR *ppSecPkgInfo)
{
SECURITY_STATUS ssResult;
// BUGBUG - ALLOW ASSERTS?
ssResult = QuerySecurityPackageInfoA(PACKAGE_NAME, ppSecPkgInfo);
if (ssResult == SEC_E_OK)
{
*pcPackages = 1;
}
return ssResult;
}
//--------------------------------------------------------------------------
//
// Function: QuerySecurityPackageInfoA
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
SECURITY_STATUS SEC_ENTRY
QuerySecurityPackageInfoA(LPSTR szPackageName,
PSecPkgInfoA SEC_FAR *ppSecPkgInfo)
{
// BUGBUG - ALLOW ASSERTS?
PSecPkgInfoA pSecPkgInfo;
DWORD cbSecPkgInfo;
SECURITY_STATUS ssResult;
LPSTR pCur;
if (strcmp(szPackageName, PACKAGE_NAME))
{
ssResult = SEC_E_SECPKG_NOT_FOUND;
goto exit;
}
cbSecPkgInfo = sizeof(SecPkgInfoA)
+ sizeof(PACKAGE_NAME)
+ sizeof(PACKAGE_COMMENT);
pSecPkgInfo = (PSecPkgInfoA) LocalAlloc(0,cbSecPkgInfo);
if (!pSecPkgInfo)
{
ssResult = SEC_E_INSUFFICIENT_MEMORY;
goto exit;
}
pSecPkgInfo->fCapabilities = PACKAGE_CAPABILITIES;
pSecPkgInfo->wVersion = PACKAGE_VERSION;
pSecPkgInfo->wRPCID = PACKAGE_RPCID;
pSecPkgInfo->cbMaxToken = PACKAGE_MAXTOKEN;
pCur = (LPSTR) (pSecPkgInfo) + sizeof(SecPkgInfoA);
pSecPkgInfo->Name = pCur;
memcpy(pSecPkgInfo->Name, PACKAGE_NAME, sizeof(PACKAGE_NAME));
pCur += sizeof(PACKAGE_NAME);
pSecPkgInfo->Comment = pCur;
memcpy(pSecPkgInfo->Comment, PACKAGE_COMMENT, sizeof(PACKAGE_COMMENT));
*ppSecPkgInfo = pSecPkgInfo;
ssResult = SEC_E_OK;
exit:
return ssResult;
}
//--------------------------------------------------------------------------
//
// Function: FreeContextBuffer
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
FreeContextBuffer(void SEC_FAR *pvContextBuffer)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
LocalFree(pvContextBuffer);
return SEC_E_OK;
}
//--------------------------------------------------------------------------
//
// Function: CompleteAuthToken
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
CompleteAuthToken(
PCtxtHandle phContext, // Context to complete
PSecBufferDesc pToken // Token to complete
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}
//--------------------------------------------------------------------------
//
// Function: ImpersonateSecurityContext
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
ImpersonateSecurityContext(
PCtxtHandle phContext // Context to impersonate
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}
//--------------------------------------------------------------------------
//
// Function: RevertSecurityContext
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
RevertSecurityContext(
PCtxtHandle phContext // Context from which to re
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}
//--------------------------------------------------------------------------
//
// Function: QueryContextAttributesA
//
// Synopsis:
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
QueryContextAttributesA(
PCtxtHandle phContext, // Context to query
unsigned long ulAttribute, // Attribute to query
void SEC_FAR * pBuffer // Buffer for attributes
)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}
//--------------------------------------------------------------------------
//
// Function: MakeSignature
//
// Synopsis:
//
// Effects:
//
// Arguments: [phContext] -- context to use
// [fQOP] -- quality of protection to use
// [pMessage] -- message
// [MessageSeqNo] -- sequence number of message
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
MakeSignature( PCtxtHandle phContext,
ULONG fQOP,
PSecBufferDesc pMessage,
ULONG MessageSeqNo)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}
//--------------------------------------------------------------------------
//
// Function: VerifySignature
//
// Synopsis:
//
// Effects:
//
// Arguments: [phContext] -- Context performing the unseal
// [pMessage] -- Message to verify
// [MessageSeqNo] -- Sequence number of this message
// [pfQOPUsed] -- quality of protection used
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
extern "C" SECURITY_STATUS SEC_ENTRY
VerifySignature(PCtxtHandle phContext,
PSecBufferDesc pMessage,
ULONG MessageSeqNo,
ULONG * pfQOP)
{
if (!InitGlobals())
return SEC_E_INTERNAL_ERROR;
return SEC_E_UNSUPPORTED_FUNCTION;
}