| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | #ifndef __STRONG_NAME_H |
| 5 | #define __STRONG_NAME_H |
| 6 | |
| 7 | // =========================================================================== |
| 8 | // File: StrongName.h |
| 9 | // |
| 10 | // Wrappers for signing and hashing functions needed to implement strong names |
| 11 | // =========================================================================== |
| 12 | |
| 13 | |
| 14 | #include <windows.h> |
| 15 | #include <wincrypt.h> |
| 16 | #include <ole2.h> |
| 17 | |
| 18 | #include <corerror.h> |
| 19 | #include <winapifamily.h> |
| 20 | |
| 21 | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
| 22 | |
| 23 | #ifdef __cplusplus |
| 24 | extern "C" { |
| 25 | #endif |
| 26 | |
| 27 | |
| 28 | // Public key blob binary format. |
| 29 | typedef struct { |
| 30 | unsigned int SigAlgID; // (ALG_ID) signature algorithm used to create the signature |
| 31 | unsigned int HashAlgID; // (ALG_ID) hash algorithm used to create the signature |
| 32 | ULONG cbPublicKey; // length of the key in bytes |
| 33 | BYTE PublicKey[1]; // variable length byte array containing the key value in format output by CryptoAPI |
| 34 | } PublicKeyBlob; |
| 35 | |
| 36 | |
| 37 | // Location in the registry (under HKLM) that strong name configuration info is |
| 38 | // stored. |
| 39 | #define SN_CONFIG_KEY "Software\\Microsoft\\StrongName" |
| 40 | #define SN_CONFIG_CSP "CSP" // REG_SZ |
| 41 | #define SN_CONFIG_MACHINE_KEYSET "MachineKeyset" // REG_DWORD |
| 42 | #define SN_CONFIG_KEYSPEC "KeySpec" // REG_DWORD |
| 43 | #define SN_CONFIG_HASH_ALG "HashAlgorithm" // REG_DWORD |
| 44 | #define SN_CONFIG_SIGN_ALG "SignAlgorithm" // REG_DWORD |
| 45 | #define SN_CONFIG_VERIFICATION "Verification" // Registry subkey |
| 46 | #define SN_CONFIG_USERLIST "UserList" // REG_MULTI_SZ |
| 47 | #define SN_CONFIG_CACHE_VERIFY "CacheVerify" // REG_DWORD |
| 48 | |
| 49 | #define SN_CONFIG_KEY_W L"Software\\Microsoft\\StrongName" |
| 50 | #define SN_CONFIG_CSP_W L"CSP" // REG_SZ |
| 51 | #define SN_CONFIG_PROV_TYPE_W L"ProvType" // REG_DWORD |
| 52 | #define SN_CONFIG_MACHINE_KEYSET_W L"MachineKeyset" // REG_DWORD |
| 53 | #define SN_CONFIG_KEYSPEC_W L"KeySpec" // REG_DWORD |
| 54 | #define SN_CONFIG_HASH_ALG_W L"HashAlgorithm" // REG_DWORD |
| 55 | #define SN_CONFIG_SIGN_ALG_W L"SignAlgorithm" // REG_DWORD |
| 56 | #define SN_CONFIG_VERIFICATION_W L"Verification" // Registry subkey |
| 57 | #define SN_CONFIG_USERLIST_W L"UserList" // REG_MULTI_SZ |
| 58 | #define SN_CONFIG_TESTPUBLICKEY_W L"TestPublicKey" // REG_SZ |
| 59 | #define SN_CONFIG_CACHE_VERIFY_W L"CacheVerify" // REG_DWORD |
| 60 | |
| 61 | // VM related registry locations (Note, these values are under HKLM\Software\Microsoft\.NETFramework, rather |
| 62 | // than SN_CONFIG_KEY |
| 63 | #define SN_CONFIG_BYPASS_POLICY "AllowStrongNameBypass" // REG_DWORD |
| 64 | #define SN_CONFIG_BYPASS_POLICY_W L"AllowStrongNameBypass" // REG_DWORD |
| 65 | |
| 66 | #if defined(_MSC_VER) && !defined(USE_DEPRECATED_CLR_API_WITHOUT_WARNING) |
| 67 | #define DEPRECATED_CLR_API_MESG "This API has been deprecated. Refer to http://go.microsoft.com/fwlink/?LinkId=143720 for more details." |
| 68 | #define DECLARE_DEPRECATED __declspec(deprecated(DEPRECATED_CLR_API_MESG)) |
| 69 | #else // _MSC_VER && !USE_DEPRECATED_CLR_API_WITHOUT_WARNING |
| 70 | #define DECLARE_DEPRECATED |
| 71 | #endif // _MSC_VER && !USE_DEPRECATED_CLR_API_WITHOUT_WARNING |
| 72 | |
| 73 | #define SNAPI DECLARE_DEPRECATED BOOLEAN __stdcall |
| 74 | #define SNAPI_(_type) DECLARE_DEPRECATED _type __stdcall |
| 75 | |
| 76 | // Return last error. |
| 77 | SNAPI_(DWORD) StrongNameErrorInfo(VOID); |
| 78 | |
| 79 | |
| 80 | // Free buffer allocated by routines below. |
| 81 | SNAPI_(VOID) StrongNameFreeBuffer(BYTE *pbMemory); // [in] address of memory to free |
| 82 | |
| 83 | |
| 84 | // Generate a new key pair for strong name use. |
| 85 | SNAPI StrongNameKeyGen(LPCWSTR wszKeyContainer, // [in] desired key container name |
| 86 | DWORD dwFlags, // [in] flags (see below) |
| 87 | BYTE **ppbKeyBlob, // [out] public/private key blob |
| 88 | ULONG *pcbKeyBlob); |
| 89 | |
| 90 | // Generate a new key pair with the specified key size for strong name use. |
| 91 | SNAPI StrongNameKeyGenEx(LPCWSTR wszKeyContainer, // [in] desired key container name, must be a non-empty string |
| 92 | DWORD dwFlags, // [in] flags (see below) |
| 93 | DWORD dwKeySize, // [in] desired key size. |
| 94 | BYTE **ppbKeyBlob, // [out] public/private key blob |
| 95 | ULONG *pcbKeyBlob); |
| 96 | |
| 97 | // Flags for StrongNameKeyGen. |
| 98 | #define SN_LEAVE_KEY 0x00000001 // Leave key pair registered with CSP |
| 99 | |
| 100 | |
| 101 | // Import key pair into a key container. |
| 102 | SNAPI StrongNameKeyInstall(LPCWSTR wszKeyContainer,// [in] desired key container name, must be a non-empty string |
| 103 | BYTE *pbKeyBlob, // [in] public/private key pair blob |
| 104 | ULONG cbKeyBlob); |
| 105 | |
| 106 | |
| 107 | // Delete a key pair. |
| 108 | SNAPI StrongNameKeyDelete(LPCWSTR wszKeyContainer); // [in] desired key container name |
| 109 | |
| 110 | // Retrieve the public portion of a key pair. |
| 111 | SNAPI StrongNameGetPublicKey (LPCWSTR wszKeyContainer, // [in] desired key container name |
| 112 | BYTE *pbKeyBlob, // [in] public/private key blob (optional) |
| 113 | ULONG cbKeyBlob, |
| 114 | BYTE **ppbPublicKeyBlob, // [out] public key blob |
| 115 | ULONG *pcbPublicKeyBlob); |
| 116 | |
| 117 | // Retrieve the public portion of a key pair. |
| 118 | SNAPI StrongNameGetPublicKeyEx (LPCWSTR wszKeyContainer, // [in] desired key container name |
| 119 | BYTE *pbKeyBlob, // [in] public/private key blob (optional) |
| 120 | ULONG cbKeyBlob, |
| 121 | BYTE **ppbPublicKeyBlob, // [out] public key blob |
| 122 | ULONG *pcbPublicKeyBlob, |
| 123 | ULONG uHashAlgId, |
| 124 | ULONG uReserved); // reserved for future use |
| 125 | |
| 126 | // Hash and sign a manifest. |
| 127 | SNAPI StrongNameSignatureGeneration(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 128 | LPCWSTR wszKeyContainer, // [in] desired key container name |
| 129 | BYTE *pbKeyBlob, // [in] public/private key blob (optional) |
| 130 | ULONG cbKeyBlob, |
| 131 | BYTE **ppbSignatureBlob, // [out] signature blob |
| 132 | ULONG *pcbSignatureBlob); |
| 133 | |
| 134 | SNAPI StrongNameSignatureGenerationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 135 | LPCWSTR wszKeyContainer, // [in] desired key container name |
| 136 | BYTE *pbKeyBlob, // [in] public/private key blob (optional) |
| 137 | ULONG cbKeyBlob, |
| 138 | BYTE **ppbSignatureBlob, // [out] signature blob |
| 139 | ULONG *pcbSignatureBlob, |
| 140 | DWORD dwFlags); // [in] modifer flags; see below |
| 141 | |
| 142 | #define SN_SIGN_ALL_FILES 0x00000001 // Rehash all linked modules as well as resigning the manifest |
| 143 | #define SN_TEST_SIGN 0x00000002 // Test sign the assembly |
| 144 | #define SN_ECMA_SIGN 0x00000004 // Sign the assembly treating the input key as the real ECMA key |
| 145 | |
| 146 | // Digest signing support |
| 147 | |
| 148 | // Generate the digest of an input assembly, which can be signed with StrongNameDigestSign |
| 149 | SNAPI StrongNameDigestGenerate(_In_z_ LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 150 | _Outptr_result_bytebuffer_(*pcbDigestBlob) BYTE** ppbDigestBlob, // [out] digest of the assembly, free with StrongNameFreeBuffer |
| 151 | _Out_ ULONG* pcbDigestBlob, // [out] number of bytes in the assembly digest |
| 152 | DWORD dwFlags); // [in] modifier flags (see StrongNameSignatureGenerationEx) |
| 153 | |
| 154 | // Sign an the digest of an assembly calculated by StrongNameDigestGenerate |
| 155 | SNAPI StrongNameDigestSign(_In_opt_z_ LPCWSTR wszKeyContainer, // [in] desired key container name (optional) |
| 156 | _In_reads_bytes_opt_(cbKeyBlob) BYTE* pbKeyBlob, // [in] public/private key blob (optional) |
| 157 | ULONG cbKeyBlob, |
| 158 | _In_reads_bytes_(cbDigestBlob) BYTE* pbDigestBlob, // [in] digest blob, from StrongNameDigestGenerate |
| 159 | ULONG cbDigestBlob, |
| 160 | DWORD hashAlgId, // [in] algorithm id of the hash algorithm used with pbDigestBlob |
| 161 | _Outptr_result_bytebuffer_(*pcbSignatureBlob) BYTE** ppbSignatureBlob, // [out] signature blob, freed with StrongNameFreeBuffer |
| 162 | _Out_ ULONG* pcbSignatureBlob, |
| 163 | DWORD dwFlags); // [in] modifier flags (see StrongNameSignatureGenerationEx) |
| 164 | |
| 165 | // Embed a digest signature generated with StrongNameDigestSign into an assembly |
| 166 | SNAPI StrongNameDigestEmbed(_In_z_ LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly to update |
| 167 | _In_reads_bytes_(cbSignatureBlob) BYTE* pbSignatureBlob, // [in] signature blob for the assembly |
| 168 | ULONG cbSignatureBlob); |
| 169 | |
| 170 | // Create a strong name token from an assembly file. |
| 171 | SNAPI StrongNameTokenFromAssembly(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 172 | BYTE **ppbStrongNameToken, // [out] strong name token |
| 173 | ULONG *pcbStrongNameToken); |
| 174 | |
| 175 | // Create a strong name token from an assembly file and additionally return the full public key. |
| 176 | SNAPI StrongNameTokenFromAssemblyEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 177 | BYTE **ppbStrongNameToken, // [out] strong name token |
| 178 | ULONG *pcbStrongNameToken, |
| 179 | BYTE **ppbPublicKeyBlob, // [out] public key blob |
| 180 | ULONG *pcbPublicKeyBlob); |
| 181 | |
| 182 | // Create a strong name token from a public key blob. |
| 183 | SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] public key blob |
| 184 | ULONG cbPublicKeyBlob, |
| 185 | BYTE **ppbStrongNameToken, // [out] strong name token |
| 186 | ULONG *pcbStrongNameToken); |
| 187 | |
| 188 | |
| 189 | // Verify a strong name/manifest against a public key blob. |
| 190 | SNAPI StrongNameSignatureVerification(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 191 | DWORD dwInFlags, // [in] flags modifying behaviour (see below) |
| 192 | DWORD *pdwOutFlags); // [out] additional output info (see below) |
| 193 | |
| 194 | |
| 195 | // Verify a strong name/manifest against a public key blob. |
| 196 | SNAPI StrongNameSignatureVerificationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 197 | BOOLEAN fForceVerification, // [in] verify even if settings in the registry disable it |
| 198 | BOOLEAN *pfWasVerified); // [out] set to false if verify succeeded due to registry settings |
| 199 | |
| 200 | // Verify a strong name/manifest against a public key blob. |
| 201 | SNAPI StrongNameSignatureVerificationEx2(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 202 | BOOLEAN fForceVerification, // [in] verify even if settings in the registry disable it |
| 203 | BYTE *pbEcmaPublicKey, // [in] mapping from the ECMA public key to the real key used for verification |
| 204 | DWORD cbEcmaPublicKey, // [in] length of the real ECMA public key |
| 205 | BOOLEAN *pfWasVerified); // [out] set to false if verify succeeded due to registry settings |
| 206 | |
| 207 | // Verify a strong name/manifest against a public key blob when the assembly is |
| 208 | // already memory mapped. |
| 209 | SNAPI StrongNameSignatureVerificationFromImage(BYTE *pbBase, // [in] base address of mapped manifest file |
| 210 | DWORD dwLength, // [in] length of mapped image in bytes |
| 211 | DWORD dwInFlags, // [in] flags modifying behaviour (see below) |
| 212 | DWORD *pdwOutFlags); // [out] additional output info (see below) |
| 213 | |
| 214 | // Flags for use with the verify routines. |
| 215 | #define SN_INFLAG_FORCE_VER 0x00000001 // verify even if settings in the registry disable it |
| 216 | #define SN_INFLAG_INSTALL 0x00000002 // verification is the first (on entry to the cache) |
| 217 | #define SN_INFLAG_ADMIN_ACCESS 0x00000004 // cache protects assembly from all but admin access |
| 218 | #define SN_INFLAG_USER_ACCESS 0x00000008 // cache protects user's assembly from other users |
| 219 | #define SN_INFLAG_ALL_ACCESS 0x00000010 // cache provides no access restriction guarantees |
| 220 | |
| 221 | #define SN_INFLAG_RUNTIME 0x80000000 // internal debugging use only |
| 222 | |
| 223 | #define SN_OUTFLAG_WAS_VERIFIED 0x00000001 // set to false if verify succeeded due to registry settings |
| 224 | #define SN_OUTFLAG_MICROSOFT_SIGNATURE 0x00000002 // set if the public key corresponds to SN_THE_KEY |
| 225 | |
| 226 | // Verify that two assemblies differ only by signature blob. |
| 227 | SNAPI StrongNameCompareAssemblies(LPCWSTR wszAssembly1, // [in] file name of first assembly |
| 228 | LPCWSTR wszAssembly2, // [in] file name of second assembly |
| 229 | DWORD *pdwResult); // [out] result of comparison (see codes below) |
| 230 | |
| 231 | #define SN_CMP_DIFFERENT 0 // Assemblies contain different data |
| 232 | #define SN_CMP_IDENTICAL 1 // Assemblies are exactly the same, even signatures |
| 233 | #define SN_CMP_SIGONLY 2 // Assemblies differ only by signature (and checksum etc.) |
| 234 | |
| 235 | |
| 236 | // Compute the size of buffer needed to hold a hash for a given hash algorithm. |
| 237 | SNAPI StrongNameHashSize(ULONG ulHashAlg, // [in] hash algorithm |
| 238 | DWORD *pcbSize); // [out] size of the hash in bytes |
| 239 | |
| 240 | |
| 241 | // Compute the size that needs to be allocated for a signature in an assembly. |
| 242 | SNAPI StrongNameSignatureSize(BYTE *pbPublicKeyBlob, // [in] public key blob |
| 243 | ULONG cbPublicKeyBlob, |
| 244 | DWORD *pcbSize); // [out] size of the signature in bytes |
| 245 | |
| 246 | |
| 247 | SNAPI_(DWORD) GetHashFromAssemblyFile(LPCSTR szFilePath, // [IN] location of file to be hashed |
| 248 | unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) |
| 249 | BYTE *pbHash, // [OUT] hash buffer |
| 250 | DWORD cchHash, // [IN] max size of buffer |
| 251 | DWORD *pchHash); // [OUT] length of hash byte array |
| 252 | |
| 253 | SNAPI_(DWORD) GetHashFromAssemblyFileW(LPCWSTR wszFilePath, // [IN] location of file to be hashed |
| 254 | unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) |
| 255 | BYTE *pbHash, // [OUT] hash buffer |
| 256 | DWORD cchHash, // [IN] max size of buffer |
| 257 | DWORD *pchHash); // [OUT] length of hash byte array |
| 258 | |
| 259 | SNAPI_(DWORD) GetHashFromFile(LPCSTR szFilePath, // [IN] location of file to be hashed |
| 260 | unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) |
| 261 | BYTE *pbHash, // [OUT] hash buffer |
| 262 | DWORD cchHash, // [IN] max size of buffer |
| 263 | DWORD *pchHash); // [OUT] length of hash byte array |
| 264 | |
| 265 | SNAPI_(DWORD) GetHashFromFileW(LPCWSTR wszFilePath, // [IN] location of file to be hashed |
| 266 | unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) |
| 267 | BYTE *pbHash, // [OUT] hash buffer |
| 268 | DWORD cchHash, // [IN] max size of buffer |
| 269 | DWORD *pchHash); // [OUT] length of hash byte array |
| 270 | |
| 271 | SNAPI_(DWORD) GetHashFromHandle(HANDLE hFile, // [IN] handle of file to be hashed |
| 272 | unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) |
| 273 | BYTE *pbHash, // [OUT] hash buffer |
| 274 | DWORD cchHash, // [IN] max size of buffer |
| 275 | DWORD *pchHash); // [OUT] length of hash byte array |
| 276 | |
| 277 | SNAPI_(DWORD) GetHashFromBlob(BYTE *pbBlob, // [IN] pointer to memory block to hash |
| 278 | DWORD cchBlob, // [IN] length of blob |
| 279 | unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default) |
| 280 | BYTE *pbHash, // [OUT] hash buffer |
| 281 | DWORD cchHash, // [IN] max size of buffer |
| 282 | DWORD *pchHash); // [OUT] length of hash byte array |
| 283 | |
| 284 | SNAPI StrongNameGetBlob(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly |
| 285 | BYTE *pbBlob, // [in] buffer to fill with blob |
| 286 | DWORD *pcbBlob); // [in/out] size of buffer/number of bytes put into buffer |
| 287 | |
| 288 | SNAPI StrongNameGetBlobFromImage(BYTE *pbBase, // [in] base address of mapped manifest file |
| 289 | DWORD dwLength, // [in] length of mapped image in bytes |
| 290 | BYTE *pbBlob, // [in] buffer to fill with blob |
| 291 | DWORD *pcbBlob); // [in/out] size of buffer/number of bytes put into buffer |
| 292 | |
| 293 | #undef DECLARE_DEPRECATED |
| 294 | #undef DEPRECATED_CLR_API_MESG |
| 295 | #undef SNAPI |
| 296 | #undef SNAPI_ |
| 297 | #define SNAPI BOOLEAN __stdcall |
| 298 | #define SNAPI_(_type) _type __stdcall |
| 299 | |
| 300 | #ifdef __cplusplus |
| 301 | } |
| 302 | #endif |
| 303 | |
| 304 | #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
| 305 | |
| 306 | #endif |
| 307 | |