/*
 * Copyright 2002 Mike McCormack for CodeWeavers
 * Copyright 2005 Juan Lang
 * Copyright 2006 Paul Vriens
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "winreg.h"
#include "winnls.h"
#include "mssip.h"
#include "winuser.h"

#include "wine/debug.h"
#include "wine/list.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

static const WCHAR szOID[] = {
    'S','o','f','t','w','a','r','e','\\',
    'M','i','c','r','o','s','o','f','t','\\',
    'C','r','y','p','t','o','g','r','a','p','h','y','\\',
    'O','I','D','\\',
    'E','n','c','o','d','i','n','g','T','y','p','e',' ','0','\\',
    'C','r','y','p','t','S','I','P','D','l','l', 0 };

static const WCHAR szPutSigned[] = {
    'P','u','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szGetSigned[] = {
    'G','e','t','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szRemoveSigned[] = {
    'R','e','m','o','v','e','S','i','g','n','e','d','D','a','t','a','M','s','g','\\',0};
static const WCHAR szCreate[] = {
    'C','r','e','a','t','e','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
static const WCHAR szVerify[] = {
    'V','e','r','i','f','y','I','n','d','i','r','e','c','t','D','a','t','a','\\',0};
static const WCHAR szIsMyFile[] = {
    'I','s','M','y','F','i','l','e','T','y','p','e','\\',0};
static const WCHAR szIsMyFile2[] = {
    'I','s','M','y','F','i','l','e','T','y','p','e','2','\\',0};

static const WCHAR szDllName[] = { 'D','l','l',0 };
static const WCHAR szFuncName[] = { 'F','u','n','c','N','a','m','e',0 };

/* convert a guid to a wide character string */
static void CRYPT_guid2wstr( const GUID *guid, LPWSTR wstr )
{
    char str[40];

    sprintf(str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
           guid->Data1, guid->Data2, guid->Data3,
           guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
           guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
    MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 );
}

/***********************************************************************
 *              CRYPT_SIPDeleteFunction
 *
 * Helper function for CryptSIPRemoveProvider
 */
static LONG CRYPT_SIPDeleteFunction( const GUID *guid, LPCWSTR szKey )
{
    WCHAR szFullKey[ 0x100 ];
    LONG r = ERROR_SUCCESS;

    /* max length of szFullKey depends on our code only, so we won't overrun */
    lstrcpyW( szFullKey, szOID );
    lstrcatW( szFullKey, szKey );
    CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );

    r = RegDeleteKeyW(HKEY_LOCAL_MACHINE, szFullKey);

    return r;
}

/***********************************************************************
 *             CryptSIPRemoveProvider (CRYPT32.@)
 *
 * Remove a SIP provider and its functions from the registry.
 *
 * PARAMS
 *  pgProv     [I] Pointer to a GUID for this SIP provider
 *
 * RETURNS
 *  Success: TRUE.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  Registry errors are always reported via SetLastError(). Every registry
 *  deletion will be tried.
 */
BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv)
{
    LONG r = ERROR_SUCCESS;
    LONG remove_error = ERROR_SUCCESS;

    TRACE("%s\n", debugstr_guid(pgProv));

    if (!pgProv)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }


#define CRYPT_SIPREMOVEPROV( key ) \
    r = CRYPT_SIPDeleteFunction( pgProv, key); \
    if (r != ERROR_SUCCESS) remove_error = r

    CRYPT_SIPREMOVEPROV( szPutSigned);
    CRYPT_SIPREMOVEPROV( szGetSigned);
    CRYPT_SIPREMOVEPROV( szRemoveSigned);
    CRYPT_SIPREMOVEPROV( szCreate);
    CRYPT_SIPREMOVEPROV( szVerify);
    CRYPT_SIPREMOVEPROV( szIsMyFile);
    CRYPT_SIPREMOVEPROV( szIsMyFile2);

#undef CRYPT_SIPREMOVEPROV

    if (remove_error != ERROR_SUCCESS)
    {
        SetLastError(remove_error);
        return FALSE;
    }

    return TRUE;
}

/*
 * Helper for CryptSIPAddProvider
 *
 * Add a registry key containing a dll name and function under
 *  "Software\\Microsoft\\Cryptography\\OID\\EncodingType 0\\<func>\\<guid>"
 */
static LONG CRYPT_SIPWriteFunction( const GUID *guid, LPCWSTR szKey,
              LPCWSTR szDll, LPCWSTR szFunction )
{
    WCHAR szFullKey[ 0x100 ];
    LONG r = ERROR_SUCCESS;
    HKEY hKey;

    if( !szFunction )
         return ERROR_SUCCESS;

    /* max length of szFullKey depends on our code only, so we won't overrun */
    lstrcpyW( szFullKey, szOID );
    lstrcatW( szFullKey, szKey );
    CRYPT_guid2wstr( guid, &szFullKey[ lstrlenW( szFullKey ) ] );

    TRACE("key is %s\n", debugstr_w( szFullKey ) );

    r = RegCreateKeyW( HKEY_LOCAL_MACHINE, szFullKey, &hKey );
    if( r != ERROR_SUCCESS ) goto error_close_key;

    /* write the values */
    r = RegSetValueExW( hKey, szFuncName, 0, REG_SZ, (const BYTE*) szFunction,
                        ( lstrlenW( szFunction ) + 1 ) * sizeof (WCHAR) );
    if( r != ERROR_SUCCESS ) goto error_close_key;
    r = RegSetValueExW( hKey, szDllName, 0, REG_SZ, (const BYTE*) szDll,
                        ( lstrlenW( szDll ) + 1) * sizeof (WCHAR) );

error_close_key:

    RegCloseKey( hKey );

    return r;
}

/***********************************************************************
 *             CryptSIPAddProvider (CRYPT32.@)
 *
 * Add a SIP provider and its functions to the registry.
 *
 * PARAMS
 *  psNewProv       [I] Pointer to a structure with information about
 *                      the functions this SIP provider can perform.
 *
 * RETURNS
 *  Success: TRUE.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  Registry errors are always reported via SetLastError(). If a
 *  registry error occurs the rest of the registry write operations
 *  will be skipped.
 */
BOOL WINAPI CryptSIPAddProvider(SIP_ADD_NEWPROVIDER *psNewProv)
{
    LONG r = ERROR_SUCCESS;

    TRACE("%p\n", psNewProv);

    if (!psNewProv ||
        psNewProv->cbStruct != sizeof(SIP_ADD_NEWPROVIDER) ||
        !psNewProv->pwszGetFuncName ||
        !psNewProv->pwszPutFuncName ||
        !psNewProv->pwszCreateFuncName ||
        !psNewProv->pwszVerifyFuncName ||
        !psNewProv->pwszRemoveFuncName)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    TRACE("%s %s %s %s %s\n",
          debugstr_guid( psNewProv->pgSubject ),
          debugstr_w( psNewProv->pwszDLLFileName ),
          debugstr_w( psNewProv->pwszMagicNumber ),
          debugstr_w( psNewProv->pwszIsFunctionName ),
          debugstr_w( psNewProv->pwszIsFunctionNameFmt2 ) );

#define CRYPT_SIPADDPROV( key, field ) \
    r = CRYPT_SIPWriteFunction( psNewProv->pgSubject, key, \
           psNewProv->pwszDLLFileName, psNewProv->field); \
    if (r != ERROR_SUCCESS) goto end_function

    CRYPT_SIPADDPROV( szPutSigned, pwszPutFuncName );
    CRYPT_SIPADDPROV( szGetSigned, pwszGetFuncName );
    CRYPT_SIPADDPROV( szRemoveSigned, pwszRemoveFuncName );
    CRYPT_SIPADDPROV( szCreate, pwszCreateFuncName );
    CRYPT_SIPADDPROV( szVerify, pwszVerifyFuncName );
    CRYPT_SIPADDPROV( szIsMyFile, pwszIsFunctionName );
    CRYPT_SIPADDPROV( szIsMyFile2, pwszIsFunctionNameFmt2 );

#undef CRYPT_SIPADDPROV

end_function:

    if (r != ERROR_SUCCESS)
    {
        SetLastError(r);
        return FALSE;
    }

    return TRUE;
}

/***********************************************************************
 *             CryptSIPRetrieveSubjectGuid (CRYPT32.@)
 *
 * Determine the right SIP GUID for the given file.
 *
 * PARAMS
 *  FileName   [I] Filename.
 *  hFileIn    [I] Optional handle to the file.
 *  pgSubject  [O] The SIP's GUID.
 *
 * RETURNS
 *  Success: TRUE. pgSubject contains the SIP GUID.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  On failure pgSubject will contain a NULL GUID.
 *  The handle is always preferred above the filename.
 */
BOOL WINAPI CryptSIPRetrieveSubjectGuid
      (LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject)
{
    HANDLE hFile;
    HANDLE hFilemapped;
    LPVOID pMapped;
    BOOL   bRet = FALSE;
    DWORD  fileSize;
    IMAGE_DOS_HEADER *dos;
    /* FIXME, find out if there is a name for this GUID */
    static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }};

    TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject);

    if (!pgSubject || (!FileName && !hFileIn))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Set pgSubject to zero's */
    memset(pgSubject, 0 , sizeof(GUID));

    if (hFileIn)
        /* Use the given handle, make sure not to close this one ourselves */
        hFile = hFileIn;
    else
    {
        hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        /* Last error is set by CreateFile */
        if (hFile == INVALID_HANDLE_VALUE) return FALSE;
    }

    hFilemapped = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    /* Last error is set by CreateFileMapping */
    if (!hFilemapped) goto cleanup3;

    pMapped = MapViewOfFile(hFilemapped, FILE_MAP_READ, 0, 0, 0);
    /* Last error is set by MapViewOfFile */
    if (!pMapped) goto cleanup2;

    /* Native checks it right here */
    fileSize = GetFileSize(hFile, NULL);
    if (fileSize < 4)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto cleanup1;
    }

    /* As everything is in place now we start looking at the file header */
    dos = (IMAGE_DOS_HEADER *)pMapped;
    if (dos->e_magic == IMAGE_DOS_SIGNATURE)
    {
        memcpy(pgSubject, &unknown, sizeof(GUID));
        SetLastError(S_OK);
        bRet = TRUE;
        goto cleanup1;
    }

    /* FIXME
     * There is a lot more to be checked:
     * - Check for MSFC in the header
     * - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2
     *   under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are 
     *   functions listed that need check if a SIP Provider can deal with the 
     *   given file.
     */

    /* Let's set the most common error for now */
    SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);

    /* The 3 different cleanups are here because we shouldn't overwrite the last error */
cleanup1:
    UnmapViewOfFile(pMapped);
cleanup2:
    CloseHandle(hFilemapped);
cleanup3:
    /* If we didn't open this one we shouldn't close it (hFile is a copy) */
    if (!hFileIn) CloseHandle(hFile);

    return bRet;
}

static LONG CRYPT_OpenSIPFunctionKey(const GUID *guid, LPCWSTR function,
 HKEY *key)
{
    WCHAR szFullKey[ 0x100 ];

    lstrcpyW(szFullKey, szOID);
    lstrcatW(szFullKey, function);
    CRYPT_guid2wstr(guid, &szFullKey[lstrlenW(szFullKey)]);
    return RegOpenKeyExW(HKEY_LOCAL_MACHINE, szFullKey, 0, KEY_READ, key);
}

/* Loads the function named function for the SIP specified by pgSubject, and
 * returns it if found.  Returns NULL on error.  If the function is loaded,
 * *pLib is set to the library in which it is found.
 */
static void *CRYPT_LoadSIPFunc(const GUID *pgSubject, LPCWSTR function,
 HMODULE *pLib)
{
    LONG r;
    HKEY key = NULL;
    DWORD size;
    WCHAR dllName[MAX_PATH];
    char functionName[MAX_PATH];
    HMODULE lib;
    void *func = NULL;

    TRACE("(%s, %s)\n", debugstr_guid(pgSubject), debugstr_w(function));

    r = CRYPT_OpenSIPFunctionKey(pgSubject, function, &key);
    if (r) goto error;

    /* Read the DLL entry */
    size = sizeof(dllName);
    r = RegQueryValueExW(key, szDllName, NULL, NULL, (LPBYTE)dllName, &size);
    if (r) goto error;

    /* Read the Function entry */
    size = sizeof(functionName);
    r = RegQueryValueExA(key, "FuncName", NULL, NULL, (LPBYTE)functionName,
     &size);
    if (r) goto error;

    lib = LoadLibraryW(dllName);
    if (!lib)
        goto error;
    func = GetProcAddress(lib, functionName);
    if (func)
        *pLib = lib;
    else
        FreeLibrary(lib);

error:
    RegCloseKey(key);
    TRACE("returning %p\n", func);
    return func;
}

typedef struct _WINE_SIP_PROVIDER {
    GUID              subject;
    SIP_DISPATCH_INFO info;
    struct list       entry;
} WINE_SIP_PROVIDER;

static struct list providers = { &providers, &providers };
static CRITICAL_SECTION providers_cs;
static CRITICAL_SECTION_DEBUG providers_cs_debug =
{
    0, 0, &providers_cs,
    { &providers_cs_debug.ProcessLocksList,
    &providers_cs_debug.ProcessLocksList },
    0, 0, { (DWORD_PTR)(__FILE__ ": providers_cs") }
};
static CRITICAL_SECTION providers_cs = { &providers_cs_debug, -1, 0, 0, 0, 0 };

static void CRYPT_CacheSIP(const GUID *pgSubject, SIP_DISPATCH_INFO *info)
{
    WINE_SIP_PROVIDER *prov = CryptMemAlloc(sizeof(WINE_SIP_PROVIDER));

    if (prov)
    {
        memcpy(&prov->subject, pgSubject, sizeof(prov->subject));
        memcpy(&prov->info, info, sizeof(prov->info));
        EnterCriticalSection(&providers_cs);
        list_add_tail(&providers, &prov->entry);
        LeaveCriticalSection(&providers_cs);
    }
}

static WINE_SIP_PROVIDER *CRYPT_GetCachedSIP(const GUID *pgSubject)
{
    WINE_SIP_PROVIDER *provider = NULL, *ret = NULL;

    EnterCriticalSection(&providers_cs);
    LIST_FOR_EACH_ENTRY(provider, &providers, WINE_SIP_PROVIDER, entry)
    {
        if (IsEqualGUID(pgSubject, &provider->subject))
            break;
    }
    if (provider && IsEqualGUID(pgSubject, &provider->subject))
        ret = provider;
    LeaveCriticalSection(&providers_cs);
    return ret;
}

static inline BOOL CRYPT_IsSIPCached(const GUID *pgSubject)
{
    return CRYPT_GetCachedSIP(pgSubject) != NULL;
}

void crypt_sip_free(void)
{
    WINE_SIP_PROVIDER *prov, *next;

    LIST_FOR_EACH_ENTRY_SAFE(prov, next, &providers, WINE_SIP_PROVIDER, entry)
    {
        list_remove(&prov->entry);
        FreeLibrary(prov->info.hSIP);
        CryptMemFree(prov);
    }
}

/* Loads the SIP for pgSubject into the global cache.  Returns FALSE if the
 * SIP isn't registered or is invalid.
 */
static BOOL CRYPT_LoadSIP(const GUID *pgSubject)
{
    SIP_DISPATCH_INFO sip = { 0 };
    HMODULE lib = NULL, temp = NULL;

    sip.pfGet = CRYPT_LoadSIPFunc(pgSubject, szGetSigned, &lib);
    if (!sip.pfGet)
        goto error;
    sip.pfPut = CRYPT_LoadSIPFunc(pgSubject, szPutSigned, &temp);
    if (!sip.pfPut || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.pfCreate = CRYPT_LoadSIPFunc(pgSubject, szCreate, &temp);
    if (!sip.pfCreate || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.pfVerify = CRYPT_LoadSIPFunc(pgSubject, szVerify, &temp);
    if (!sip.pfVerify || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.pfRemove = CRYPT_LoadSIPFunc(pgSubject, szRemoveSigned, &temp);
    if (!sip.pfRemove || temp != lib)
        goto error;
    FreeLibrary(temp);
    sip.hSIP = lib;
    CRYPT_CacheSIP(pgSubject, &sip);
    return TRUE;

error:
    FreeLibrary(lib);
    FreeLibrary(temp);
    SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN);
    return FALSE;
}

/***********************************************************************
 *             CryptSIPLoad (CRYPT32.@)
 *
 * Load some internal crypt32 functions into a SIP_DISPATCH_INFO structure.
 *
 * PARAMS
 *  pgSubject    [I] The GUID.
 *  dwFlags      [I] Flags.
 *  pSipDispatch [I] The loaded functions.
 *
 * RETURNS
 *  Success: TRUE. pSipDispatch contains the functions.
 *  Failure: FALSE. (Look at GetLastError()).
 *
 * NOTES
 *  CryptSIPLoad uses caching for the list of GUIDs and whether a SIP is
 *  already loaded.
 *
 *  An application calls CryptSipLoad which will return a structure with the
 *  function addresses of some internal crypt32 functions. The application will
 *  then call these functions which will be forwarded to the appropriate SIP.
 *
 *  CryptSIPLoad will load the needed SIP but doesn't unload this dll. The unloading
 *  is done when crypt32 is unloaded.
 */
BOOL WINAPI CryptSIPLoad
       (const GUID *pgSubject, DWORD dwFlags, SIP_DISPATCH_INFO *pSipDispatch)
{
    TRACE("(%s %d %p)\n", debugstr_guid(pgSubject), dwFlags, pSipDispatch);

    if (!pgSubject || dwFlags != 0 || !pSipDispatch)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if (!CRYPT_IsSIPCached(pgSubject) && !CRYPT_LoadSIP(pgSubject))
        return FALSE;

    pSipDispatch->hSIP = NULL;
    pSipDispatch->pfGet = CryptSIPGetSignedDataMsg;
    pSipDispatch->pfPut = CryptSIPPutSignedDataMsg;
    pSipDispatch->pfCreate = CryptSIPCreateIndirectData;
    pSipDispatch->pfVerify = CryptSIPVerifyIndirectData;
    pSipDispatch->pfRemove = CryptSIPRemoveSignedDataMsg;

    return TRUE;
}

/***********************************************************************
 *             CryptSIPCreateIndirectData (CRYPT32.@)
 */
BOOL WINAPI CryptSIPCreateIndirectData(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pcbIndirectData,
                                       SIP_INDIRECT_DATA* pIndirectData)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %p %p)\n", pSubjectInfo, pcbIndirectData, pIndirectData);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfCreate(pSubjectInfo, pcbIndirectData, pIndirectData);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPGetSignedDataMsg (CRYPT32.@)
 */
BOOL WINAPI CryptSIPGetSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD* pdwEncodingType,
                                       DWORD dwIndex, DWORD* pcbSignedDataMsg, BYTE* pbSignedDataMsg)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %p %d %p %p)\n", pSubjectInfo, pdwEncodingType, dwIndex,
          pcbSignedDataMsg, pbSignedDataMsg);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfGet(pSubjectInfo, pdwEncodingType, dwIndex,
         pcbSignedDataMsg, pbSignedDataMsg);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPPutSignedDataMsg (CRYPT32.@)
 */
BOOL WINAPI CryptSIPPutSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo, DWORD pdwEncodingType,
                                       DWORD* pdwIndex, DWORD cbSignedDataMsg, BYTE* pbSignedDataMsg)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %d %p %d %p)\n", pSubjectInfo, pdwEncodingType, pdwIndex,
          cbSignedDataMsg, pbSignedDataMsg);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfPut(pSubjectInfo, pdwEncodingType, pdwIndex,
         cbSignedDataMsg, pbSignedDataMsg);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPRemoveSignedDataMsg (CRYPT32.@)
 */
BOOL WINAPI CryptSIPRemoveSignedDataMsg(SIP_SUBJECTINFO* pSubjectInfo,
                                       DWORD dwIndex)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %d)\n", pSubjectInfo, dwIndex);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfRemove(pSubjectInfo, dwIndex);
    TRACE("returning %d\n", ret);
    return ret;
}

/***********************************************************************
 *             CryptSIPVerifyIndirectData (CRYPT32.@)
 */
BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO* pSubjectInfo,
                                       SIP_INDIRECT_DATA* pIndirectData)
{
    WINE_SIP_PROVIDER *sip;
    BOOL ret = FALSE;

    TRACE("(%p %p)\n", pSubjectInfo, pIndirectData);

    if ((sip = CRYPT_GetCachedSIP(pSubjectInfo->pgSubjectType)))
        ret = sip->info.pfVerify(pSubjectInfo, pIndirectData);
    TRACE("returning %d\n", ret);
    return ret;
}
