' ########################################################################################
' Microsoft Windows
' File: mssip.inc
' Contents: Microsoft SIP Provider Main Include File
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_mssip_PBI)
#DEFINE PBX_mssip_PBI
%EQUATE `MSSIP_INC = 1
#INCLUDE ONCE "Core/Windows.inc"
#INCLUDE ONCE "Legacy/Platform/WinCrypt.inc"
#INCLUDE ONCE "Legacy/System/mscat.inc"
'#pragma pack (8)
'typedef CRYPT_HASH_BLOB CRYPT_DIGEST_DATA;
'//
'// dwflags
'//
%EQUATE `MSSIP_FLAGS_PROHIBIT_RESIZE_ON_CREATE = &H00010000
%EQUATE `MSSIP_FLAGS_USE_CATALOG = &H00020000
%EQUATE `SPC_INC_PE_RESOURCES_FLAG = &H80
%EQUATE `SPC_INC_PE_DEBUG_INFO_FLAG = &H40
%EQUATE `SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG = &H20
%EQUATE `SPC_EXC_PE_PAGE_HASHES_FLAG = &H10
'// The above SPC_EXC_PE_PAGE_HASHES_FLAG takes precedence if also set.
%EQUATE `SPC_INC_PE_PAGE_HASHES_FLAG = &H100
'//////////////////////////////////////////////////////////////////////////////
'//
'// SIP_INDIRECT_DATA
'//----------------------------------------------------------------------------
'// Indirect data structure is used to store the hash of the subject
'// along with data that is relevant to the subject. This can include
'// names etc.
'//
' Also declared in mscat.inc
#IF NOT %DEF(%SIP_INDIRECT_DATA_DEFINED)
%EQUATE `SIP_INDIRECT_DATA_DEFINED = 1
' // Size = 32 bytes
TYPE SIP_INDIRECT_DATA DWORD
 Data AS CRYPT_ATTRIBUTE_TYPE_VALUE
 DigestAlgorithm AS CRYPT_ALGORITHM_IDENTIFIER
 Digest AS CRYPT_HASH_BLOB
END TYPE
#ENDIF
' Also declared in mscat.inc
#IF NOT %DEF(%CRYPTCATSTORE_DEFINED)
%EQUATE `CRYPTCATSTORE_DEFINED = 1
' // Size = 40 bytes
TYPE CRYPTCATSTORE DWORD
 cbStruct AS DWORD ' DWORD // = sizeof(CRYPTCATSTORE)
 dwPublicVersion AS DWORD
 pwszP7File AS WSTRINGZ PTR
 hProv AS DWORD ' HCRYPTPROV
 dwEncodingType AS DWORD
 fdwStoreFlags AS DWORD
 hReserved AS DWORD ' HANDLE // pStack(members) (null if init/pbData) INTERNAL!
 hAttrs AS DWORD ' HANDLE // pStack(Catalog attrs) INTERNAL!
 ' // Following is only set if opened with CRYPTCAT_OPEN_NO_CONTENT_HCRYPTMSG
 hCryptMsg AS DWORD ' HCRYPTMSG
 ' // Following is only set if opened with CRYPTCAT_OPEN_SORTED
 hSorted AS DWORD ' HANDLE // INTERNAL ONLY!
END TYPE
#ENDIF
' Also declared in mscat.inc
#IF NOT %DEF(%CRYPTCATMEMBER_DEFINED)
%EQUATE `CRYPTCATMEMBER_DEFINED = 1
' // Size = 64 bytes
TYPE CRYPTCATMEMBER DWORD
 cbStruct AS DWORD ' DWORD // = sizeof(CRYPTCATMEMBER)
 pwszReferenceTag AS WSTRINGZ PTR
 pwszFileName AS WSTRINGZ PTR ' LPWSTR // used only by the CDF APIs
 gSubjectType AS GUID ' GUID // may be zeros -- see sEncodedMemberInfo
 fdwMemberFlags AS DWORD
 pIndirectData AS SIP_INDIRECT_DATA PTR ' struct SIP_INDIRECT_DATA_* // may be null -- see sEncodedIndirectData
 dwCertVersion AS DWORD ' DWORD // may be zero -- see sEncodedMemberInfo
 dwReserved AS DWORD ' DWORD // used by enum -- DO NOT USE!
 hReserved AS DWORD ' HANDLE // pStack(attrs) (null if init) INTERNAL!
 sEncodedIndirectData AS CRYPT_ATTR_BLOB ' CRYPT_ATTR_BLOB // lazy decode
 sEncodedMemberInfo AS CRYPT_ATTR_BLOB ' CRYPT_ATTR_BLOB // lazy decode
END TYPE
#ENDIF
'//////////////////////////////////////////////////////////////////////////////
'//
'// MS_ADDINFO_FLAT
'//----------------------------------------------------------------------------
'// Flat or End-To-End types
'// needed for flat type files during indirect calls
'// "Digest" of file.
'//
' // Size = 8 bytes
TYPE MS_ADDINFO_FLAT DWORD
 cbStruct AS DWORD
 pIndirectData AS SIP_INDIRECT_DATA PTR
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'//
'// MS_ADDINFO_CATALOGMEMBER
'//----------------------------------------------------------------------------
'// Catalog Member verification.
'//
'typedef struct MS_ADDINFO_CATALOGMEMBER_
'{
' DWORD cbStruct; // = sizeof(MS_ADDINFO_CATALOGMEMBER)
' struct CRYPTCATSTORE_ *pStore; // defined in mscat.h
' struct CRYPTCATMEMBER_ *pMember; // defined in mscat.h
'} MS_ADDINFO_CATALOGMEMBER, *PMS_ADDINFO_CATALOGMEMBER;
' // Size = 12 bytes
TYPE MS_ADDINFO_CATALOGMEMBER DWORD
 cbStruct AS DWORD
 pStore AS CRYPTCATSTORE PTR
 pMember AS CRYPTCATMEMBER PTR
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'//
'// MS_ADDINFO_BLOB
'//----------------------------------------------------------------------------
'// Memory "blob" verification.
'//
' // Size = 20 bytes
TYPE MS_ADDINFO_BLOB DWORD
 cbStruct AS DWORD
 cbMemObject AS DWORD
 pbMemObject AS BYTE PTR
 cbMemSignedMsg AS DWORD
 pbMemSignedMsg AS BYTE PTR
END TYPE
'//////////////////////////////////////////////////////////////////////////////
'//
'// SIP_SUBJECTINFO
'//----------------------------------------------------------------------------
'// pass this structure to all defined SIPs. Make sure to initialize
'// the ENTIRE structure to binary zero before the FIRST call is made. Do
'// not initialize it BETWEEN calls!
'//
'typedef struct SIP_SUBJECTINFO_
'{
' DWORD cbSize; // set to sizeof(SIP_SUBJECTINFO)
' GUID *pgSubjectType; // subject type
' HANDLE hFile; // set to File handle that represents the subject
' // set to INVALID_HANDLE VALUE to allow
' // SIP to use pwsFileName for persistent
' // storage types (will handle open/close)
' LPCWSTR pwsFileName; // set to file name
' LPCWSTR pwsDisplayName; // optional: set to display name of
' // subject.
' DWORD dwReserved1; // do not use!
' DWORD dwIntVersion; // DO NOT SET OR CLEAR THIS.
' // This member is used by the sip for
' // passing the internal version number
' // between the ..get and verify... functions.
' HCRYPTPROV hProv;
' CRYPT_ALGORITHM_IDENTIFIER DigestAlgorithm;
' DWORD dwFlags;
' DWORD dwEncodingType;
' DWORD dwReserved2; // do not use!
' DWORD fdwCAPISettings; // setreg settings
' DWORD fdwSecuritySettings; // IE security settings
' DWORD dwIndex; // message index of last "Get"
' DWORD dwUnionChoice;
'# define MSSIP_ADDINFO_NONE 0
'# define MSSIP_ADDINFO_FLAT 1
'# define MSSIP_ADDINFO_CATMEMBER 2
'# define MSSIP_ADDINFO_BLOB 3
'# define MSSIP_ADDINFO_NONMSSIP 500 // everything < is reserved by MS.
' union
' {
' struct MS_ADDINFO_FLAT_ *psFlat;
' struct MS_ADDINFO_CATALOGMEMBER_ *psCatMember;
' struct MS_ADDINFO_BLOB_ *psBlob;
' };
' LPVOID pClientData; // data pased in from client to SIP
'} SIP_SUBJECTINFO, *LPSIP_SUBJECTINFO;
%EQUATE `MSSIP_ADDINFO_NONE = 0
%EQUATE `MSSIP_ADDINFO_FLAT = 1
%EQUATE `MSSIP_ADDINFO_CATMEMBER = 2
%EQUATE `MSSIP_ADDINFO_BLOB = 3
%EQUATE `MSSIP_ADDINFO_NONMSSIP = 500 ' // everything < is reserved by MS.
' // Size = 4 bytes
UNION SIP_SUBJECTINFO_UNION DWORD
 psFlat AS MS_ADDINFO_FLAT PTR
 psCatMember AS MS_ADDINFO_CATALOGMEMBER PTR
 psBlob AS MS_ADDINFO_BLOB PTR
END UNION
' // Size = 80 bytes
TYPE SIP_SUBJECTINFO DWORD
 cbSize AS DWORD
 pgSubjectType AS GUID PTR
 hFile AS DWORD
 pwsFileName AS WSTRINGZ PTR
 pwsDisplayName AS WSTRINGZ PTR
 dwReserved1 AS DWORD
 dwIntVersion AS DWORD
 hProv AS DWORD
 DigestAlgorithm AS CRYPT_ALGORITHM_IDENTIFIER
 dwFlags AS DWORD
 dwEncodingType AS DWORD
 dwReserved2 AS DWORD
 fdwCAPISettings AS DWORD
 fdwSecuritySettings AS DWORD
 dwIndex AS DWORD
 dwUnionChoice AS DWORD
 SIP_SUBJECTINFO_UNION
 pClientData AS DWORD
END TYPE
'#pragma pack()
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPGetSignedDataMsg
'//----------------------------------------------------------------------------
'// Returns the message specified by the index count. Data, specific to
'// the subject is passed in through pSubjectInfo. To retrieve the
'// size of the signature, set pbData to NULL.
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
'// Last Errors:
'// ERROR_NOT_ENOUGH_MEMORY: error allocating memory
'// TRUST_E_SUBJECT_FORM_UNKNOWN: unknown subject type.
'// ERROR_INVALID_PARAMETER: bad argument passed in
'// ERROR_BAD_FORMAT: file/data format is not correct
'// for the requested SIP.
'// CRYPT_E_NO_MATCH: the signature could not be found
'// based on the dwIndex provided.
'// ERROR_INSUFFICIENT_BUFFER: the pbSignedDataMsg was not big
'// enough to hold the data. pcbSignedDataMsg
'// contains the required size.
'//
DECLARE FUNCTION CryptSIPGetSignedDataMsg LIB "crypt32.dll" ALIAS "CryptSIPGetSignedDataMsg" ( BYREF pSubjectInfo AS SIP_SUBJECTINFO , BYREF pdwEncodingType AS QUAD , BYVAL dwIndex AS QUAD , BYREF pcbSignedDataMsg AS QUAD , BYREF pbSignedDataMsg AS BYTE ) AS LONG
'typedef BOOL (WINAPI * pCryptSIPGetSignedDataMsg)(
' IN SIP_SUBJECTINFO *pSubjectInfo,
' OUT DWORD *pdwEncodingType,
' IN DWORD dwIndex,
' IN OUT DWORD *pcbSignedDataMsg,
' OUT BYTE *pbSignedDataMsg);
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPPuttSignedDataMsg
'//----------------------------------------------------------------------------
'// Adds a signature to the subject. The index that it was
'// stored with is returned for future reference.
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
'// Last Errors:
'// ERROR_NOT_ENOUGH_MEMORY: error allocating memory
'// TRUST_E_SUBJECT_FORM_UNKNOWN: unknown subject type.
'// CRYPT_E_BAD_LEN: the length specified in
'// psData->dwSignature was
'// insufficient.
'// CRYPT_E_NO_MATCH: could not find the specified index
'// ERROR_INVALID_PARAMETER: bad argument passed in
'// ERROR_BAD_FORMAT: file/data format is not correct
'// for the requested SIP.
'// CRYPT_E_FILERESIZED: returned when signing a fixed-length
'// file (e.g.: CABs) and the message
'// is larger than the pre-allocated
'// size. The 'put' function will re-
'// size the file and return this error.
'// The CreateIndirect function MUST be
'// called again to recalculate the
'// indirect data (hash). Then, call the
'// 'put' function again.
'//
DECLARE FUNCTION CryptSIPPutSignedDataMsg LIB "crypt32.dll" ALIAS "CryptSIPPutSignedDataMsg" ( BYREF pSubjectInfo AS SIP_SUBJECTINFO , BYVAL dwEncodingType AS QUAD , BYREF pdwIndex AS QUAD , BYVAL cbSignedDataMsg AS QUAD , BYVAL pbSignedDataMsg AS BYTE PTR ) AS LONG
'typedef BOOL (WINAPI * pCryptSIPPutSignedDataMsg)(
' IN SIP_SUBJECTINFO *pSubjectInfo,
' IN DWORD dwEncodingType,
' OUT DWORD *pdwIndex,
' IN DWORD cbSignedDataMsg,
' IN BYTE *pbSignedDataMsg);
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPCreateIndirectData
'//----------------------------------------------------------------------------
'// Returns a PSIP_INDIRECT_DATA structure filled in the hash, digest alogrithm
'// and an encoded attribute. If pcIndirectData points to a DWORD and
'// psIndirect data points to null the the size of the data should be returned
'// in pcIndirectData.
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
'// Last Errors:
'// NTE_BAD_ALGID: Bad Algorithm Identifyer
'// ERROR_NOT_ENOUGH_MEMORY: error allocating memory
'// TRUST_E_SUBJECT_FORM_UNKNOWN: unknown subject type.
'// ERROR_INVALID_PARAMETER: bad argument passed in
'// ERROR_BAD_FORMAT: file/data format is not correct
'// for the requested SIP.
'//
DECLARE FUNCTION CryptSIPCreateIndirectData LIB "crypt32.dll" ALIAS "CryptSIPCreateIndirectData" ( BYREF pSubjectInfo AS SIP_SUBJECTINFO , BYREF pcbIndirectData AS QUAD , BYREF pIndirectData AS SIP_INDIRECT_DATA ) AS LONG
'typedef BOOL (WINAPI * pCryptSIPCreateIndirectData)(
' IN SIP_SUBJECTINFO *pSubjectInfo,
' IN OUT DWORD *pcbIndirectData,
' OUT SIP_INDIRECT_DATA *pIndirectData);
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPVerifyIndirectData
'//----------------------------------------------------------------------------
'// Takes the information stored in the indirect data and compares it to the
'// subject.
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
'// Last Errors:
'// NTE_BAD_ALGID: Bad Algorithm Identifyer
'// ERROR_NOT_ENOUGH_MEMORY: error allocating memory
'// TRUST_E_SUBJECT_FORM_UNKNOWN: unknown subject type.
'// CRYPT_E_NO_MATCH: could not find the specified index
'// CRYPT_E_SECURITY_SETTINGS: due to security settings, the file
'// was not verified.
'// ERROR_INVALID_PARAMETER: bad argument passed in
'// ERROR_BAD_FORMAT: file/data format is not correct
'// for the requested SIP.
DECLARE FUNCTION CryptSIPVerifyIndirectData LIB "crypt32.dll" ALIAS "CryptSIPVerifyIndirectData" ( BYREF pSubjectInfo AS SIP_SUBJECTINFO , BYREF pIndirectData AS SIP_INDIRECT_DATA ) AS LONG
'typedef BOOL (WINAPI * pCryptSIPVerifyIndirectData)(
' IN SIP_SUBJECTINFO *pSubjectInfo,
' IN SIP_INDIRECT_DATA *pIndirectData);
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPRemoveSignedDataMsg
'//----------------------------------------------------------------------------
'// Removes the signature at the specified index
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
'// Last Errors:
'// TRUST_E_SUBJECT_FORM_UNKNOWN: unknown subject type.
'// CRYPT_E_NO_MATCH: could not find the specified index
'// ERROR_INVALID_PARAMETER: bad argument passed in
'// ERROR_BAD_FORMAT: file/data format is not correct
'// for the requested SIP.
'//
DECLARE FUNCTION CryptSIPRemoveSignedDataMsg LIB "crypt32.dll" ALIAS "CryptSIPRemoveSignedDataMsg" ( BYREF pSubjectInfo AS SIP_SUBJECTINFO , BYVAL dwIndex AS QUAD ) AS LONG
'typedef BOOL (WINAPI * pCryptSIPRemoveSignedDataMsg)(
' IN SIP_SUBJECTINFO *pSubjectInfo,
' IN DWORD dwIndex);
'#pragma pack(8)
'//////////////////////////////////////////////////////////////////////////////
'//
'// SIP_DISPATCH_INFO
'//----------------------------------------------------------------------------
'//
'typedef struct SIP_DISPATCH_INFO_
'{
' DWORD cbSize; // = sizeof(SIP_DISPATCH_INFO)
' HANDLE hSIP; // used internal
' pCryptSIPGetSignedDataMsg pfGet;
' pCryptSIPPutSignedDataMsg pfPut;
' pCryptSIPCreateIndirectData pfCreate;
' pCryptSIPVerifyIndirectData pfVerify;
' pCryptSIPRemoveSignedDataMsg pfRemove;
'} SIP_DISPATCH_INFO, *LPSIP_DISPATCH_INFO;
' // Size = 28 bytes
TYPE SIP_DISPATCH_INFO DWORD
 cbSize AS DWORD
 hSIP AS DWORD
 pfGet AS DWORD
 pfPut AS DWORD
 pfCreate AS DWORD
 pfVerify AS DWORD
 pfRemove AS DWORD
END TYPE
'//
'// the sip exports this function to allow verification and signing
'// processes to pass in the file handle and check if the sip supports
'// this type of file. if it does, the sip will return TRUE and fill
'// out the pgSubject with the appropiate GUID.
'//
'typedef BOOL (WINAPI *pfnIsFileSupported)(IN HANDLE hFile,
' OUT GUID *pgSubject);
'FUNCTION IsFileSupported (BYVAL hFile AS DWORD, BYREF pgSubject AS GUID) AS LONG
'typedef BOOL (WINAPI *pfnIsFileSupportedName)(IN WCHAR *pwszFileName,
' OUT GUID *pgSubject);
'FUNCTION IsFileSupportedName (BYVAL pwszFileName AS DWORD, BYREF pgSubject AS GUID) AS LONG
'typedef struct SIP_ADD_NEWPROVIDER_
'{
' DWORD cbStruct;
' GUID *pgSubject;
' WCHAR *pwszDLLFileName;
' WCHAR *pwszMagicNumber; // optional
' WCHAR *pwszIsFunctionName; // optiona: pfnIsFileSupported
' WCHAR *pwszGetFuncName;
' WCHAR *pwszPutFuncName;
' WCHAR *pwszCreateFuncName;
' WCHAR *pwszVerifyFuncName;
' WCHAR *pwszRemoveFuncName;
' WCHAR *pwszIsFunctionNameFmt2; // optiona: pfnIsFileSupported
'} SIP_ADD_NEWPROVIDER, *PSIP_ADD_NEWPROVIDER;
' // Size = 44 bytes
TYPE SIP_ADD_NEWPROVIDER DWORD
 cbStruct AS DWORD
 pgSubject AS GUID PTR
 pwszDLLFileName AS WSTRINGZ PTR
 pwszMagicNumber AS WSTRINGZ PTR
 pwszIsFunctionName AS WSTRINGZ PTR
 pwszGetFuncName AS WSTRINGZ PTR
 pwszPutFuncName AS WSTRINGZ PTR
 pwszCreateFuncName AS WSTRINGZ PTR
 pwszVerifyFuncName AS WSTRINGZ PTR
 pwszRemoveFuncName AS WSTRINGZ PTR
 pwszIsFunctionNameFmt2 AS WSTRINGZ PTR
END TYPE
%EQUATE `SIP_MAX_MAGIC_NUMBER = 4
'#pragma pack()
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptLoadSIP
'//----------------------------------------------------------------------------
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
DECLARE FUNCTION CryptSIPLoad LIB "crypt32.dll" ALIAS "CryptSIPLoad" ( BYREF pgSubject AS GUID , BYVAL dwFlags AS QUAD , BYREF pSipDispatch AS SIP_DISPATCH_INFO ) AS LONG
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPRetrieveSubjectGuid (defined in crypt32.dll)
'//----------------------------------------------------------------------------
'// looks at the file's "Magic Number" and tries to determine which
'// SIP's object ID is right for the file type.
'//
'// NOTE: This function only supports the MSSIP32.DLL set of SIPs.
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
DECLARE FUNCTION CryptSIPRetrieveSubjectGuid LIB "crypt32.dll" ALIAS "CryptSIPRetrieveSubjectGuid" ( BYREF FileName AS WSTRINGZ , BYVAL hFileIn AS QUAD , BYREF pgSubject AS GUID ) AS LONG
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPRetrieveSubjectGuidForCatalogFile (defined in crypt32.dll)
'//----------------------------------------------------------------------------
'// looks at the file's "Magic Number" and tries to determine which
'// SIP's object ID is right for the file type.
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
DECLARE FUNCTION CryptSIPRetrieveSubjectGuidForCatalogFile LIB "crypt32.dll" ALIAS "CryptSIPRetrieveSubjectGuidForCatalogFile" ( BYREF FileName AS WSTRINGZ , BYVAL hFileIn AS QUAD , BYREF pgSubject AS GUID ) AS LONG
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPAddProvider
'//----------------------------------------------------------------------------
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
DECLARE FUNCTION CryptSIPAddProvider LIB "crypt32.dll" ALIAS "CryptSIPAddProvider" ( BYREF psNewProv AS SIP_ADD_NEWPROVIDER ) AS LONG
'//////////////////////////////////////////////////////////////////////////////
'//
'// CryptSIPRemoveProvider
'//----------------------------------------------------------------------------
'//
'// Returns:
'// TRUE: No fatal errors
'// FALSE: Errors occured. See GetLastError()
'//
DECLARE FUNCTION CryptSIPRemoveProvider LIB "crypt32.dll" ALIAS "CryptSIPRemoveProvider" ( BYREF pgProv AS GUID ) AS LONG
#ENDIF
