diff options
Diffstat (limited to 'src')
35 files changed, 63 insertions, 5323 deletions
diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp index b6336fb143..3cdebcf0f4 100644 --- a/src/ToolBox/SOS/Strike/util.cpp +++ b/src/ToolBox/SOS/Strike/util.cpp @@ -4793,10 +4793,8 @@ HRESULT InitCorDebugInterface() // Need to pick the appropriate SKU of CLR to detect #if defined(FEATURE_CORESYSTEM) GUID skuId = CLR_ID_ONECORE_CLR; -#elif defined(FEATURE_CORECLR) - GUID skuId = CLR_ID_CORECLR; #else - GUID skuId = CLR_ID_V4_DESKTOP; + GUID skuId = CLR_ID_CORECLR; #endif CLRDebuggingImpl* pDebuggingImpl = new CLRDebuggingImpl(skuId); hr = pDebuggingImpl->QueryInterface(IID_ICLRDebugging, (LPVOID *)&pClrDebugging); diff --git a/src/debug/di/cordb.cpp b/src/debug/di/cordb.cpp index c993fa095f..76cfc85ffa 100644 --- a/src/debug/di/cordb.cpp +++ b/src/debug/di/cordb.cpp @@ -86,7 +86,7 @@ HINSTANCE g_hInst; // Instance handle to this piece of code //***************************************************************************** STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb) { -#if defined(FEATURE_CORECLR) && !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM) +#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM) // This API should not be called for Windows CoreCLR unless we are doing interop-debugging // (which is only supported internally). Use code:CoreCLRCreateCordbObject instead. if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgEnableMixedModeDebugging) == 0) @@ -94,7 +94,7 @@ STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb) _ASSERTE(!"Deprecated entry point CreateCordbObject() is called on Windows CoreCLR\n"); return E_NOTIMPL; } -#endif // FEATURE_CORECLR && !FEATURE_DBGIPC_TRANSPORT_DI +#endif // !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM) if (ppCordb == NULL) { diff --git a/src/debug/di/rsmain.cpp b/src/debug/di/rsmain.cpp index cd2063a5a0..2a93619b2a 100644 --- a/src/debug/di/rsmain.cpp +++ b/src/debug/di/rsmain.cpp @@ -1423,14 +1423,14 @@ bool Cordb::IsInteropDebuggingSupported() // ICorDebug::SetUnmanagedHandler for details. #ifdef FEATURE_INTEROP_DEBUGGING -#if defined(FEATURE_CORECLR) && !defined(FEATURE_CORESYSTEM) +#if !defined(FEATURE_CORESYSTEM) // Interop debugging is only supported internally on CoreCLR. // Check if the special reg key is set. If not, then we don't allow interop debugging. if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgEnableMixedModeDebugging) == 0) { return false; } -#endif // FEATURE_CORECLR +#endif // FEATURE_CORESYSTEM return true; #else diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp index d77227f213..143c44c921 100644 --- a/src/debug/ee/debugger.cpp +++ b/src/debug/ee/debugger.cpp @@ -1964,7 +1964,7 @@ void NotifyDebuggerOfTelestoStartup() g_hContinueStartupEvent = NULL; } -#endif // FEATURE_CORECLR && !FEATURE_PAL +#endif // !FEATURE_PAL //--------------------------------------------------------------------------------------- // @@ -2016,7 +2016,7 @@ HRESULT Debugger::Startup(void) // The transport requires the debug pack to be present. Otherwise it'll raise a fatal error. return S_FALSE; } -#endif // FEATURE_CORECLR && !FEATURE_PAL +#endif // !FEATURE_PAL { DebuggerLockHolder dbgLockHolder(this); diff --git a/src/dlls/dbgshim/dbgshim.cpp b/src/dlls/dbgshim/dbgshim.cpp index 5f15cabe97..39c966a3ce 100644 --- a/src/dlls/dbgshim/dbgshim.cpp +++ b/src/dlls/dbgshim/dbgshim.cpp @@ -1818,10 +1818,8 @@ CLRCreateInstance( #if defined(FEATURE_CORESYSTEM) GUID skuId = CLR_ID_ONECORE_CLR; -#elif defined(FEATURE_CORECLR) - GUID skuId = CLR_ID_CORECLR; #else - GUID skuId = CLR_ID_V4_DESKTOP; + GUID skuId = CLR_ID_CORECLR; #endif CLRDebuggingImpl *pDebuggingImpl = new CLRDebuggingImpl(skuId); diff --git a/src/inc/MSCOREE.IDL b/src/inc/MSCOREE.IDL index 67605e23d4..e543124304 100644 --- a/src/inc/MSCOREE.IDL +++ b/src/inc/MSCOREE.IDL @@ -10,21 +10,9 @@ ** ** **************************************************************************************/ -#ifdef FEATURE_CORECLR -// API deprecation does not apply to CoreCLR cpp_quote("#define DECLARE_DEPRECATED ") cpp_quote("#define DEPRECATED_CLR_STDAPI STDAPI") -#else // !FEATURE_CORECLR -// API deprecation is only applicable to Desktop runtime. -cpp_quote("#ifndef USE_DEPRECATED_CLR_API_WITHOUT_WARNING") -cpp_quote("#define DEPRECATED_CLR_API_MESG \"This API has been deprecated. Refer to http://go.microsoft.com/fwlink/?LinkId=143720 for more details.\"") -cpp_quote("#define DECLARE_DEPRECATED __declspec(deprecated(DEPRECATED_CLR_API_MESG))") -cpp_quote("#define DEPRECATED_CLR_STDAPI EXTERN_C DECLARE_DEPRECATED HRESULT STDAPICALLTYPE") -cpp_quote("#else // USE_DEPRECATED_CLR_API_WITHOUT_WARNING") -cpp_quote("#define DECLARE_DEPRECATED ") -cpp_quote("#define DEPRECATED_CLR_STDAPI STDAPI") -cpp_quote("#endif // !USE_DEPRECATED_CLR_API_WITHOUT_WARNING") -#endif // FEATURE_CORECLR + cpp_quote("") // @@ -38,10 +26,8 @@ import "ivalidator.idl"; #include "product_version.h" -#ifdef FEATURE_CORECLR cpp_quote("struct IActivationFactory;") interface IActivationFactory; -#endif const char* CLR_MAJOR_VERSION = VER_MAJORVERSION; const char* CLR_MINOR_VERSION = VER_MINORVERSION; @@ -192,15 +178,12 @@ cpp_quote("EXTERN_GUID(IID_ICLROnEventManager, 0x1D0E0132, 0xE64F, 0x493D, 0x92, // IID ICLRRuntimeHost: uuid(90F1A06C-7712-4762-86B5-7A5EBA6BDB02) cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);") -#ifdef FEATURE_CORECLR // IID ICLRRuntimeHost2: uuid(712AB73F-2C22-4807-AD7E-F501D7B72C2D) cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost2, 0x712AB73F, 0x2C22, 0x4807, 0xAD, 0x7E, 0xF5, 0x01, 0xD7, 0xb7, 0x2C, 0x2D);") // IID IID_ICLRExecutionManager: uuid(1000A3E7-B420-4620-AE30-FB19B587AD1D) cpp_quote("EXTERN_GUID(IID_ICLRExecutionManager, 0x1000A3E7, 0xB420, 0x4620, 0xAE, 0x30, 0xFB, 0x19, 0xB5, 0x87, 0xAD, 0x1D);") -#endif // FEATURE_CORECLR - #ifdef FEATURE_INCLUDE_ALL_INTERFACES // IID ICLRHostProtectionManager : uuid{89F25F5C-CEEF-43e1-9CFA-A68CE863AAAC} cpp_quote("EXTERN_GUID(IID_ICLRHostProtectionManager, 0x89f25f5c, 0xceef, 0x43e1, 0x9c, 0xfa, 0xa6, 0x8c, 0xe8, 0x63, 0xaa, 0xac);") @@ -271,24 +254,7 @@ cpp_quote("EXTERN_GUID(IID_ITypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0 #pragma midl_echo("DEPRECATED_CLR_STDAPI LoadStringRCEx(LCID lcid, UINT iResouceID, _Out_writes_z_(iMax) LPWSTR szBuffer, int iMax, int bQuiet, int *pcwchUsed);") #endif -#ifndef FEATURE_CORECLR -// Ideally we would like to make the function pointer definition below as DEPRECATED_CLR_STDAPI. However, -// since it is referenced in the following definition of LockClrVersion, it will result in a build failure -// in our own build (since we treat warnings as errors). -// -// However, there is no other usage of this pointer outside LockClrVersion. Thus, we will not mark -// the pointer as legacy API. This will ensure we can build the runtime and if someone tries to use -// it via LockClrVersion, they will have build warning since LockClrVersion is marked as legacy API. -#pragma midl_echo("typedef HRESULT (__stdcall *FLockClrVersionCallback) ();") -#pragma midl_echo("DEPRECATED_CLR_STDAPI LockClrVersion(FLockClrVersionCallback hostCallback,FLockClrVersionCallback *pBeginHostSetup,FLockClrVersionCallback *pEndHostSetup);") -#pragma midl_echo("DEPRECATED_CLR_STDAPI CreateDebuggingInterfaceFromVersion(int iDebuggerVersion, LPCWSTR szDebuggeeVersion, IUnknown ** ppCordb);") -#pragma midl_echo("DEPRECATED_CLR_STDAPI GetVersionFromProcess(HANDLE hProcess, _Out_writes_to_(cchBuffer, *dwLength) LPWSTR pVersion, DWORD cchBuffer, _Out_ DWORD* dwLength);") -#endif - - -#ifdef FEATURE_CORECLR #pragma midl_echo("typedef HRESULT (STDAPICALLTYPE *FnGetCLRRuntimeHost)(REFIID riid, IUnknown **pUnk);") -#endif typedef enum { HOST_TYPE_DEFAULT = 0x0, @@ -324,11 +290,9 @@ typedef enum { STARTUP_TRIM_GC_COMMIT = 0x80000, // GC uses less committed space when system memory low STARTUP_ETW = 0x100000, STARTUP_ARM = 0x400000, // Enable the ARM feature. -#ifdef FEATURE_CORECLR STARTUP_SINGLE_APPDOMAIN = 0x800000, // application runs in default domain, no more domains are created STARTUP_APPX_APP_MODEL = 0x1000000, // jupiter app STARTUP_DISABLE_RANDOMIZED_STRING_HASHING = 0x2000000 // Disable the randomized string hashing -#endif } STARTUP_FLAGS; typedef enum { @@ -356,11 +320,8 @@ typedef enum APPDOMAIN_SECURITY_DEFAULT =0x0, APPDOMAIN_SECURITY_SANDBOXED = 0x1, // appdomain is sandboxed APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE = 0x2, // no cross ad reverse pinvokes -#ifdef FEATURE_CORECLR APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS = 0x4, // -#endif //FEATURE_CORECLR APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS = 0x08, // do not pump messages during wait operations, do not call sync context -#ifdef FEATURE_CORECLR // When passed by the host, this flag will allow any assembly to perform PInvoke or COMInterop operations. // Otherwise, by default, only platform assemblies can perform those operations. APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x10, @@ -369,7 +330,6 @@ typedef enum APPDOMAIN_ENABLE_ASSEMBLY_LOADFILE = 0x80, APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT = 0x100, -#endif //FEATURE_CORECLR } APPDOMAIN_SECURITY_FLAGS; #pragma midl_echo("STDAPI GetRequestedRuntimeVersionForCLSID(REFCLSID rclsid, _Out_writes_opt_(cchBuffer) LPWSTR pVersion, DWORD cchBuffer, _Out_opt_ DWORD* dwLength, CLSID_RESOLUTION_FLAGS dwResolutionFlags);") @@ -1980,8 +1940,6 @@ interface ICLRRuntimeHost : IUnknown [out] DWORD *pReturnValue); }; -#ifdef FEATURE_CORECLR - // Keys for ICLRRuntmeHost2::Authenticate. No longer required. cpp_quote("#define CORECLR_HOST_AUTHENTICATION_KEY 0x1C6CA6F94025800LL") cpp_quote("#define CORECLR_HOST_AUTHENTICATION_KEY_NONGEN 0x1C6CA6F94025801LL") @@ -2054,8 +2012,6 @@ interface ICLRExecutionManager : IUnknown HRESULT Resume([in] DWORD dwAppDomainId); } -#endif // FEATURE_CORECLR - //***************************************************************************** // Interface to utilize HostProtection //***************************************************************************** diff --git a/src/inc/clrtypes.h b/src/inc/clrtypes.h index 5f9de0cbf1..b0b1fc23f4 100644 --- a/src/inc/clrtypes.h +++ b/src/inc/clrtypes.h @@ -12,7 +12,7 @@ #ifndef CLRTYPES_H_ #define CLRTYPES_H_ -#if defined(_MSC_VER) && !defined(SOURCE_FORMATTING) && (!defined(FEATURE_CORECLR) || defined(FEATURE_CORESYSTEM)) +#if defined(_MSC_VER) && !defined(SOURCE_FORMATTING) && defined(FEATURE_CORESYSTEM) // Prefer intsafe.h when available, which defines many of the MAX/MIN // values below (which is why they are in #ifndef blocks). #include <intsafe.h> diff --git a/src/inc/stacktrace.h b/src/inc/stacktrace.h index 24fdf9482c..9152116d39 100644 --- a/src/inc/stacktrace.h +++ b/src/inc/stacktrace.h @@ -83,9 +83,9 @@ void GetStringFromAddr(DWORD_PTR dwAddr, __out_ecount(cchMaxAssertStackLevelStri * support this, so we need it for CoreCLR 4, if we require Win2K support ****************************************************************************/ extern "C" void __stdcall ClrCaptureContext(__out PCONTEXT ctx); -#else // _TARGET_X86_ && FEATURE_CORECLR && !FEATURE_PAL +#else // _TARGET_X86_ && !FEATURE_PAL #define ClrCaptureContext RtlCaptureContext -#endif // _TARGET_X86_ && FEATURE_CORECLR && !FEATURE_PAL +#endif // _TARGET_X86_ && !FEATURE_PAL #endif diff --git a/src/inc/zapper.h b/src/inc/zapper.h index 4356f5e682..26ac7e8f14 100644 --- a/src/inc/zapper.h +++ b/src/inc/zapper.h @@ -125,10 +125,10 @@ class Zapper #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) SString m_CLRJITPath; bool m_fDontLoadJit; -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) #if !defined(NO_NGENPDB) SString m_DiasymreaderPath; -#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB) +#endif // !defined(NO_NGENPDB) bool m_fForceFullTrust; SString m_outputFilename; @@ -392,11 +392,11 @@ class Zapper #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) void SetCLRJITPath(LPCWSTR pwszCLRJITPath); void SetDontLoadJit(); -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) #if !defined(NO_NGENPDB) void SetDiasymreaderPath(LPCWSTR pwzDiasymreaderPath); -#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB) +#endif // !defined(NO_NGENPDB) void SetOutputFilename(LPCWSTR pwszOutputFilename); SString GetOutputFileName(); diff --git a/src/strongname/api/strongname.cpp b/src/strongname/api/strongname.cpp index 00b115698c..09c438b213 100644 --- a/src/strongname/api/strongname.cpp +++ b/src/strongname/api/strongname.cpp @@ -113,9 +113,6 @@ enum StrongNameCachedCsp { // allocated lazily as needed. struct SN_THREAD_CTX { DWORD m_dwLastError; -#if !defined(FEATURE_CORECLR) - HCRYPTPROV m_hProv[CachedCspCount]; -#endif // !FEATURE_CORECLR }; #endif // !DACCESS_COMPILE @@ -170,8 +167,6 @@ struct SN_THREAD_CTX { memcmp((_pk), g_rbTheKey, sizeof(g_rbTheKey)) == 0) -#ifdef FEATURE_CORECLR - // Silverlight platform key #define SN_THE_SILVERLIGHT_PLATFORM_KEYTOKEN() ((PublicKeyBlob*)g_rbTheSilverlightPlatformKeyToken) #define SN_IS_THE_SILVERLIGHT_PLATFORM_KEY(_pk) (SN_SIZEOF_KEY((PublicKeyBlob*)(_pk)) == sizeof(g_rbTheSilverlightPlatformKey) && \ @@ -197,4480 +192,9 @@ struct SN_THREAD_CTX { memcmp((_pk), g_rbTheMicrosoftXNAKey, sizeof(g_rbTheMicrosoftXNAKey)) == 0) #endif // FEATURE_WINDOWSPHONE -#endif // FEATURE_CORECLR - -#if !defined(FEATURE_CORECLR) - -#ifdef FEATURE_STRONGNAME_MIGRATION -#include "caparser.h" -#include "custattr.h" -#include "cahlprinternal.h" -#endif // FEATURE_STRONGNAME_MIGRATION - -// The maximum length of CSP name we support (in characters). -#define SN_MAX_CSP_NAME 1024 - -// If we're being built as a standalone library, then we shouldn't redirect through the hosting APIs -#if !STRONGNAME_IN_VM - -#undef MapViewOfFile -#undef UnmapViewOfFile - -#define CLRMapViewOfFile MapViewOfFile -#define CLRUnmapViewOfFile UnmapViewOfFile - -#if FEATURE_STANDALONE_SN && !FEATURE_CORECLR - -// We will need to call into shim, therefore include new hosting APIs -#include "metahost.h" -#include "clrinternal.h" - -#endif //FEATURE_STANDALONE_SN && !FEATURE_CORECLR - -#define DONOT_DEFINE_ETW_CALLBACK - -#endif // !STRONGNAME_IN_VM -#include "eventtracebase.h" - -#ifndef DACCESS_COMPILE - -// Flag indicating whether the initialization of the strong name APIs has been completed. -BOOLEAN g_bStrongNamesInitialized = FALSE; - -// Flag indicating whether it's OK to cache the results of verifying an assembly -// whose file is accessible to users. -BOOLEAN g_fCacheVerify = TRUE; - -// Algorithm IDs for hashing and signing. Like the CSP name, these values are -// read from the registry at initialization time. -ALG_ID g_uHashAlgId; -ALG_ID g_uSignAlgId; - -// Flag read from the registry at initialization time. It controls the key spec -// to be used. AT_SIGNATURE will be the default. -DWORD g_uKeySpec; - -// CSP provider type. PROV_RSA_FULL will be the default. -DWORD g_uProvType; - -// Critical section used to serialize some non-thread safe crypto APIs. -CRITSEC_COOKIE g_rStrongNameMutex = NULL; - -// Name of CSP to use. This is read from the registry at initialization time. If -// not found we look up a CSP by hashing and signing algorithms (see below) or -// use the default CSP. - -BOOLEAN g_bHasCSPName = FALSE; -WCHAR g_wszCSPName[SN_MAX_CSP_NAME + 1] = {0}; - -// Flag read from the registry at initialization time. Controls whether we use -// machine or user based key containers. -BOOLEAN g_bUseMachineKeyset = TRUE; - -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED -// Verification Skip Records -// -// These are entries in the registry (usually set up by SN) that control whether -// an assembly needs to pass signature verification to be considered valid (i.e. -// return TRUE from StrongNameSignatureVerification). This is useful during -// development when it's not feasible to fully sign each assembly on each build. -// Assemblies to be skipped can be specified by name and public key token, all -// assemblies with a given public key token or just all assemblies. Each entry -// can be further qualified by a list of user names to which the records -// applies. When matching against an entry, the most specific one wins. -// -// We read these entries at startup time and place them into a global, singly -// linked, NULL terminated list. - -// Structure used to represent each record we find in the registry. -struct SN_VER_REC { - SN_VER_REC *m_pNext; // Pointer to next record (or NULL) - WCHAR *m_wszAssembly; // Assembly name/public key token as a string - WCHAR *m_mszUserList; // Pointer to multi-string list of valid users (or NULL) - WCHAR *m_wszTestPublicKey; // Test public key to use during strong name verification (or NULL) -}; - -// Head of the list of entries we found in the registry during initialization. -SN_VER_REC *g_pVerificationRecords = NULL; -#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - -#ifdef FEATURE_STRONGNAME_MIGRATION - -struct SN_REPLACEMENT_KEY_REC { - SN_REPLACEMENT_KEY_REC *m_pNext; - BYTE *m_pbReplacementKey; - ULONG m_cbReplacementKey; -}; - -struct SN_REVOCATION_REC { - SN_REVOCATION_REC *m_pNext; - BYTE *m_pbRevokedKey; - ULONG m_cbRevokedKey; - SN_REPLACEMENT_KEY_REC *m_pReplacementKeys; -}; - -SN_REVOCATION_REC *g_pRevocationRecords = NULL; - -#endif // FEATURE_STRONGNAME_MIGRATION - -#endif // #ifndef DACCESS_COMPILE - - - -#ifndef DACCESS_COMPILE - -// The actions that can be performed upon opening a CSP with LocateCSP. -#define SN_OPEN_CONTAINER 0 -#define SN_IGNORE_CONTAINER 1 -#define SN_CREATE_CONTAINER 2 -#define SN_DELETE_CONTAINER 3 -#define SN_HASH_SHA1_ONLY 4 - -// Macro to aid in setting flags for CryptAcquireContext based on container -// actions above. -#define SN_CAC_FLAGS(_act) \ - (((_act) == SN_OPEN_CONTAINER ? 0 : \ - ((_act) == SN_HASH_SHA1_ONLY) || ((_act) == SN_IGNORE_CONTAINER) ? CRYPT_VERIFYCONTEXT : \ - (_act) == SN_CREATE_CONTAINER ? CRYPT_NEWKEYSET : \ - (_act) == SN_DELETE_CONTAINER ? CRYPT_DELETEKEYSET : \ - 0) | \ - (g_bUseMachineKeyset ? CRYPT_MACHINE_KEYSET : 0)) - -// Substitute a strong name error if the error we're wrapping is not transient -FORCEINLINE HRESULT SubstituteErrorIfNotTransient(HRESULT hrOriginal, HRESULT hrSubstitute) -{ - return Exception::IsTransient(hrOriginal) ? hrOriginal : hrSubstitute; -} - -// Private routine prototypes. -SN_THREAD_CTX *GetThreadContext(); -VOID SetStrongNameErrorInfo(DWORD dwStatus); -HCRYPTPROV LocateCSP(LPCWSTR wszKeyContainer, - DWORD dwAction, - ALG_ID uHashAlgId = 0, - ALG_ID uSignAlgId = 0); -VOID FreeCSP(HCRYPTPROV hProv); -HCRYPTPROV LookupCachedCSP(StrongNameCachedCsp cspNumber); -VOID CacheCSP(HCRYPTPROV hProv, StrongNameCachedCsp cspNumber); -BOOLEAN IsCachedCSP(HCRYPTPROV hProv); -HRESULT ReadRegistryConfig(); -BOOLEAN LoadCryptoApis(); -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED -HRESULT ReadVerificationRecords(); - -#ifdef FEATURE_STRONGNAME_MIGRATION -HRESULT ReadRevocationRecords(); -#endif // FEATURE_STRONGNAME_MIGRATION -SN_VER_REC *GetVerificationRecord(__in_z __deref LPWSTR wszAssemblyName, PublicKeyBlob *pPublicKey); -#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - -BOOLEAN IsValidUser(__in_z WCHAR *mszUserList); -BOOLEAN GetKeyContainerName(LPCWSTR *pwszKeyContainer, BOOLEAN *pbTempContainer); -VOID FreeKeyContainerName(LPCWSTR wszKeyContainer, BOOLEAN bTempContainer); -HRESULT GetMetadataImport(__in const SN_LOAD_CTX *pLoadCtx, - __in mdAssembly *ptkAssembly, - __out IMDInternalImport **ppMetaDataImport); -HRESULT FindPublicKey(const SN_LOAD_CTX *pLoadCtx, - __out_ecount_opt(cchAssemblyName) LPWSTR wszAssemblyName, - DWORD cchAssemblyName, - __out PublicKeyBlob **ppPublicKey, - DWORD *pcbPublicKey = NULL); -PublicKeyBlob *GetPublicKeyFromHex(LPCWSTR wszPublicKeyHexString); -BOOLEAN RehashModules(SN_LOAD_CTX *pLoadCtx, LPCWSTR szFilePath); -HRESULT VerifySignature(SN_LOAD_CTX *pLoadCtx, - DWORD dwInFlags, - PublicKeyBlob *pRealEcmaPublicKey, - DWORD *pdwOutFlags); -HRESULT InitStrongNameCriticalSection(); -HRESULT InitStrongName(); -typedef BOOLEAN (*HashFunc)(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie); -BOOLEAN ComputeHash(SN_LOAD_CTX *pLoadCtx, HCRYPTHASH hHash, HashFunc func, void* cookie); -bool VerifyKeyMatchesAssembly(PublicKeyBlob * pAssemblySignaturePublicKey, __in_z LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, DWORD dwFlags); - -#ifdef FEATURE_STRONGNAME_MIGRATION -HRESULT GetVerifiedSignatureKey(__in SN_LOAD_CTX *pLoadCtx, __out PublicKeyBlob **ppPublicKey, __out DWORD *pcbPublicKey = NULL); -#endif // FEATURE_STRONGNAME_MIGRATION - -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) - -void DbgCount(__in_z WCHAR *szCounterName) -{ - -#ifndef FEATURE_CORECLR - if (g_fLoggingInitialized && !(g_dwLoggingFlags & 4)) - return; - - DWORD dwError = GetLastError(); - - if (!g_fLoggingInitialized) { - g_dwLoggingFlags = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MscorsnLogging); - g_fLoggingInitialized = TRUE; - } - - if (!(g_dwLoggingFlags & 4)) { - SetLastError(dwError); - return; - } - - HKEY hKey = NULL; - DWORD dwCounter = 0; - DWORD dwBytes; - - if (WszRegCreateKeyEx(HKEY_LOCAL_MACHINE, - SN_CONFIG_KEY_W W("\\Counters"), - 0, - NULL, - 0, - KEY_ALL_ACCESS, - NULL, - &hKey, - NULL) != ERROR_SUCCESS) - goto End; - - WszRegQueryValueEx(hKey, szCounterName, NULL, NULL, (BYTE*)&dwCounter, &dwBytes); - dwCounter++; - WszRegSetValueEx(hKey, szCounterName, NULL, REG_DWORD, (BYTE*)&dwCounter, sizeof(DWORD)); - - End: - if (hKey) - RegCloseKey(hKey); - SetLastError(dwError); - -#endif //#ifndef FEATURE_CORECLR - -} - - -void HexDump(BYTE *pbData, - DWORD cbData) -{ - if (g_dwLoggingFlags == 0) - return; - - DWORD dwRow, dwCol; - WCHAR wszBuffer[1024]; - WCHAR *wszPtr = wszBuffer; - -#define SN_PUSH0(_fmt) do { wszPtr += swprintf_s(wszPtr, COUNTOF(wszBuffer) - (wszPtr - wszBuffer), _fmt); } while (false) -#define SN_PUSH1(_fmt, _arg1) do { wszPtr += swprintf_s(wszPtr, COUNTOF(wszBuffer) - (wszPtr - wszBuffer), _fmt, _arg1); } while (false) - - wszBuffer[0] = W('\0'); - - for (dwRow = 0; dwRow < ((cbData + 15) / 16); dwRow++) { - SN_PUSH1(W("%08p "), pbData + (16 * dwRow)); - for (dwCol = 0; dwCol < 16; dwCol++) - if (((dwRow * 16) + dwCol) < cbData) - SN_PUSH1(W("%02X "), pbData[(dwRow * 16) + dwCol]); - else - SN_PUSH0(W(" ")); - for (dwCol = 0; dwCol < 16; dwCol++) - if (((dwRow * 16) + dwCol) < cbData) { - unsigned char c = pbData[(dwRow * 16) + dwCol]; - if ((c >= 32) && (c <= 127)) - SN_PUSH1(W("%c"), c); - else - SN_PUSH0(W(".")); - } else - SN_PUSH0(W(" ")); - SN_PUSH0(W("\n")); - } -#undef SN_PUSH1 -#undef SN_PUSH0 - - _ASSERTE(wszPtr < &wszBuffer[COUNTOF(wszBuffer)]); - - Log(W("%s"), wszBuffer); -} - -#else // _DEBUG && !DACCESS_COMPILE - -#define HexDump(x) -#define DbgCount(x) - -#endif // _DEBUG && !DACCESS_COMPILE - - -BOOLEAN CalculateSize(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie) -{ - *(size_t*)cookie += length; - return TRUE; -} - -struct CopyDataBufferDesc -{ - PBYTE pbData; - DWORD cbDataSize; -}; - -BOOLEAN CopyData(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie) -{ - _ASSERTE(cookie); - - CopyDataBufferDesc *pBuffer = reinterpret_cast<CopyDataBufferDesc *>(cookie); - _ASSERTE(pBuffer->pbData); - - memcpy_s(pBuffer->pbData, pBuffer->cbDataSize, start, length); - pBuffer->pbData += length; - - _ASSERTE(pBuffer->cbDataSize >= length); - pBuffer->cbDataSize = pBuffer->cbDataSize >= length ? pBuffer->cbDataSize - length : 0; - - return TRUE; -} - -BOOLEAN CalcHash(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie) -{ - return CryptHashData(hHash, start, length, flags); -} - -VOID -WINAPI Fls_Callback ( - IN PVOID lpFlsData - ) -{ - STATIC_CONTRACT_SO_TOLERANT; - SN_THREAD_CTX *pThreadCtx = (SN_THREAD_CTX*)lpFlsData; - if (pThreadCtx != NULL) { - for(ULONG i = 0; i < CachedCspCount; i++) - { - if (pThreadCtx->m_hProv[i]) - CryptReleaseContext(pThreadCtx->m_hProv[i], 0); - } - - delete pThreadCtx; - } -} - -HRESULT InitStrongNameCriticalSection() -{ - if (g_rStrongNameMutex) - return S_OK; - - CRITSEC_COOKIE pv = ClrCreateCriticalSection(CrstStrongName, CRST_DEFAULT); - if (pv == NULL) - return E_OUTOFMEMORY; - - if (InterlockedCompareExchangeT(&g_rStrongNameMutex, pv, NULL) != NULL) - ClrDeleteCriticalSection(pv); - return S_OK; -} - -HRESULT InitStrongName() -{ - HRESULT hr = S_OK; - if (g_bStrongNamesInitialized) - return hr; - - // Read CSP configuration info from the registry (if provided). - hr = ReadRegistryConfig(); - if (FAILED(hr)) - return hr; - - // Associate a callback for freeing our TLS data. - ClrFlsAssociateCallback(TlsIdx_StrongName, Fls_Callback); - - g_bStrongNamesInitialized = TRUE; - - return hr; -} - -// Generate a new key pair for strong name use. -SNAPI StrongNameKeyGen(LPCWSTR wszKeyContainer, // [in] desired key container name, must be a non-empty string - DWORD dwFlags, // [in] flags (see below) - BYTE **ppbKeyBlob, // [out] public/private key blob - ULONG *pcbKeyBlob) -{ - BOOLEAN retVal = FALSE; - BEGIN_ENTRYPOINT_VOIDRET; - - SN_COMMON_PROLOG(); - - if (wszKeyContainer == NULL && ppbKeyBlob == NULL) - SN_ERROR(E_INVALIDARG); - if (ppbKeyBlob != NULL && pcbKeyBlob == NULL) - SN_ERROR(E_POINTER); - - DWORD dwKeySize; - - // We set a key size of 1024 if we're using the default - // signing algorithm (RSA), otherwise we leave it at the default. - if (g_uSignAlgId == CALG_RSA_SIGN) - dwKeySize = 1024; - else - dwKeySize = 0; - - retVal = StrongNameKeyGenEx(wszKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob); - -Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// Generate a new key pair with the specified key size for strong name use. -SNAPI StrongNameKeyGenEx(LPCWSTR wszKeyContainer, // [in] desired key container name, must be a non-empty string - DWORD dwFlags, // [in] flags (see below) - DWORD dwKeySize, // [in] desired key size. - BYTE **ppbKeyBlob, // [out] public/private key blob - ULONG *pcbKeyBlob) -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - HCRYPTPROV hProv = NULL; - HCRYPTKEY hKey = NULL; - BOOLEAN bTempContainer = FALSE; - - SNLOG((W("StrongNameKeyGenEx(\"%s\", %08X, %08X, %08X, %08X)\n"), wszKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob)); - - SN_COMMON_PROLOG(); - - if (wszKeyContainer == NULL && ppbKeyBlob == NULL) - SN_ERROR(E_INVALIDARG); - if (ppbKeyBlob != NULL && pcbKeyBlob == NULL) - SN_ERROR(E_POINTER); - - // Check to see if a temporary container name is needed. - _ASSERTE((wszKeyContainer != NULL) || !(dwFlags & SN_LEAVE_KEY)); - if (!GetKeyContainerName(&wszKeyContainer, &bTempContainer)) - { - goto Exit; - } - - // Open a CSP and container. - hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER); - if (!hProv) - goto Error; - - - // Generate the new key pair, try for exportable first. - // Note: The key size in bits is encoded in the upper - // 16-bits of a DWORD (and OR'd together with other flags for the - // CryptGenKey call). - if (!CryptGenKey(hProv, g_uKeySpec, (dwKeySize << 16) | CRYPT_EXPORTABLE, &hKey)) { - SNLOG((W("Couldn't create exportable key, trying for non-exportable: %08X\n"), GetLastError())); - if (!CryptGenKey(hProv, g_uKeySpec, dwKeySize << 16, &hKey)) { - SNLOG((W("Couldn't create key pair: %08X\n"), GetLastError())); - goto Error; - } - } - -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) - if (g_bHasCSPName) { - ALG_ID uAlgId; - DWORD dwAlgIdLen = sizeof(uAlgId); - // Check that signature algorithm used was the one we expected. - if (CryptGetKeyParam(hKey, KP_ALGID, (BYTE*)&uAlgId, &dwAlgIdLen, 0)) { - _ASSERTE(uAlgId == g_uSignAlgId); - } else - SNLOG((W("Failed to get key params: %08X\n"), GetLastError())); - } -#endif // _DEBUG - - // If the user wants the key pair back, attempt to export it. - if (ppbKeyBlob) { - - // Calculate length of blob first; - if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, NULL, pcbKeyBlob)) { - SNLOG((W("Couldn't export key pair: %08X\n"), GetLastError())); - goto Error; - } - - // Allocate a buffer of the right size. - *ppbKeyBlob = new (nothrow) BYTE[*pcbKeyBlob]; - if (*ppbKeyBlob == NULL) { - SetLastError(E_OUTOFMEMORY); - goto Error; - } - - // Export the key pair. - if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, *ppbKeyBlob, pcbKeyBlob)) { - SNLOG((W("Couldn't export key pair: %08X\n"), GetLastError())); - delete[] *ppbKeyBlob; - *ppbKeyBlob = NULL; - goto Error; - } - } - - // Destroy the key handle (but not the key pair itself). - CryptDestroyKey(hKey); - hKey = NULL; - - // Release the CSP. - FreeCSP(hProv); - - // If the user didn't explicitly want to keep the key pair around, delete the - // key container. - if (!(dwFlags & SN_LEAVE_KEY) || bTempContainer) - LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER); - - // Free temporary key container name if allocated. - FreeKeyContainerName(wszKeyContainer, bTempContainer); - retVal = TRUE; - goto Exit; - - Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (hKey) - CryptDestroyKey(hKey); - if (hProv) { - FreeCSP(hProv); - if (!(dwFlags & SN_LEAVE_KEY) || bTempContainer) - LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER); - } - FreeKeyContainerName(wszKeyContainer, bTempContainer); - - Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - - -// Import key pair into a key container. -SNAPI StrongNameKeyInstall(LPCWSTR wszKeyContainer,// [in] desired key container name, must be a non-empty string - BYTE *pbKeyBlob, // [in] public/private key pair blob - ULONG cbKeyBlob) -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - HCRYPTPROV hProv = NULL; - HCRYPTKEY hKey = NULL; - - SNLOG((W("StrongNameKeyInstall(\"%s\", %08X, %08X)\n"), wszKeyContainer, pbKeyBlob, cbKeyBlob)); - - SN_COMMON_PROLOG(); - - if (wszKeyContainer == NULL) - SN_ERROR(E_POINTER); - if (pbKeyBlob == NULL) - SN_ERROR(E_POINTER); - if (cbKeyBlob == 0) - SN_ERROR(E_INVALIDARG); - - // Open a CSP and container. - hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER); - if (!hProv) { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - goto Exit; - } - - // Import the key pair. - if (!CryptImportKey(hProv, - pbKeyBlob, - cbKeyBlob, - 0, 0, &hKey)) { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - FreeCSP(hProv); - goto Exit; - } - - // Release the CSP. - FreeCSP(hProv); - retVal = TRUE; -Exit: - - END_ENTRYPOINT_VOIDRET; - return retVal; -} - - -// Delete a key pair. -SNAPI StrongNameKeyDelete(LPCWSTR wszKeyContainer) // [in] desired key container name -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - HCRYPTPROV hProv; - - SNLOG((W("StrongNameKeyDelete(\"%s\")\n"), wszKeyContainer)); - - SN_COMMON_PROLOG(); - - if (wszKeyContainer == NULL) - SN_ERROR(E_POINTER); - - // Open and delete the named container. - hProv = LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER); - if (hProv) { - // Returned handle isn't actually valid in the delete case, so we're - // finished. - retVal = TRUE; - } else { - SetStrongNameErrorInfo(CORSEC_E_CONTAINER_NOT_FOUND); - retVal = FALSE; - } -Exit: - - END_ENTRYPOINT_VOIDRET; - return retVal; - -} - -// Retrieve the public portion of a key pair. -SNAPI StrongNameGetPublicKey (LPCWSTR wszKeyContainer, // [in] desired key container name - BYTE *pbKeyBlob, // [in] public/private key blob (optional) - ULONG cbKeyBlob, - BYTE **ppbPublicKeyBlob, // [out] public key blob - ULONG *pcbPublicKeyBlob) -{ - LIMITED_METHOD_CONTRACT; - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - retVal = StrongNameGetPublicKeyEx( - wszKeyContainer, - pbKeyBlob, - cbKeyBlob, - ppbPublicKeyBlob, - pcbPublicKeyBlob, - 0, - 0); - - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// Holder for any HCRYPTPROV handles allocated by the strong name APIs -typedef Wrapper<HCRYPTPROV, DoNothing, FreeCSP, 0> HandleStrongNameCspHolder; - - -SNAPI StrongNameGetPublicKeyEx (LPCWSTR wszKeyContainer, // [in] desired key container name - BYTE *pbKeyBlob, // [in] public/private key blob (optional) - ULONG cbKeyBlob, - BYTE **ppbPublicKeyBlob, // [out] public key blob - ULONG *pcbPublicKeyBlob, - ULONG uHashAlgId, - ULONG uReserved) // reserved for future use as uSigAlgId (signature algorithm id) -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - HandleStrongNameCspHolder hProv(NULL); - CapiKeyHolder hKey(NULL); - DWORD dwKeyLen; - PublicKeyBlob *pKeyBlob; - DWORD dwSigAlgIdLen; - - SNLOG((W("StrongNameGetPublicKeyEx(\"%s\", %08X, %08X, %08X, %08X, %08X)\n"), wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob, uHashAlgId)); - - SN_COMMON_PROLOG(); - - if (wszKeyContainer == NULL && pbKeyBlob == NULL) - SN_ERROR(E_INVALIDARG); - if (pbKeyBlob != NULL && !(StrongNameIsEcmaKey(pbKeyBlob, cbKeyBlob) || StrongNameIsValidKeyPair(pbKeyBlob, cbKeyBlob))) - SN_ERROR(E_INVALIDARG); - if (ppbPublicKeyBlob == NULL) - SN_ERROR(E_POINTER); - if (pcbPublicKeyBlob == NULL) - SN_ERROR(E_POINTER); - if (uReserved != 0) - SN_ERROR(E_INVALIDARG); - - bool fHashAlgorithmValid; - fHashAlgorithmValid = uHashAlgId == 0 || - (GET_ALG_CLASS(uHashAlgId) == ALG_CLASS_HASH && GET_ALG_SID(uHashAlgId) >= ALG_SID_SHA1 && GET_ALG_SID(uHashAlgId) <= ALG_SID_SHA_512); - if(!fHashAlgorithmValid) - SN_ERROR(E_INVALIDARG); - - if(uHashAlgId == 0) - uHashAlgId = g_uHashAlgId; - - // If we're handed a platform neutral public key, just hand it right back to - // the user. Well, hand back a copy at least. - if (pbKeyBlob && cbKeyBlob && SN_IS_NEUTRAL_KEY(pbKeyBlob)) { - *pcbPublicKeyBlob = sizeof(g_rbNeutralPublicKey); - *ppbPublicKeyBlob = (BYTE*)g_rbNeutralPublicKey; - retVal = TRUE; - goto Exit; - } - - // Open a CSP. Create a key container if a public/private key blob is - // provided, otherwise we assume a key container already exists. - if (pbKeyBlob) - hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER); - else - hProv = LocateCSP(wszKeyContainer, SN_OPEN_CONTAINER); - if (!hProv) - goto Error; - - // If a key blob was provided, import the key pair into the container. - if (pbKeyBlob) { - if (!CryptImportKey(hProv, - pbKeyBlob, - cbKeyBlob, - 0, 0, &hKey)) - goto Error; - } else { -#if !defined(FEATURE_CORESYSTEM) - // Else fetch the signature key pair from the container. - if (!CryptGetUserKey(hProv, g_uKeySpec, &hKey)) - goto Error; -#else // FEATURE_CORESYSTEM - SetLastError(E_NOTIMPL); - goto Error; -#endif // !FEATURE_CORESYSTEM - } - - // Determine the length of the public key part as a blob. - if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwKeyLen)) - goto Error; - - -#ifdef _PREFAST_ -#pragma warning(push) -#pragma warning(disable:22011) // Suppress this PREFast warning which gets triggered by the offset macro expansion. -#endif - // And then the length of the PublicKeyBlob structure we return to the - // caller. - *pcbPublicKeyBlob = offsetof(PublicKeyBlob, PublicKey) + dwKeyLen; -#ifdef _PREFAST_ -#pragma warning(pop) -#endif - - // Allocate a large enough buffer. - *ppbPublicKeyBlob = new (nothrow) BYTE[*pcbPublicKeyBlob]; - if (*ppbPublicKeyBlob == NULL) { - SetLastError(E_OUTOFMEMORY); - goto Error; - } - - pKeyBlob = (PublicKeyBlob*)*ppbPublicKeyBlob; - - // Extract the public part as a blob. - if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pKeyBlob->PublicKey, &dwKeyLen)) { - delete[] *ppbPublicKeyBlob; - *ppbPublicKeyBlob = NULL; - goto Error; - } - - // Extract key's signature algorithm and store it in the key blob. - dwSigAlgIdLen = sizeof(unsigned int); - ALG_ID SigAlgID; - if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE*)&SigAlgID, &dwSigAlgIdLen, 0)) { - delete[] *ppbPublicKeyBlob; - *ppbPublicKeyBlob = NULL; - goto Error; - } - SET_UNALIGNED_VAL32(&pKeyBlob->SigAlgID, SigAlgID); - - // Fill in the other public key blob fields. - SET_UNALIGNED_VAL32(&pKeyBlob->HashAlgID, uHashAlgId); - SET_UNALIGNED_VAL32(&pKeyBlob->cbPublicKey, dwKeyLen); - - retVal = TRUE; - goto Exit; - -Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); -Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// Hash and sign a manifest. -SNAPI StrongNameSignatureGeneration(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - LPCWSTR wszKeyContainer, // [in] desired key container name - BYTE *pbKeyBlob, // [in] public/private key blob (optional) - ULONG cbKeyBlob, - BYTE **ppbSignatureBlob, // [out] signature blob - ULONG *pcbSignatureBlob) -{ - BOOL fRetVal = FALSE; - BEGIN_ENTRYPOINT_VOIDRET; - fRetVal = StrongNameSignatureGenerationEx(wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, 0); - END_ENTRYPOINT_VOIDRET; - return fRetVal; -} - -HRESULT FindAssemblySignaturePublicKey(const SN_LOAD_CTX *pLoadCtx, - __out PublicKeyBlob **ppPublicKey) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - HRESULT hr; - StrongNameBufferHolder<PublicKeyBlob> result = NULL; - - IfFailRet(FindPublicKey(pLoadCtx, NULL, 0, &result)); - -#ifdef FEATURE_STRONGNAME_MIGRATION - PublicKeyBlob *pSignaturePublicKey = NULL; - IfFailRet(GetVerifiedSignatureKey((SN_LOAD_CTX*) pLoadCtx, &pSignaturePublicKey)); - - if(hr != S_FALSE) - { - result = pSignaturePublicKey; - } -#endif // FEATURE_STRONGNAME_MIGRATION - - *ppPublicKey = result.Extract(); - - return S_OK; -} - -SNAPI StrongNameSignatureGenerationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - LPCWSTR wszKeyContainer, // [in] desired key container name - BYTE *pbKeyBlob, // [in] public/private key blob (optional) - ULONG cbKeyBlob, - BYTE **ppbSignatureBlob, // [out] signature blob - ULONG *pcbSignatureBlob, - DWORD dwFlags) // [in] modifer flags -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - HandleStrongNameCspHolder hProv(NULL); - CapiHashHolder hHash(NULL); - NewArrayHolder<BYTE> pbSig(NULL); - ULONG cbSig = 0; - SN_LOAD_CTX sLoadCtx; - BOOLEAN bImageLoaded = FALSE; - ALG_ID uHashAlgId; - StrongNameBufferHolder<PublicKeyBlob> pSignatureKey = NULL; - - SNLOG((W("StrongNameSignatureGenerationEx(\"%s\", \"%s\", %08X, %08X, %08X, %08X, %08X)\n"), wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, dwFlags)); - - SN_COMMON_PROLOG(); - - uHashAlgId = g_uHashAlgId; - - if (pbKeyBlob != NULL && !StrongNameIsValidKeyPair(pbKeyBlob, cbKeyBlob)) - SN_ERROR(E_INVALIDARG); - if (ppbSignatureBlob != NULL && pcbSignatureBlob == NULL) - SN_ERROR(E_POINTER); - - if (wszFilePath != NULL) { - // Map the assembly into memory. - sLoadCtx.m_fReadOnly = FALSE; - if (!LoadAssembly(&sLoadCtx, wszFilePath)) - goto Error; - bImageLoaded = TRUE; - - // If we've asked to recalculate the file hashes of linked modules we have - // to load the metadata engine and search for file references. - if (dwFlags & SN_SIGN_ALL_FILES) - if (!RehashModules(&sLoadCtx, wszFilePath)) - goto Error; - - // If no key pair is provided, then we were only called to re-compute the hashes of - // linked modules in the assembly. - if (!wszKeyContainer && !pbKeyBlob) - { - retVal = TRUE; - goto Exit; - } - - HRESULT hr; - if(FAILED(hr = FindAssemblySignaturePublicKey(&sLoadCtx, &pSignatureKey))) - { - SN_ERROR(hr); - } - - // Ecma key has an algorithm of zero, so we ignore that case. - ALG_ID uKeyHashAlgId = GET_UNALIGNED_VAL32(&pSignatureKey->HashAlgID); - if(uKeyHashAlgId != 0) - { - uHashAlgId = uKeyHashAlgId; - } - } - - if (wszKeyContainer || pbKeyBlob) { // We have a key pair in a container, or in a blob - // Open a CSP. If a public/private key blob is provided, use CRYPT_VERIFYCONTEXT, - // otherwise we assume the key container already exists. - if (pbKeyBlob) - hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, uHashAlgId); - else - hProv = LocateCSP(wszKeyContainer, SN_OPEN_CONTAINER, uHashAlgId); - - if (hProv.GetValue() == NULL) - goto Error; - - // If a key blob was provided, import the key pair into the container. - // This might be the real key or the test-sign key. In the case of test signing, - // there's no way to specify hash algorithm, so we use the one from the - // assembly signature public key (in the metadata table, or the migration attribute). - if (pbKeyBlob) { - // The provider holds a reference to the key, so we don't need to - // keep one around. - CapiKeyHolder hKey(NULL); - if (!CryptImportKey(hProv, - pbKeyBlob, - cbKeyBlob, - 0, - 0, - &hKey)) - goto Error; - } - - // Create a hash object. - if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash)) - goto Error; - - // Compute size of the signature blob. - if (!CryptSignHashW(hHash, g_uKeySpec, NULL, 0, NULL, &cbSig)) - goto Error; - - // If the caller only wants the size of the signature, return it now and - // exit. - // RSA signature length is independent of the hash size, so hash algorithm - // doesn't matter here (we don't know the algorithm if the assembly path was passed in as NULL) - if (wszFilePath == NULL) { - *pcbSignatureBlob = cbSig; - retVal = TRUE; - goto Exit; - } - } - - // Verify that the public key of the assembly being signed matches the private key we're signing with - if ((wszKeyContainer != NULL || pbKeyBlob != NULL) && !VerifyKeyMatchesAssembly(pSignatureKey, wszKeyContainer, pbKeyBlob, cbKeyBlob, dwFlags)) - { - SetLastError(StrongNameErrorInfo()); - goto Error; - } - - // We set a bit in the header to indicate we're fully signing the assembly. - if (!(dwFlags & SN_TEST_SIGN)) - sLoadCtx.m_pCorHeader->Flags |= VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED); - else - sLoadCtx.m_pCorHeader->Flags &= ~VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED); - - // Destroy the old hash object and create a new one - // because CryptoAPI says you can't reuse a hash once you've signed it - // Note that this seems to work with MS-based CSPs but breaks on - // at least newer nCipher CSPs. - if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash)) - goto Error; - - // Compute a hash over the image. - if (!ComputeHash(&sLoadCtx, hHash, CalcHash, NULL)) - goto Error; - - // Allocate the blob. - pbSig = new (nothrow) BYTE[cbSig]; - if (pbSig == NULL) { - SetLastError(E_OUTOFMEMORY); - goto Error; - } - - // Compute a signature blob over the hash of the manifest. - if (!CryptSignHashW(hHash, g_uKeySpec, NULL, 0, pbSig, &cbSig)) - goto Error; - - // Check the signature size - if (sLoadCtx.m_cbSignature != cbSig) { - SetLastError(CORSEC_E_SIGNATURE_MISMATCH); - goto Error; - } - - // If the user hasn't asked for the signature to be returned as a pointer, write it to file. - if (!ppbSignatureBlob) - { - memcpy_s(sLoadCtx.m_pbSignature, sLoadCtx.m_cbSignature, pbSig, cbSig); - - // - // Memory-mapped IO in Windows doesn't guarantee that it will update - // the file's "Modified" timestamp, so we update it ourselves. - // - _ASSERTE(sLoadCtx.m_hFile != INVALID_HANDLE_VALUE); - - FILETIME ft; - SYSTEMTIME st; - - GetSystemTime(&st); - - // We don't care if updating the timestamp fails for any reason. - if(SystemTimeToFileTime(&st, &ft)) - { - SetFileTime(sLoadCtx.m_hFile, (LPFILETIME) NULL, (LPFILETIME) NULL, &ft); - } - } - - // Unmap the image (automatically recalculates and updates the image - // checksum). - bImageLoaded = FALSE; - if (!UnloadAssembly(&sLoadCtx)) - goto Error; - - if (ppbSignatureBlob) { - *ppbSignatureBlob = pbSig.Extract(); - *pcbSignatureBlob = cbSig; - } - - retVal = TRUE; - goto Exit; - -Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); -Exit: - if (bImageLoaded) - UnloadAssembly(&sLoadCtx); - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// -// Generate the digest of a delay signed assembly, which can be signed with StrongNameDigestSign. The digest -// algorithm is determined from the HashAlgID of the assembly's public key blob. -// -// Parameters: -// wszFilePath - path to the delay signed assembly to generate the digest of -// ppbDigestBlob - on success this will point to a buffer that contains the digest of the wszFilePath -// assembly. This buffer should be freed with StrongNameFreeBuffer. -// pcbDigestBlob - on success this will point to the size of the digest buffer in *ppbDigestBlob -// dwFlags - flags used to control signing. This is the same set of flags used by -// StrongNameSignatureGenerationEx -// - -bool StrongNameDigestGenerate_Internal(_In_z_ LPCWSTR wszFilePath, - _Outptr_result_bytebuffer_(*pcbDigestBlob) BYTE** ppbDigestBlob, - _Out_ ULONG* pcbDigestBlob, - DWORD dwFlags) -{ - // Load up the assembly and find its public key - this tells us which hash algorithm we need to use - // Note that it cannot be loaded read-only since we need to toggle the fully siged bit in order to - // calculate the correct hash for the signature. - StrongNameAssemblyLoadHolder assembly(wszFilePath, false /* read only */); - if (!assembly.IsLoaded()) - { - return false; - } - - // If we were asked to do a full rehashing of all modules that needs to be done before calculating the digest - if ((dwFlags & SN_SIGN_ALL_FILES) == SN_SIGN_ALL_FILES) - { - if (!RehashModules(assembly.GetLoadContext(), wszFilePath)) - { - return false; - } - } - - // During signature verification, the fully signed bit will be set in the assembly's COR header. - // Therefore, when calculating the digest of the assembly we must toggle this bit in order to make the - // digest match what will be calculated during verificaiton. However, we do not want to persist the - // bit flip on disk, since we're not actually signing the assembly now. We'll save the current COR - // flags, flip the bit for digesting, and then restore the COR flags before we finish calculating the - // digest. - class AssemblyFlagsHolder - { - private: - IMAGE_COR20_HEADER* m_pHeader; - DWORD m_originalFlags; - - public: - AssemblyFlagsHolder(_In_ IMAGE_COR20_HEADER* pHeader) - : m_pHeader(pHeader), - m_originalFlags(pHeader->Flags) - { - } - - ~AssemblyFlagsHolder() - { - m_pHeader->Flags = m_originalFlags; - } - } flagsHolder(assembly.GetLoadContext()->m_pCorHeader); - assembly.GetLoadContext()->m_pCorHeader->Flags |= VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED); - - StrongNameBufferHolder<PublicKeyBlob> pPublicKey; - HRESULT hrPublicKey = FindAssemblySignaturePublicKey(assembly.GetLoadContext(), &pPublicKey); - if (FAILED(hrPublicKey)) - { - SetStrongNameErrorInfo(hrPublicKey); - return false; - } - - // Generate the digest of the assembly - HandleStrongNameCspHolder hProv(LocateCSP(nullptr, SN_IGNORE_CONTAINER, pPublicKey->HashAlgID)); - if (!hProv) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - CapiHashHolder hHash; - if (!CryptCreateHash(hProv, pPublicKey->HashAlgID, NULL, 0, &hHash)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - if (!ComputeHash(assembly.GetLoadContext(), hHash, CalcHash, nullptr)) - { - return false; - } - - // Figure out how big the resulting digest is so that we can pass it back out - DWORD hashSize = 0; - DWORD dwordSize = sizeof(hashSize); - if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &dwordSize, 0)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - StrongNameBufferHolder<BYTE> pbHash(new (nothrow)BYTE[hashSize]); - if (!pbHash) - { - SetStrongNameErrorInfo(E_OUTOFMEMORY); - return false; - } - - if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &hashSize, 0)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - *ppbDigestBlob = pbHash.Extract(); - *pcbDigestBlob = hashSize; - return true; -} - -SNAPI StrongNameDigestGenerate(_In_z_ LPCWSTR wszFilePath, - _Outptr_result_bytebuffer_(*pcbDigestBlob) BYTE** ppbDigestBlob, - _Out_ ULONG* pcbDigestBlob, - DWORD dwFlags) -{ - BOOLEAN retVal = FALSE; - BEGIN_ENTRYPOINT_VOIDRET; - - SNLOG((W("StrongNameDigestGenerate(\"%s\", %08X, %08X, %04X)\n"), wszFilePath, ppbDigestBlob, pcbDigestBlob, dwFlags)); - - SN_COMMON_PROLOG(); - if (wszFilePath == nullptr) - SN_ERROR(E_POINTER); - if (ppbDigestBlob == nullptr) - SN_ERROR(E_POINTER); - if (pcbDigestBlob == nullptr) - SN_ERROR(E_POINTER); - - retVal = StrongNameDigestGenerate_Internal(wszFilePath, ppbDigestBlob, pcbDigestBlob, dwFlags); - - END_ENTRYPOINT_VOIDRET; - -Exit: - return retVal; -} - -// -// Sign an the digest of an assembly calculated by StrongNameDigestGenerate -// -// Parameters: -// wszKeyContainer - name of the key container that holds the key pair used to generate the signature. If -// both a key container and key blob are specified, the key container name is ignored. -// pbKeyBlob - raw key pair to be used to generate the signature. If both a key pair and a key -// container are given, the key blob will be used. -// cbKeyBlob - size of the key pair in pbKeyBlob -// pbDigestBlob - digest of the assembly, calculated by StrongNameDigestGenerate -// cbDigestBlob - size of the digest blob -// hashAlgId - algorithm ID of the hash algorithm used to generate the digest blob -// ppbSignatureBlob - on success this will point to a buffer that contains a signature over the blob. This -// buffer should be freed with StrongNameFreeBuffer. -// pcbSignatureBlob - on success this will point to the size of the signature blob in *ppbSignatureBlob -// dwFlags - flags used to control signing. This is the same set of flags used by -// StrongNameSignatureGenerationEx -// - -bool StrongNameDigestSign_Internal(_In_opt_z_ LPCWSTR wszKeyContainer, - _In_reads_bytes_opt_(cbKeyBlob) BYTE* pbKeyBlob, - ULONG cbKeyBlob, - _In_reads_bytes_(cbDigestBlob) BYTE* pbDigestBlob, - ULONG cbDigestBlob, - DWORD hashAlgId, - _Outptr_result_bytebuffer_(*pcbSignatureBlob) BYTE** ppbSignatureBlob, - _Out_ ULONG* pcbSignatureBlob, - DWORD dwFlags) -{ - // - // Get the key we'll be signing with loaded into CAPI - // - - HandleStrongNameCspHolder hProv; - CapiKeyHolder hKey; - if (pbKeyBlob != nullptr) - { - hProv = LocateCSP(nullptr, SN_IGNORE_CONTAINER, hashAlgId); - - if (hProv != NULL) - { - if (!CryptImportKey(hProv, pbKeyBlob, cbKeyBlob, 0, 0, &hKey)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - } - } - else - { - hProv = LocateCSP(wszKeyContainer, SN_OPEN_CONTAINER, hashAlgId); - } - - if (!hProv) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - // - // Get the pre-calculated digest loaded into a CAPI Hash object - // - - CapiHashHolder hHash; - if (!CryptCreateHash(hProv, hashAlgId, 0, 0, &hHash)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - DWORD hashSize = 0; - DWORD cbHashSize = sizeof(hashSize); - if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &cbHashSize, 0)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - if (hashSize != cbDigestBlob) - { - SetStrongNameErrorInfo(NTE_BAD_HASH); - return false; - } - - if (!CryptSetHashParam(hHash, HP_HASHVAL, pbDigestBlob, 0)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - // - // Sign the hash - // - - DWORD cbSignature = 0; - if (!CryptSignHashW(hHash, g_uKeySpec, nullptr, 0, nullptr, &cbSignature)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - // CAPI has a quirk where some CSPs do not allow you to sign a hash object once you've asked for the size - // of the signature. To work in those cases, we must create a new hash object to sign. - if (!CryptCreateHash(hProv, hashAlgId, 0, 0, &hHash)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &cbHashSize, 0)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - if (hashSize != cbDigestBlob) - { - SetStrongNameErrorInfo(NTE_BAD_HASH); - return false; - } - - if (!CryptSetHashParam(hHash, HP_HASHVAL, pbDigestBlob, 0)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - // Now that we've got a fresh hash object to sign, we can compute the final signature - StrongNameBufferHolder<BYTE> pbSignature(new (nothrow)BYTE[cbSignature]); - if (pbSignature == nullptr) - { - SetStrongNameErrorInfo(E_OUTOFMEMORY); - return false; - } - - if (!CryptSignHashW(hHash, g_uKeySpec, nullptr, 0, pbSignature, &cbSignature)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - *ppbSignatureBlob = pbSignature.Extract(); - *pcbSignatureBlob = cbSignature; - return true; -} - -SNAPI StrongNameDigestSign(_In_opt_z_ LPCWSTR wszKeyContainer, - _In_reads_bytes_opt_(cbKeyBlob) BYTE* pbKeyBlob, - ULONG cbKeyBlob, - _In_reads_bytes_(cbDigestBlob) BYTE* pbDigestBlob, - ULONG cbDigestBlob, - DWORD hashAlgId, - _Outptr_result_bytebuffer_(*pcbSignatureBlob) BYTE** ppbSignatureBlob, - _Out_ ULONG* pcbSignatureBlob, - DWORD dwFlags) -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - SNLOG((W("StrongNameDigestSign(\"%s\", %08X, %04X, %08X, %04X, %04X, %08X, %08X, %04X)\n"), wszKeyContainer, pbKeyBlob, cbKeyBlob, pbDigestBlob, cbDigestBlob, hashAlgId, ppbSignatureBlob, pcbSignatureBlob, dwFlags)); - SN_COMMON_PROLOG(); - - if (wszKeyContainer == nullptr && pbKeyBlob == nullptr) - SN_ERROR(E_POINTER); - if (pbKeyBlob != nullptr && !StrongNameIsValidKeyPair(pbKeyBlob, cbKeyBlob)) - SN_ERROR(E_INVALIDARG); - if (pbDigestBlob == nullptr) - SN_ERROR(E_POINTER); - if (ppbSignatureBlob == nullptr) - SN_ERROR(E_POINTER); - if (pcbSignatureBlob == nullptr) - SN_ERROR(E_POINTER); - - *ppbSignatureBlob = nullptr; - *pcbSignatureBlob = 0; - - retVal = StrongNameDigestSign_Internal(wszKeyContainer, pbKeyBlob, cbKeyBlob, pbDigestBlob, cbDigestBlob, hashAlgId, ppbSignatureBlob, pcbSignatureBlob, dwFlags); - - END_ENTRYPOINT_VOIDRET; -Exit: - return retVal; -} - -// -// Embed a digest signature generated with StrongNameDigestSign into a delay signed assembly, completing -// the signing process for that assembly. -// -// Parameters: -// wszFilePath - path to the assembly to sign -// pbSignatureBlob - signature blob to embed in the assembly -// cbSignatureBlob - size of the signature blob -// - -bool StrongNameDigestEmbed_Internal(_In_z_ LPCWSTR wszFilePath, - _In_reads_bytes_(cbSignatureBlob) BYTE* pbSignatureBlob, - ULONG cbSignatureBlob) -{ - StrongNameAssemblyLoadHolder assembly(wszFilePath, false); - if (!assembly.IsLoaded()) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - - memcpy_s(assembly.GetLoadContext()->m_pbSignature, assembly.GetLoadContext()->m_cbSignature, pbSignatureBlob, cbSignatureBlob); - assembly.GetLoadContext()->m_pCorHeader->Flags |= VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED); - - FILETIME ft = { 0 }; - SYSTEMTIME st = { 0 }; - GetSystemTime(&st); - if (SystemTimeToFileTime(&st, &ft)) - { - SetFileTime(assembly.GetLoadContext()->m_hFile, nullptr, nullptr, &ft); - } - - return true; -} - -SNAPI StrongNameDigestEmbed(_In_z_ LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly to update - _In_reads_bytes_(cbSignatureBlob) BYTE* pbSignatureBlob, // [in] signatuer blob for the assembly - ULONG cbSignatureBlob) -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - SNLOG((W("StrongNameDigestEmbed(\"%s\", %08X, %04X)\n"), wszFilePath, pbSignatureBlob, cbSignatureBlob)); - SN_COMMON_PROLOG(); - - if (wszFilePath == nullptr) - SN_ERROR(E_POINTER); - if (pbSignatureBlob == nullptr) - SN_ERROR(E_POINTER); - - retVal = StrongNameDigestEmbed_Internal(wszFilePath, pbSignatureBlob, cbSignatureBlob); - - END_ENTRYPOINT_VOIDRET; -Exit: - return retVal; -} - -// Create a strong name token from an assembly file. -SNAPI StrongNameTokenFromAssembly(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - BYTE **ppbStrongNameToken, // [out] strong name token - ULONG *pcbStrongNameToken) -{ - BOOL fRetValue = FALSE; - BEGIN_ENTRYPOINT_VOIDRET; - fRetValue = StrongNameTokenFromAssemblyEx(wszFilePath, - ppbStrongNameToken, - pcbStrongNameToken, - NULL, - NULL); - END_ENTRYPOINT_VOIDRET; - return fRetValue; -} - -// Create a strong name token from an assembly file and additionally return the full public key. -SNAPI StrongNameTokenFromAssemblyEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - BYTE **ppbStrongNameToken, // [out] strong name token - ULONG *pcbStrongNameToken, - BYTE **ppbPublicKeyBlob, // [out] public key blob - ULONG *pcbPublicKeyBlob) -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - SN_LOAD_CTX sLoadCtx; - BOOLEAN fMapped = FALSE; - BOOLEAN fSetErrorInfo = TRUE; - PublicKeyBlob *pPublicKey = NULL; - HRESULT hrKey = S_OK; - - SNLOG((W("StrongNameTokenFromAssemblyEx(\"%s\", %08X, %08X, %08X, %08X)\n"), wszFilePath, ppbStrongNameToken, pcbStrongNameToken, ppbPublicKeyBlob, pcbPublicKeyBlob)); - - SN_COMMON_PROLOG(); - - if (wszFilePath == NULL) - SN_ERROR(E_POINTER); - if (ppbStrongNameToken == NULL) - SN_ERROR(E_POINTER); - if (pcbStrongNameToken == NULL) - SN_ERROR(E_POINTER); - - // Map the assembly into memory. - sLoadCtx.m_fReadOnly = TRUE; - if (!LoadAssembly(&sLoadCtx, wszFilePath)) - goto Error; - fMapped = TRUE; - - // Read the public key used to sign the assembly from the assembly metadata. - hrKey = FindPublicKey(&sLoadCtx, NULL, 0, &pPublicKey); - if (FAILED(hrKey)) - { - SetStrongNameErrorInfo(hrKey); - fSetErrorInfo = FALSE; - goto Error; - } - - // Unload the assembly. - fMapped = FALSE; - if (!UnloadAssembly(&sLoadCtx)) - goto Error; - - // Now we have a public key blob, we can call our more direct API to do the - // actual work. - if (!StrongNameTokenFromPublicKey((BYTE*)pPublicKey, - SN_SIZEOF_KEY(pPublicKey), - ppbStrongNameToken, - pcbStrongNameToken)) { - fSetErrorInfo = FALSE; - goto Error; - } - - if (pcbPublicKeyBlob) - *pcbPublicKeyBlob = SN_SIZEOF_KEY(pPublicKey); - - // Return public key information. - if (ppbPublicKeyBlob) - *ppbPublicKeyBlob = (BYTE*)pPublicKey; - else - delete [] (BYTE*)pPublicKey; - - retVal = TRUE; - goto Exit; - - Error: - if (fSetErrorInfo) - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (pPublicKey) - delete [] (BYTE*)pPublicKey; - if (fMapped) - UnloadAssembly(&sLoadCtx); - -Exit: - END_ENTRYPOINT_VOIDRET; - - return retVal; -} - -bool StrongNameSignatureVerificationEx2_Internal(LPCWSTR wszFilePath, - BOOLEAN fForceVerification, - BYTE *pbEcmaPublicKey, - DWORD cbEcmaPublicKey, - BOOLEAN *pfWasVerified) -{ - StrongNameAssemblyLoadHolder assembly(wszFilePath, true); - if (!assembly.IsLoaded()) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - return false; - } - else - { - DWORD dwOutFlags = 0; - HRESULT hrVerify = VerifySignature(assembly.GetLoadContext(), - SN_INFLAG_INSTALL | SN_INFLAG_ALL_ACCESS | (fForceVerification ? SN_INFLAG_FORCE_VER : 0), - reinterpret_cast<PublicKeyBlob *>(pbEcmaPublicKey), - &dwOutFlags); - if (FAILED(hrVerify)) - { - SetStrongNameErrorInfo(hrVerify); - return false; - } - - if (pfWasVerified) - { - *pfWasVerified = (dwOutFlags & SN_OUTFLAG_WAS_VERIFIED) != 0; - } - - return true; - } -} - -// -// Verify the signature of a strongly named assembly, providing a mapping from the ECMA key to a real key -// -// Arguments: -// wszFilePath - valid path to the PE file for the assembly -// fForceVerification - verify even if settings in the registry disable it -// pbEcmaPublicKey - mapping from the ECMA public key to the real key used for verification -// cbEcmaPublicKey - length of the real ECMA public key -// fWasVerified - [out] set to false if verify succeeded due to registry settings -// -// Return Value: -// TRUE if the signature was successfully verified, FALSE otherwise -// - -SNAPI StrongNameSignatureVerificationEx2(LPCWSTR wszFilePath, - BOOLEAN fForceVerification, - BYTE *pbEcmaPublicKey, - DWORD cbEcmaPublicKey, - BOOLEAN *pfWasVerified) -{ - BOOLEAN retVal = FALSE; - BEGIN_ENTRYPOINT_VOIDRET; - - SNLOG((W("StrongNameSignatureVerificationEx2(\"%s\", %d, %08X, %08X, %08X)\n"), wszFilePath, fForceVerification, pbEcmaPublicKey, cbEcmaPublicKey, pfWasVerified)); - - SN_COMMON_PROLOG(); - - if (wszFilePath == NULL) - SN_ERROR(E_POINTER); - if (pbEcmaPublicKey == NULL) - SN_ERROR(E_POINTER); - if (!StrongNameIsValidPublicKey(pbEcmaPublicKey, cbEcmaPublicKey, false)) - SN_ERROR(CORSEC_E_INVALID_PUBLICKEY); - - retVal = StrongNameSignatureVerificationEx2_Internal(wszFilePath, fForceVerification, pbEcmaPublicKey, cbEcmaPublicKey, pfWasVerified); - -Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// Verify a strong name/manifest against a public key blob. -SNAPI StrongNameSignatureVerificationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - BOOLEAN fForceVerification, // [in] verify even if settings in the registry disable it - BOOLEAN *pfWasVerified) // [out] set to false if verify succeeded due to registry settings -{ - BOOLEAN fRet = FALSE; - BEGIN_ENTRYPOINT_VOIDRET; - - fRet = StrongNameSignatureVerificationEx2(wszFilePath, - fForceVerification, - const_cast<BYTE *>(g_rbTheKey), - COUNTOF(g_rbTheKey), - pfWasVerified); - - END_ENTRYPOINT_VOIDRET; - return fRet; -} - - -// Verify a strong name/manifest against a public key blob. -SNAPI StrongNameSignatureVerification(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - DWORD dwInFlags, // [in] flags modifying behaviour - DWORD *pdwOutFlags) // [out] additional output info -{ - BOOLEAN retVal = TRUE; - - BEGIN_ENTRYPOINT_VOIDRET; - - SN_LOAD_CTX sLoadCtx; - BOOLEAN fMapped = FALSE; - - SNLOG((W("StrongNameSignatureVerification(\"%s\", %08X, %08X, %08X)\n"), wszFilePath, dwInFlags, pdwOutFlags)); - - SN_COMMON_PROLOG(); - - if (wszFilePath == NULL) - SN_ERROR(E_POINTER); - - // Map the assembly into memory. - sLoadCtx.m_fReadOnly = TRUE; - if (LoadAssembly(&sLoadCtx, wszFilePath)) - { - fMapped = TRUE; - } - else - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - retVal = FALSE; - } - - // Go to common code to process the verification. - if (fMapped) - { - HRESULT hrVerify = VerifySignature(&sLoadCtx, dwInFlags, reinterpret_cast<PublicKeyBlob *>(const_cast<BYTE *>(g_rbTheKey)), pdwOutFlags); - if (FAILED(hrVerify)) - { - SetStrongNameErrorInfo(hrVerify); - retVal = FALSE; - } - - // Unmap the image. Only set error information if VerifySignature succeeded, since we do not want to - // overwrite its error information with the error code from UnloadAssembly. - if (!UnloadAssembly(&sLoadCtx)) - { - if (retVal) - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - retVal = FALSE; - } - } - - // SN_COMMON_PROLOG requires an Exit location -Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - - -// Verify a strong name/manifest against a public key blob when the assembly is -// already memory mapped. -SNAPI StrongNameSignatureVerificationFromImage(BYTE *pbBase, // [in] base address of mapped manifest file - DWORD dwLength, // [in] length of mapped image in bytes - DWORD dwInFlags, // [in] flags modifying behaviour - DWORD *pdwOutFlags) // [out] additional output info -{ - BOOLEAN retVal = TRUE; - - BEGIN_ENTRYPOINT_VOIDRET - - SN_LOAD_CTX sLoadCtx; - BOOLEAN fMapped = FALSE; - - SNLOG((W("StrongNameSignatureVerificationFromImage(%08X, %08X, %08X, %08X)\n"), pbBase, dwLength, dwInFlags, pdwOutFlags)); - - SN_COMMON_PROLOG(); - - if (pbBase == NULL) - SN_ERROR(E_POINTER); - - // We don't need to map the image, it's already in memory. But we do need to - // set up a load context for some of the following routines. LoadAssembly - // copes with this case for us. - sLoadCtx.m_pbBase = pbBase; - sLoadCtx.m_dwLength = dwLength; - sLoadCtx.m_fReadOnly = TRUE; - if (LoadAssembly(&sLoadCtx, NULL, dwInFlags)) - { - fMapped = TRUE; - } - else - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - retVal = FALSE; - } - - if (fMapped) - { - // Go to common code to process the verification. - HRESULT hrVerify = VerifySignature(&sLoadCtx, dwInFlags, reinterpret_cast<PublicKeyBlob *>(const_cast<BYTE *>(g_rbTheKey)), pdwOutFlags); - if (FAILED(hrVerify)) - { - SetStrongNameErrorInfo(hrVerify); - retVal = FALSE; - } - - // Unmap the image. - if (!UnloadAssembly(&sLoadCtx)) - { - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - retVal = FALSE; - } - } - - // SN_COMMON_PROLOG requires an Exit location -Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// Find portions of an assembly to hash. -BOOLEAN CollectBlob(SN_LOAD_CTX *pLoadCtx, PBYTE pbBlob, DWORD* pcbBlob) -{ - // Calculate the required size - DWORD cbRequired = 0; - BOOLEAN bRetval = ComputeHash(pLoadCtx, (HCRYPTHASH)INVALID_HANDLE_VALUE, CalculateSize, &cbRequired); - if (!bRetval) - return FALSE; - if (*pcbBlob < cbRequired) { - *pcbBlob = cbRequired; - SetLastError( E_INVALIDARG ); - return FALSE; - } - - CopyDataBufferDesc buffer = { pbBlob, *pcbBlob }; - if (!ComputeHash(pLoadCtx, (HCRYPTHASH)INVALID_HANDLE_VALUE, CopyData, &buffer)) - return FALSE; - - *pcbBlob = cbRequired; - return TRUE; -} - -// ensure that the symbol will be exported properly -extern "C" SNAPI StrongNameGetBlob(LPCWSTR wszFilePath, - PBYTE pbBlob, - DWORD *cbBlob); - -SNAPI StrongNameGetBlob(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly - PBYTE pbBlob, // [in] buffer to fill with blob - DWORD *cbBlob) // [in/out] size of buffer/number of bytes put into buffer -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - SN_LOAD_CTX sLoadCtx; - BOOLEAN fMapped = FALSE; - - SNLOG((W("StrongNameGetBlob(\"%s\", %08X, %08X)\n"), wszFilePath, pbBlob, cbBlob)); - - SN_COMMON_PROLOG(); - - if (wszFilePath == NULL) - SN_ERROR(E_POINTER); - if (pbBlob == NULL) - SN_ERROR(E_POINTER); - if (cbBlob == NULL) - SN_ERROR(E_POINTER); - - // Map the assembly into memory. - sLoadCtx.m_fReadOnly = TRUE; - if (!LoadAssembly(&sLoadCtx, wszFilePath, 0, FALSE)) - goto Error; - fMapped = TRUE; - - if (!CollectBlob(&sLoadCtx, pbBlob, cbBlob)) - goto Error; - - // Unmap the image. - fMapped = FALSE; - if (!UnloadAssembly(&sLoadCtx)) - goto Error; - - retVal = TRUE; - goto Exit; - - Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (fMapped) - UnloadAssembly(&sLoadCtx); -Exit: - END_ENTRYPOINT_VOIDRET; - return retVal; -} - -// ensure that the symbol will be exported properly -extern "C" SNAPI StrongNameGetBlobFromImage(BYTE *pbBase, - DWORD dwLength, - PBYTE pbBlob, - DWORD *cbBlob); - -SNAPI StrongNameGetBlobFromImage(BYTE *pbBase, // [in] base address of mapped manifest file - DWORD dwLength, // [in] length of mapped image in bytes - PBYTE pbBlob, // [in] buffer to fill with blob - DWORD *cbBlob) // [in/out] size of buffer/number of bytes put into buffer -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - SN_LOAD_CTX sLoadCtx; - BOOLEAN fMapped = FALSE; - - - SNLOG((W("StrongNameGetBlobFromImage(%08X, %08X, %08X, %08X)\n"), pbBase, dwLength, pbBlob, cbBlob)); - - SN_COMMON_PROLOG(); - - if (pbBase == NULL) - SN_ERROR(E_POINTER); - if (pbBlob == NULL) - SN_ERROR(E_POINTER); - if (cbBlob == NULL) - SN_ERROR(E_POINTER); - - // We don't need to map the image, it's already in memory. But we do need to - // set up a load context for some of the following routines. LoadAssembly - // copes with this case for us. - sLoadCtx.m_pbBase = pbBase; - sLoadCtx.m_dwLength = dwLength; - sLoadCtx.m_fReadOnly = TRUE; - if (!LoadAssembly(&sLoadCtx, NULL, 0, FALSE)) - goto Error; - fMapped = TRUE; - - // Go to common code to process the verification. - if (!CollectBlob(&sLoadCtx, pbBlob, cbBlob)) - goto Error; - - // Unmap the image. - fMapped = FALSE; - if (!UnloadAssembly(&sLoadCtx)) - goto Error; - - retVal = TRUE; - goto Exit; - - Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (fMapped) - UnloadAssembly(&sLoadCtx); - -Exit: - END_ENTRYPOINT_VOIDRET; - - return retVal; -} - - -// Verify that two assemblies differ only by signature blob. -SNAPI StrongNameCompareAssemblies(LPCWSTR wszAssembly1, // [in] file name of first assembly - LPCWSTR wszAssembly2, // [in] file name of second assembly - DWORD *pdwResult) // [out] result of comparison -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - - SN_LOAD_CTX sLoadCtx1; - SN_LOAD_CTX sLoadCtx2; - size_t dwSkipOffsets[3]; - size_t dwSkipLengths[3]; - BOOLEAN bMappedAssem1 = FALSE; - BOOLEAN bMappedAssem2 = FALSE; - BOOLEAN bIdentical; - BOOLEAN bSkipping; - DWORD i, j; - - - - SNLOG((W("StrongNameCompareAssemblies(\"%s\", \"%s\", %08X)\n"), wszAssembly1, wszAssembly2, pdwResult)); - - SN_COMMON_PROLOG(); - - if (wszAssembly1 == NULL) - SN_ERROR(E_POINTER); - if (wszAssembly2 == NULL) - SN_ERROR(E_POINTER); - if (pdwResult == NULL) - SN_ERROR(E_POINTER); - - // Map each assembly. - sLoadCtx1.m_fReadOnly = TRUE; - if (!LoadAssembly(&sLoadCtx1, wszAssembly1)) - goto Error; - bMappedAssem1 = TRUE; - - sLoadCtx2.m_fReadOnly = TRUE; - if (!LoadAssembly(&sLoadCtx2, wszAssembly2)) - goto Error; - bMappedAssem2 = TRUE; - - // If the files aren't even the same length then they must be different. - if (sLoadCtx1.m_dwLength != sLoadCtx2.m_dwLength) - goto ImagesDiffer; - - // Check that the signatures are located at the same offset and are the same - // length in each assembly. - if (sLoadCtx1.m_pCorHeader->StrongNameSignature.VirtualAddress != - sLoadCtx2.m_pCorHeader->StrongNameSignature.VirtualAddress) - goto ImagesDiffer; - if (sLoadCtx1.m_pCorHeader->StrongNameSignature.Size != - sLoadCtx2.m_pCorHeader->StrongNameSignature.Size) - goto ImagesDiffer; - - // Set up list of image ranges to skip in the upcoming comparison. - // First there's the signature blob. - dwSkipOffsets[0] = sLoadCtx1.m_pbSignature - sLoadCtx1.m_pbBase; - dwSkipLengths[0] = sLoadCtx1.m_cbSignature; - - // Then there's the checksum. - if (sLoadCtx1.m_pNtHeaders->OptionalHeader.Magic != sLoadCtx2.m_pNtHeaders->OptionalHeader.Magic) - goto ImagesDiffer; - if (sLoadCtx1.m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC)) - dwSkipOffsets[1] = (BYTE*)&((IMAGE_NT_HEADERS32*)sLoadCtx1.m_pNtHeaders)->OptionalHeader.CheckSum - sLoadCtx1.m_pbBase; - else if (sLoadCtx1.m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC)) - dwSkipOffsets[1] = (BYTE*)&((IMAGE_NT_HEADERS64*)sLoadCtx1.m_pNtHeaders)->OptionalHeader.CheckSum - sLoadCtx1.m_pbBase; - else { - SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT); - goto Error; - } - dwSkipLengths[1] = sizeof(DWORD); - - // Skip the COM+ 2.0 PE header extension flags field. It's updated by the - // signing operation. - dwSkipOffsets[2] = (BYTE*)&sLoadCtx1.m_pCorHeader->Flags - sLoadCtx1.m_pbBase; - dwSkipLengths[2] = sizeof(DWORD); - - // Compare the two mapped images, skipping the ranges we defined above. - bIdentical = TRUE; - for (i = 0; i < sLoadCtx1.m_dwLength; i++) { - - // Determine if we're skipping the check on the current byte. - bSkipping = FALSE; - for (j = 0; j < (sizeof(dwSkipOffsets) / sizeof(dwSkipOffsets[0])); j++) - if ((i >= dwSkipOffsets[j]) && (i < (dwSkipOffsets[j] + dwSkipLengths[j]))) { - bSkipping = TRUE; - break; - } - - // Perform comparisons as desired. - if (sLoadCtx1.m_pbBase[i] != sLoadCtx2.m_pbBase[i]) - if (bSkipping) - bIdentical = FALSE; - else - goto ImagesDiffer; - } - - // The assemblies are the same. - *pdwResult = bIdentical ? SN_CMP_IDENTICAL : SN_CMP_SIGONLY; - - UnloadAssembly(&sLoadCtx1); - UnloadAssembly(&sLoadCtx2); - - retVal = TRUE; - goto Exit; - - Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (bMappedAssem1) - UnloadAssembly(&sLoadCtx1); - if (bMappedAssem2) - UnloadAssembly(&sLoadCtx2); - goto Exit; - - ImagesDiffer: - if (bMappedAssem1) - UnloadAssembly(&sLoadCtx1); - if (bMappedAssem2) - UnloadAssembly(&sLoadCtx2); - *pdwResult = SN_CMP_DIFFERENT; - retVal = TRUE; - -Exit: - END_ENTRYPOINT_VOIDRET; - - return retVal; -} - - -// Compute the size of buffer needed to hold a hash for a given hash algorithm. -SNAPI StrongNameHashSize(ULONG ulHashAlg, // [in] hash algorithm - DWORD *pcbSize) // [out] size of the hash in bytes -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - HCRYPTPROV hProv = NULL; - HCRYPTHASH hHash = NULL; - DWORD dwSize; - - - SNLOG((W("StrongNameHashSize(%08X, %08X)\n"), ulHashAlg, pcbSize)); - - SN_COMMON_PROLOG(); - - if (pcbSize == NULL) - SN_ERROR(E_POINTER); - - // Default hashing algorithm ID if necessary. - if (ulHashAlg == 0) - ulHashAlg = CALG_SHA1; - - // Find a CSP supporting the required algorithm. - hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, ulHashAlg); - if (!hProv) - goto Error; - - // Create a hash object. - if (!CryptCreateHash(hProv, ulHashAlg, 0, 0, &hHash)) - goto Error; - - // And ask for the size of the hash. - dwSize = sizeof(DWORD); - if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)pcbSize, &dwSize, 0)) - goto Error; - - // Cleanup and exit. - CryptDestroyHash(hHash); - FreeCSP(hProv); - - retVal = TRUE; - goto Exit; - - Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (hHash) - CryptDestroyHash(hHash); - if (hProv) - FreeCSP(hProv); - - Exit: - - END_ENTRYPOINT_VOIDRET; - - return retVal; -} - - -// Compute the size that needs to be allocated for a signature in an assembly. -SNAPI StrongNameSignatureSize(BYTE *pbPublicKeyBlob, // [in] public key blob - ULONG cbPublicKeyBlob, - DWORD *pcbSize) // [out] size of the signature in bytes -{ - BOOLEAN retVal = FALSE; - - BEGIN_ENTRYPOINT_VOIDRET; - - PublicKeyBlob *pPublicKey = (PublicKeyBlob*)pbPublicKeyBlob; - ALG_ID uHashAlgId; - ALG_ID uSignAlgId; - HCRYPTPROV hProv = NULL; - HCRYPTHASH hHash = NULL; - HCRYPTKEY hKey = NULL; - LPCWSTR wszKeyContainer = NULL; - BOOLEAN bTempContainer = FALSE; - DWORD dwKeyLen; - DWORD dwBytes; - - SNLOG((W("StrongNameSignatureSize(%08X, %08X, %08X)\n"), pbPublicKeyBlob, cbPublicKeyBlob, pcbSize)); - - SN_COMMON_PROLOG(); - - if (pbPublicKeyBlob == NULL) - SN_ERROR(E_POINTER); - if (!StrongNameIsValidPublicKey(pbPublicKeyBlob, cbPublicKeyBlob, false)) - SN_ERROR(CORSEC_E_INVALID_PUBLICKEY); - if (pcbSize == NULL) - SN_ERROR(E_POINTER); - - // Special case neutral key. - if (SN_IS_NEUTRAL_KEY(pPublicKey)) - pPublicKey = SN_THE_KEY(); - - // Determine hashing/signing algorithms. - uHashAlgId = GET_UNALIGNED_VAL32(&pPublicKey->HashAlgID); - uSignAlgId = GET_UNALIGNED_VAL32(&pPublicKey->SigAlgID); - - // Default hashing and signing algorithm IDs if necessary. - if (uHashAlgId == 0) - uHashAlgId = CALG_SHA1; - if (uSignAlgId == 0) - uSignAlgId = CALG_RSA_SIGN; - - // Create a temporary key container name. - if (!GetKeyContainerName(&wszKeyContainer, &bTempContainer)) - goto Exit; - - // Find a CSP supporting the required algorithms and create a temporary key - // container. - hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER, uHashAlgId, uSignAlgId); - if (!hProv) - goto Error; - - // Import the public key (we need to do this in order to determine the key - // length reliably). - if (!CryptImportKey(hProv, - pPublicKey->PublicKey, - GET_UNALIGNED_VAL32(&pPublicKey->cbPublicKey), - 0, 0, &hKey)) - goto Error; - - // Query the key attributes (it's the length we're interested in). - dwBytes = sizeof(dwKeyLen); - if (!CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwBytes, 0)) - goto Error; - - // Delete the key container. - if (LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER) == NULL) { - SetLastError(CORSEC_E_CONTAINER_NOT_FOUND); - goto Error; - } - - // Take shortcut for the typical case - if ((uSignAlgId == CALG_RSA_SIGN) && (dwKeyLen % 8 == 0)) { - // The signature size known for CALG_RSA_SIGN - *pcbSize = dwKeyLen / 8; - } - else { - // Recreate the container so we can create a temporary key pair. - hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER, uHashAlgId, uSignAlgId); - if (!hProv) - goto Error; - - // Create the temporary key pair. - if (!CryptGenKey(hProv, g_uKeySpec, dwKeyLen << 16, &hKey)) - goto Error; - - // Create a hash. - if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash)) - goto Error; - - // Compute size of the signature blob. - if (!CryptSignHashW(hHash, g_uKeySpec, NULL, 0, NULL, pcbSize)) - goto Error; - CryptDestroyHash(hHash); - - if (bTempContainer) - LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER); - } - - SNLOG((W("Signature size for hashalg %08X, %08X key (%08X bits) is %08X bytes\n"), uHashAlgId, uSignAlgId, dwKeyLen, *pcbSize)); - - CryptDestroyKey(hKey); - FreeCSP(hProv); - FreeKeyContainerName(wszKeyContainer, bTempContainer); - - retVal = TRUE; - goto Exit; - - Error: - SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); - if (hHash) - CryptDestroyHash(hHash); - if (hKey) - CryptDestroyKey(hKey); - if (hProv) - FreeCSP(hProv); - if (bTempContainer) - LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER); - FreeKeyContainerName(wszKeyContainer, bTempContainer); - - Exit: - END_ENTRYPOINT_VOIDRET; - - return retVal; -} - -// Locate CSP based on criteria specified in the registry (CSP name etc). -// Optionally create or delete a named key container within that CSP. -HCRYPTPROV LocateCSP(LPCWSTR wszKeyContainer, - DWORD dwAction, - ALG_ID uHashAlgId, - ALG_ID uSignAlgId) -{ - DWORD i; - DWORD dwType; - WCHAR wszName[SN_MAX_CSP_NAME + 1]; - DWORD dwNameLength; - HCRYPTPROV hProv; - BOOLEAN bFirstAlg; - BOOLEAN bFoundHash; - BOOLEAN bFoundSign; - PROV_ENUMALGS rAlgs; - HCRYPTPROV hRetProv; - DWORD dwAlgsLen; - - DWORD dwProvType = g_uProvType; - - // If a CSP name has been provided (and we're not opening a CSP just to do a - // SHA1 hash or a verification), open the CSP directly. - if (g_bHasCSPName && - (dwAction != SN_HASH_SHA1_ONLY)) - { - if (StrongNameCryptAcquireContext(&hProv, - wszKeyContainer ? wszKeyContainer : NULL, - g_wszCSPName, - dwProvType, - SN_CAC_FLAGS(dwAction))) - return (dwAction == SN_DELETE_CONTAINER) ? (HCRYPTPROV)~0 : hProv; - else { - SNLOG((W("Failed to open CSP '%s': %08X\n"), g_wszCSPName, GetLastError())); - return NULL; - } - } - - // Set up hashing and signing algorithms to look for based upon input - // parameters. Or if these haven't been supplied use the configured defaults - // instead. - if (uHashAlgId == 0) - uHashAlgId = g_uHashAlgId; - if (uSignAlgId == 0) - uSignAlgId = g_uSignAlgId; - - // If default hashing and signing algorithms have been selected (SHA1 and - // RSA), we select the default CSP for the RSA_FULL type. - // For SHA2 and RSA, we select the default CSP For RSA_AES. - // Otherwise, you just get the first CSP that supports the algorithms - // you specified (with no guarantee that the selected CSP is a default of any type). - // This is because we have no way of forcing the enumeration to just give us default - // CSPs. - bool fUseDefaultCsp = false; - StrongNameCachedCsp cachedCspNumber = None; - - // We know what container to use for SHA1 algorithms with RSA - if (((uHashAlgId == CALG_SHA1) && (uSignAlgId == CALG_RSA_SIGN)) || - (dwAction == SN_HASH_SHA1_ONLY)) { - fUseDefaultCsp = true; - cachedCspNumber = Sha1CachedCsp; - dwProvType = PROV_RSA_FULL; - - SNLOG((W("Attempting to open default provider\n"))); - } - - // We know what container to use for SHA2 algorithms with RSA - if ((uHashAlgId == CALG_SHA_256 || uHashAlgId == CALG_SHA_384 || uHashAlgId == CALG_SHA_512) - && uSignAlgId == CALG_RSA_SIGN) { - fUseDefaultCsp = true; - cachedCspNumber = Sha2CachedCsp; - dwProvType = PROV_RSA_AES; - - SNLOG((W("Attempting to open default SHA2 provider\n"))); - } - - if (fUseDefaultCsp) - { - // If we're not trying to create/open/delete a key container, see if a - // CSP is cached. - if (wszKeyContainer == NULL && dwAction != SN_DELETE_CONTAINER) { - hProv = LookupCachedCSP(cachedCspNumber); - if (hProv) { - SNLOG((W("Found provider in cache\n"))); - return hProv; - } - } - if (StrongNameCryptAcquireContext(&hProv, - wszKeyContainer ? wszKeyContainer : NULL, - NULL, - dwProvType, - SN_CAC_FLAGS(dwAction))) { - // If we're not trying to create/open/delete a key container, cache - // the CSP returned. - if (wszKeyContainer == NULL && dwAction != SN_DELETE_CONTAINER) - CacheCSP(hProv, cachedCspNumber); - return (dwAction == SN_DELETE_CONTAINER) ? (HCRYPTPROV)~0 : hProv; - } else { - SNLOG((W("Failed to open: %08X\n"), GetLastError())); - return NULL; - } - } - - HRESULT hr = InitStrongNameCriticalSection(); - if (FAILED(hr)) { - SetLastError(hr); - return NULL; - } - - // Some crypto APIs are non thread safe (e.g. enumerating CSP - // hashing/signing algorithms). Use a mutex to serialize these operations. - // The following usage is GC-safe and exception-safe: - { - CRITSEC_Holder csh(g_rStrongNameMutex); - - for (i = 0; ; i++) { - - // Enumerate all CSPs. - dwNameLength = sizeof(wszName); - if (CryptEnumProvidersW(i, 0, 0, &dwType, wszName, &dwNameLength)) { - - // Open the currently selected CSP. - SNLOG((W("Considering CSP '%s'\n"), wszName)); - if (StrongNameCryptAcquireContext(&hProv, - NULL, - wszName, - dwType, - CRYPT_SILENT | - CRYPT_VERIFYCONTEXT | - (g_bUseMachineKeyset ? CRYPT_MACHINE_KEYSET : 0))) { - - // Enumerate all the algorithms the CSP supports. - bFirstAlg = TRUE; - bFoundHash = FALSE; - bFoundSign = FALSE; - for (;;) { - - dwAlgsLen = sizeof(rAlgs); - if (CryptGetProvParam(hProv, - PP_ENUMALGS, (BYTE*)&rAlgs, &dwAlgsLen, - bFirstAlg ? CRYPT_FIRST : 0)) { - - if (rAlgs.aiAlgid == uHashAlgId) - bFoundHash = TRUE; - else if (rAlgs.aiAlgid == uSignAlgId) - bFoundSign = TRUE; - - if (bFoundHash && bFoundSign) { - - // Found a CSP that supports the required - // algorithms. Re-open the context with access to - // the required key container. - - SNLOG((W("CSP matches\n"))); - - if (StrongNameCryptAcquireContext(&hRetProv, - wszKeyContainer ? wszKeyContainer : NULL, - wszName, - dwType, - CRYPT_SILENT | - SN_CAC_FLAGS(dwAction))) { - CryptReleaseContext(hProv, 0); - return (dwAction == SN_DELETE_CONTAINER) ? (HCRYPTPROV)~0 : hRetProv; - } else { - SNLOG((W("Failed to re-open for container: %08X\n"), GetLastError())); - break; - } - } - - bFirstAlg = FALSE; - - } else { - _ASSERTE(GetLastError() == ERROR_NO_MORE_ITEMS); - break; - } - - } - - CryptReleaseContext(hProv, 0); - - } else - SNLOG((W("Failed to open CSP: %08X\n"), GetLastError())); - - } else if (GetLastError() == ERROR_NO_MORE_ITEMS) - break; - - } - // csh for g_rStrongNameMutex goes out of scope here - } - - // No matching CSP found. - SetLastError(CORSEC_E_NO_SUITABLE_CSP); - return NULL; -} - - -// Release a CSP acquired through LocateCSP. -VOID FreeCSP(HCRYPTPROV hProv) -{ - // If the CSP is currently cached, don't release it yet. - if (!IsCachedCSP(hProv)) - CryptReleaseContext(hProv, 0); -} - -// Locate a cached CSP for this thread. -HCRYPTPROV LookupCachedCSP(StrongNameCachedCsp cspNumber) -{ - SN_THREAD_CTX *pThreadCtx = GetThreadContext(); - if (pThreadCtx == NULL) - return NULL; - return pThreadCtx->m_hProv[cspNumber]; -} - - -// Update the CSP cache for this thread (freeing any CSP displaced). -VOID CacheCSP(HCRYPTPROV hProv, StrongNameCachedCsp cspNumber) -{ - SN_THREAD_CTX *pThreadCtx = GetThreadContext(); - if (pThreadCtx == NULL) - return; - if (pThreadCtx->m_hProv[cspNumber]) - CryptReleaseContext(pThreadCtx->m_hProv[cspNumber], 0); - pThreadCtx->m_hProv[cspNumber] = hProv; -} - - -// Determine whether a given CSP is currently cached. -BOOLEAN IsCachedCSP(HCRYPTPROV hProv) -{ - SN_THREAD_CTX *pThreadCtx = GetThreadContext(); - if (pThreadCtx == NULL) - return FALSE; - for (ULONG i = 0; i < CachedCspCount; i++) - { - if(pThreadCtx->m_hProv[i] == hProv) - { - return TRUE; - } - } - return FALSE; -} - -// rehash all files in a multi-module assembly -BOOLEAN RehashModules (SN_LOAD_CTX *pLoadCtx, LPCWSTR wszFilePath) { - HRESULT hr; - ULONG ulHashAlg; - mdAssembly tkAssembly; - HENUMInternal hFileEnum; - mdFile tkFile; - LPCSTR pszFile; - BYTE *pbFileHash; - DWORD cbFileHash; - NewArrayHolder<BYTE> pbNewFileHash(NULL); - DWORD cbNewFileHash = 0; - DWORD cchDirectory; - DWORD cchFullFile; - CHAR szFullFile[MAX_LONGPATH + 1]; - WCHAR wszFullFile[MAX_LONGPATH + 1]; - LPCWSTR pszSlash; - DWORD cchFile; - IMDInternalImport *pMetaDataImport = NULL; - - // Determine the directory the assembly lives in (this is where we'll - // look for linked files). - if (((pszSlash = wcsrchr(wszFilePath, W('\\'))) != NULL) || ((pszSlash = wcsrchr(wszFilePath, W('/'))) != NULL)) { - cchDirectory = (DWORD) (pszSlash - wszFilePath + 1); - cchDirectory = WszWideCharToMultiByte(CP_UTF8, 0, wszFilePath, cchDirectory, szFullFile, MAX_LONGPATH, NULL, NULL); - if (cchDirectory >= MAX_LONGPATH) { - SNLOG((W("Assembly directory name too long\n"))); - hr = ERROR_BUFFER_OVERFLOW; - goto Error; - } - } else - cchDirectory = 0; - - // Open the scope on the mapped image. - if (FAILED(hr = GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport))) - { - goto Error; - } - - // Determine the hash algorithm used for file references. - if (FAILED(hr = pMetaDataImport->GetAssemblyProps( - tkAssembly, // [IN] The Assembly for which to get the properties - NULL, // [OUT] Pointer to the Originator blob - NULL, // [OUT] Count of bytes in the Originator Blob - &ulHashAlg, // [OUT] Hash Algorithm - NULL, // [OUT] Buffer to fill with name - NULL, // [OUT] Assembly MetaData - NULL))) // [OUT] Flags - { - SNLOG((W("Failed to get assembly 0x%08X info, %08X\n"), tkAssembly, hr)); - goto Error; - } - - // Enumerate all file references. - if (FAILED(hr = pMetaDataImport->EnumInit(mdtFile, mdTokenNil, &hFileEnum))) - { - SNLOG((W("Failed to enumerate linked files, %08X\n"), hr)); - goto Error; - } - - for (; pMetaDataImport->EnumNext(&hFileEnum, &tkFile); ) { - - // Determine the file name and the location of the hash. - if (FAILED(hr = pMetaDataImport->GetFileProps( - tkFile, - &pszFile, - (const void **)&pbFileHash, - &cbFileHash, - NULL))) - { - SNLOG((W("Failed to get file 0x%08X info, %08X\n"), tkFile, hr)); - goto Error; - } - - // Build the full filename by appending to the assembly directory we - // calculated earlier. - cchFile = (DWORD) strlen(pszFile); - if ((cchFile + cchDirectory) >= COUNTOF(szFullFile)) { - pMetaDataImport->EnumClose(&hFileEnum); - SNLOG((W("Linked file name too long (%S)\n"), pszFile)); - hr = ERROR_BUFFER_OVERFLOW; - goto Error; - } - memcpy_s(&szFullFile[cchDirectory], COUNTOF(szFullFile) - cchDirectory, pszFile, cchFile + 1); - - // Allocate enough buffer for the new hash. - if (cbNewFileHash < cbFileHash) { - pbNewFileHash = new (nothrow) BYTE[cbFileHash]; - if (pbNewFileHash == NULL) { - hr = E_OUTOFMEMORY; - goto Error; - } - cbNewFileHash = cbFileHash; - } - - cchFullFile = WszMultiByteToWideChar(CP_UTF8, 0, szFullFile, -1, wszFullFile, MAX_LONGPATH); - if (cchFullFile == 0 || cchFullFile >= MAX_LONGPATH) { - pMetaDataImport->EnumClose(&hFileEnum); - SNLOG((W("Assembly directory name too long\n"))); - hr = ERROR_BUFFER_OVERFLOW; - goto Error; - } - - // Compute a new hash for the file. - if (FAILED(hr = GetHashFromFileW(wszFullFile, - (unsigned*)&ulHashAlg, - pbNewFileHash, - cbNewFileHash, - &cbNewFileHash))) { - pMetaDataImport->EnumClose(&hFileEnum); - SNLOG((W("Failed to get compute file hash, %08X\n"), hr)); - goto Error; - } - - // The new hash has to be the same size (since we used the same - // algorithm). - _ASSERTE(cbNewFileHash == cbFileHash); - - // We make the assumption here that the pointer to the file hash - // handed to us by the metadata is a direct pointer and not a - // buffered copy. If this changes, we'll need a new metadata API to - // support updates of this type. - memcpy_s(pbFileHash, cbFileHash, pbNewFileHash, cbFileHash); - } - - pMetaDataImport->EnumClose(&hFileEnum); - pMetaDataImport->Release(); - return TRUE; - -Error: - if (pMetaDataImport) - pMetaDataImport->Release(); - if (pbNewFileHash) - pbNewFileHash.Release(); - SetLastError(hr); - return FALSE; -} - -// -// Check that the public key portion of an assembly's identity matches the private key that it is being -// signed with. -// -// Arguments: -// pAssemblySignaturePublicKey - Assembly signature public key blob -// wszKeyContainer - Key container holding the key the assembly is signed with -// dwFlags - SN_ECMA_SIGN if the assembly is being ECMA signed, SN_TEST_SIGN if it is being test signed -// -// Return Value: -// true if the assembly's public key matches the private key in wszKeyContainer, otherwise false -// - -bool VerifyKeyMatchesAssembly(PublicKeyBlob * pAssemblySignaturePublicKey, __in_z LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, DWORD dwFlags) -{ - _ASSERTE(wszKeyContainer != NULL || pbKeyBlob != NULL); - - // If we're test signing, then the assembly's public key will not match the private key by design. - // Since there's nothing to check, we can quit early. - if ((dwFlags & SN_TEST_SIGN) == SN_TEST_SIGN) - { - return true; - } - - if (SN_IS_NEUTRAL_KEY(pAssemblySignaturePublicKey)) - { - // If we're ECMA signing an assembly with the ECMA public key, then by definition the key matches. - if ((dwFlags & SN_ECMA_SIGN) == SN_ECMA_SIGN) - { - return true; - } - - // Swap the real public key in for ECMA signing - pAssemblySignaturePublicKey = SN_THE_KEY(); - } - - // Otherwise, we need to check that the public key from the key container matches the public key from - // the assembly. - StrongNameBufferHolder<BYTE> pbSignaturePublicKey = NULL; - DWORD cbSignaturePublicKey; - if (!StrongNameGetPublicKeyEx(wszKeyContainer, pbKeyBlob, cbKeyBlob, &pbSignaturePublicKey, &cbSignaturePublicKey, GET_UNALIGNED_VAL32(&pAssemblySignaturePublicKey->HashAlgID), 0 /*Should be GET_UNALIGNED_VAL32(&pAssemblySignaturePublicKey->HashAlgID) once we support different signature algorithms*/)) - { - // We failed to get the public key for the key in the given key container. StrongNameGetPublicKey - // has already set the error information, so we can just return false here without resetting it. - return false; - } - _ASSERTE(!pbSignaturePublicKey.IsNull() && pAssemblySignaturePublicKey != NULL); - - // Do a raw compare on the public key blobs to see if they match - if (SN_SIZEOF_KEY(reinterpret_cast<PublicKeyBlob *>(pbSignaturePublicKey.GetValue())) == SN_SIZEOF_KEY(pAssemblySignaturePublicKey) && - memcmp(static_cast<void *>(pAssemblySignaturePublicKey), - static_cast<void *>(pbSignaturePublicKey.GetValue()), - cbSignaturePublicKey) == 0) - { - return true; - } - - SetStrongNameErrorInfo(SN_E_PUBLICKEY_MISMATCH); - return false; -} - -// Map an assembly into memory. -BOOLEAN LoadAssembly(SN_LOAD_CTX *pLoadCtx, LPCWSTR wszFilePath, DWORD inFlags, BOOLEAN fRequireSignature) -{ - DWORD dwError = S_OK; - - // If a filename is not supplied, the image has already been mapped (and the - // image base and length fields set up correctly). - if (wszFilePath == NULL) - { - pLoadCtx->m_fPreMapped = TRUE; - pLoadCtx->m_pedecoder = new (nothrow) PEDecoder(pLoadCtx->m_pbBase, static_cast<COUNT_T>(pLoadCtx->m_dwLength)); - if (pLoadCtx->m_pedecoder == NULL) { - dwError = E_OUTOFMEMORY; - goto Error; - } - } - else { - - pLoadCtx->m_hMap = INVALID_HANDLE_VALUE; - pLoadCtx->m_pbBase = NULL; - - // Open the file for reading or writing. - pLoadCtx->m_hFile = WszCreateFile(wszFilePath, - GENERIC_READ | (pLoadCtx->m_fReadOnly ? 0 : GENERIC_WRITE), - pLoadCtx->m_fReadOnly ? FILE_SHARE_READ : FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (pLoadCtx->m_hFile == INVALID_HANDLE_VALUE) { - dwError = HRESULT_FROM_GetLastError(); - goto Error; - } - - pLoadCtx->m_dwLength = SafeGetFileSize(pLoadCtx->m_hFile, NULL); - if (pLoadCtx->m_dwLength == 0xffffffff) { - dwError = HRESULT_FROM_GetLastError(); - goto Error; - } - - // Create a mapping handle for the file. - pLoadCtx->m_hMap = WszCreateFileMapping(pLoadCtx->m_hFile, NULL, pLoadCtx->m_fReadOnly ? PAGE_READONLY : PAGE_READWRITE, 0, 0, NULL); - if (pLoadCtx->m_hMap == NULL) { - dwError = HRESULT_FROM_GetLastError(); - goto Error; - } - - // And map it into memory. - pLoadCtx->m_pbBase = (BYTE*)CLRMapViewOfFile(pLoadCtx->m_hMap, pLoadCtx->m_fReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0); - if (pLoadCtx->m_pbBase == NULL) { - dwError = HRESULT_FROM_GetLastError(); - goto Error; - } - pLoadCtx->m_pedecoder = new (nothrow) PEDecoder(pLoadCtx->m_pbBase, static_cast<COUNT_T>(pLoadCtx->m_dwLength)); - if (pLoadCtx->m_pedecoder == NULL) { - dwError = E_OUTOFMEMORY; - goto Error; - } - } - - if (!pLoadCtx->m_pedecoder->HasContents() || !pLoadCtx->m_pedecoder->CheckCORFormat()) { - dwError = CORSEC_E_INVALID_IMAGE_FORMAT; - goto Error; - } - - // Locate standard NT image header. - pLoadCtx->m_pNtHeaders = pLoadCtx->m_pedecoder->GetNTHeaders32(); - - if (pLoadCtx->m_pNtHeaders == NULL) { - dwError = CORSEC_E_INVALID_IMAGE_FORMAT; - goto Error; - } - - pLoadCtx->m_pCorHeader = pLoadCtx->m_pedecoder->GetCorHeader(); - - if (pLoadCtx->m_pCorHeader == NULL) { - dwError = CORSEC_E_INVALID_IMAGE_FORMAT; - goto Error; - } - - // Set up signature pointer (if we require it). - if (fRequireSignature && pLoadCtx->m_pedecoder->HasStrongNameSignature()) - { - COUNT_T size = 0; - BYTE* pbSignature = (BYTE*)pLoadCtx->m_pedecoder->GetStrongNameSignature(&size); - - // Make sure the signature doesn't point back into the header - if (pbSignature <= reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader) && - pbSignature > reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader) - size) - { - dwError = CORSEC_E_INVALID_IMAGE_FORMAT; - goto Error; - } - if (pbSignature >= reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader) && - pbSignature - sizeof(IMAGE_COR20_HEADER) < reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader)) - { - dwError = CORSEC_E_INVALID_IMAGE_FORMAT; - goto Error; - } - - pLoadCtx->m_pbSignature = pbSignature; - pLoadCtx->m_cbSignature = static_cast<DWORD>(size); - } - - return TRUE; - - Error: - if (!pLoadCtx->m_fPreMapped) { - if (pLoadCtx->m_pbBase) - CLRUnmapViewOfFile(pLoadCtx->m_pbBase); - if (pLoadCtx->m_hMap != INVALID_HANDLE_VALUE) - CloseHandle(pLoadCtx->m_hMap); - if (pLoadCtx->m_hFile != INVALID_HANDLE_VALUE) - CloseHandle(pLoadCtx->m_hFile); - } - SetLastError(dwError); - return FALSE; -} - - -// Unload an assembly loaded with LoadAssembly (recomputing checksum if -// necessary). -BOOLEAN UnloadAssembly(SN_LOAD_CTX *pLoadCtx) -{ - BOOLEAN bResult = TRUE; - - if (!pLoadCtx->m_fReadOnly) { - - IMAGE_NT_HEADERS *pNtHeaders = NULL; - DWORD dwCheckSum = 0; - - // We late bind CheckSumMappedFile to avoid bringing in IMAGEHLP unless - // we need to. - HMODULE hLibrary = WszLoadLibrary(W("imagehlp.dll")); - if (hLibrary) { - IMAGE_NT_HEADERS *(*SN_CheckSumMappedFile)(BYTE*, DWORD, DWORD*, DWORD*); - - if ((*(FARPROC*)&SN_CheckSumMappedFile = GetProcAddress(hLibrary, "CheckSumMappedFile")) != NULL) { - DWORD dwOldCheckSum; - - pNtHeaders = SN_CheckSumMappedFile(pLoadCtx->m_pbBase, - pLoadCtx->m_dwLength, - &dwOldCheckSum, - &dwCheckSum); - } - - FreeLibrary(hLibrary); - - } - - if (pNtHeaders != NULL) { - if (pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC)) - ((IMAGE_NT_HEADERS32*)pNtHeaders)->OptionalHeader.CheckSum = VAL32(dwCheckSum); - else - if (pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC)) - ((IMAGE_NT_HEADERS64*)pNtHeaders)->OptionalHeader.CheckSum = VAL32(dwCheckSum); - } else - bResult = FALSE; - - if (!pLoadCtx->m_fPreMapped && !FlushViewOfFile(pLoadCtx->m_pbBase, 0)) - bResult = FALSE; - } - - if (!pLoadCtx->m_fPreMapped) { - if (!CLRUnmapViewOfFile(pLoadCtx->m_pbBase)) - bResult = FALSE; - - if (!CloseHandle(pLoadCtx->m_hMap)) - bResult = FALSE; - - if (!CloseHandle(pLoadCtx->m_hFile)) - bResult = FALSE; - } - - if (pLoadCtx->m_pedecoder != NULL) - { - delete (pLoadCtx->m_pedecoder); - pLoadCtx->m_pedecoder = NULL; - } - - return bResult; -} - -template<class T> -LONG RegQueryValueT(HKEY hKey, LPCWSTR pValueName, T * pData) -{ - DWORD dwLength = sizeof(T); - - LONG status = WszRegQueryValueEx(hKey, pValueName, NULL, NULL, (BYTE*) pData, & dwLength); - - return status; -} - -// Reads CSP configuration info (name of CSP to use, IDs of hashing/signing -// algorithms) from the registry. -HRESULT ReadRegistryConfig() -{ - HKEY hKey; - DWORD dwLength; - - // Initialize all settings to their default values, in case they've not been - // specified in the registry. - g_bHasCSPName = FALSE; - g_bUseMachineKeyset = TRUE; - g_uKeySpec = AT_SIGNATURE; - g_uHashAlgId = CALG_SHA1; - g_uSignAlgId = CALG_RSA_SIGN; - g_uProvType = PROV_RSA_FULL; - -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - g_pVerificationRecords = NULL; -#endif - - g_fCacheVerify = TRUE; - - // Open the configuration key in the registry. - if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, SN_CONFIG_KEY_W, 0, KEY_READ, &hKey) != ERROR_SUCCESS) - return S_OK; - - // Read the preferred CSP name. - { - // Working set optimization: avoid touching g_wszCSPName (2052 bytes in size) unless registry has value for it - WCHAR tempCSPName[_countof(g_wszCSPName)]; - dwLength = sizeof(tempCSPName); - - tempCSPName[0] = 0; - - // If the registry key value is too long, that means it is invalid. - VERIFY(WszRegQueryValueEx(hKey, SN_CONFIG_CSP_W, NULL, NULL, - (BYTE*) tempCSPName, &dwLength) != ERROR_MORE_DATA); - tempCSPName[COUNTOF(tempCSPName) - 1] = W('\0'); // make sure the string is NULL-terminated - SNLOG((W("Preferred CSP name: '%s'\n"), tempCSPName)); - - if (tempCSPName[0] != W('\0')) - { - memcpy(g_wszCSPName, tempCSPName, sizeof(g_wszCSPName)); - g_bHasCSPName = TRUE; - } - } - - // Read the machine vs user key container flag. - DWORD dwUseMachineKeyset = TRUE; - RegQueryValueT(hKey, SN_CONFIG_MACHINE_KEYSET_W, & dwUseMachineKeyset); - SNLOG((W("Use machine keyset: %s\n"), dwUseMachineKeyset ? W("TRUE") : W("FALSE"))); - g_bUseMachineKeyset = (BOOLEAN)dwUseMachineKeyset; - - // Read the key spec. - RegQueryValueT(hKey, SN_CONFIG_KEYSPEC_W, & g_uKeySpec); - SNLOG((W("Key spec: %08X\n"), g_uKeySpec)); - - // Read the provider type - RegQueryValueT(hKey, SN_CONFIG_PROV_TYPE_W, & g_uProvType); - SNLOG((W("Provider Type: %08X\n"), g_uProvType)); - - // Read the hashing algorithm ID. - RegQueryValueT(hKey, SN_CONFIG_HASH_ALG_W, & g_uHashAlgId); - SNLOG((W("Hashing algorithm: %08X\n"), g_uHashAlgId)); - - // Read the signing algorithm ID. - RegQueryValueT(hKey, SN_CONFIG_SIGN_ALG_W, & g_uSignAlgId); - SNLOG((W("Signing algorithm: %08X\n"), g_uSignAlgId)); - - // Read the OK to cache verifications flag. - DWORD dwCacheVerify = TRUE; - RegQueryValueT(hKey, SN_CONFIG_CACHE_VERIFY_W, & dwCacheVerify); - SNLOG((W("OK to cache verifications: %s\n"), dwCacheVerify ? W("TRUE") : W("FALSE"))); - g_fCacheVerify = (BOOLEAN)dwCacheVerify; - - RegCloseKey(hKey); - - HRESULT hr = S_OK; -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - // Read verify disable records. - IfFailRet(ReadVerificationRecords()); -#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - -#ifdef FEATURE_STRONGNAME_MIGRATION - IfFailRet(ReadRevocationRecords()); -#endif // FEATURE_STRONGNAME_MIGRATION - - return hr; -} - -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED -// Read verification records from the registry during startup. -HRESULT ReadVerificationRecords() -{ - HKEYHolder hKey; - WCHAR wszSubKey[MAX_PATH_FNAME + 1]; - DWORD cchSubKey; - SN_VER_REC *pVerificationRecords = NULL; - HRESULT hr = S_OK; - - // Open the verification subkey in the registry. - if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, SN_CONFIG_KEY_W W("\\") SN_CONFIG_VERIFICATION_W, 0, KEY_READ, &hKey) != ERROR_SUCCESS) - return hr; - - // Assembly specific records are represented as subkeys of the key we've - // just opened. - for (DWORD i = 0; ; i++) { - // Get the name of the next subkey. - cchSubKey = MAX_PATH_FNAME + 1; - FILETIME sFiletime; - if (WszRegEnumKeyEx(hKey, i, wszSubKey, &cchSubKey, NULL, NULL, NULL, &sFiletime) != ERROR_SUCCESS) - break; - - // Open the subkey. - HKEYHolder hSubKey; - if (WszRegOpenKeyEx(hKey, wszSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) { - NewArrayHolder<WCHAR> mszUserList(NULL); - DWORD cbUserList; - NewArrayHolder<WCHAR> wszTestPublicKey(NULL); - DWORD cbTestPublicKey; - NewArrayHolder<WCHAR> wszAssembly(NULL); - SN_VER_REC *pVerRec; - - // Read a list of valid users, if supplied. - if ((WszRegQueryValueEx(hSubKey, SN_CONFIG_USERLIST_W, NULL, NULL, NULL, &cbUserList) == ERROR_SUCCESS) && - (cbUserList > 0)) { - mszUserList = new (nothrow) WCHAR[cbUserList / sizeof(WCHAR)]; - if (!mszUserList) { - hr = E_OUTOFMEMORY; - goto FreeListExit; - } - WszRegQueryValueEx(hSubKey, SN_CONFIG_USERLIST_W, NULL, NULL, (BYTE*)mszUserList.GetValue(), &cbUserList); - } - - // Read the test public key, if supplied - if ((WszRegQueryValueEx(hSubKey, SN_CONFIG_TESTPUBLICKEY_W, NULL, NULL, NULL, &cbTestPublicKey) == ERROR_SUCCESS) && - (cbTestPublicKey > 0)) { - wszTestPublicKey = new (nothrow) WCHAR[cbTestPublicKey / sizeof(WCHAR)]; - if (!wszTestPublicKey) { - hr = E_OUTOFMEMORY; - goto FreeListExit; - } - WszRegQueryValueEx(hSubKey, SN_CONFIG_TESTPUBLICKEY_W, NULL, NULL, (BYTE*)wszTestPublicKey.GetValue(), &cbTestPublicKey); - } - - size_t dwSubKeyLen = wcslen(wszSubKey); - wszAssembly = new (nothrow) WCHAR[dwSubKeyLen+1]; - if (!wszAssembly) { - hr = E_OUTOFMEMORY; - goto FreeListExit; - } - wcsncpy_s(wszAssembly, dwSubKeyLen+1, wszSubKey, _TRUNCATE); - wszAssembly[dwSubKeyLen] = W('\0'); - - // We've found a valid entry, add it to the local list. - pVerRec = new (nothrow) SN_VER_REC; - if (!pVerRec) { - hr = E_OUTOFMEMORY; - goto FreeListExit; - } - - pVerRec->m_mszUserList = mszUserList; - pVerRec->m_wszTestPublicKey = wszTestPublicKey; - pVerRec->m_wszAssembly = wszAssembly; - - mszUserList.SuppressRelease(); - wszTestPublicKey.SuppressRelease(); - wszAssembly.SuppressRelease(); - - pVerRec->m_pNext = pVerificationRecords; - pVerificationRecords = pVerRec; - SNLOG((W("Verification record for '%s' found in registry\n"), wszSubKey)); - } - } - - // Initialize the global list of verification records. - PVOID pv = InterlockedCompareExchangeT(&g_pVerificationRecords, pVerificationRecords, NULL); - if (pv == NULL) - return hr; - -FreeListExit: - // Iterate over local list of verification records and free allocated memory. - SN_VER_REC *pVerRec = pVerificationRecords; - while (pVerRec) { - delete [] pVerRec->m_mszUserList; - delete [] pVerRec->m_wszTestPublicKey; - delete [] pVerRec->m_wszAssembly; - SN_VER_REC *tmp = pVerRec->m_pNext; - delete pVerRec; - pVerRec = tmp; - } - return hr; -} -#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - - -#ifdef FEATURE_STRONGNAME_MIGRATION - -#define SN_REVOCATION_KEY_NAME_W W("RevokedKeys") // Registry revocation key name -#define SN_REVOKEDKEY_VALUE_NAME_W W("RevokedKey") // Registry value name - -HRESULT ReadReplacementKeys(HKEY hKey, SN_REPLACEMENT_KEY_REC **ppReplacementRecords) -{ - HRESULT hr = S_OK; - - DWORD uValueCount; - DWORD cchMaxValueNameLen; - - NewArrayHolder<WCHAR> wszValueName(NULL); - - if(RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &uValueCount, &cchMaxValueNameLen, NULL, NULL, NULL) != ERROR_SUCCESS) - return hr; - - cchMaxValueNameLen++; // Add 1 for null character - - DWORD cchValueName; - wszValueName = new (nothrow) WCHAR[cchMaxValueNameLen]; - if (!wszValueName) { - return E_OUTOFMEMORY; - } - - for (DWORD j = 0; j < uValueCount; j++) { - cchValueName = cchMaxValueNameLen; - if (WszRegEnumValue(hKey, j, wszValueName, &cchValueName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) - break; - - if(SString::_wcsicmp(wszValueName, SN_REVOKEDKEY_VALUE_NAME_W) == 0) // Skip over the "RevokedKey" value - continue; - - NewArrayHolder<BYTE> pbReplacementKey(NULL); - DWORD cbReplacementKey; - DWORD dwValType; - if ((WszRegQueryValueEx(hKey, wszValueName, NULL, &dwValType, NULL, &cbReplacementKey) == ERROR_SUCCESS) && - (cbReplacementKey > 0) && (dwValType == REG_BINARY)) { - pbReplacementKey = new (nothrow) BYTE[cbReplacementKey]; - if (!pbReplacementKey) { - return E_OUTOFMEMORY; - } - if(WszRegQueryValueEx(hKey, wszValueName, NULL, NULL, (BYTE*)pbReplacementKey.GetValue(), &cbReplacementKey) == ERROR_SUCCESS) - { - NewHolder<SN_REPLACEMENT_KEY_REC> pReplacementRecord(new (nothrow) SN_REPLACEMENT_KEY_REC); - if (pReplacementRecord == NULL) { - return E_OUTOFMEMORY; - } - - pReplacementRecord->m_pbReplacementKey = pbReplacementKey.Extract(); - pReplacementRecord->m_cbReplacementKey = cbReplacementKey; - // Insert into list - pReplacementRecord->m_pNext = *ppReplacementRecords; - *ppReplacementRecords = pReplacementRecord.Extract(); - } - } - } - - return hr; -} - -// Read revocation records from the registry during startup. -HRESULT ReadRevocationRecordsFromKey(REGSAM samDesired, SN_REVOCATION_REC **ppRevocationRecords) -{ - HKEYHolder hKey; - WCHAR wszSubKey[MAX_PATH_FNAME + 1]; - DWORD cchSubKey; - HRESULT hr = S_OK; - - // Open the revocation subkey in the registry. - if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, SN_CONFIG_KEY_W W("\\") SN_REVOCATION_KEY_NAME_W, 0, samDesired, &hKey) != ERROR_SUCCESS) - return hr; - - // Assembly specific records are represented as subkeys of the key we've - // just opened. - for (DWORD i = 0; ; i++) { - // Read the next subkey - cchSubKey = MAX_PATH_FNAME + 1; // reset size of buffer, as the following call changes it - if (WszRegEnumKeyEx(hKey, i, wszSubKey, &cchSubKey, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) - break; - - // Open the subkey. - HKEYHolder hSubKey; - if (WszRegOpenKeyEx(hKey, wszSubKey, 0, samDesired, &hSubKey) == ERROR_SUCCESS) { - NewArrayHolder<BYTE> pbRevokedKey(NULL); - DWORD cbRevokedKey; - DWORD dwValType; - - // Read the "RevokedKey" value - if ((WszRegQueryValueEx(hSubKey, SN_REVOKEDKEY_VALUE_NAME_W, NULL, &dwValType, NULL, &cbRevokedKey) == ERROR_SUCCESS) && - (cbRevokedKey > 0) && (dwValType == REG_BINARY)) { - pbRevokedKey = new (nothrow) BYTE[cbRevokedKey]; - if (!pbRevokedKey) { - return E_OUTOFMEMORY; - } - - if(WszRegQueryValueEx(hSubKey, SN_REVOKEDKEY_VALUE_NAME_W, NULL, NULL, (BYTE*)pbRevokedKey.GetValue(), &cbRevokedKey) == ERROR_SUCCESS) - { - // We've found a valid entry, store it - NewHolder<SN_REVOCATION_REC> pRevocationRecord(new (nothrow) SN_REVOCATION_REC); - if (pRevocationRecord == NULL) { - return E_OUTOFMEMORY; - } - - pRevocationRecord->m_pbRevokedKey = pbRevokedKey.Extract(); - pRevocationRecord->m_cbRevokedKey = cbRevokedKey; - pRevocationRecord->m_pReplacementKeys = NULL; - - // Insert into list - pRevocationRecord->m_pNext = *ppRevocationRecords; - *ppRevocationRecords = pRevocationRecord.Extract(); - - IfFailRet(ReadReplacementKeys(hSubKey, &pRevocationRecord->m_pReplacementKeys)); - - SNLOG((W("Revocation record '%s' found in registry\n"), wszSubKey)); - } - } - } - } - - return hr; -} - -HRESULT ReadRevocationRecords() -{ - HRESULT hr = S_OK; - - SYSTEM_INFO systemInfo; - SN_REVOCATION_REC *pRevocationRecords = NULL; - - GetNativeSystemInfo(&systemInfo); - // Read both Software\ and Software\WOW6432Node\ on 64-bit systems - if(systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - { - IfFailGoto(ReadRevocationRecordsFromKey(KEY_READ | KEY_WOW64_64KEY, &pRevocationRecords), FreeListExit); - IfFailGoto(ReadRevocationRecordsFromKey(KEY_READ | KEY_WOW64_32KEY, &pRevocationRecords), FreeListExit); - } - else - { - IfFailGoto(ReadRevocationRecordsFromKey(KEY_READ, &pRevocationRecords), FreeListExit); - } - - // Initialize the global list of verification records. - PVOID pv = InterlockedCompareExchangeT(&g_pRevocationRecords, pRevocationRecords, NULL); - - if (pv == NULL) // Successfully inserted the list we just created - return hr; - -FreeListExit: - // Iterate over local list of verification records and free allocated memory. - SN_REVOCATION_REC *pRevRec = pRevocationRecords; - while (pRevRec) { - if(pRevRec->m_pbRevokedKey) - delete [] pRevRec->m_pbRevokedKey; - - SN_REPLACEMENT_KEY_REC *pKeyRec = pRevRec->m_pReplacementKeys; - while (pKeyRec) { - if(pKeyRec->m_pbReplacementKey) - delete [] pKeyRec->m_pbReplacementKey; - - SN_REPLACEMENT_KEY_REC *tmp = pKeyRec->m_pNext; - delete pKeyRec; - pKeyRec = tmp; - } - - SN_REVOCATION_REC *tmp2 = pRevRec->m_pNext; - delete pRevRec; - pRevRec = tmp2; - } - return hr; -} - -#endif // FEATURE_STRONGNAME_MIGRATION - -// Check current user name against a multi-string user name list. Return true if -// the name is found (or the list is empty). -BOOLEAN IsValidUser(__in_z WCHAR *mszUserList) -{ - HANDLE hToken; - DWORD dwRetLen; - TOKEN_USER *pUser; - WCHAR wszUser[1024]; - WCHAR wszDomain[1024]; - DWORD cchUser; - DWORD cchDomain; - SID_NAME_USE eSidUse; - WCHAR *wszUserEntry; - - // Empty list implies no user name checking. - if (mszUserList == NULL) - return TRUE; - - // Get current user name. Don't cache this to avoid threading/impersonation - // problems. - // First look to see if there's a security token on the current thread - // (maybe we're impersonating). If not, we'll get the token from the - // process. - if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, FALSE, &hToken)) - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) { - SNLOG((W("Failed to find a security token, error %08X\n"), GetLastError())); - return FALSE; - } - - // Get the user SID. (Calculate buffer size first). - if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwRetLen) && - GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - SNLOG((W("Failed to calculate token information buffer size, error %08X\n"), GetLastError())); - CloseHandle(hToken); - return FALSE; - } - - NewArrayHolder<BYTE> pvBuffer = new (nothrow) BYTE[dwRetLen]; - if (pvBuffer == NULL) - { - SetLastError(E_OUTOFMEMORY); - return FALSE; - } - - if (!GetTokenInformation(hToken, TokenUser, reinterpret_cast<LPVOID>((BYTE*)pvBuffer), dwRetLen, &dwRetLen)) { - SNLOG((W("Failed to acquire token information, error %08X\n"), GetLastError())); - CloseHandle(hToken); - return FALSE; - } - - pUser = reinterpret_cast<TOKEN_USER *>(pvBuffer.GetValue()); - - // Get the user and domain names. - cchUser = sizeof(wszUser) / sizeof(WCHAR); - cchDomain = sizeof(wszDomain) / sizeof(WCHAR); - if (!WszLookupAccountSid(NULL, pUser->User.Sid, - wszUser, &cchUser, - wszDomain, &cchDomain, - &eSidUse)) { - SNLOG((W("Failed to lookup account information, error %08X\n"), GetLastError())); - CloseHandle(hToken); - return FALSE; - } - - CloseHandle(hToken); - - // Concatenate user and domain name to get a fully qualified account name. - if (((wcslen(wszUser) + wcslen(wszDomain) + 2) * sizeof(WCHAR)) > sizeof(wszDomain)) { - SNLOG((W("Fully qualified account name was too long\n"))); - return FALSE; - } - wcscat_s(wszDomain, COUNTOF(wszDomain), W("\\")); - wcscat_s(wszDomain, COUNTOF(wszDomain), wszUser); - SNLOG((W("Current username is '%s'\n"), wszDomain)); - - // Check current user against each name in the multi-string (packed - // list of nul terminated strings terminated with an additional nul). - wszUserEntry = mszUserList; - while (*wszUserEntry) { - if (!SString::_wcsicmp(wszDomain, wszUserEntry)) - return TRUE; - wszUserEntry += wcslen(wszUserEntry) + 1; - } - - // No user name match, fail search. - SNLOG((W("No username match\n"))); - - return FALSE; -} - -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED -// See if there's a verification records for the given assembly. -SN_VER_REC *GetVerificationRecord(__in_z __deref LPWSTR wszAssemblyName, PublicKeyBlob *pPublicKey) -{ - SN_VER_REC *pVerRec; - SN_VER_REC *pWildcardVerRec = NULL; - LPWSTR pAssembly = NULL; - BYTE *pbToken; - DWORD cbToken; - WCHAR wszStrongName[(SN_SIZEOF_TOKEN * 2) + 1]; - DWORD i; - - // Compress the public key to make for a shorter assembly name. - if (!StrongNameTokenFromPublicKey((BYTE*)pPublicKey, - SN_SIZEOF_KEY(pPublicKey), - &pbToken, - &cbToken)) - return NULL; - - if (cbToken > SN_SIZEOF_TOKEN) - return NULL; - - // Turn the token into hex. - for (i = 0; i < cbToken; i++) { - static WCHAR *wszHex = W("0123456789ABCDEF"); - wszStrongName[(i * 2) + 0] = wszHex[(pbToken[i] >> 4)]; - wszStrongName[(i * 2) + 1] = wszHex[(pbToken[i] & 0x0F)]; - } - wszStrongName[i * 2] = W('\0'); - delete[] pbToken; - - // Build the full assembly name. - - size_t nLen = wcslen(wszAssemblyName) + wcslen(W(",")) + wcslen(wszStrongName); - pAssembly = new (nothrow) WCHAR[nLen +1]; // +1 for NULL - if (pAssembly == NULL) - return NULL; - wcscpy_s(pAssembly, nLen + 1, wszAssemblyName); - wcscat_s(pAssembly, nLen + 1, W(",")); - wcscat_s(pAssembly, nLen + 1, wszStrongName); - - // Iterate over global list of verification records. - for (pVerRec = g_pVerificationRecords; pVerRec; pVerRec = pVerRec->m_pNext) { - // Look for matching assembly name. - if (!SString::_wcsicmp(pAssembly, pVerRec->m_wszAssembly)) { - delete[] pAssembly; - // Check current user against allowed user name list. - if (IsValidUser(pVerRec->m_mszUserList)) - return pVerRec; - else - return NULL; - } else if (!wcscmp(W("*,*"), pVerRec->m_wszAssembly)) { - // Found a wildcard record, it'll do if we don't find something more - // specific. - if (pWildcardVerRec == NULL) - pWildcardVerRec = pVerRec; - } else if (!wcsncmp(W("*,"), pVerRec->m_wszAssembly, 2)) { - // Found a wildcard record (with a specific strong name). If the - // strong names match it'll do unless we find something more - // specific (it overrides "*,*" wildcards though). - if (!SString::_wcsicmp(wszStrongName, &pVerRec->m_wszAssembly[2])) - pWildcardVerRec = pVerRec; - } - } - - delete[] pAssembly; - - // No match on specific assembly name, see if there's a wildcard entry. - if (pWildcardVerRec) - // Check current user against allowed user name list. - if (IsValidUser(pWildcardVerRec->m_mszUserList)) - return pWildcardVerRec; - else - return NULL; - - return NULL; -} -#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - -HRESULT -CallGetMetaDataInternalInterface( - LPVOID pData, - ULONG cbData, - DWORD flags, - REFIID riid, - LPVOID *ppInterface) -{ -#ifdef FEATURE_STRONGNAME_STANDALONE_WINRT - return E_NOTIMPL; -#elif STRONGNAME_IN_VM || !FEATURE_STANDALONE_SN - // We link the GetMetaDataInternalInterface, so just call it - return GetMetaDataInternalInterface( - pData, - cbData, - flags, - riid, - ppInterface); -#elif FEATURE_CORECLR - return E_NOTIMPL; -#else - - // We late bind the metadata function to avoid having a direct dependence on - // mscoree.dll unless we absolutely need to. - - HRESULT hr = S_OK; - ICLRMetaHost *pCLRMetaHost = NULL; - ICLRRuntimeInfo *pCLRRuntimeInfo = NULL; - ICLRRuntimeHostInternal *pCLRRuntimeHostInternal = NULL; - - HMODULE hLibrary = WszLoadLibrary(MSCOREE_SHIM_W); - if (hLibrary == NULL) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("WszLoadLibrary(\"") MSCOREE_SHIM_W W("\") failed with %08x\n"), hr)); - goto ErrExit; - } - - typedef HRESULT (__stdcall *PFNCLRCreateInstance)(REFCLSID clsid, REFIID riid, /*iid_is(riid)*/ LPVOID *ppInterface); - PFNCLRCreateInstance pfnCLRCreateInstance = reinterpret_cast<PFNCLRCreateInstance>(GetProcAddress( - hLibrary, - "CLRCreateInstance")); - if (pfnCLRCreateInstance == NULL) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Couldn't find CLRCreateInstance() in ") MSCOREE_SHIM_W W(": %08x\n"), hr)); - goto ErrExit; - } - - if (FAILED(hr = pfnCLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID *)&pCLRMetaHost))) - { - SNLOG((W("Error calling CLRCreateInstance() in ") MSCOREE_SHIM_W W(": %08x\n"), hr)); - goto ErrExit; - } - - if (FAILED(hr = pCLRMetaHost->GetRuntime( - W("v") VER_PRODUCTVERSION_NO_QFE_STR_L, - IID_ICLRRuntimeInfo, - (LPVOID *)&pCLRRuntimeInfo))) - { - SNLOG((W("Error calling ICLRMetaHost::GetRuntime() in ") MSCOREE_SHIM_W W(": %08x\n"), hr)); - goto ErrExit; - } - - if (FAILED(hr = pCLRRuntimeInfo->GetInterface( - CLSID_CLRRuntimeHostInternal, - IID_ICLRRuntimeHostInternal, - (LPVOID *)&pCLRRuntimeHostInternal))) - { - SNLOG((W("Error calling ICLRRuntimeInfo::GetInterface() in ") MSCOREE_SHIM_W W(": %08x\n"), hr)); - goto ErrExit; - } - - hr = pCLRRuntimeHostInternal->GetMetaDataInternalInterface( - (BYTE *)pData, - cbData, - flags, - riid, - ppInterface); - -ErrExit: - if (pCLRMetaHost != NULL) - { - pCLRMetaHost->Release(); - } - if (pCLRRuntimeInfo != NULL) - { - pCLRRuntimeInfo->Release(); - } - if (pCLRRuntimeHostInternal != NULL) - { - pCLRRuntimeHostInternal->Release(); - } - - return hr; - -#endif -} // CallGetMetaDataInternalInterface - -// Load metadata engine and return an importer. -HRESULT -GetMetadataImport( - __in const SN_LOAD_CTX *pLoadCtx, - __in mdAssembly *ptkAssembly, - __out IMDInternalImport **ppMetaDataImport) -{ - HRESULT hr = E_FAIL; - BYTE *pMetaData = NULL; - - // Locate the COM+ meta data within the header. - if (pLoadCtx->m_pedecoder->CheckCorHeader()) - { - pMetaData = (BYTE *)pLoadCtx->m_pedecoder->GetMetadata(); - } - - if (pMetaData == NULL) - { - SNLOG((W("Couldn't locate the COM+ header\n"))); - return CORSEC_E_INVALID_IMAGE_FORMAT; - } - - // Open a metadata scope on the memory directly. - ReleaseHolder<IMDInternalImport> pMetaDataImportHolder; - if (FAILED(hr = CallGetMetaDataInternalInterface( - pMetaData, - VAL32(pLoadCtx->m_pCorHeader->MetaData.Size), - ofRead, - IID_IMDInternalImport, - &pMetaDataImportHolder))) - { - SNLOG((W("GetMetaDataInternalInterface() failed with %08x\n"), hr)); - return SubstituteErrorIfNotTransient(hr, CORSEC_E_INVALID_IMAGE_FORMAT); - } - - // Determine the metadata token for the assembly from the scope. - if (FAILED(hr = pMetaDataImportHolder->GetAssemblyFromScope(ptkAssembly))) - { - SNLOG((W("pMetaData->GetAssemblyFromScope() failed with %08x\n"), hr)); - return SubstituteErrorIfNotTransient(hr, CORSEC_E_INVALID_IMAGE_FORMAT); - } - - *ppMetaDataImport = pMetaDataImportHolder.Extract(); - return S_OK; -} -#if STRONGNAME_IN_VM -// Function to form the fully qualified assembly name from the load context -BOOL FormFullyQualifiedAssemblyName(SN_LOAD_CTX *pLoadCtx, SString &assemblyName) -{ - mdAssembly tkAssembly; - // Open a metadata scope on the image. - ReleaseHolder<IMDInternalImport> pMetaDataImport; - HRESULT hr; - if (FAILED(hr = GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport))) - return FALSE; - - if (pMetaDataImport != NULL) - { - PEAssembly::GetFullyQualifiedAssemblyName(pMetaDataImport, tkAssembly, assemblyName); - return TRUE; - } - return FALSE; -} -#endif - - -// Locate the public key blob located within the metadata of an assembly file -// and return a copy (use delete to deallocate). Optionally get the assembly -// name as well. -HRESULT FindPublicKey(const SN_LOAD_CTX *pLoadCtx, - __out_ecount_opt(cchAssemblyName) LPWSTR wszAssemblyName, - DWORD cchAssemblyName, - __out PublicKeyBlob **ppPublicKey, - DWORD *pcbPublicKey) -{ - HRESULT hr = S_OK; - *ppPublicKey = NULL; - - // Open a metadata scope on the image. - mdAssembly tkAssembly; - ReleaseHolder<IMDInternalImport> pMetaDataImport; - if (FAILED(hr = GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport))) - return hr; - - // Read the public key location from the assembly properties (it's known as - // the originator property). - PublicKeyBlob *pKey; - DWORD dwKeyLen; - LPCSTR szAssemblyName; - if (FAILED(hr = pMetaDataImport->GetAssemblyProps(tkAssembly, // [IN] The Assembly for which to get the properties - (const void **)&pKey, // [OUT] Pointer to the Originator blob - &dwKeyLen, // [OUT] Count of bytes in the Originator Blob - NULL, // [OUT] Hash Algorithm - &szAssemblyName, // [OUT] Buffer to fill with name - NULL, // [OUT] Assembly MetaData - NULL))) // [OUT] Flags - { - SNLOG((W("Did not get public key property: %08x\n"), hr)); - return SubstituteErrorIfNotTransient(hr, CORSEC_E_MISSING_STRONGNAME); - } - - if (dwKeyLen == 0) - { - SNLOG((W("No public key stored in metadata\n"))); - return CORSEC_E_MISSING_STRONGNAME; - } - - // Make a copy of the key blob (because we're going to close the metadata scope). - NewArrayHolder<BYTE> pKeyCopy(new (nothrow) BYTE[dwKeyLen]); - if (pKeyCopy == NULL) - return E_OUTOFMEMORY; - memcpy_s(pKeyCopy, dwKeyLen, pKey, dwKeyLen); - - // Copy the assembly name as well (if it was asked for). We also convert - // from UTF8 to UNICODE while we're at it. - if (wszAssemblyName) - WszMultiByteToWideChar(CP_UTF8, 0, szAssemblyName, -1, wszAssemblyName, cchAssemblyName); - - *ppPublicKey = reinterpret_cast<PublicKeyBlob *>(pKeyCopy.Extract()); - if(pcbPublicKey != NULL) - *pcbPublicKey = dwKeyLen; - - return S_OK; -} - -BYTE HexToByte (WCHAR wc) { - if (!iswxdigit(wc)) return (BYTE) 0xff; - if (iswdigit(wc)) return (BYTE) (wc - W('0')); - if (iswupper(wc)) return (BYTE) (wc - W('A') + 10); - return (BYTE) (wc - W('a') + 10); -} - -// Read the hex string into a PublicKeyBlob structure. -// Caller owns the blob. -PublicKeyBlob *GetPublicKeyFromHex(LPCWSTR wszPublicKeyHexString) { - size_t cchHex = wcslen(wszPublicKeyHexString); - size_t cbHex = cchHex / 2; - if (cchHex % 2 != 0) - return NULL; - - BYTE *pKey = new (nothrow) BYTE[cbHex]; - if (!pKey) - return NULL; - for (size_t i = 0; i < cbHex; i++) { - pKey[i] = (BYTE) ((HexToByte(*wszPublicKeyHexString) << 4) | HexToByte(*(wszPublicKeyHexString + 1))); - wszPublicKeyHexString += 2; - } - return (PublicKeyBlob*) pKey; -} - -// Create a temporary key container name likely to be unique to this process and -// thread. Any existing container with the same name is deleted. -BOOLEAN GetKeyContainerName(LPCWSTR *pwszKeyContainer, BOOLEAN *pbTempContainer) -{ - *pbTempContainer = FALSE; - - if (*pwszKeyContainer != NULL) - return TRUE; - - GUID guid; - HRESULT hr = CoCreateGuid(&guid); - if (FAILED(hr)) { - SetStrongNameErrorInfo(hr); - return FALSE; - } - - WCHAR wszGuid[64]; - if (GuidToLPWSTR(guid, wszGuid, sizeof(wszGuid) / sizeof(WCHAR)) == 0) { - SetStrongNameErrorInfo(E_UNEXPECTED); // this operation should never fail - return FALSE; - } - - // Name is of form '__MSCORSN__<guid>__' where <guid> is a GUID. - const size_t cchLengthOfKeyContainer = sizeof("__MSCORSN____") + (sizeof(wszGuid) / sizeof(WCHAR)) + 1 /* null */; - LPWSTR wszKeyContainer = new (nothrow) WCHAR[cchLengthOfKeyContainer]; - if (wszKeyContainer == NULL) { - SetStrongNameErrorInfo(E_OUTOFMEMORY); - return FALSE; - } - - _snwprintf_s(wszKeyContainer, cchLengthOfKeyContainer - 1 /* exclude null */, _TRUNCATE, - W("__MSCORSN__%s__"), - wszGuid); - - // Delete any stale container with the same name. - LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER); - - SNLOG((W("Creating temporary key container name '%s'\n"), wszKeyContainer)); - - *pwszKeyContainer = wszKeyContainer; - *pbTempContainer = TRUE; - - return TRUE; -} - - -// Free resources allocated by GetKeyContainerName and delete the named -// container. -VOID FreeKeyContainerName(LPCWSTR wszKeyContainer, BOOLEAN bTempContainer) -{ - if (bTempContainer) { - // Free the name. - delete [] (WCHAR*)wszKeyContainer; - } -} - -static DWORD GetSpecialKeyFlags(PublicKeyBlob* pKey) -{ - if (SN_IS_THE_KEY(pKey)) - return SN_OUTFLAG_MICROSOFT_SIGNATURE; - - return 0; -} - -#ifdef FEATURE_STRONGNAME_MIGRATION - -HRESULT VerifyCounterSignature( - PublicKeyBlob *pSignaturePublicKey, - ULONG cbSignaturePublicKey, - PublicKeyBlob *pIdentityPublicKey, - BYTE *pCounterSignature, - ULONG cbCounterSignature) -{ - LIMITED_METHOD_CONTRACT; - - HRESULT hr = S_OK; - - HandleStrongNameCspHolder hProv(NULL); - HandleKeyHolder hKey(NULL); - HandleHashHolder hHash(NULL); - - hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, GET_UNALIGNED_VAL32(&pIdentityPublicKey->HashAlgID), GET_UNALIGNED_VAL32(&pIdentityPublicKey->SigAlgID)); - - if (!hProv) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to acquire a CSP: %08x"), hr)); - return hr; - } - - if(SN_IS_NEUTRAL_KEY(pIdentityPublicKey)) - { - pIdentityPublicKey = reinterpret_cast<PublicKeyBlob *>(const_cast<BYTE *>(g_rbTheKey)); - } - - BYTE *pbRealPublicKey = pIdentityPublicKey->PublicKey; - DWORD cbRealPublicKey = GET_UNALIGNED_VAL32(&pIdentityPublicKey->cbPublicKey); - - if (!CryptImportKey(hProv, pbRealPublicKey, cbRealPublicKey, 0, 0, &hKey)) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to import key: %08x"), hr)); - return hr; - } - - // Create a hash object. - if (!CryptCreateHash(hProv, GET_UNALIGNED_VAL32(&pIdentityPublicKey->HashAlgID), 0, 0, &hHash)) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to create hash: %08x"), hr)); - return hr; - } - - if (!CryptHashData(hHash, (BYTE*)pSignaturePublicKey, cbSignaturePublicKey, 0)) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to compute hash: %08x"), hr)); - return hr; - } - -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) - if (hHash != (HCRYPTHASH)INVALID_HANDLE_VALUE) { - DWORD cbHash; - DWORD dwRetLen = sizeof(cbHash); - if (CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHash, &dwRetLen, 0)) - { - NewArrayHolder<BYTE> pbHash(new (nothrow) BYTE[cbHash]); - if (pbHash != NULL) - { - if (CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0)) - { - SNLOG((W("Computed Hash Value (%u bytes):\n"), cbHash)); - HexDump(pbHash, cbHash); - } - else - { - SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError())); - } - } - } - else - { - SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError())); - } - } -#endif // _DEBUG - - // Verify the hash against the signature. - //DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeVerify") : W("FusionVerify")); - if (pCounterSignature != NULL && cbCounterSignature != 0 && - CryptVerifySignatureW(hHash, pCounterSignature, cbCounterSignature, hKey, NULL, 0)) - { - SNLOG((W("Counter-signature verification succeeded\n"))); - } - else - { - SNLOG((W("Counter-signature verification failed\n"))); - hr = CORSEC_E_INVALID_COUNTERSIGNATURE; - } - - return hr; -} - -HRESULT ParseStringArgs( - CustomAttributeParser &ca, // The Custom Attribute blob. - CaArg* pArgs, // Array of argument descriptors. - ULONG cArgs) // Count of argument descriptors. -{ - LIMITED_METHOD_CONTRACT; - - HRESULT hr = S_OK; - - // For each expected arg... - for (ULONG ix=0; ix<cArgs; ++ix) - { - CaArg* pArg = &pArgs[ix]; - if(pArg->type.tag != SERIALIZATION_TYPE_STRING) - { - return E_UNEXPECTED; // The blob shouldn't have anything other than strings - } - IfFailGo(ca.GetString(&pArg->val.str.pStr, &pArg->val.str.cbStr)); - } - -ErrExit: - return hr; -} - -HRESULT GetVerifiedSignatureKey(__in SN_LOAD_CTX *pLoadCtx, __out PublicKeyBlob **ppPublicKey, __out_opt DWORD *pcbPublicKey) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - mdAssembly tkAssembly; - ReleaseHolder<IMDInternalImport> pMetaDataImport; - IfFailRet(GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport)); - - HRESULT attributeHr; - void *pAttribute; - ULONG cbAttribute; - hr = pMetaDataImport->GetCustomAttributeByName(tkAssembly, g_AssemblySignatureKeyAttribute, const_cast<const void**>(&pAttribute), &cbAttribute); - - if (SUCCEEDED(hr) && hr != S_FALSE) - { - CustomAttributeParser parser(pAttribute, cbAttribute); - IfFailRet(parser.ValidateProlog()); - - CaType caTypeString; - caTypeString.Init(SERIALIZATION_TYPE_STRING); - - CaArg args[2]; - - CaArg* argPublicKey = &args[0]; - argPublicKey->Init(caTypeString); - - CaArg* argCounterSignature = &args[1]; - argCounterSignature->Init(caTypeString); - - IfFailRet(ParseStringArgs(parser, args, lengthof(args))); - - StrongNameBufferHolder<PublicKeyBlob> pSignaturePublicKey; - ULONG cbSignaturePublicKey; - if (argPublicKey->val.str.pStr == NULL || argPublicKey->val.str.cbStr == 0 || - (!GetBytesFromHex(argPublicKey->val.str.pStr, argPublicKey->val.str.cbStr, (BYTE**)(pSignaturePublicKey.GetAddr()), &cbSignaturePublicKey)) || - !StrongNameIsValidPublicKey((BYTE*)pSignaturePublicKey.GetValue(), cbSignaturePublicKey, false)) - { - return CORSEC_E_INVALID_SIGNATUREKEY; - } - - NewArrayHolder<BYTE> pCounterSignature; - ULONG cbCounterSignature; - if (argCounterSignature->val.str.pStr == NULL || argCounterSignature->val.str.cbStr == 0 || - (!GetBytesFromHex(argCounterSignature->val.str.pStr, argCounterSignature->val.str.cbStr, &pCounterSignature, &cbCounterSignature))) - { - return CORSEC_E_INVALID_COUNTERSIGNATURE; - } - - StrongNameBufferHolder<PublicKeyBlob> pIdentityPublicKey = NULL; - IfFailRet(FindPublicKey(pLoadCtx, NULL, 0, &pIdentityPublicKey)); - - IfFailRet(VerifyCounterSignature(pSignaturePublicKey, cbSignaturePublicKey, pIdentityPublicKey, pCounterSignature, cbCounterSignature)); - - *ppPublicKey = pSignaturePublicKey.Extract(); - if (pcbPublicKey != NULL) - *pcbPublicKey = cbSignaturePublicKey; - } - else - { - *ppPublicKey = NULL; - if (pcbPublicKey != NULL) - *pcbPublicKey = 0; - } - - return hr; -} - -// Checks revocation list against the assembly's public keys. -// If the identity key has been revoked, then the signature key must be non-null and -// must be in the replacement keys list to be allowed. -bool AreKeysAllowedByRevocationList(BYTE* pbAssemblyIdentityKey, DWORD cbAssemblyIdentityKey, BYTE* pbAssemblySignatureKey, DWORD cbAssemblySignatureKey) -{ - LIMITED_METHOD_CONTRACT; - - bool fRevoked = false; - - SN_REVOCATION_REC *pRevocationRec = g_pRevocationRecords; - while (pRevocationRec) - { - if (pRevocationRec->m_cbRevokedKey == cbAssemblyIdentityKey && - memcmp(pRevocationRec->m_pbRevokedKey, pbAssemblyIdentityKey, cbAssemblyIdentityKey) == 0) - { - fRevoked = true; // Identity key can't be trusted. - - if (pbAssemblySignatureKey != NULL) - { - SN_REPLACEMENT_KEY_REC *pReplacementKeyRec = pRevocationRec->m_pReplacementKeys; - - while (pReplacementKeyRec) - { - if (pReplacementKeyRec->m_cbReplacementKey == cbAssemblySignatureKey && - memcmp(pReplacementKeyRec->m_pbReplacementKey, pbAssemblySignatureKey, cbAssemblySignatureKey) == 0) - { - // Signature key was allowed as a replacement for the revoked identity key. - return true; - } - - pReplacementKeyRec = pReplacementKeyRec->m_pNext; - } - } - // We didn't find the signature key in the list of allowed replacement keys for this record. - // However, we don't return here, because another record might have the same identity key - // and allow the signature key as a replacement. - } - - pRevocationRec = pRevocationRec->m_pNext; - } - - return !fRevoked; -} - -#endif // FEATURE_STRONGNAME_MIGRATION - -// The common code used to verify a signature (taking into account whether skip -// verification is enabled for the given assembly). -HRESULT VerifySignature(__in SN_LOAD_CTX *pLoadCtx, DWORD dwInFlags, PublicKeyBlob *pRealEcmaPublicKey,__out_opt DWORD *pdwOutFlags) -{ - if (pdwOutFlags) - *pdwOutFlags = 0; - - // Read the public key used to sign the assembly from the assembly metadata. - // Also get the assembly name, we might need this if we fail the - // verification and need to look up a verification disablement entry. - WCHAR wszSimpleAssemblyName[MAX_PATH_FNAME + 1]; - SString strFullyQualifiedAssemblyName; - BOOL bSuccess = FALSE; -#if STRONGNAME_IN_VM - BOOL bAssemblyNameFormed = FALSE; - BOOL bVerificationBegun = FALSE; -#endif - - HandleKeyHolder hKey(NULL); - HandleHashHolder hHash(NULL); - HandleStrongNameCspHolder hProv(NULL); - - StrongNameBufferHolder<PublicKeyBlob> pAssemblyIdentityKey; - DWORD cbAssemblyIdentityKey; - HRESULT hr = FindPublicKey(pLoadCtx, - wszSimpleAssemblyName, - sizeof(wszSimpleAssemblyName) / sizeof(WCHAR), - &pAssemblyIdentityKey, - &cbAssemblyIdentityKey); - if (FAILED(hr)) - return hr; - - BOOL isEcmaKey = SN_IS_NEUTRAL_KEY(pAssemblyIdentityKey); - // If we're handed the ECMA key, we translate it to the real key at this point. - // Note: gcc gets confused with the complexity of StrongNameBufferHolder<> and - // won't auto-convert pAssemblyIdentityKey to type PublicKeyBlob*, so cast it explicitly. - PublicKeyBlob *pRealPublicKey = isEcmaKey ? pRealEcmaPublicKey : static_cast<PublicKeyBlob*>(pAssemblyIdentityKey); - -// An assembly can specify a signature public key in an attribute. -// If one is present, we verify the signature using that public key. -#ifdef FEATURE_STRONGNAME_MIGRATION - StrongNameBufferHolder<PublicKeyBlob> pAssemblySignaturePublicKey; - DWORD cbAssemblySignaturePublicKey; - IfFailRet(GetVerifiedSignatureKey(pLoadCtx, &pAssemblySignaturePublicKey, &cbAssemblySignaturePublicKey)); - if(hr != S_FALSE) // Attribute was found - { - pRealPublicKey = pAssemblySignaturePublicKey; - } - -#endif // FEATURE_STRONGNAME_MIGRATION - - DWORD dwSpecialKeys = GetSpecialKeyFlags(pRealPublicKey); - - // If this isn't the first time we've been called for this assembly and we - // know it was fully signed and we're confident it couldn't have been - // tampered with in the meantime, we can just skip the verification. - if (!(dwInFlags & SN_INFLAG_FORCE_VER) && - !(dwInFlags & SN_INFLAG_INSTALL) && - (pLoadCtx->m_pCorHeader->Flags & VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED)) && - ((dwInFlags & SN_INFLAG_ADMIN_ACCESS) || g_fCacheVerify)) - { - SNLOG((W("Skipping verification due to cached result\n"))); - DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeSkipCache") : W("FusionSkipCache")); - return S_OK; - } - -#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - // If we're not forcing verification, let's see if there's a skip - // verification entry for this assembly. If there is we can skip all the - // hard work and just lie about the strong name now. The exception is if the - // assembly is marked as fully signed, in which case we have to force a - // verification to see if they're telling the truth. - StrongNameBufferHolder<PublicKeyBlob> pTestKey = NULL; - SN_VER_REC *pVerRec = GetVerificationRecord(wszSimpleAssemblyName, pAssemblyIdentityKey); - if (!(dwInFlags & SN_INFLAG_FORCE_VER) && !(pLoadCtx->m_pCorHeader->Flags & VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED))) - { - if (pVerRec != NULL) - { - if (pVerRec->m_wszTestPublicKey) - { - // substitute the public key with the test public key. - pTestKey = GetPublicKeyFromHex(pVerRec->m_wszTestPublicKey); - if (pTestKey != NULL) - { - - SNLOG((W("Using test public key for verification due to registry entry\n"))); - DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeSkipDelay") : W("FusionSkipDelay")); - - // If the assembly was not ECMA signed, then we need to update the key that it will be - // verified with as well. - if (!isEcmaKey) - { - // When test signing, there's no way to specify a hash algorithm. - // So instead of defaulting to SHA1, we pick the algorithm the assembly - // would've been signed with, if the test key wasn't present. - // Thus we use the same algorithm when verifying the signature. - SET_UNALIGNED_VAL32(&pTestKey->HashAlgID, GET_UNALIGNED_VAL32(&pRealPublicKey->HashAlgID)); - - pRealPublicKey = pTestKey; - } - } - } - else - { - SNLOG((W("Skipping verification due to registry entry\n"))); - DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeSkipDelay") : W("FusionSkipDelay")); - if (pdwOutFlags) - { - *pdwOutFlags |= dwSpecialKeys; - } - return S_OK; - } - } - } -#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED - -#ifdef FEATURE_STRONGNAME_MIGRATION - if(!isEcmaKey) // We should never revoke the ecma key, as it is tied strongly to the runtime - { - if(!AreKeysAllowedByRevocationList((BYTE*)pAssemblyIdentityKey.GetValue(), cbAssemblyIdentityKey, (BYTE*)pAssemblySignaturePublicKey.GetValue(), cbAssemblySignaturePublicKey)) - { - if(pAssemblySignaturePublicKey == NULL) - { - SNLOG((W("Verification failed. Assembly public key has been revoked\n"))); - } - else - { - SNLOG((W("Verification failed. Assembly identity key has been revoked, an the assembly signature key isn't in the replacement key list\n"))); - } - - hr = CORSEC_E_INVALID_STRONGNAME; - goto Error; - } - } - -#endif // FEATURE_STRONGNAME_MIGRATION - -#ifdef FEATURE_CORECLR - // TritonTODO: check with security team on this - if (pLoadCtx->m_pbSignature == NULL) - { - hr = CORSEC_E_MISSING_STRONGNAME; - goto Error; - } -#endif //FEATURE_CORECLR - -#if STRONGNAME_IN_VM - bVerificationBegun = TRUE; - // SN verification start event - if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_SECURITY_KEYWORD)) - { - // form the fully qualified assembly name using the load context - bAssemblyNameFormed = FormFullyQualifiedAssemblyName(pLoadCtx, strFullyQualifiedAssemblyName); - if(bAssemblyNameFormed) - { - ETW::SecurityLog::StrongNameVerificationStart(dwInFlags,(LPWSTR)strFullyQualifiedAssemblyName.GetUnicode()); - } - } -#endif // STRONGNAME_IN_VM - - ALG_ID uHashAlgId = GET_UNALIGNED_VAL32(&pRealPublicKey->HashAlgID); - ALG_ID uSignAlgId = GET_UNALIGNED_VAL32(&pRealPublicKey->SigAlgID); - - // Default hashing and signing algorithm IDs if necessary. - if (uHashAlgId == 0) - uHashAlgId = CALG_SHA1; - if (uSignAlgId == 0) - uSignAlgId = CALG_RSA_SIGN; - - // Find a CSP supporting the required algorithms. - hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, uHashAlgId, uSignAlgId); - if (!hProv) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to acquire a CSP: %08x"), hr)); - goto Error; - } - - BYTE *pbRealPublicKey; - pbRealPublicKey = pRealPublicKey->PublicKey; - DWORD cbRealPublicKey; - cbRealPublicKey = GET_UNALIGNED_VAL32(&pRealPublicKey->cbPublicKey); - - if (!CryptImportKey(hProv, pbRealPublicKey, cbRealPublicKey, 0, 0, &hKey)) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to import key: %08x"), hr)); - goto Error; - } - - // Create a hash object. - - if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash)) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to create hash: %08x"), hr)); - goto Error; - } - - // Compute a hash over the image. - if (!ComputeHash(pLoadCtx, hHash, CalcHash, NULL)) - { - hr = HRESULT_FROM_GetLastError(); - SNLOG((W("Failed to compute hash: %08x"), hr)); - goto Error; - } - - // Verify the hash against the signature. - DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeVerify") : W("FusionVerify")); - if (pLoadCtx->m_pbSignature != NULL && pLoadCtx->m_cbSignature != 0 && - CryptVerifySignatureW(hHash, pLoadCtx->m_pbSignature, pLoadCtx->m_cbSignature, hKey, NULL, 0)) - { - SNLOG((W("Verification succeeded (for real)\n"))); - if (pdwOutFlags) - { - *pdwOutFlags |= dwSpecialKeys | SN_OUTFLAG_WAS_VERIFIED; - } - bSuccess = TRUE; - } - else - { - SNLOG((W("Verification failed\n"))); - hr = CORSEC_E_INVALID_STRONGNAME; - } - -Error: - -#if STRONGNAME_IN_VM - // SN verification end event - if(bVerificationBegun && - ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_VERBOSE, CLR_SECURITY_KEYWORD)) - { - // form the fully qualified assembly name using the load context if it has not yet been formed - if(!bAssemblyNameFormed) - { - strFullyQualifiedAssemblyName.Clear(); - bAssemblyNameFormed = FormFullyQualifiedAssemblyName(pLoadCtx, strFullyQualifiedAssemblyName); - } - if(bAssemblyNameFormed) - { - ETW::SecurityLog::StrongNameVerificationStop(dwInFlags,(ULONG)hr, (LPWSTR)strFullyQualifiedAssemblyName.GetUnicode()); - } - } -#endif // STRONGNAME_IN_VM - - if (bSuccess) - return S_OK; - else - return hr; -} - -// Compute a hash over the elements of an assembly manifest file that should -// remain static (skip checksum, Authenticode signatures and strong name -// signature blob). -// This function can also be used to get the blob of bytes that would be -// hashed without actually hashing. -BOOLEAN ComputeHash(SN_LOAD_CTX *pLoadCtx, HCRYPTHASH hHash, HashFunc func, void* cookie) -{ - union { - IMAGE_NT_HEADERS32 m_32; - IMAGE_NT_HEADERS64 m_64; - } sHeaders; - IMAGE_SECTION_HEADER *pSections; - ULONG i; - BYTE *pbSig = pLoadCtx->m_pbSignature; - DWORD cbSig = pLoadCtx->m_cbSignature; - -#define LIMIT_CHECK(_start, _length, _fileStart, _fileLength) \ - do { if (((_start) < (_fileStart)) || \ - (((_start)+(_length)) < (_start)) || \ - (((_start)+(_length)) < (_fileStart)) || \ - (((_start)+(_length)) > ((_fileStart)+(_fileLength))) ) \ - { SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT); return FALSE; } } while (false) - -#define FILE_LIMIT_CHECK(_start, _length) LIMIT_CHECK(_start, _length, pLoadCtx->m_pbBase, pLoadCtx->m_dwLength) - -#define SN_HASH(_start, _length) do { if (!func(hHash, (_start), (_length), 0, cookie)) return FALSE; } while (false) - -#define SN_CHECK_AND_HASH(_start, _length) do { FILE_LIMIT_CHECK(_start, _length); SN_HASH(_start, _length); } while (false) - - // Make sure the file size doesn't wrap around. - if (pLoadCtx->m_pbBase + pLoadCtx->m_dwLength <= pLoadCtx->m_pbBase) - { - SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT); - return FALSE; - } - - // Make sure the signature is completely contained within the file. - FILE_LIMIT_CHECK(pbSig, cbSig); - - // Hash the DOS header if it exists. - if ((BYTE*)pLoadCtx->m_pNtHeaders != pLoadCtx->m_pbBase) - SN_CHECK_AND_HASH(pLoadCtx->m_pbBase, (DWORD)((BYTE*)pLoadCtx->m_pNtHeaders - pLoadCtx->m_pbBase)); - - // Add image headers minus the checksum and security data directory. - if (pLoadCtx->m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC)) { - sHeaders.m_32 = *((IMAGE_NT_HEADERS32*)pLoadCtx->m_pNtHeaders); - sHeaders.m_32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0; - sHeaders.m_32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0; - sHeaders.m_32.OptionalHeader.CheckSum = 0; - SN_HASH((BYTE*)&sHeaders.m_32, sizeof(sHeaders.m_32)); - } else if (pLoadCtx->m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC)) { - sHeaders.m_64 = *((IMAGE_NT_HEADERS64*)pLoadCtx->m_pNtHeaders); - sHeaders.m_64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0; - sHeaders.m_64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0; - sHeaders.m_64.OptionalHeader.CheckSum = 0; - SN_HASH((BYTE*)&sHeaders.m_64, sizeof(sHeaders.m_64)); - } else { - SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT); - return FALSE; - } - - // Then the section headers. - pSections = IMAGE_FIRST_SECTION(pLoadCtx->m_pNtHeaders); - SN_CHECK_AND_HASH((BYTE*)pSections, VAL16(pLoadCtx->m_pNtHeaders->FileHeader.NumberOfSections) * sizeof(IMAGE_SECTION_HEADER)); - - // Finally, add data from each section. - for (i = 0; i < VAL16(pLoadCtx->m_pNtHeaders->FileHeader.NumberOfSections); i++) { - BYTE *pbData = pLoadCtx->m_pbBase + VAL32(pSections[i].PointerToRawData); - DWORD cbData = VAL32(pSections[i].SizeOfRawData); - - // We need to exclude the strong name signature blob from the hash. The - // blob could intersect the section in a number of ways. - - if ((pbSig + cbSig) <= pbData || pbSig >= (pbData + cbData)) - // No intersection at all. Hash all data. - SN_CHECK_AND_HASH(pbData, cbData); - else if (pbSig == pbData && cbSig == cbData) - // Signature consumes entire block. Hash no data. - ; - else if (pbSig == pbData) - // Signature at start. Hash end. - SN_CHECK_AND_HASH(pbData + cbSig, cbData - cbSig); - else if ((pbSig + cbSig) == (pbData + cbData)) - // Signature at end. Hash start. - SN_CHECK_AND_HASH(pbData, cbData - cbSig); - else { - // Signature in the middle. Hash head and tail. - SN_CHECK_AND_HASH(pbData, (DWORD)(pbSig - pbData)); - SN_CHECK_AND_HASH(pbSig + cbSig, cbData - (DWORD)(pbSig + cbSig - pbData)); - } - } - -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) - if (hHash != (HCRYPTHASH)INVALID_HANDLE_VALUE) { - DWORD cbHash; - DWORD dwRetLen = sizeof(cbHash); - if (CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHash, &dwRetLen, 0)) - { - NewArrayHolder<BYTE> pbHash(new (nothrow) BYTE[cbHash]); - if (pbHash != NULL) - { - if (CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0)) - { - SNLOG((W("Computed Hash Value (%u bytes):\n"), cbHash)); - HexDump(pbHash, cbHash); - } - else - { - SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError())); - } - } - } - else - { - SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError())); - } - } -#endif // _DEBUG - - return TRUE; - -#undef SN_CHECK_AND_HASH -#undef SN_HASH -#undef FILE_LIMIT_CHECK -#undef LIMIT_CHECK -} - - -SNAPI_(DWORD) GetHashFromAssemblyFile(LPCSTR szFilePath, // [IN] location of file to be hashed - unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) - BYTE *pbHash, // [OUT] hash buffer - DWORD cchHash, // [IN] max size of buffer - DWORD *pchHash) // [OUT] length of hash byte array -{ - BOOL retVal = FALSE; - - BEGIN_ENTRYPOINT_NOTHROW; - // Convert filename to wide characters and call the W version of this - // function. - - MAKE_WIDEPTR_FROMANSI(wszFilePath, szFilePath); - retVal = GetHashFromAssemblyFileW(wszFilePath, piHashAlg, pbHash, cchHash, pchHash); - END_ENTRYPOINT_NOTHROW; - return retVal; -} - -SNAPI_(DWORD) GetHashFromAssemblyFileW(LPCWSTR wszFilePath, // [IN] location of file to be hashed - unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) - BYTE *pbHash, // [OUT] hash buffer - DWORD cchHash, // [IN] max size of buffer - DWORD *pchHash) // [OUT] length of hash byte array -{ - HRESULT hr; - - BEGIN_ENTRYPOINT_NOTHROW; - - SN_LOAD_CTX sLoadCtx; - BYTE *pbMetaData = NULL; - DWORD cbMetaData; - - sLoadCtx.m_fReadOnly = TRUE; - if (!LoadAssembly(&sLoadCtx, wszFilePath, 0, FALSE)) - IfFailGo(HRESULT_FROM_GetLastError()); - - if (sLoadCtx.m_pedecoder->CheckCorHeader()) - { - pbMetaData = (BYTE *)sLoadCtx.m_pedecoder->GetMetadata(); - } - if (pbMetaData == NULL) { - UnloadAssembly(&sLoadCtx); - IfFailGo(E_INVALIDARG); - } - cbMetaData = VAL32(sLoadCtx.m_pCorHeader->MetaData.Size); - - hr = GetHashFromBlob(pbMetaData, cbMetaData, piHashAlg, pbHash, cchHash, pchHash); - - UnloadAssembly(&sLoadCtx); -ErrExit: - - END_ENTRYPOINT_NOTHROW; - return hr; -} - -SNAPI_(DWORD) GetHashFromFile(LPCSTR szFilePath, // [IN] location of file to be hashed - unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) - BYTE *pbHash, // [OUT] hash buffer - DWORD cchHash, // [IN] max size of buffer - DWORD *pchHash) // [OUT] length of hash byte array -{ - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - HANDLE hFile = CreateFileA(szFilePath, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - hr = HRESULT_FROM_GetLastError(); - } - else - { - hr = GetHashFromHandle(hFile, piHashAlg, pbHash, cchHash, pchHash); - CloseHandle(hFile); - } - END_ENTRYPOINT_NOTHROW; - return hr; -} - -SNAPI_(DWORD) GetHashFromFileW(LPCWSTR wszFilePath, // [IN] location of file to be hashed - unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) - BYTE *pbHash, // [OUT] hash buffer - DWORD cchHash, // [IN] max size of buffer - DWORD *pchHash) // [OUT] length of hash byte array -{ - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - HANDLE hFile = WszCreateFile(wszFilePath, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); - if (hFile == INVALID_HANDLE_VALUE) - IfFailGo(HRESULT_FROM_GetLastError()); - - hr = GetHashFromHandle(hFile, piHashAlg, pbHash, cchHash, pchHash); - CloseHandle(hFile); -ErrExit: - - END_ENTRYPOINT_NOTHROW; - return hr; -} - -SNAPI_(DWORD) GetHashFromHandle(HANDLE hFile, // [IN] handle of file to be hashed - unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) - BYTE *pbHash, // [OUT] hash buffer - DWORD cchHash, // [IN] max size of buffer - DWORD *pchHash) // [OUT] length of hash byte array -{ - HRESULT hr; - - BEGIN_ENTRYPOINT_NOTHROW; - - PBYTE pbBuffer = NULL; - DWORD dwFileLen = SafeGetFileSize(hFile, 0); - if (dwFileLen == 0xffffffff) - IfFailGo(HRESULT_FROM_GetLastError()); - - if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF) - IfFailGo(HRESULT_FROM_GetLastError()); - - DWORD dwResultLen; - pbBuffer = new (nothrow) BYTE[dwFileLen]; - IfNullGo(pbBuffer); - - if (ReadFile(hFile, pbBuffer, dwFileLen, &dwResultLen, NULL)) - hr = GetHashFromBlob(pbBuffer, dwResultLen, piHashAlg, pbHash, cchHash, pchHash); - else - hr = HRESULT_FROM_GetLastError(); - - delete[] pbBuffer; - -ErrExit: - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -SNAPI_(DWORD) GetHashFromBlob(BYTE *pbBlob, // [IN] pointer to memory block to hash - DWORD cchBlob, // [IN] length of blob - unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) - BYTE *pbHash, // [OUT] hash buffer - DWORD cchHash, // [IN] max size of buffer - DWORD *pchHash) // [OUT] length of hash byte array -{ - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - HandleStrongNameCspHolder hProv(NULL); - CapiHashHolder hHash(NULL); - - if (!piHashAlg || !pbHash || !pchHash) - IfFailGo(E_INVALIDARG); - - if (!(*piHashAlg)) - *piHashAlg = CALG_SHA1; - - *pchHash = cchHash; - - hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, *piHashAlg); - - if (!hProv || - (!CryptCreateHash(hProv, *piHashAlg, 0, 0, &hHash)) || - (!CryptHashData(hHash, pbBlob, cchBlob, 0)) || - (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, pchHash, 0))) - hr = HRESULT_FROM_GetLastError(); - -ErrExit: - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -#endif // #ifndef DACCESS_COMPILE - -#else // !defined(FEATURE_CORECLR) #define InitStrongName() S_OK -#endif // !defined(FEATURE_CORECLR) - // Free buffer allocated by routines below. SNAPI_(VOID) StrongNameFreeBuffer(BYTE *pbMemory) // [in] address of memory to free @@ -4695,12 +219,6 @@ SN_THREAD_CTX *GetThreadContext() if (pThreadCtx == NULL) return NULL; pThreadCtx->m_dwLastError = S_OK; -#if !defined(FEATURE_CORECLR) - for (ULONG i = 0; i < CachedCspCount; i++) - { - pThreadCtx->m_hProv[i] = NULL; - } -#endif // !FEATURE_CORECLR EX_TRY { ClrFlsSetValue(TlsIdx_StrongName, pThreadCtx); @@ -4760,18 +278,8 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ #ifndef DACCESS_COMPILE -#ifndef FEATURE_CORECLR - HCRYPTPROV hProv = NULL; - HCRYPTHASH hHash = NULL; - HCRYPTKEY hKey = NULL; - DWORD dwHashLen; - DWORD dwRetLen; - NewArrayHolder<BYTE> pHash(NULL); -#else // !FEATURE_CORECLR SHA1Hash sha1; BYTE *pHash = NULL; -#endif // !FEATURE_CORECLR - DWORD i; DWORD cbKeyBlob; PublicKeyBlob *pPublicKey = NULL; @@ -4814,7 +322,7 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ retVal = TRUE; goto Exit; } -#ifdef FEATURE_CORECLR + if (SN_IS_THE_SILVERLIGHT_PLATFORM_KEY(pbPublicKeyBlob)) { memcpy_s(*ppbStrongNameToken, *pcbStrongNameToken, SN_THE_SILVERLIGHT_PLATFORM_KEYTOKEN(), SN_SIZEOF_TOKEN); @@ -4846,7 +354,6 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ } #endif //FEATURE_WINDOWSPHONE -#endif //FEATURE_CORECLR // To compute the correct public key token, we need to make sure the public key blob // was not padded with extra bytes that CAPI CryptImportKey would've ignored. @@ -4876,79 +383,11 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ goto Error; } -#ifndef FEATURE_CORECLR - - // Look for a CSP to hash the public key. - hProv = LocateCSP(NULL, SN_HASH_SHA1_ONLY); - if (!hProv) - goto Error; - - if (!CryptImportKey(hProv, - pPublicKey->PublicKey, - GET_UNALIGNED_VAL32(&pPublicKey->cbPublicKey), - 0, - 0, - &hKey)) - goto Error; - - cbKeyBlob = sizeof(DWORD); - if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &cbKeyBlob)) - goto Error; - - if ((offsetof(PublicKeyBlob, PublicKey) + cbKeyBlob) != cbPublicKeyBlob) { - SetLastError(CORSEC_E_INVALID_PUBLICKEY); - goto Error; - } - - // Create a hash object. - if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) - goto Error; - - // Compute a hash over the public key. - if (!CryptHashData(hHash, pbPublicKeyBlob, cbPublicKeyBlob, 0)) - goto Error; - - // Get the length of the hash. - dwRetLen = sizeof(dwHashLen); - if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&dwHashLen, &dwRetLen, 0)) - goto Error; - - // Allocate a temporary block to hold the hash. - pHash = new (nothrow) BYTE[dwHashLen]; - if (pHash == NULL) - { - SetLastError(E_OUTOFMEMORY); - goto Error; - } - - // Read the hash value. - if (!CryptGetHashParam(hHash, HP_HASHVAL, pHash, &dwHashLen, 0)) - goto Error; - - // We no longer need the hash object or the provider. - CryptDestroyHash(hHash); - CryptDestroyKey(hKey); - FreeCSP(hProv); - - // Take the last few bytes of the hash value for our token. (These are the - // low order bytes from a network byte order point of view). Reverse the - // order of these bytes in the output buffer to get host byte order. - _ASSERTE(dwHashLen >= SN_SIZEOF_TOKEN); - if (!ClrSafeInt<DWORD>::subtraction(dwHashLen, SN_SIZEOF_TOKEN, dwHashLenMinusTokenSize)) - { - SetLastError(COR_E_OVERFLOW); - goto Error; - } - -#else // !FEATURE_CORECLR - // Compute a hash over the public key. sha1.AddData(pbPublicKeyBlob, cbPublicKeyBlob); pHash = sha1.GetHash(); static_assert(SHA1_HASH_SIZE >= SN_SIZEOF_TOKEN, "SN_SIZEOF_TOKEN must be smaller or equal to the SHA1_HASH_SIZE"); dwHashLenMinusTokenSize = SHA1_HASH_SIZE - SN_SIZEOF_TOKEN; - -#endif // !FEATURE_CORECLR // Take the last few bytes of the hash value for our token. (These are the // low order bytes from a network byte order point of view). Reverse the @@ -4961,14 +400,6 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ Error: SetStrongNameErrorInfo(HRESULT_FROM_GetLastError()); -#ifndef FEATURE_CORECLR - if (hHash) - CryptDestroyHash(hHash); - if (hKey) - CryptDestroyKey(hKey); - if (hProv) - FreeCSP(hProv); -#endif // !FEATURE_CORECLR if (*ppbStrongNameToken) { delete [] *ppbStrongNameToken; diff --git a/src/strongname/api/strongnamecoreclr.cpp b/src/strongname/api/strongnamecoreclr.cpp index 1ed7f0e10c..b02cde3dd9 100644 --- a/src/strongname/api/strongnamecoreclr.cpp +++ b/src/strongname/api/strongnamecoreclr.cpp @@ -10,8 +10,6 @@ #include "common.h" -#if defined(FEATURE_CORECLR) - CoreClrCallbacks *GetCoreClrCallbacks(); // @@ -95,4 +93,3 @@ void InitUtilcode() InitUtilcode(*GetCoreClrCallbacks()); } -#endif // FEATURE_CORECLR && !STRONGNAME_IN_VM diff --git a/src/strongname/api/strongnameinternal.cpp b/src/strongname/api/strongnameinternal.cpp index 0ace8a7c58..56b1c0e031 100644 --- a/src/strongname/api/strongnameinternal.cpp +++ b/src/strongname/api/strongnameinternal.cpp @@ -86,7 +86,6 @@ bool StrongNameIsTheKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey) return (memcmp(pbKey, g_rbTheKey, sizeof(g_rbTheKey)) == 0); } -#ifdef FEATURE_CORECLR //--------------------------------------------------------------------------------------- // // Check to see if a public key blob is the Silverlight Platform public key blob @@ -135,7 +134,6 @@ bool StrongNameIsSilverlightPlatformKey(const PublicKeyBlob &keyPublicKey) return StrongNameSizeOfPublicKey(keyPublicKey) == sizeof(g_rbTheSilverlightPlatformKey) && memcmp(reinterpret_cast<const BYTE *>(&keyPublicKey), g_rbTheSilverlightPlatformKey, sizeof(g_rbTheSilverlightPlatformKey)) == 0; } -#endif //FEATURE_CORECLR //--------------------------------------------------------------------------------------- // @@ -223,7 +221,7 @@ bool StrongNameIsValidPublicKey(const PublicKeyBlob &keyPublicKey, bool fImportK return false; } -#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)) +#if (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)) // Make sure the public key blob imports properly if (fImportKeys) { @@ -239,9 +237,9 @@ bool StrongNameIsValidPublicKey(const PublicKeyBlob &keyPublicKey, bool fImportK return false; } } -#else // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX) +#else // (CROSSGEN_COMPILE && !PLATFORM_UNIX) _ASSERTE(!fImportKeys); -#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX) +#endif // (CROSSGEN_COMPILE && !PLATFORM_UNIX) return true; } @@ -268,7 +266,7 @@ DWORD StrongNameSizeOfPublicKey(const PublicKeyBlob &keyPublicKey) GET_UNALIGNED_VAL32(&keyPublicKey.cbPublicKey); // the number of bytes in the key } -#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)) +#if (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)) //--------------------------------------------------------------------------------------- // @@ -367,5 +365,5 @@ bool StrongNameCryptAcquireContext(HCRYPTPROV *phProv, LPCWSTR pwszContainer, LP return !!WszCryptAcquireContext(phProv, pwszContainer, pwszProvider, dwProvType, dwFlags); } -#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX) +#endif // (CROSSGEN_COMPILE && !PLATFORM_UNIX) diff --git a/src/strongname/inc/strongnameholders.h b/src/strongname/inc/strongnameholders.h index b6af80f583..1a95c87aa7 100644 --- a/src/strongname/inc/strongnameholders.h +++ b/src/strongname/inc/strongnameholders.h @@ -40,7 +40,7 @@ inline void ReleaseCapiHash(HCRYPTHASH hHash) CryptDestroyHash(hHash); } typedef Wrapper<HCRYPTHASH, DoNothing, ReleaseCapiHash, 0> CapiHashHolder; -#endif // !FEATURE_CORECLR || CROSSGEN_COMPILE +#endif // defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX) #if SNAPI_INTERNAL diff --git a/src/strongname/inc/strongnameinternal.h b/src/strongname/inc/strongnameinternal.h index 5aae39daa2..7cbf5d87a8 100644 --- a/src/strongname/inc/strongnameinternal.h +++ b/src/strongname/inc/strongnameinternal.h @@ -43,7 +43,7 @@ bool StrongNameIsValidKeyPair(__in_ecount(cbKeyPair) const BYTE *pbKeyPair, DWOR bool GetBytesFromHex(LPCUTF8 szHexString, ULONG cchHexString, BYTE** buffer, ULONG *cbBufferSize); bool StrongNameCryptAcquireContext(HCRYPTPROV *phProv, LPCWSTR pwszContainer, LPCWSTR pwszProvider, DWORD dwProvType, DWORD dwFlags); -#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX) +#endif // (CROSSGEN_COMPILE && !PLATFORM_UNIX) bool StrongNameIsSilverlightPlatformKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey); bool StrongNameIsSilverlightPlatformKey(const PublicKeyBlob &keyPublicKey); diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp index 285714c777..625789613f 100644 --- a/src/tools/crossgen/crossgen.cpp +++ b/src/tools/crossgen/crossgen.cpp @@ -147,7 +147,7 @@ void PrintUsageHelper() #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) W(" /JITPath <path>\n") W(" - Specifies the absolute file path to JIT compiler to be used.\n") -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) #ifdef FEATURE_READYTORUN_COMPILER W(" /ReadyToRun - Generate images resilient to the runtime and\n") W(" dependency versions\n") @@ -443,7 +443,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) LPCWSTR pwszCLRJITPath = nullptr; -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) LPCWSTR pwzDiasymreaderPath = nullptr; @@ -794,7 +794,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) Output(W("The /JITPath switch can not be used with the /CreatePDB switch.\n")); exit(FAILURE_RESULT); } -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) #if !defined(NO_NGENPDB) if (pwzDiasymreaderPath != nullptr && !fCreatePDB) @@ -802,7 +802,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) Output(W("The /DiasymreaderPath switch can only be used with the /CreatePDB switch.\n")); exit(FAILURE_RESULT); } -#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB) +#endif // !defined(NO_NGENPDB) if ((pwzTrustedPlatformAssemblies != nullptr) && (pwzPlatformAssembliesPaths != nullptr)) { @@ -949,7 +949,7 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv) , NULL, // ICorSvcLogger pwszCLRJITPath -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) ); } diff --git a/src/utilcode/clrhost.cpp b/src/utilcode/clrhost.cpp index 5b28018514..15678a9861 100644 --- a/src/utilcode/clrhost.cpp +++ b/src/utilcode/clrhost.cpp @@ -430,7 +430,7 @@ void OnUninitializedCoreClrCallbacks() // (other than coreclr.dll) that links to utilcode.lib, or that you're using a nohost // variant of utilcode.lib but hitting code that assumes there is a CLR in the process. // - // Under FEATURE_CORECLR (and not SELF_NO_HOST), it is expected that coreclr.dll + // It is expected that coreclr.dll // is the ONLY dll that links to utilcode libraries. // // If you must introduce a new dll that links to utilcode.lib, it is your responsibility diff --git a/src/utilcode/ex.cpp b/src/utilcode/ex.cpp index 5d060660e3..92b25b0aaf 100644 --- a/src/utilcode/ex.cpp +++ b/src/utilcode/ex.cpp @@ -2039,7 +2039,7 @@ static DWORD MarkAsThrownByUsWorker(UINT numArgs, /*out*/ ULONG_PTR exceptionArg #if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) exceptionArgs[INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE - 1] = (ULONG_PTR) (GetCLRModule()); -#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE) +#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) return INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE; } @@ -2092,9 +2092,9 @@ BOOL WasThrownByUs(const EXCEPTION_RECORD *pcER, DWORD dwExceptionCode) return FALSE; } return TRUE; -#else // !(!defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE))) +#else // !(!defined(FEATURE_UTILCODE_NO_DEPENDENCIES) return FALSE; -#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE) +#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) } diff --git a/src/utilcode/stacktrace.cpp b/src/utilcode/stacktrace.cpp index 8fbc457019..3dee1802f4 100644 --- a/src/utilcode/stacktrace.cpp +++ b/src/utilcode/stacktrace.cpp @@ -989,4 +989,4 @@ ClrCaptureContext(__out PCONTEXT ctx) ret 4 } } -#endif // _TARGET_X86_ && FEATURE_CORECLR +#endif // _TARGET_X86 diff --git a/src/utilcode/utilmessagebox.cpp b/src/utilcode/utilmessagebox.cpp index 5ceb3909f6..58fd7554c2 100644 --- a/src/utilcode/utilmessagebox.cpp +++ b/src/utilcode/utilmessagebox.cpp @@ -49,16 +49,6 @@ BOOL ShouldDisplayMsgBoxOnCriticalFailure() } -#if !defined(FEATURE_CORESYSTEM) && !defined(FEATURE_CORECLR) -enum ProbedTaskDialogIndirectState -{ - ProbedTaskDialogIndirectState_NotProbed = 0, - ProbedTaskDialogIndirectState_NotAvailable = 1, - ProbedTaskDialogIndirectState_Available = 2 -}; - -static ProbedTaskDialogIndirectState siProbedTaskDialogIndirect = ProbedTaskDialogIndirectState_NotProbed; -#endif // !FEATURE_CORESYSTEM && !FEATURE_CORECLR // We'd like to use TaskDialogIndirect for asserts coming from managed code in particular @@ -86,157 +76,7 @@ int MessageBoxImpl( } CONTRACTL_END; -#if defined(FEATURE_CORESYSTEM) || defined (FEATURE_CORECLR) return WszMessageBox(hWnd, message, title, uType); -#else - bool mustUseMessageBox = false; // Mac, Silverlight, pre-Vista? Do we support this type of message box? - decltype(TaskDialogIndirect)* pfnTaskDialogIndirect = NULL; - ULONG_PTR cookie = NULL; // For activation context. - bool activatedActivationContext = false; - HModuleHolder hmodComctl32; - HANDLE hActCtx = INVALID_HANDLE_VALUE; - - // Note: TaskDialogIndirect is only in the v6 and above versions of comctl32. Windows - // stores that library in the WinSxS directory in a directory with - // "Microsoft.Windows.Common-Controls" in the name. Your application can only see - // this library if the linker has added a manifest dependency on the V6 common controls - // to your application. Or, you can create an activation context to make this work, - // if your library also has the appropriate manifest dependency. - // Also, I'm not going to leave comctl32.dll mapped, to ensure it can't somehow - // interfere with older versions. Therefore, re-load comctl32.dll every time through - // this method. We will record whether TaskDialogIndirect is available though, so - // we can fall back to MessageBox faster. - - // We don't yet have a perfect mapping from all MessageBox behavior to TaskDialogIndirect behavior. - // Use MessageBox to avoid most of this complexity. - if (((uType & MB_ICONMASK) != MB_ICONWARNING) && (uType & MB_ICONMASK) != MB_ICONERROR || - (uType & MB_TYPEMASK) != MB_ABORTRETRYIGNORE || - (uType & MB_DEFMASK) != 0 || - (uType & MB_MODEMASK) != 0 || - (uType & MB_MISCMASK) != 0) - mustUseMessageBox = true; - else if (mustUseMessageBox || siProbedTaskDialogIndirect == ProbedTaskDialogIndirectState_NotAvailable) - mustUseMessageBox = true; - else { - // Replace our application's ActivationContext temporarily, load comctl32 - // & look for TaskDialogIndirect. Don't cache pointer. - // The following code was suggested by some Windows experts. We do not want - // to add a manifest to our library saying we use comctl32 v6, because that - // will mean loading a lot of extra libraries on startup (a significant perf hit). - // We could either store the manifest as a resource, or more creatively since - // we are effectively a Windows component, rely on %windir%\WindowsShell.manifest. - ACTCTX ctx = { sizeof(ACTCTX) }; - ctx.dwFlags = 0; - StackSString manifestPath; // Point this at %windir%\WindowsShell.manifest, for comctl32 version 6. - UINT numChars = WszGetWindowsDirectory(manifestPath.OpenUnicodeBuffer(MAX_PATH_FNAME), MAX_PATH_FNAME); - if (numChars == 0 || numChars >= MAX_PATH_FNAME) - { - _ASSERTE(0); // How did this fail? - } - else { - manifestPath.CloseBuffer(numChars); - if (manifestPath[manifestPath.GetCount() - 1] != W('\\')) - manifestPath.Append(W('\\')); - manifestPath.Append(W("WindowsShell.manifest")); // Other Windows components have already loaded this. - ctx.lpSource = manifestPath.GetUnicode(); - hActCtx = CreateActCtx(&ctx); - if (hActCtx != INVALID_HANDLE_VALUE) - { - if (!ActivateActCtx(hActCtx, &cookie)) - { - cookie = NULL; - _ASSERTE(0); // Why did ActivateActCtx fail? (We'll continue executing & cope with the failure.) - } - else { - activatedActivationContext = true; - // Activation context was replaced - now we can load comctl32 version 6. - hmodComctl32 = WszLoadLibrary(W("comctl32.dll")); - - if (hmodComctl32 != INVALID_HANDLE_VALUE) { - pfnTaskDialogIndirect = (decltype(TaskDialogIndirect)*)GetProcAddress(hmodComctl32, "TaskDialogIndirect"); - if (pfnTaskDialogIndirect == NULL) { - hmodComctl32.Release(); - } - } - } - } - } - - siProbedTaskDialogIndirect = (pfnTaskDialogIndirect == NULL) ? ProbedTaskDialogIndirectState_NotAvailable : ProbedTaskDialogIndirectState_Available; - mustUseMessageBox = (pfnTaskDialogIndirect == NULL); - } - - int result = MB_OK; - if (mustUseMessageBox) { - result = WszMessageBox(hWnd, message, title, uType); - } - else { - _ASSERTE(pfnTaskDialogIndirect != NULL); - int nButtonPressed = 0; - TASKDIALOGCONFIG config = {0}; - config.cbSize = sizeof(config); - config.hwndParent = hWnd; - config.dwCommonButtons = 0; - config.pszWindowTitle = title; - config.dwFlags = (uType & MB_RTLREADING) ? TDF_RTL_LAYOUT : 0; - - // Set the user-visible icon in the window. - _ASSERTE(((uType & MB_ICONMASK) == MB_ICONWARNING) || ((uType & MB_ICONMASK) == MB_ICONERROR)); - config.pszMainIcon = ((uType & MB_ICONMASK) == MB_ICONWARNING) ? TD_WARNING_ICON : TD_ERROR_ICON; - - config.pszMainInstruction = title; - config.pszContent = message; - config.pszExpandedInformation = detailedText; - - // Set up the buttons - // Note about button hot keys: Windows keeps track of of where the last input came from - // (ie, mouse or keyboard). If you use the mouse to interact w/ one dialog box and then use - // the keyboard, the next dialog will not include hot keys. This is a Windows feature to - // minimize clutter on the screen for mouse users. - _ASSERTE((uType & MB_TYPEMASK) == MB_ABORTRETRYIGNORE); - StackSString abortLabel, debugLabel, ignoreLabel; - const WCHAR *pAbortLabel, *pDebugLabel, *pIgnoreLabel; - - if (abortLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_ABORT_BUTTON)) - pAbortLabel = abortLabel.GetUnicode(); - else - pAbortLabel = W("&Abort"); - if (debugLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_DEBUG_BUTTON)) - pDebugLabel = debugLabel.GetUnicode(); - else - pDebugLabel = W("&Debug"); - if (ignoreLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_IGNORE_BUTTON)) - pIgnoreLabel = ignoreLabel.GetUnicode(); - else - pIgnoreLabel = W("&Ignore"); - - const TASKDIALOG_BUTTON abortDebugIgnoreButtons[] = { - { IDOK, pAbortLabel }, - { IDRETRY, pDebugLabel }, - { IDIGNORE, pIgnoreLabel } - }; - config.pButtons = abortDebugIgnoreButtons; - config.cButtons = 3; - - HRESULT hr = pfnTaskDialogIndirect(&config, &nButtonPressed, NULL, NULL); - _ASSERTE(hr == S_OK); - if (hr == S_OK) { - result = nButtonPressed; - } - else { - result = IDOK; - } - - _ASSERTE(result == IDOK || result == IDRETRY || result == IDIGNORE); - } - - if (activatedActivationContext) { - DeactivateActCtx(0, cookie); - ReleaseActCtx(hActCtx); // perf isn't important so we won't bother caching the actctx - } - - return result; -#endif } int UtilMessageBoxVA( diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index f1452adb5c..0386c5f431 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -13625,7 +13625,7 @@ HRESULT AppDomain::SetWinrtApplicationContext(SString &appLocalWinMD) return m_pWinRtBinder->SetApplicationContext(pApplicationContext, appLocalWinMD); } -#endif // FEATURE_CORECLR && FEATURE_COMINTEROP +#endif // FEATURE_COMINTEROP #endif //!DACCESS_COMPILE diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index 1cae7e887b..f785bf0718 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -1979,7 +1979,7 @@ public: #if defined(FEATURE_COMINTEROP) HRESULT SetWinrtApplicationContext(SString &appLocalWinMD); -#endif // FEATURE_CORECLR && FEATURE_COMINTEROP +#endif // FEATURE_COMINTEROP BOOL CanReversePInvokeEnter(); void SetReversePInvokeCannotEnter(); diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp index 8cc53216a9..a896313943 100644 --- a/src/vm/assemblynative.cpp +++ b/src/vm/assemblynative.cpp @@ -43,19 +43,8 @@ #include "policy.h" #endif -#ifdef FEATURE_CORECLR #include "appdomainnative.hpp" #include "../binder/inc/clrprivbindercoreclr.h" -#endif // FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -#include "assemblynativeresource.h" -#endif // !FEATURE_CORECLR - -#if !defined(FEATURE_CORECLR) -#include "clrprivbinderloadfile.h" -#endif - #ifdef FEATURE_FUSION //---------------------------------------------------------------------------------------------------- @@ -318,12 +307,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs if (pAssemblyData == NULL) COMPlusThrow(kArgumentNullException, W("ArgumentNull_Array")); -#ifndef FEATURE_CORECLR - // Event Tracing for Windows is used to log data for performance and functional testing purposes. - // The events in this function are used to help measure the performance of assembly loading as a whole when loading from a buffer. - FireEtwLoaderPhaseStart(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, NULL, NULL, GetClrInstanceId()); -#endif // FEATURE_CORECLR - if (fForIntrospection) { if (!GetThread()->GetDomain()->IsVerificationDomain()) GetThread()->GetDomain()->SetIllegalVerificationDomain(); @@ -357,13 +340,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs CLRPrivBinderLoadFile* pBinderToUse = NULL; -#if !defined(FEATURE_CORECLR) - if (GetAppDomain()->HasLoadContextHostBinder()) - { - pBinderToUse = CLRPrivBinderLoadFile::GetOrCreateBinder(); - } -#endif // !FEATURE_CORECLR - pFile = PEAssembly::OpenMemory(pCallersAssembly->GetManifestFile(), pAssemblyData, (COUNT_T)uAssemblyLength, fForIntrospection, @@ -447,9 +423,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs } #endif // FEATURE_REFLECTION_ONLY_LOAD -#ifndef FEATURE_CORECLR - FireEtwLoaderPhaseEnd(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, NULL, NULL, GetClrInstanceId()); -#endif // FEATURE_CORECLR LOG((LF_CLASSLOADER, LL_INFO100, "\tLoaded in-memory module\n")); @@ -1120,15 +1093,6 @@ void QCALLTYPE AssemblyNative::GetLocation(QCall::AssemblyHandle pAssembly, QCal BEGIN_QCALL; -#ifndef FEATURE_CORECLR - // workaround - lie about where mscorlib is. Mscorlib is now loaded out of the GAC, - // but some apps query its location to find the system directory. (Notably system.web) - if (pAssembly->IsSystem()) - { - retString.Set(SystemDomain::System()->BaseLibrary()); - } - else -#endif // !FEATURE_CORECLR { retString.Set(pAssembly->GetFile()->GetPath()); } @@ -1225,26 +1189,6 @@ void QCALLTYPE AssemblyNative::GetPublicKey(QCall::AssemblyHandle pAssembly, QCa END_QCALL; } -#if !FEATURE_CORECLR - -BYTE QCALLTYPE AssemblyNative::GetSecurityRuleSet(QCall::AssemblyHandle pAssembly) -{ - QCALL_CONTRACT; - - SecurityRuleSet ruleSet = SecurityRuleSet_Default; - - BEGIN_QCALL; - - ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pAssembly->GetAssembly()); - ruleSet = pMSD->GetSecurityRuleSet(); - - END_QCALL; - - return static_cast<BYTE>(ruleSet); -} - -#endif // !FEATURE_CORECLR - void QCALLTYPE AssemblyNative::GetSimpleName(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retSimpleName) { QCALL_CONTRACT; @@ -1277,14 +1221,6 @@ void QCALLTYPE AssemblyNative::GetCodeBase(QCall::AssemblyHandle pAssembly, BOOL StackSString codebase; -#ifndef FEATURE_CORECLR - if (pAssembly->IsSystem()) { - // workaround: lie about the location of mscorlib. Some callers assume it is in the install dir. - codebase.Set(SystemDomain::System()->BaseLibrary()); - PEAssembly::PathToUrl(codebase); - } - else -#endif // !FEATURE_CORECLR { pAssembly->GetFile()->GetCodeBase(codebase); } @@ -1350,23 +1286,6 @@ BYTE * QCALLTYPE AssemblyNative::GetResource(QCall::AssemblyHandle pAssembly, LP return pbInMemoryResource; } -#ifndef FEATURE_CORECLR - -BOOL QCALLTYPE AssemblyNative::UseRelativeBindForSatellites() -{ - QCALL_CONTRACT; - - BOOL retVal = TRUE; - - BEGIN_QCALL; - retVal = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_RelativeBindForResources); - END_QCALL; - - return retVal; - -} -#endif // !FEATURE_CORECLR - INT32 QCALLTYPE AssemblyNative::GetManifestResourceInfo(QCall::AssemblyHandle pAssembly, LPCWSTR wszName, QCall::ObjectHandleOnStack retAssembly, QCall::StringHandleOnStack retFileName, QCall::StackCrawlMarkHandle stackMark) { QCALL_CONTRACT; @@ -1878,121 +1797,6 @@ void QCALLTYPE AssemblyNative::GetEntryPoint(QCall::AssemblyHandle pAssembly, QC return; } -#ifndef FEATURE_CORECLR -// prepare saving manifest to disk -void QCALLTYPE AssemblyNative::PrepareForSavingManifestToDisk(QCall::AssemblyHandle pAssembly, QCall::ModuleHandle pAssemblyModule) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - pAssembly->GetAssembly()->PrepareSavingManifest((ReflectionModule *)(Module *)pAssemblyModule); - - END_QCALL; -} - -#endif - -#ifndef FEATURE_CORECLR -// add a file name to the file list of this assembly. On disk only. -mdFile QCALLTYPE AssemblyNative::AddFile(QCall::AssemblyHandle pAssembly, LPCWSTR wszFileName) -{ - QCALL_CONTRACT; - - mdFile retVal = 0; - - BEGIN_QCALL; - - retVal = pAssembly->GetAssembly()->AddFile(wszFileName); - - END_QCALL; - - return retVal; -} -#endif //FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -// set the hash value on a file. -void QCALLTYPE AssemblyNative::SetFileHashValue(QCall::AssemblyHandle pAssembly, INT32 tkFile, LPCWSTR wszFullFileName) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - pAssembly->GetAssembly()->SetFileHashValue(tkFile, wszFullFileName); - - END_QCALL; -} -#endif //FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -// Add a Type name to the ExportedType table in the on-disk assembly manifest. -mdExportedType QCALLTYPE AssemblyNative::AddExportedTypeOnDisk(QCall::AssemblyHandle pAssembly, LPCWSTR wszCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags) -{ - QCALL_CONTRACT; - - mdExportedType retVal = 0; - - BEGIN_QCALL; - - retVal = pAssembly->GetAssembly()->AddExportedTypeOnDisk(wszCOMTypeName, tkImpl, tkTypeDef, (CorTypeAttr)flags); - - END_QCALL; - - return retVal; -} - -// Add a Type name to the ExportedType table in the in-memory assembly manifest. -mdExportedType QCALLTYPE AssemblyNative::AddExportedTypeInMemory(QCall::AssemblyHandle pAssembly, LPCWSTR wszCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags) -{ - QCALL_CONTRACT; - - mdExportedType retVal = 0; - - BEGIN_QCALL; - - retVal = pAssembly->GetAssembly()->AddExportedTypeInMemory(wszCOMTypeName, tkImpl, tkTypeDef, (CorTypeAttr)flags); - - END_QCALL; - - return retVal; -} -#endif //FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -// add a Stand alone resource to ManifestResource table -void QCALLTYPE AssemblyNative::AddStandAloneResource(QCall::AssemblyHandle pAssembly, LPCWSTR wszName, LPCWSTR wszFileName, LPCWSTR wszFullFileName, INT32 iAttribute) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - pAssembly->GetAssembly()->AddStandAloneResource( - wszName, - NULL, - NULL, - wszFileName, - wszFullFileName, - iAttribute); - - END_QCALL; -} -#endif //FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -// Save security permission requests. -void QCALLTYPE AssemblyNative::AddDeclarativeSecurity(QCall::AssemblyHandle pAssembly, INT32 action, PVOID blob, INT32 length) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - pAssembly->GetAssembly()->AddDeclarativeSecurity(action, blob, length); - - END_QCALL; -} -#endif //FEATURE_CORECLR - //--------------------------------------------------------------------------------------- // // Get the raw bytes making up this assembly @@ -2057,27 +1861,6 @@ extern void ManagedBitnessFlagsToUnmanagedBitnessFlags( INT32 portableExecutableKind, INT32 imageFileMachine, DWORD* pPeFlags, DWORD* pCorhFlags); -#ifndef FEATURE_CORECLR -void QCALLTYPE AssemblyNative::SaveManifestToDisk(QCall::AssemblyHandle pAssembly, - LPCWSTR wszManifestFileName, - INT32 entrypoint, - INT32 fileKind, - INT32 portableExecutableKind, - INT32 imageFileMachine) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - DWORD peFlags = 0, corhFlags = 0; - ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags); - - pAssembly->GetAssembly()->SaveManifestToDisk(wszManifestFileName, entrypoint, fileKind, corhFlags, peFlags); - - END_QCALL; -} -#endif // !FEATURE_CORECLR - void QCALLTYPE AssemblyNative::GetFullName(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retString) { QCALL_CONTRACT; @@ -2258,89 +2041,6 @@ FCIMPL1(ReflectModuleBaseObject *, AssemblyNative::GetInMemoryAssemblyModule, As } FCIMPLEND - -#ifndef FEATURE_CORECLR -// Create a stand-alone resource file for version resource. -void QCALLTYPE AssemblyNative::CreateVersionInfoResource(LPCWSTR pwzFilename, - LPCWSTR pwzTitle, - LPCWSTR pwzIconFilename, - LPCWSTR pwzDescription, - LPCWSTR pwzCopyright, - LPCWSTR pwzTrademark, - LPCWSTR pwzCompany, - LPCWSTR pwzProduct, - LPCWSTR pwzProductVersion, - LPCWSTR pwzFileVersion, - INT32 lcid, - BOOL fIsDll, - QCall::StringHandleOnStack retFileName) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - Win32Res res; // Resource helper object. - const void *pvData=0; // Pointer to the resource. - ULONG cbData; // Size of the resource data. - ULONG cbWritten; - PathString szFile; // File name for resource file. - PathString szPath; // Path name for resource file. - HandleHolder hFile; - - res.SetInfo(pwzFilename, - pwzTitle, - pwzIconFilename, - pwzDescription, - pwzCopyright, - pwzTrademark, - pwzCompany, - pwzProduct, - pwzProductVersion, - pwzFileVersion, - lcid, - fIsDll); - - res.MakeResFile(&pvData, &cbData); - - //<TODO>Change the COMPlusThrowWin32's to exceptions with - // messages including the path/file name</TODO> - - // Persist to a file. - if (!WszGetTempPath(szPath)) - COMPlusThrowWin32(); - if (!WszGetTempFileName(szPath.GetUnicode(), W("RES"), 0, szFile)) - COMPlusThrowWin32(); - - hFile = WszCreateFile(szFile, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - COMPlusThrowWin32(); - - if (!WriteFile(hFile, pvData, cbData, &cbWritten, NULL)) - COMPlusThrowWin32(); - - retFileName.Set(szFile); - - END_QCALL; -} -#endif // !FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -FCIMPL1(FC_BOOL_RET, AssemblyNative::IsGlobalAssemblyCache, AssemblyBaseObject* pAssemblyUNSAFE) -{ - FCALL_CONTRACT; - - ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE); - - if (refAssembly == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - DomainAssembly *pAssembly = refAssembly->GetDomainAssembly(); - - FC_RETURN_BOOL(pAssembly->GetFile()->IsSourceGAC()); -} -FCIMPLEND -#endif // !FEATURE_CORECLR - void QCALLTYPE AssemblyNative::GetImageRuntimeVersion(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retString) { QCALL_CONTRACT; @@ -2355,9 +2055,6 @@ void QCALLTYPE AssemblyNative::GetImageRuntimeVersion(QCall::AssemblyHandle pAss IfFailThrow(pPEFile->GetMDImport()->GetVersionString(&pszVersion)); SString version(SString::Utf8, pszVersion); - #ifndef FEATURE_CORECLR - AdjustImageRuntimeVersion(&version); -#endif // FEATURE_CORECLR // Allocate a managed string that contains the version and return it. retString.Set(version); diff --git a/src/vm/assemblyspec.hpp b/src/vm/assemblyspec.hpp index 94a7844464..d2e2ab604b 100644 --- a/src/vm/assemblyspec.hpp +++ b/src/vm/assemblyspec.hpp @@ -673,7 +673,7 @@ class AssemblySpecBindingCache ++i; } } -#endif // defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE) +#endif // !defined(DACCESS_COMPILE) static BOOL CompareSpecs(UPTR u1, UPTR u2); }; diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp index 94bae80c7e..ad4c5196b1 100644 --- a/src/vm/codeman.cpp +++ b/src/vm/codeman.cpp @@ -1400,7 +1400,7 @@ JIT_LOAD_DATA g_JitLoadData; // Global that holds the path to custom JIT location extern "C" LPCWSTR g_CLRJITPath = nullptr; -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) // LoadAndInitializeJIT: load the JIT dll into the process, and initialize it (call the UtilCode initialization function, @@ -1693,7 +1693,7 @@ BOOL EEJitManager::LoadJIT() } } } -#endif // (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) || (defined(_TARGET_X86_) && defined(FEATURE_CORECLR)) +#endif // (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE)) || (defined(_TARGET_X86_) ) #endif // !FEATURE_MERGE_JIT_AND_ENGINE diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp index a82289c30a..891c302402 100644 --- a/src/vm/comutilnative.cpp +++ b/src/vm/comutilnative.cpp @@ -1498,7 +1498,7 @@ void QCALLTYPE Buffer::MemMove(void *dst, void *src, size_t length) { QCALL_CONTRACT; -#if defined(FEATURE_CORECLR) && !defined(FEATURE_CORESYSTEM) +#if !defined(FEATURE_CORESYSTEM) // Callers of memcpy do expect and handle access violations in some scenarios. // Access violations in the runtime dll are turned into fail fast by the vector exception handler by default. // We need to supress this behavior for CoreCLR using AVInRuntimeImplOkayHolder because of memcpy is statically linked in. diff --git a/src/vm/comwaithandle.cpp b/src/vm/comwaithandle.cpp index 7b15ae5acd..610bb867be 100644 --- a/src/vm/comwaithandle.cpp +++ b/src/vm/comwaithandle.cpp @@ -242,8 +242,6 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF // Because it's not, CoreCLR will allow WaitAll on STA threads. // But fixing this would be a breaking change at this point, since we already shipped // SL 2 and 3 this way. - // We we'll also check for FEATURE_CORECLR here, so that if we enable FEATURE_COMINTEROP - // on CoreCLR we won't break anyone. // Perhaps in a future release we can fix this, if we aren't quite so concerned about // compatibility.... diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp index 8b27799b44..64f4e2b4cb 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -2168,7 +2168,7 @@ HRESULT CCLRGCManager::_SetGCMaxGen0Size(SIZE_T MaxGen0Size) } static CCLRGCManager s_GCManager; -#endif // !FEATURE_CORECLR || FEATURE_WINDOWSPHONE +#endif //FEATURE_WINDOWSPHONE #ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING class CCLRAppDomainResourceMonitor : public ICLRAppDomainResourceMonitor @@ -2343,7 +2343,7 @@ public: return S_OK; } else -#endif // !FEATURE_CORECLR || defined(FEATURE_WINDOWSPHONE) +#endif //defined(FEATURE_WINDOWSPHONE) if (g_fEEStarted && !m_fFullAccess) { // If runtime has been started, do not allow user to obtain CLR managers. @@ -2364,7 +2364,7 @@ public: *ppObject = &s_GCManager; return S_OK; } -#endif // !FEATURE_CORECLR || FEATURE_WINDOWSPHONE +#endif //FEATURE_WINDOWSPHONE #ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING else if (riid == IID_ICLRAppDomainResourceMonitor) @@ -4902,7 +4902,7 @@ SIZE_T STDMETHODCALLTYPE CExecutionEngine::ClrVirtualQuery(LPCVOID lpAddress, static VolatilePtr<BYTE> s_pStartOfUEFSection = NULL; static VolatilePtr<BYTE> s_pEndOfUEFSectionBoundary = NULL; static Volatile<DWORD> s_dwProtection = 0; -#endif // _DEBUG && FEATURE_CORECLR && !FEATURE_PAL +#endif // _DEBUG && !FEATURE_PAL #undef ClrVirtualProtect @@ -5018,7 +5018,7 @@ BOOL STDMETHODCALLTYPE CExecutionEngine::ClrVirtualProtect(LPVOID lpAddress, "Do not virtual protect the section in which UEF lives!"); } } -#endif // _DEBUG && FEATURE_CORECLR && !FEATURE_PAL +#endif // _DEBUG && !FEATURE_PAL return EEVirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect); } diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp index 627239c487..f342933899 100644 --- a/src/vm/domainfile.cpp +++ b/src/vm/domainfile.cpp @@ -1258,7 +1258,7 @@ void DomainFile::FinishLoad() } } } -#endif // defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP) +#endif //defined(FEATURE_COMINTEROP) #endif // FEATURE_PREJIT // Flush any log messages diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp index 922b14df45..7a7b55b8e9 100644 --- a/src/vm/excep.cpp +++ b/src/vm/excep.cpp @@ -5579,7 +5579,7 @@ LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData) //------------------------------------------------------------------------------ #if !defined(FEATURE_PAL) #pragma code_seg(push, uef, CLR_UEF_SECTION_NAME) -#endif // FEATURE_CORECLR && !FEATURE_PAL +#endif // !FEATURE_PAL LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or EXCEPTION_CONTINUE_EXECUTION EXCEPTION_POINTERS *pExceptionInfo) // Information about the exception. { @@ -5621,7 +5621,7 @@ LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or } // LONG __stdcall COMUnhandledExceptionFilter() #if !defined(FEATURE_PAL) #pragma code_seg(pop, uef) -#endif // FEATURE_CORECLR && !FEATURE_PAL +#endif // !FEATURE_PAL void PrintStackTraceToStdout(); @@ -7026,9 +7026,9 @@ DWORD GetGcMarkerExceptionCode(LPVOID ip) { return STATUS_CLR_GCCOVER_CODE; } -#else // !(defined(HAVE_GCCOVER) && defined(FEATURE_CORECLR)) +#else // defined(HAVE_GCCOVER) LIMITED_METHOD_CONTRACT; -#endif // defined(HAVE_GCCOVER) && defined(FEATURE_CORECLR) +#endif // defined(HAVE_GCCOVER) return 0; } @@ -11268,7 +11268,7 @@ PTR_VOID EHWatsonBucketTracker::RetrieveWatsonBuckets() { return NULL; } -#endif // defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE) +#endif //!defined(DACCESS_COMPILE) CONTRACTL { diff --git a/src/vm/excep.h b/src/vm/excep.h index 7e7df4fbcb..13d8a3b847 100644 --- a/src/vm/excep.h +++ b/src/vm/excep.h @@ -193,7 +193,7 @@ void UninstallUnhandledExceptionFilter(); // section that comes after UEF section, it can affect the UEF section and we will // assert about it in "CExecutionEngine::ClrVirtualProtect". #define CLR_UEF_SECTION_NAME ".CLR_UEF" -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_PAL) +#endif //!defined(FEATURE_PAL) LONG __stdcall COMUnhandledExceptionFilter(EXCEPTION_POINTERS *pExceptionInfo); diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 55f1afd965..35fcb2c1ee 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -5141,18 +5141,6 @@ void MethodTableBuilder::SetSecurityFlagsOnMethod(bmtRTMethod* pParentMethod, // for linktime checks on these. // Also place linktime checks on all P/Invoke calls. if ( -#ifndef FEATURE_CORECLR - (IsInterface() && - (GetMDImport()->GetCustomAttributeByName(GetCl(), - COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI, - NULL, - NULL) == S_OK || - GetMDImport()->GetCustomAttributeByName(pNewMD->GetMemberDef(), - COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI, - NULL, - NULL) == S_OK) ) || - -#endif // !FEATURE_CORECLR pNewMD->IsNDirect() || (pNewMD->IsComPlusCall() && !IsInterface())) { @@ -12177,19 +12165,6 @@ VOID MethodTableBuilder::VerifyClassInheritanceSecurityHelper( // This method throws on failure. Security::ClassInheritanceCheck(pChildMT, pParentMT); -#ifndef FEATURE_CORECLR - // Check the entire parent chain for inheritance permission demands. - while (pParentMT != NULL) - { - if (pParentMT->GetClass()->RequiresInheritanceCheck()) - { - // This method throws on failure. - Security::ClassInheritanceCheck(pChildMT, pParentMT); - } - - pParentMT = pParentMT->GetParentMethodTable(); - } -#endif // !FEATURE_CORECLR } //******************************************************************************* @@ -12208,74 +12183,6 @@ VOID MethodTableBuilder::VerifyMethodInheritanceSecurityHelper( Security::MethodInheritanceCheck(pChildMD, pParentMD); -#ifndef FEATURE_CORECLR - - // If no inheritance checks are required, just return. - if (!pParentMD->RequiresInheritanceCheck() && - !pParentMD->ParentRequiresInheritanceCheck()) - { - return; - } - - DWORD dwSlot = pParentMD->GetSlot(); - -#ifdef _DEBUG - // Get the name and signature for the method so we can find the new parent method desc. - // We use the parent MethodDesc for this because the child could actually have a very - // different name in the case that the child is MethodImpling the parent. - - // Get the name. - LPCUTF8 szName; - szName = pParentMD->GetName(); - - // Get the signature. - PCCOR_SIGNATURE pSignature; - DWORD cSignature; - pParentMD->GetSig(&pSignature, &cSignature); - Module *pModule = pParentMD->GetModule(); -#endif // _DEBUG - - do - { - if (pParentMD->RequiresInheritanceCheck()) - { - Security::MethodInheritanceCheck(pChildMD, pParentMD); - } - - if (pParentMD->ParentRequiresInheritanceCheck()) - { - MethodTable *pGrandParentMT = pParentMD->GetMethodTable()->GetParentMethodTable(); - CONSISTENCY_CHECK(CheckPointer(pGrandParentMT)); - - // Find this method in the parent. - // If it does exist in the parent, it would be at the same vtable slot. - if (dwSlot >= pGrandParentMT->GetNumVirtuals()) - { - // Parent does not have this many vtable slots, so it doesn't exist there - pParentMD = NULL; - } - else - { - // It is in the vtable of the parent - pParentMD = pGrandParentMT->GetMethodDescForSlot(dwSlot); - _ASSERTE(pParentMD != NULL); - -#ifdef _DEBUG - _ASSERTE(pParentMD == MemberLoader::FindMethod(pGrandParentMT, - szName, - pSignature, - cSignature, - pModule)); -#endif // _DEBUG - } - } - else - { - pParentMD = NULL; - } - } while (pParentMD != NULL); - -#endif // !FEATURE_CORECLR } //******************************************************************************* @@ -12520,7 +12427,6 @@ void MethodTableBuilder::VerifyInheritanceSecurity() // permission demands on the current class. If these first checks // succeeded, then the cached declared method list is scanned for // methods that have inheritance permission demands. -#ifdef FEATURE_CORECLR // // If we are transparent, and every class up the inheritence chain is also entirely transparent, // that means that no inheritence rules could be broken. If that's the case, we don't need to check @@ -12551,12 +12457,9 @@ void MethodTableBuilder::VerifyInheritanceSecurity() } } -#endif // FEATURE_CORECLR if (GetParentMethodTable() != NULL -#if FEATURE_CORECLR && !fInheritenceChainTransparent -#endif // FEATURE_CORECLR ) { // Check the parent for inheritance permission demands. @@ -12641,18 +12544,10 @@ void MethodTableBuilder::VerifyInheritanceSecurity() MethodTable *pCurItfMT = itfIt.GetInterface(); CONSISTENCY_CHECK(CheckPointer(pCurItfMT)); -#ifdef FEATURE_CORECLR if (fNeedTransparencyInheritanceCheck && !(Security::IsTypeAllTransparent(itfIt.GetInterface()) && fCurrentTypeAllTransparent) ) -#else // FEATURE_CORECLR - EEClass * pCurItfCls = pCurItfMT->GetClass(); - if (fNeedTransparencyInheritanceCheck || - fNeedPartialTrustInterfaceMappingCheck || - pCurItfCls->RequiresInheritanceCheck() || - pCurItfCls->SomeMethodsRequireInheritanceCheck()) -#endif // !FEATURE_CORECLR { // An interface is introduced by this type either if it is explicitly declared on the // type's interface list or if one of the type's explicit interfaces requires the diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h index c4fd43d6d7..3b57f9c8f9 100644 --- a/src/vm/mscorlib.h +++ b/src/vm/mscorlib.h @@ -134,12 +134,6 @@ DEFINE_METHOD(APP_DOMAIN, TURN_ON_BINDING_REDIRECTS, TurnOnBindingRedi DEFINE_METHOD(APP_DOMAIN, CREATE_APP_DOMAIN_MANAGER, CreateAppDomainManager, IM_RetVoid) DEFINE_METHOD(APP_DOMAIN, INITIALIZE_COMPATIBILITY_FLAGS, InitializeCompatibilityFlags, IM_RetVoid) DEFINE_METHOD(APP_DOMAIN, INITIALIZE_DOMAIN_SECURITY, InitializeDomainSecurity, IM_Evidence_Evidence_Bool_IntPtr_Bool_RetVoid) -#ifndef FEATURE_CORECLR -DEFINE_METHOD(APP_DOMAIN, PAUSE, Pause, SM_RetVoid) -DEFINE_METHOD(APP_DOMAIN, RESUME, Resume, SM_RetVoid) -DEFINE_CLASS(APPDOMAIN_MANAGER, System, AppDomainManager) -DEFINE_PROPERTY(APPDOMAIN_MANAGER, ENTRY_ASSEMBLY, EntryAssembly, AssemblyBase) -#endif // FEATURE_CORECLR DEFINE_CLASS(CLEANUP_WORK_LIST, StubHelpers, CleanupWorkList) @@ -167,9 +161,6 @@ DEFINE_FIELD_U(_AppDomainManagerType, AppDomainSetupObject, m_App DEFINE_FIELD_U(_CompatFlags, AppDomainSetupObject, m_CompatFlags) DEFINE_FIELD_U(_TargetFrameworkName, AppDomainSetupObject, m_TargetFrameworkName) DEFINE_FIELD_U(_LoaderOptimization, AppDomainSetupObject, m_LoaderOptimization) -#ifndef FEATURE_CORECLR -DEFINE_FIELD_U(_AppDomainSortingSetupInfo, AppDomainSetupObject, m_AppDomainSortingSetupInfo) -#endif // FEATURE_CORECLR #ifdef FEATURE_COMINTEROP DEFINE_FIELD_U(_DisableInterfaceCache, AppDomainSetupObject, m_DisableInterfaceCache) #endif // FEATURE_COMINTEROP @@ -245,9 +236,6 @@ DEFINE_FIELD_U(_ModuleResolve, AssemblyBaseObject, m_pModuleEven DEFINE_FIELD_U(m_fullname, AssemblyBaseObject, m_fullname) DEFINE_FIELD_U(m_syncRoot, AssemblyBaseObject, m_pSyncRoot) DEFINE_FIELD_U(m_assembly, AssemblyBaseObject, m_pAssembly) -#ifndef FEATURE_CORECLR -DEFINE_FIELD_U(m_flags, AssemblyBaseObject, m_flags) -#endif DEFINE_CLASS(ASSEMBLY, Reflection, RuntimeAssembly) DEFINE_FIELD(ASSEMBLY, HANDLE, m_assembly) DEFINE_METHOD(ASSEMBLY, GET_NAME, GetName, IM_RetAssemblyName) @@ -391,18 +379,6 @@ DEFINE_METHOD(CONTEXT, RESERVE_SLOT, ReserveSlot, DEFINE_CLASS(CONTEXT_BOUND_OBJECT, System, ContextBoundObject) #endif -#ifndef FEATURE_CORECLR -DEFINE_CLASS_U(Globalization, AppDomainSortingSetupInfo, AppDomainSortingSetupInfoObject) -DEFINE_FIELD_U(_pfnIsNLSDefinedString, AppDomainSortingSetupInfoObject, m_pfnIsNLSDefinedString) -DEFINE_FIELD_U(_pfnCompareStringEx, AppDomainSortingSetupInfoObject, m_pfnCompareStringEx) -DEFINE_FIELD_U(_pfnLCMapStringEx, AppDomainSortingSetupInfoObject, m_pfnLCMapStringEx) -DEFINE_FIELD_U(_pfnFindNLSStringEx, AppDomainSortingSetupInfoObject, m_pfnFindNLSStringEx) -DEFINE_FIELD_U(_pfnCompareStringOrdinal, AppDomainSortingSetupInfoObject, m_pfnCompareStringOrdinal) -DEFINE_FIELD_U(_pfnGetNLSVersionEx, AppDomainSortingSetupInfoObject, m_pfnGetNLSVersionEx) -DEFINE_FIELD_U(_pfnFindStringOrdinal, AppDomainSortingSetupInfoObject, m_pfnFindStringOrdinal) -DEFINE_FIELD_U(_useV2LegacySorting, AppDomainSortingSetupInfoObject, m_useV2LegacySorting) -DEFINE_FIELD_U(_useV4LegacySorting, AppDomainSortingSetupInfoObject, m_useV4LegacySorting) -#endif // FEATURE_CORECLR #ifndef FEATURE_COREFX_GLOBALIZATION DEFINE_CLASS_U(Globalization, CultureData, CultureDataBaseObject) @@ -579,9 +555,7 @@ DEFINE_CLASS(ENUM, System, Enum) DEFINE_CLASS(ENVIRONMENT, System, Environment) DEFINE_METHOD(ENVIRONMENT, GET_RESOURCE_STRING_LOCAL, GetResourceStringLocal, SM_Str_RetStr) -#ifdef FEATURE_CORECLR DEFINE_METHOD(ENVIRONMENT, SET_COMMAND_LINE_ARGS, SetCommandLineArgs, SM_ArrStr_RetVoid) -#endif #ifdef FEATURE_COMINTEROP DEFINE_CLASS(ERROR_WRAPPER, Interop, ErrorWrapper) @@ -632,12 +606,10 @@ DEFINE_METHOD(EXCEPTION, ADD_EXCEPTION_DATA_FOR_RESTRICTED_ERROR_INFO DEFINE_METHOD(EXCEPTION, TRY_GET_RESTRICTED_LANGUAGE_ERROR_OBJECT, TryGetRestrictedLanguageErrorObject, IM_RefObject_RetBool) #endif // FEATURE_COMINTEROP -#ifdef FEATURE_CORECLR DEFINE_CLASS(CROSSAPPDOMAINMARSHALEDEXCEPTION, System, CrossAppDomainMarshaledException) DEFINE_METHOD(CROSSAPPDOMAINMARSHALEDEXCEPTION, STR_INT_CTOR, .ctor, IM_Str_Int_RetVoid) -#endif //FEATURE_CORECLR DEFINE_CLASS(SYSTEM_EXCEPTION, System, SystemException) @@ -677,22 +649,6 @@ DEFINE_CLASS(I_RT_FIELD_INFO, System, IRuntimeFieldInfo) DEFINE_CLASS(FIELD_INFO, Reflection, FieldInfo) -#ifndef FEATURE_CORECLR -DEFINE_CLASS_U(IO, FileStreamAsyncResult, AsyncResultBase) -DEFINE_FIELD_U(_userCallback, AsyncResultBase, _userCallback) -DEFINE_FIELD_U(_userStateObject, AsyncResultBase, _userStateObject) -DEFINE_FIELD_U(_waitHandle, AsyncResultBase, _waitHandle) -DEFINE_FIELD_U(_handle, AsyncResultBase, _fileHandle) -DEFINE_FIELD_U(_overlapped, AsyncResultBase, _overlapped) -DEFINE_FIELD_U(_EndXxxCalled, AsyncResultBase, _EndXxxCalled) -DEFINE_FIELD_U(_numBytes, AsyncResultBase, _numBytes) -DEFINE_FIELD_U(_errorCode, AsyncResultBase, _errorCode) -DEFINE_FIELD_U(_numBufferedBytes, AsyncResultBase, _numBufferedBytes) -DEFINE_FIELD_U(_isWrite, AsyncResultBase, _isWrite) -DEFINE_FIELD_U(_isComplete, AsyncResultBase, _isComplete) -DEFINE_FIELD_U(_completedSynchronously, AsyncResultBase, _completedSynchronously) -DEFINE_CLASS(FILESTREAM_ASYNCRESULT, IO, FileStreamAsyncResult) -#endif // !FEATURE_CORECLR DEFINE_CLASS(GUID, System, Guid) @@ -1195,9 +1151,6 @@ DEFINE_METHOD(SAFE_HANDLE, RELEASE_HANDLE, ReleaseHandle, DEFINE_METHOD(SAFE_HANDLE, DISPOSE, Dispose, IM_RetVoid) DEFINE_METHOD(SAFE_HANDLE, DISPOSE_BOOL, Dispose, IM_Bool_RetVoid) -#ifndef FEATURE_CORECLR -DEFINE_CLASS(SAFE_TOKENHANDLE, SafeHandles, SafeAccessTokenHandle) -#endif DEFINE_CLASS(SAFE_TYPENAMEPARSER_HANDLE, System, SafeTypeNameParserHandle) @@ -1283,9 +1236,6 @@ DEFINE_METHOD(STRING_BUILDER, REPLACE_BUFFER_INTERNAL,ReplaceBufferInterna DEFINE_METHOD(STRING_BUILDER, REPLACE_BUFFER_ANSI_INTERNAL,ReplaceBufferAnsiInternal, IM_PtrSByt_Int_RetVoid) DEFINE_CLASS(STRONG_NAME_KEY_PAIR, Reflection, StrongNameKeyPair) -#ifndef FEATURE_CORECLR -DEFINE_METHOD(STRONG_NAME_KEY_PAIR, GET_KEY_PAIR, GetKeyPair, IM_RefObject_RetBool) -#endif DEFINE_CLASS_U(Threading, SynchronizationContext, SynchronizationContextObject) DEFINE_FIELD_U(_props, SynchronizationContextObject, _props) @@ -1304,9 +1254,6 @@ DEFINE_CLASS_U(Threading, Thread, ThreadBaseObj #ifdef FEATURE_REMOTING DEFINE_FIELD_U(m_Context, ThreadBaseObject, m_ExposedContext) #endif -#ifndef FEATURE_CORECLR -DEFINE_FIELD_U(m_ExecutionContext, ThreadBaseObject, m_ExecutionContext) -#endif DEFINE_FIELD_U(m_Name, ThreadBaseObject, m_Name) DEFINE_FIELD_U(m_Delegate, ThreadBaseObject, m_Delegate) #ifdef FEATURE_LEAK_CULTURE_INFO @@ -1428,13 +1375,6 @@ DEFINE_METHOD(STUBHELPERS, IS_QCALL, IsQCall, DEFINE_METHOD(STUBHELPERS, INIT_DECLARING_TYPE, InitDeclaringType, SM_IntPtr_RetVoid) DEFINE_METHOD(STUBHELPERS, GET_NDIRECT_TARGET, GetNDirectTarget, SM_IntPtr_RetIntPtr) DEFINE_METHOD(STUBHELPERS, GET_DELEGATE_TARGET, GetDelegateTarget, SM_Delegate_RefIntPtr_RetIntPtr) -#ifndef FEATURE_CORECLR // CAS -DEFINE_METHOD(STUBHELPERS, DEMAND_PERMISSION, DemandPermission, SM_IntPtr_RetVoid) -#ifdef _TARGET_X86_ -DEFINE_METHOD(STUBHELPERS, SET_COPY_CTOR_COOKIE_CHAIN, SetCopyCtorCookieChain, SM_IntPtr_IntPtr_Int_IntPtr_RetVoid) -DEFINE_FIELD(STUBHELPERS, COPY_CTOR_STUB_DESC, s_copyCtorStubDesc) -#endif // _TARGET_X86_ -#endif // !FEATURE_CORECLR #ifdef FEATURE_COMINTEROP DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT, GetCOMHRExceptionObject, SM_Int_IntPtr_Obj_RetException) DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT_WINRT, GetCOMHRExceptionObject_WinRT, SM_Int_IntPtr_Obj_RetException) @@ -1453,13 +1393,11 @@ DEFINE_METHOD(STUBHELPERS, GET_OUTER_INSPECTABLE, Ge DEFINE_METHOD(STUBHELPERS, TRIGGER_EXCEPTION_SWALLOWED_MDA, TriggerExceptionSwallowedMDA, SM_Exception_IntPtr_RetException) #endif // MDA_SUPPORTED #endif // FEATURE_COMINTEROP -#if defined(MDA_SUPPORTED) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) +#if defined(MDA_SUPPORTED) DEFINE_METHOD(STUBHELPERS, CHECK_COLLECTED_DELEGATE_MDA, CheckCollectedDelegateMDA, SM_IntPtr_RetVoid) #endif // MDA_SUPPORTED DEFINE_METHOD(STUBHELPERS, SET_LAST_ERROR, SetLastError, SM_RetVoid) -#ifdef FEATURE_CORECLR DEFINE_METHOD(STUBHELPERS, CLEAR_LAST_ERROR, ClearLastError, SM_RetVoid) -#endif DEFINE_METHOD(STUBHELPERS, THROW_INTEROP_PARAM_EXCEPTION, ThrowInteropParamException, SM_Int_Int_RetVoid) DEFINE_METHOD(STUBHELPERS, ADD_TO_CLEANUP_LIST, AddToCleanupList, SM_RefCleanupWorkList_SafeHandle_RetIntPtr) @@ -1504,12 +1442,6 @@ DEFINE_METHOD(STUBHELPERS, ARRAY_TYPE_CHECK, ArrayTypeCheck, DEFINE_METHOD(STUBHELPERS, MULTICAST_DEBUGGER_TRACE_HELPER, MulticastDebuggerTraceHelper, SM_Obj_Int_RetVoid) #endif -#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR) -DEFINE_CLASS(COPYCTORSTUBCOOKIE, StubHelpers, CopyCtorStubCookie) -DEFINE_METHOD(COPYCTORSTUBCOOKIE, SET_DATA, SetData, IM_IntPtr_UInt_IntPtr_IntPtr_RetVoid) -DEFINE_METHOD(COPYCTORSTUBCOOKIE, SET_NEXT, SetNext, IM_IntPtr_RetVoid) -#endif // _TARGET_X86_ && !FEATURE_CORECLR - DEFINE_CLASS(ANSICHARMARSHALER, StubHelpers, AnsiCharMarshaler) DEFINE_METHOD(ANSICHARMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Char_Bool_Bool_RetByte) DEFINE_METHOD(ANSICHARMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Byte_RetChar) diff --git a/src/vm/mtypes.h b/src/vm/mtypes.h index 71241efa78..1a14760372 100644 --- a/src/vm/mtypes.h +++ b/src/vm/mtypes.h @@ -60,7 +60,7 @@ DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_UTF8_BUFFER, UTF8BufferMarshaler, // CoreCLR doesn't have any support for marshalling interface pointers. // Not even support for fake CCWs. DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_INTERFACE, InterfaceMarshaler, true) -#endif // defined(FEATURE_COMINTEROP) || !defined(FEATURE_CORECLR) +#endif // defined(FEATURE_COMINTEROP) #ifdef FEATURE_COMINTEROP DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_SAFEARRAY, SafeArrayMarshaler, false) diff --git a/src/vm/pefile.inl b/src/vm/pefile.inl index 455a46d919..fb73e5df4a 100644 --- a/src/vm/pefile.inl +++ b/src/vm/pefile.inl @@ -1333,7 +1333,7 @@ inline BOOL PEFile::IsPtrInILImage(PTR_CVOID data) TADDR taddrILMetadata = dac_cast<TADDR>(pDecoder->GetMetadata(&cbILMetadata)); return ((taddrILMetadata <= taddrData) && (taddrData < taddrILMetadata + cbILMetadata)); } -#endif // defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR) +#endif // defined(FEATURE_PREJIT) return GetOpenedILimage()->IsPtrInImage(data); } else diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp index b8b674d99b..4f4ba529c2 100644 --- a/src/zap/zapper.cpp +++ b/src/zap/zapper.cpp @@ -196,7 +196,7 @@ STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembl #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) if (pwszCLRJITPath != nullptr) zap->SetCLRJITPath(pwszCLRJITPath); -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) zap->SetForceFullTrust(!!(dwFlags & NGENWORKER_FLAGS_FULLTRUSTDOMAIN)); @@ -241,7 +241,7 @@ STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPat #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) zap->SetDontLoadJit(); -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) if (pwzPlatformAssembliesPaths != nullptr) zap->SetPlatformAssembliesPaths(pwzPlatformAssembliesPaths); @@ -264,7 +264,7 @@ STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPat #if !defined(NO_NGENPDB) if (pwzDiasymreaderPath != nullptr) zap->SetDiasymreaderPath(pwzDiasymreaderPath); -#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB) +#endif // !defined(NO_NGENPDB) // Avoid unnecessary security failures, since permissions are irrelevant when // generating NGEN PDBs @@ -581,7 +581,7 @@ void Zapper::Init(ZapperOptions *pOptions, bool fFreeZapperOptions) #if !defined(FEATURE_MERGE_JIT_AND_ENGINE) m_fDontLoadJit = false; -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) m_fForceFullTrust = false; } @@ -625,7 +625,7 @@ void Zapper::LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJi hr = S_OK; } else -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) if (WszGetModuleFileName(g_hThisInst, CoreClrFolder)) { hr = CopySystemDirectory(CoreClrFolder, CoreClrFolder); @@ -2098,7 +2098,7 @@ void Zapper::CreatePdbInCurrentDomain(BSTR pAssemblyPathOrName, BSTR pNativeImag { pDiasymreaderPath = m_DiasymreaderPath.GetUnicode(); } -#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB) +#endif //!defined(NO_NGENPDB) IfFailThrow(::CreatePdb(hAssembly, pNativeImagePath, pPdbPath, pdbLines, pManagedPdbSearchPath, pDiasymreaderPath)); } @@ -3873,14 +3873,14 @@ void Zapper::SetDontLoadJit() { m_fDontLoadJit = true; } -#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE) +#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE) #if !defined(NO_NGENPDB) void Zapper::SetDiasymreaderPath(LPCWSTR pwzDiasymreaderPath) { m_DiasymreaderPath.Set(pwzDiasymreaderPath); } -#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB) +#endif // !defined(NO_NGENPDB) void Zapper::SetPlatformAssembliesPaths(LPCWSTR pwzPlatformAssembliesPaths) |