问题描述
我正在建立一个凭据提供程序,其工作方式与Windows智能卡凭据提供程序相同,即,仅适用于域帐户。将凭据传递到Negotiate ssp
时遇到问题,并且我使用Microsoft基本智能卡加密提供程序作为CSP。输入密码后,锁定屏幕上出现The parameter is incorrect
错误。
GetSerialization
HRESULT CCredential::GetSerialization(
CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr,CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs,PWSTR* ppwszOptionalStatusText,CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon
)
{
UNREFERENCED_ParaMETER(ppwszOptionalStatusText);
UNREFERENCED_ParaMETER(pcpsiOptionalStatusIcon);
HRESULT hr;
WCHAR dmz[244] = L"demodomain";
PWSTR pwzProtectedPin;
hr = ProtectIfNecessaryAndcopyPassword(_rgFieldStrings[SFI_PIN],_cpus,_dwFlags,&pwzProtectedPin);
if (SUCCEEDED(hr))
{
KERB_CERTIFICATE_UNLOCK_logoN kiul;
// Initialize kiul with weak references to our credential.
hr = UnlocklogonInit(dmz,_rgFieldStrings[SFI_USERNAME],pwzProtectedPin,&kiul);
if (SUCCEEDED(hr))
{
PBASE_SMARTCARD_CSP_INFO pCspInfo = _pContainer->GetCSPInfo();
if (pCspInfo)
{
CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcp;
hr = UnlocklogonPack(kiul,pCspInfo,&pcpcs->rgbSerialization,&pcpcs->cbSerialization);
_pContainer->FreeCSPInfo(pCspInfo);
if (SUCCEEDED(hr))
{
ULONG ulAuthPackage;
hr = RetrieveNegotiateAuthPackage(&ulAuthPackage);
if (SUCCEEDED(hr))
{
pcpcs->ulAuthenticationPackage = ulAuthPackage;
pcpcs->clsidCredentialProvider = CLSID_CProvider;
// At this point the credential has created the serialized credential used for logon
// By setting this to CPGSR_RETURN_CREDENTIAL_FINISHED we are letting logonUI kNow
// that we have all the information we need and it should attempt to submit the
// serialized credential.
*pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING,L"RetrieveNegotiateAuthPackage not SUCCEEDED hr=0x%08x",hr);
}
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING,L"UnlocklogonPack not SUCCEEDED hr=0x%08x",hr);
}
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING,L"pCspInfo NULL");
}
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING,L"UnlocklogonInit not SUCCEEDED hr=0x%08x",hr);
}
CoTaskMemFree(pwzProtectedPin);
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING,L"ProtectIfNecessaryAndcopyPassword not SUCCEEDED hr=0x%08x",hr);
}
if (!SUCCEEDED(hr))
{
PrintLn(WINEVENT_LEVEL_WARNING,L"not SUCCEEDED hr=0x%08x",hr);
}
else
{
PrintLn(WINEVENT_LEVEL_WARNING,L"OK");
}
return hr;
}
UnlocklogonInit
HRESULT UnlocklogonInit(
PWSTR pwzDomain,PWSTR pwzUsername,PWSTR pwzPin,CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,KERB_CERTIFICATE_UNLOCK_logoN* pkiul
)
{
UNREFERENCED_ParaMETER(cpus);
KERB_CERTIFICATE_UNLOCK_logoN kiul;
ZeroMemory(&kiul,sizeof(kiul));
KERB_CERTIFICATE_logoN* pkil = &kiul.logon;
HRESULT hr = UnicodeStringInitWithString(pwzDomain,&pkil->logonDomainName);
if (SUCCEEDED(hr))
{
hr = UnicodeStringInitWithString(pwzUsername,&pkil->UserName);
if (SUCCEEDED(hr))
{
hr = UnicodeStringInitWithString(pwzPin,&pkil->Pin);
if (SUCCEEDED(hr))
{
// Set a MessageType based on the usage scenario.
pkil->MessageType = KerbCertificatelogon; //13
pkil->CspDataLength = 0;
pkil->CspData = NULL;
pkil->Flags = 0;
if (SUCCEEDED(hr))
{
// KERB_INteraCTIVE_UNLOCK_logoN is just a series of structures. A
// flat copy will properly initialize the output parameter.
copyMemory(pkiul,&kiul,sizeof(*pkiul));
}
}
}
}
return hr;
}
UnlocklogonPack
HRESULT UnlocklogonPack(
const KERB_CERTIFICATE_UNLOCK_logoN& rkiulIn,const PBASE_SMARTCARD_CSP_INFO pCspInfo,BYTE** prgb,DWORD* pcb
)
{
HRESULT hr;
const KERB_CERTIFICATE_logoN* pkilIn = &rkiulIn.logon;
// alloc space for struct plus extra for the three strings
DWORD cb = sizeof(rkiulIn) +
pkilIn->logonDomainName.Length +
pkilIn->UserName.Length +
pkilIn->Pin.Length +
pCspInfo->dwCspInfoLen;
KERB_CERTIFICATE_UNLOCK_logoN* pkiulOut = (KERB_CERTIFICATE_UNLOCK_logoN*)CoTaskMemAlloc(cb);
if (pkiulOut)
{
ZeroMemory(&pkiulOut->logonId,sizeof(LUID));
//
// point pbBuffer at the beginning of the extra space
//
BYTE* pbBuffer = (BYTE*)pkiulOut + sizeof(*pkiulOut);
KERB_CERTIFICATE_logoN* pkilOut = &pkiulOut->logon;
pkilOut->MessageType = pkilIn->MessageType;
pkilOut->Flags = pkilIn->Flags;
//
// copy each string,// fix up appropriate buffer pointer to be offset,// advance buffer pointer over copied characters in extra space
//
_UnicodeStringPackedUnicodeStringcopy(pkilIn->logonDomainName,(PWSTR)pbBuffer,&pkilOut->logonDomainName);
pkilOut->logonDomainName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
pbBuffer += pkilOut->logonDomainName.Length;
_UnicodeStringPackedUnicodeStringcopy(pkilIn->UserName,&pkilOut->UserName);
pkilOut->UserName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
pbBuffer += pkilOut->UserName.Length;
_UnicodeStringPackedUnicodeStringcopy(pkilIn->Pin,&pkilOut->Pin);
pkilOut->Pin.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
pbBuffer += pkilOut->Pin.Length;
pkilOut->CspData = (PUCHAR) (pbBuffer - (BYTE*)pkiulOut);
pkilOut->CspDataLength = pCspInfo->dwCspInfoLen;
memcpy(pbBuffer,pCspInfo->dwCspInfoLen);
*prgb = (BYTE*)pkiulOut;
*pcb = cb;
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
_KERB_SMARTCARD_CSP_INFO结构和GetCSPInfo
// based on _KERB_SMARTCARD_CSP_INFO
typedef struct _BASE_SMARTCARD_CSP_INFO
{
DWORD dwCspInfoLen;
DWORD MessageType;
union {
PVOID Contextinformation;
ULONG64 SpaceHolderForWow64;
} ;
DWORD flags;
DWORD KeySpec;
ULONG nCardNameOffset;
ULONG nReaderNameOffset;
ULONG nContainerNameOffset;
ULONG nCSPNameOffset;
TCHAR bBuffer[sizeof(DWORD)];
} BASE_SMARTCARD_CSP_INFO,*PBASE_SMARTCARD_CSP_INFO;
PBASE_SMARTCARD_CSP_INFO CContainer::GetCSPInfo()
{
//szreaderName,szCardname,szproviderName,szContainerName are initialized with respective values in constructor
_ASSERTE( _CrtCheckMemory( ) );
DWORD dwReaderLen = (DWORD) _tcslen(_szReaderName)+1;
DWORD dwCardLen = (DWORD) _tcslen(_szCardName)+1;
DWORD dwProviderLen = (DWORD) _tcslen(_szProviderName)+1;
DWORD dwContainerLen = (DWORD) _tcslen(_szContainerName)+1;
DWORD dwBufferSize = dwReaderLen + dwCardLen + dwProviderLen + dwContainerLen;
PBASE_SMARTCARD_CSP_INFO pCspInfo = (PBASE_SMARTCARD_CSP_INFO) BASEAlloc(sizeof(BASE_SMARTCARD_CSP_INFO)+dwBufferSize*sizeof(TCHAR));
if (!pCspInfo) return NULL;
//ZeroMemory(pCspInfo);
memset(pCspInfo,sizeof(BASE_SMARTCARD_CSP_INFO));
pCspInfo->dwCspInfoLen = sizeof(BASE_SMARTCARD_CSP_INFO)+dwBufferSize*sizeof(TCHAR);
pCspInfo->MessageType = 1;
pCspInfo->KeySpec = _KeySpec;
pCspInfo->nCardNameOffset = ARRAYSIZE(pCspInfo->bBuffer);
pCspInfo->nReaderNameOffset = pCspInfo->nCardNameOffset + dwCardLen;
pCspInfo->nContainerNameOffset = pCspInfo->nReaderNameOffset + dwReaderLen;
pCspInfo->nCSPNameOffset = pCspInfo->nContainerNameOffset + dwContainerLen;
memset(pCspInfo->bBuffer,sizeof(pCspInfo->bBuffer));
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nCardNameOffset],dwBufferSize + 4 - pCspInfo->nCardNameOffset,_szCardName);
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nReaderNameOffset],dwBufferSize + 4 - pCspInfo->nReaderNameOffset,_szReaderName);
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nContainerNameOffset],dwBufferSize + 4 - pCspInfo->nContainerNameOffset,_szContainerName);
_tcscpy_s(&pCspInfo->bBuffer[pCspInfo->nCSPNameOffset],dwBufferSize + 4 - pCspInfo->nCSPNameOffset,_szProviderName);
_ASSERTE( _CrtCheckMemory( ) );
return pCspInfo;
}
我不知道我在哪里做错了,现在被困在这里了一段时间。任何帮助将不胜感激。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)