Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 如何在智能卡凭据提供程序中序列化域帐户的凭据以进行登录和解锁?_Windows_Visual C++_Smartcard_Credential Providers_Local Security Authority - Fatal编程技术网

Windows 如何在智能卡凭据提供程序中序列化域帐户的凭据以进行登录和解锁?

Windows 如何在智能卡凭据提供程序中序列化域帐户的凭据以进行登录和解锁?,windows,visual-c++,smartcard,credential-providers,local-security-authority,Windows,Visual C++,Smartcard,Credential Providers,Local Security Authority,我正在构建一个与windows智能卡凭据提供程序相同的凭据提供程序,即它仅适用于域帐户。将凭据传递给协商SSP时,我遇到了一个问题,我使用microsoft base智能卡加密提供商作为CSP。输入pin后,我在锁屏上看到参数不正确错误 GetSerialization HRESULT CCredential::GetSerialization( CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr, CREDENTIAL_

我正在构建一个与windows智能卡凭据提供程序相同的凭据提供程序,即它仅适用于域帐户。将凭据传递给
协商SSP
时,我遇到了一个问题,我使用microsoft base智能卡加密提供商作为CSP。输入pin后,我在锁屏上看到
参数不正确
错误

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, _cpus, &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;
}

解锁LOGONINIT

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;
}
解锁logonpack

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, (PWSTR)pbBuffer, &pkilOut->UserName);
        pkilOut->UserName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkiulOut);
        pbBuffer += pkilOut->UserName.Length;

        _UnicodeStringPackedUnicodeStringCopy(pkilIn->Pin, (PWSTR)pbBuffer, &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,pCspInfo->dwCspInfoLen);

        *prgb = (BYTE*)pkiulOut;
        *pcb = cb;

        hr = S_OK;
    }
    else
    {
        hr = E_OUTOFMEMORY;
    }

    return hr;
}

\u KERB\u智能卡\u CSP\u信息结构和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,0,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,0,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;
}
我不明白我做错了什么,被困在这里有一段时间了。任何帮助都将不胜感激