Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

433 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. // Microsoft Windows
  3. //
  4. // Copyright (C) Microsoft Corporation, 2001 - 2001
  5. //
  6. // File: mincrypt.h
  7. //
  8. // Contents: Minimal Cryptographic API Prototypes and Definitions
  9. //
  10. // Contains cryptographic functions to verify PKCS #7 Signed Data
  11. // messages, X.509 certificate chains, Authenticode signed
  12. // files and file hashes in system catalogs.
  13. //
  14. // These APIs rely on the APIs defined in minasn1.h for doing
  15. // the low level ASN.1 parsing.
  16. //
  17. // These APIs are implemented to be self contained and to
  18. // allow for code obfuscation. These APIs will be included
  19. // in such applications as, DRM or licensing verification.
  20. //
  21. // If the file name or file handle option is selected,
  22. // the following APIs will need to call the kernel32.dll APIs
  23. // to open, map and unmap files:
  24. // MinCryptHashFile
  25. // MinCryptVerifySignedFile
  26. // The following API will need to call kernel32.dll and
  27. // wintrust.dll APIs to find, open, map and unmap files:
  28. // MinCryptVerifyHashInSystemCatalogs
  29. // Except for the calls in the above APIs,
  30. // no calls to APIs in other DLLs.
  31. //
  32. // Additionally, since these APIs have been pared down
  33. // from their wincrypt.h and crypt32.dll counterparts they are
  34. // a good candidate for applications with minimal memory and CPU
  35. // resources.
  36. //
  37. // APIs:
  38. // MinCryptDecodeHashAlgorithmIdentifier
  39. // MinCryptHashMemory
  40. // MinCryptVerifySignedHash
  41. // MinCryptVerifyCertificate
  42. // MinCryptVerifySignedData
  43. // MinCryptHashFile
  44. // MinCryptVerifySignedFile
  45. // MinCryptVerifyHashInSystemCatalogs
  46. //
  47. //----------------------------------------------------------------------------
  48. #ifndef __MINCRYPT_H__
  49. #define __MINCRYPT_H__
  50. #if defined (_MSC_VER)
  51. #if ( _MSC_VER >= 800 )
  52. #if _MSC_VER >= 1200
  53. #pragma warning(push)
  54. #endif
  55. #pragma warning(disable:4201) /* Nameless struct/union */
  56. #endif
  57. #if (_MSC_VER > 1020)
  58. #pragma once
  59. #endif
  60. #endif
  61. #include <wincrypt.h>
  62. #include <minasn1.h>
  63. #ifdef __cplusplus
  64. extern "C" {
  65. #endif
  66. #define MINCRYPT_MAX_HASH_LEN 20
  67. #define MINCRYPT_SHA1_HASH_LEN 20
  68. #define MINCRYPT_MD5_HASH_LEN 16
  69. #define MINCRYPT_MD2_HASH_LEN 16
  70. //+-------------------------------------------------------------------------
  71. // Release any global resources consumed by the mincrypt
  72. // library. This should be called during DLL_PROCESS_DETACH
  73. // since a critical section has possibly been created.
  74. //
  75. // Currently, the global state (and its critical section) is
  76. // initialized only on-demand for systems that make use of the
  77. // Microsoft Test Root Certificate.
  78. //--------------------------------------------------------------------------
  79. /*
  80. DWORD
  81. WINAPI
  82. MinCryptUninitialize(void);
  83. */
  84. //+-------------------------------------------------------------------------
  85. // Decodes an ASN.1 encoded Algorithm Identifier and converts to
  86. // a CAPI Hash AlgID, such as, CALG_SHA1 or CALG_MD5.
  87. //
  88. // Returns 0 if there isn't a CAPI AlgId corresponding to the Algorithm
  89. // Identifier.
  90. //
  91. // Only CALG_SHA1, CALG_MD5 and CALG_MD2 are supported.
  92. //--------------------------------------------------------------------------
  93. ALG_ID
  94. WINAPI
  95. MinCryptDecodeHashAlgorithmIdentifier(
  96. IN PCRYPT_DER_BLOB pAlgIdValueBlob
  97. );
  98. //+-------------------------------------------------------------------------
  99. // Hashes one or more memory blobs according to the Hash ALG_ID.
  100. //
  101. // rgbHash is updated with the resultant hash. *pcbHash is updated with
  102. // the length associated with the hash algorithm.
  103. //
  104. // If the function succeeds, the return value is ERROR_SUCCESS. Otherwise,
  105. // a nonzero error code is returned.
  106. //
  107. // Only CALG_SHA1, CALG_MD5 and CALG_MD2 are supported.
  108. //--------------------------------------------------------------------------
  109. LONG
  110. WINAPI
  111. MinCryptHashMemory(
  112. IN ALG_ID HashAlgId,
  113. IN DWORD cBlob,
  114. IN PCRYPT_DER_BLOB rgBlob,
  115. OUT BYTE rgbHash[MINCRYPT_MAX_HASH_LEN],
  116. OUT DWORD *pcbHash
  117. );
  118. //+-------------------------------------------------------------------------
  119. // Verifies a signed hash.
  120. //
  121. // The ASN.1 encoded Public Key Info is parsed and used to decrypt the
  122. // signed hash. The decrypted signed hash is compared with the input
  123. // hash.
  124. //
  125. // If the signed hash was successfully verified, ERROR_SUCCESS is returned.
  126. // Otherwise, a nonzero error code is returned.
  127. //
  128. // Only RSA signatures are supported.
  129. //
  130. // Only MD2, MD5 and SHA1 hashes are supported.
  131. //--------------------------------------------------------------------------
  132. LONG
  133. WINAPI
  134. MinCryptVerifySignedHash(
  135. IN ALG_ID HashAlgId,
  136. IN BYTE *pbHash,
  137. IN DWORD cbHash,
  138. IN PCRYPT_DER_BLOB pSignedHashContentBlob,
  139. IN PCRYPT_DER_BLOB pPubKeyInfoValueBlob
  140. );
  141. //+-------------------------------------------------------------------------
  142. // Verifies a previously parsed X.509 Certificate.
  143. //
  144. // Assumes the ASN.1 encoded X.509 certificate was parsed via
  145. // MinAsn1ParseCertificate() and the set of potential issuer certificates
  146. // were parsed via one or more of:
  147. // - MinAsn1ParseCertificate()
  148. // - MinAsn1ParseSignedDataCertificates()
  149. // - MinAsn1ExtractParsedCertificatesFromSignedData()
  150. //
  151. // Iteratively finds the issuer certificate via its encoded name. The
  152. // public key in the issuer certificate is used to verify the subject
  153. // certificate's signature. This is repeated until finding a self signed
  154. // certificate or a baked in root identified by its encoded name.
  155. // For a self signed certificate, compares against the baked in root
  156. // public keys.
  157. //
  158. // If the certificate and its issuers were successfully verified to a
  159. // baked in root, ERROR_SUCCESS is returned. Otherwise, a nonzero error
  160. // code is returned.
  161. //--------------------------------------------------------------------------
  162. LONG
  163. WINAPI
  164. MinCryptVerifyCertificate(
  165. IN CRYPT_DER_BLOB rgSubjectCertBlob[MINASN1_CERT_BLOB_CNT],
  166. IN DWORD cIssuerCert,
  167. IN CRYPT_DER_BLOB rgrgIssuerCertBlob[][MINASN1_CERT_BLOB_CNT]
  168. );
  169. //+-------------------------------------------------------------------------
  170. // Function: MinCryptVerifySignedData
  171. //
  172. // Verifies an ASN.1 encoded PKCS #7 Signed Data Message.
  173. //
  174. // Assumes the PKCS #7 message is definite length encoded.
  175. // Assumes PKCS #7 version 1.5, ie, not the newer CMS version.
  176. // We only look at the first signer.
  177. //
  178. // The Signed Data message is parsed. Its signature is verified. Its
  179. // signer certificate chain is verified to a baked in root public key.
  180. //
  181. // If the Signed Data was successfully verified, ERROR_SUCCESS is returned.
  182. // Otherwise, a nonzero error code is returned.
  183. //
  184. // Here are some interesting errors that can be returned:
  185. // CRYPT_E_BAD_MSG - unable to ASN1 parse as a signed data message
  186. // ERROR_NO_DATA - the content is empty
  187. // CRYPT_E_NO_SIGNER - not signed or unable to find signer cert
  188. // CRYPT_E_UNKNOWN_ALGO- unknown MD5 or SHA1 ASN.1 algorithm identifier
  189. // CERT_E_UNTRUSTEDROOT- the signer chain's root wasn't baked in
  190. // CERT_E_CHAINING - unable to build signer chain to a root
  191. // CRYPT_E_AUTH_ATTR_MISSING - missing digest authenticated attribute
  192. // CRYPT_E_HASH_VALUE - content hash != authenticated digest attribute
  193. // NTE_BAD_ALGID - unsupported hash or public key algorithm
  194. // NTE_BAD_PUBLIC_KEY - not a valid RSA public key
  195. // NTE_BAD_SIGNATURE - bad PKCS #7 or signer chain signature
  196. //
  197. // The rgVerSignedDataBlob[] is updated with pointer to and length of the
  198. // following fields in the encoded PKCS #7 message.
  199. //--------------------------------------------------------------------------
  200. // Content Object Identifier content bytes (OID)
  201. #define MINCRYPT_VER_SIGNED_DATA_CONTENT_OID_IDX 0
  202. // Content data content bytes excluding "[0] EXPLICIT" tag
  203. // (OPTIONAL MinAsn1ParseCTL, MinAsn1ParseIndirectData)
  204. #define MINCRYPT_VER_SIGNED_DATA_CONTENT_DATA_IDX 1
  205. // Signer certificate's encoded bytes (MinAsn1ParseCertificate)
  206. #define MINCRYPT_VER_SIGNED_DATA_SIGNER_CERT_IDX 2
  207. // Authenticated attributes value bytes including "[0] IMPLICIT" tag
  208. // (OPTIONAL, MinAsn1ParseAttributes)
  209. #define MINCRYPT_VER_SIGNED_DATA_AUTH_ATTRS_IDX 3
  210. // Unauthenticated attributes value bytes including "[1] IMPLICIT" tag
  211. // (OPTIONAL, MinAsn1ParseAttributes)
  212. #define MINCRYPT_VER_SIGNED_DATA_UNAUTH_ATTRS_IDX 4
  213. #define MINCRYPT_VER_SIGNED_DATA_BLOB_CNT 5
  214. LONG
  215. WINAPI
  216. MinCryptVerifySignedData(
  217. IN const BYTE *pbEncoded,
  218. IN DWORD cbEncoded,
  219. OUT CRYPT_DER_BLOB rgVerSignedDataBlob[MINCRYPT_VER_SIGNED_DATA_BLOB_CNT]
  220. );
  221. //+-------------------------------------------------------------------------
  222. // File Type Definitions
  223. //
  224. // Specifies the type of the "const VOID *pvFile" parameter
  225. //--------------------------------------------------------------------------
  226. // pvFile - LPCWSTR pwszFilename
  227. #define MINCRYPT_FILE_NAME 1
  228. // pvFile - HANDLE hFile
  229. #define MINCRYPT_FILE_HANDLE 2
  230. // pvFile - PCRYPT_DATA_BLOB pFileBlob
  231. #define MINCRYPT_FILE_BLOB 3
  232. //+-------------------------------------------------------------------------
  233. // Hashes the file according to the Hash ALG_ID.
  234. //
  235. // According to dwFileType, pvFile can be a pwszFilename, hFile or pFileBlob.
  236. // Only requires READ access.
  237. //
  238. // dwFileType:
  239. // MINCRYPT_FILE_NAME : pvFile - LPCWSTR pwszFilename
  240. // MINCRYPT_FILE_HANDLE : pvFile - HANDLE hFile
  241. // MINCRYPT_FILE_BLOB : pvFile - PCRYPT_DATA_BLOB pFileBlob
  242. //
  243. // rgbHash is updated with the resultant hash. *pcbHash is updated with
  244. // the length associated with the hash algorithm.
  245. //
  246. // If the function succeeds, the return value is ERROR_SUCCESS. Otherwise,
  247. // a nonzero error code is returned.
  248. //
  249. // Only CALG_SHA1 and CALG_MD5 are supported.
  250. //
  251. // If a NT PE 32 bit file format, hashed according to imagehlp rules, ie, skip
  252. // section containing potential signature, ... . Otherwise, the entire file
  253. // is hashed.
  254. //--------------------------------------------------------------------------
  255. LONG
  256. WINAPI
  257. MinCryptHashFile(
  258. IN DWORD dwFileType,
  259. IN const VOID *pvFile,
  260. IN ALG_ID HashAlgId,
  261. OUT BYTE rgbHash[MINCRYPT_MAX_HASH_LEN],
  262. OUT DWORD *pcbHash
  263. );
  264. //+-------------------------------------------------------------------------
  265. // Verifies a previously signed file.
  266. //
  267. // According to dwFileType, pvFile can be a pwszFilename, hFile or pFileBlob.
  268. // Only requires READ access.
  269. //
  270. // dwFileType:
  271. // MINCRYPT_FILE_NAME : pvFile - LPCWSTR pwszFilename
  272. // MINCRYPT_FILE_HANDLE : pvFile - HANDLE hFile
  273. // MINCRYPT_FILE_BLOB : pvFile - PCRYPT_DATA_BLOB pFileBlob
  274. //
  275. // Checks if the file has an embedded PKCS #7 Signed Data message containing
  276. // Indirect Data. The PKCS #7 is verified via MinCryptVerifySignedData().
  277. // The Indirect Data is parsed via MinAsn1ParseIndirectData() to get the
  278. // HashAlgId and the file hash. MinCryptHashFile() is called to hash the
  279. // file. The returned hash is compared against the Indirect Data's hash.
  280. //
  281. // The caller can request one or more signer authenticated attribute values
  282. // to be returned. The still encoded values are returned in the
  283. // caller allocated memory. The beginning of this returned memory will
  284. // be set to an array of attribute value blobs pointing to these
  285. // encoded values (CRYPT_DER_BLOB rgAttrBlob[cAttrOID]).
  286. // For performance reasons, the caller should make every attempt to allow
  287. // for a single pass call. The necessary memory size is:
  288. // (cAttrOID * sizeof(CRYPT_DER_BLOB)) +
  289. // total length of encoded attribute values.
  290. //
  291. // *pcbAttr will be updated with the number of bytes required to contain
  292. // the attribute blobs and values. If the input memory is insufficient,
  293. // ERROR_INSUFFICIENT_BUFFER will be returned if no other error.
  294. //
  295. // For a multi-valued attribute, only the first value is returned.
  296. //
  297. // If the function succeeds, the return value is ERROR_SUCCESS. Otherwise,
  298. // a nonzero error code is returned.
  299. //
  300. // Only NT, PE 32 bit file formats are supported.
  301. //--------------------------------------------------------------------------
  302. LONG
  303. WINAPI
  304. MinCryptVerifySignedFile(
  305. IN DWORD dwFileType,
  306. IN const VOID *pvFile,
  307. IN OPTIONAL DWORD cAttrOID,
  308. IN OPTIONAL CRYPT_DER_BLOB rgAttrEncodedOIDBlob[],
  309. // CRYPT_DER_BLOB rgAttrBlob[cAttrOID] header is at beginning
  310. // with the bytes pointed to immediately following
  311. OUT OPTIONAL CRYPT_DER_BLOB *rgAttrValueBlob,
  312. IN OUT OPTIONAL DWORD *pcbAttr
  313. );
  314. //+-------------------------------------------------------------------------
  315. // Verifies the hashes in the system catalogs.
  316. //
  317. // Iterates through the hashes and attempts to find the system catalog
  318. // containing it. If found, the system catalog file is verified as a
  319. // PKCS #7 Signed Data message with its signer cert verified up to a baked
  320. // in root.
  321. //
  322. // The following mscat32.dll APIs are called to find the system catalog file:
  323. // CryptCATAdminAcquireContext
  324. // CryptCATAdminReleaseContext
  325. // CryptCATAdminEnumCatalogFromHash
  326. // CryptCATAdminReleaseCatalogContext
  327. // CryptCATCatalogInfoFromContext
  328. //
  329. // If the hash was successfully verified, rglErr[] is set to ERROR_SUCCESS.
  330. // Otherwise, rglErr[] is set to a nonzero error code.
  331. //
  332. // The caller can request one or more catalog subject attribute,
  333. // extension or signer authenticated attribute values to be returned for
  334. // each hash. The still encoded values are returned in the
  335. // caller allocated memory. The beginning of this returned memory will
  336. // be set to a 2 dimensional array of attribute value blobs pointing to these
  337. // encoded values (CRYPT_DER_BLOB rgrgAttrValueBlob[cHash][cAttrOID]).
  338. // For performance reasons, the caller should make every attempt to allow
  339. // for a single pass call. The necessary memory size is:
  340. // (cHash * cAttrOID * sizeof(CRYPT_DER_BLOB)) +
  341. // total length of encoded attribute values.
  342. //
  343. // *pcbAttr will be updated with the number of bytes required to contain
  344. // the attribute blobs and values. If the input memory is insufficient,
  345. // ERROR_INSUFFICIENT_BUFFER will be returned if no other error.
  346. //
  347. // For a multi-valued attribute, only the first value is returned.
  348. //
  349. // If the function succeeds, the return value is ERROR_SUCCESS. This may
  350. // be returned for unsuccessful rglErr[] values. Otherwise,
  351. // a nonzero error code is returned.
  352. //--------------------------------------------------------------------------
  353. LONG
  354. WINAPI
  355. MinCryptVerifyHashInSystemCatalogs(
  356. IN ALG_ID HashAlgId,
  357. IN DWORD cHash,
  358. IN CRYPT_HASH_BLOB rgHashBlob[],
  359. OUT LONG rglErr[],
  360. IN OPTIONAL DWORD cAttrOID,
  361. IN OPTIONAL CRYPT_DER_BLOB rgAttrEncodedOIDBlob[],
  362. // CRYPT_DER_BLOB rgrgAttrValueBlob[cHash][cAttrOID] header is at beginning
  363. // with the bytes pointed to immediately following
  364. OUT OPTIONAL CRYPT_DER_BLOB *rgrgAttrValueBlob,
  365. IN OUT OPTIONAL DWORD *pcbAttr
  366. );
  367. #ifdef __cplusplus
  368. } // Balance extern "C" above
  369. #endif
  370. #if defined (_MSC_VER)
  371. #if ( _MSC_VER >= 800 )
  372. #if _MSC_VER >= 1200
  373. #pragma warning(pop)
  374. #else
  375. #pragma warning(default:4201)
  376. #endif
  377. #endif
  378. #endif
  379. #endif // __MINCRYPT_H__