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.

417 lines
15 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. // Decodes an ASN.1 encoded Algorithm Identifier and converts to
  72. // a CAPI Hash AlgID, such as, CALG_SHA1 or CALG_MD5.
  73. //
  74. // Returns 0 if there isn't a CAPI AlgId corresponding to the Algorithm
  75. // Identifier.
  76. //
  77. // Only CALG_SHA1, CALG_MD5 and CALG_MD2 are supported.
  78. //--------------------------------------------------------------------------
  79. ALG_ID
  80. WINAPI
  81. MinCryptDecodeHashAlgorithmIdentifier(
  82. IN PCRYPT_DER_BLOB pAlgIdValueBlob
  83. );
  84. //+-------------------------------------------------------------------------
  85. // Hashes one or more memory blobs according to the Hash ALG_ID.
  86. //
  87. // rgbHash is updated with the resultant hash. *pcbHash is updated with
  88. // the length associated with the hash algorithm.
  89. //
  90. // If the function succeeds, the return value is ERROR_SUCCESS. Otherwise,
  91. // a nonzero error code is returned.
  92. //
  93. // Only CALG_SHA1, CALG_MD5 and CALG_MD2 are supported.
  94. //--------------------------------------------------------------------------
  95. LONG
  96. WINAPI
  97. MinCryptHashMemory(
  98. IN ALG_ID HashAlgId,
  99. IN DWORD cBlob,
  100. IN PCRYPT_DER_BLOB rgBlob,
  101. OUT BYTE rgbHash[MINCRYPT_MAX_HASH_LEN],
  102. OUT DWORD *pcbHash
  103. );
  104. //+-------------------------------------------------------------------------
  105. // Verifies a signed hash.
  106. //
  107. // The ASN.1 encoded Public Key Info is parsed and used to decrypt the
  108. // signed hash. The decrypted signed hash is compared with the input
  109. // hash.
  110. //
  111. // If the signed hash was successfully verified, ERROR_SUCCESS is returned.
  112. // Otherwise, a nonzero error code is returned.
  113. //
  114. // Only RSA signatures are supported.
  115. //
  116. // Only MD2, MD5 and SHA1 hashes are supported.
  117. //--------------------------------------------------------------------------
  118. LONG
  119. WINAPI
  120. MinCryptVerifySignedHash(
  121. IN ALG_ID HashAlgId,
  122. IN BYTE *pbHash,
  123. IN DWORD cbHash,
  124. IN PCRYPT_DER_BLOB pSignedHashContentBlob,
  125. IN PCRYPT_DER_BLOB pPubKeyInfoValueBlob
  126. );
  127. //+-------------------------------------------------------------------------
  128. // Verifies a previously parsed X.509 Certificate.
  129. //
  130. // Assumes the ASN.1 encoded X.509 certificate was parsed via
  131. // MinAsn1ParseCertificate() and the set of potential issuer certificates
  132. // were parsed via one or more of:
  133. // - MinAsn1ParseCertificate()
  134. // - MinAsn1ParseSignedDataCertificates()
  135. // - MinAsn1ExtractParsedCertificatesFromSignedData()
  136. //
  137. // Iteratively finds the issuer certificate via its encoded name. The
  138. // public key in the issuer certificate is used to verify the subject
  139. // certificate's signature. This is repeated until finding a self signed
  140. // certificate or a baked in root identified by its encoded name.
  141. // For a self signed certificate, compares against the baked in root
  142. // public keys.
  143. //
  144. // If the certificate and its issuers were successfully verified to a
  145. // baked in root, ERROR_SUCCESS is returned. Otherwise, a nonzero error
  146. // code is returned.
  147. //--------------------------------------------------------------------------
  148. LONG
  149. WINAPI
  150. MinCryptVerifyCertificate(
  151. IN CRYPT_DER_BLOB rgSubjectCertBlob[MINASN1_CERT_BLOB_CNT],
  152. IN DWORD cIssuerCert,
  153. IN CRYPT_DER_BLOB rgrgIssuerCertBlob[][MINASN1_CERT_BLOB_CNT]
  154. );
  155. //+-------------------------------------------------------------------------
  156. // Function: MinCryptVerifySignedData
  157. //
  158. // Verifies an ASN.1 encoded PKCS #7 Signed Data Message.
  159. //
  160. // Assumes the PKCS #7 message is definite length encoded.
  161. // Assumes PKCS #7 version 1.5, ie, not the newer CMS version.
  162. // We only look at the first signer.
  163. //
  164. // The Signed Data message is parsed. Its signature is verified. Its
  165. // signer certificate chain is verified to a baked in root public key.
  166. //
  167. // If the Signed Data was successfully verified, ERROR_SUCCESS is returned.
  168. // Otherwise, a nonzero error code is returned.
  169. //
  170. // Here are some interesting errors that can be returned:
  171. // CRYPT_E_BAD_MSG - unable to ASN1 parse as a signed data message
  172. // ERROR_NO_DATA - the content is empty
  173. // CRYPT_E_NO_SIGNER - not signed or unable to find signer cert
  174. // CRYPT_E_UNKNOWN_ALGO- unknown MD5 or SHA1 ASN.1 algorithm identifier
  175. // CERT_E_UNTRUSTEDROOT- the signer chain's root wasn't baked in
  176. // CERT_E_CHAINING - unable to build signer chain to a root
  177. // CRYPT_E_AUTH_ATTR_MISSING - missing digest authenticated attribute
  178. // CRYPT_E_HASH_VALUE - content hash != authenticated digest attribute
  179. // NTE_BAD_ALGID - unsupported hash or public key algorithm
  180. // NTE_BAD_PUBLIC_KEY - not a valid RSA public key
  181. // NTE_BAD_SIGNATURE - bad PKCS #7 or signer chain signature
  182. //
  183. // The rgVerSignedDataBlob[] is updated with pointer to and length of the
  184. // following fields in the encoded PKCS #7 message.
  185. //--------------------------------------------------------------------------
  186. // Content Object Identifier content bytes (OID)
  187. #define MINCRYPT_VER_SIGNED_DATA_CONTENT_OID_IDX 0
  188. // Content data content bytes excluding "[0] EXPLICIT" tag
  189. // (OPTIONAL MinAsn1ParseCTL, MinAsn1ParseIndirectData)
  190. #define MINCRYPT_VER_SIGNED_DATA_CONTENT_DATA_IDX 1
  191. // Signer certificate's encoded bytes (MinAsn1ParseCertificate)
  192. #define MINCRYPT_VER_SIGNED_DATA_SIGNER_CERT_IDX 2
  193. // Authenticated attributes value bytes including "[0] IMPLICIT" tag
  194. // (OPTIONAL, MinAsn1ParseAttributes)
  195. #define MINCRYPT_VER_SIGNED_DATA_AUTH_ATTRS_IDX 3
  196. // Unauthenticated attributes value bytes including "[1] IMPLICIT" tag
  197. // (OPTIONAL, MinAsn1ParseAttributes)
  198. #define MINCRYPT_VER_SIGNED_DATA_UNAUTH_ATTRS_IDX 4
  199. #define MINCRYPT_VER_SIGNED_DATA_BLOB_CNT 5
  200. LONG
  201. WINAPI
  202. MinCryptVerifySignedData(
  203. IN const BYTE *pbEncoded,
  204. IN DWORD cbEncoded,
  205. OUT CRYPT_DER_BLOB rgVerSignedDataBlob[MINCRYPT_VER_SIGNED_DATA_BLOB_CNT]
  206. );
  207. //+-------------------------------------------------------------------------
  208. // File Type Definitions
  209. //
  210. // Specifies the type of the "const VOID *pvFile" parameter
  211. //--------------------------------------------------------------------------
  212. // pvFile - LPCWSTR pwszFilename
  213. #define MINCRYPT_FILE_NAME 1
  214. // pvFile - HANDLE hFile
  215. #define MINCRYPT_FILE_HANDLE 2
  216. // pvFile - PCRYPT_DATA_BLOB pFileBlob
  217. #define MINCRYPT_FILE_BLOB 3
  218. //+-------------------------------------------------------------------------
  219. // Hashes the file according to the Hash ALG_ID.
  220. //
  221. // According to dwFileType, pvFile can be a pwszFilename, hFile or pFileBlob.
  222. // Only requires READ access.
  223. //
  224. // dwFileType:
  225. // MINCRYPT_FILE_NAME : pvFile - LPCWSTR pwszFilename
  226. // MINCRYPT_FILE_HANDLE : pvFile - HANDLE hFile
  227. // MINCRYPT_FILE_BLOB : pvFile - PCRYPT_DATA_BLOB pFileBlob
  228. //
  229. // rgbHash is updated with the resultant hash. *pcbHash is updated with
  230. // the length associated with the hash algorithm.
  231. //
  232. // If the function succeeds, the return value is ERROR_SUCCESS. Otherwise,
  233. // a nonzero error code is returned.
  234. //
  235. // Only CALG_SHA1 and CALG_MD5 are supported.
  236. //
  237. // If a NT PE 32 bit file format, hashed according to imagehlp rules, ie, skip
  238. // section containing potential signature, ... . Otherwise, the entire file
  239. // is hashed.
  240. //--------------------------------------------------------------------------
  241. LONG
  242. WINAPI
  243. MinCryptHashFile(
  244. IN DWORD dwFileType,
  245. IN const VOID *pvFile,
  246. IN ALG_ID HashAlgId,
  247. OUT BYTE rgbHash[MINCRYPT_MAX_HASH_LEN],
  248. OUT DWORD *pcbHash
  249. );
  250. //+-------------------------------------------------------------------------
  251. // Verifies a previously signed file.
  252. //
  253. // According to dwFileType, pvFile can be a pwszFilename, hFile or pFileBlob.
  254. // Only requires READ access.
  255. //
  256. // dwFileType:
  257. // MINCRYPT_FILE_NAME : pvFile - LPCWSTR pwszFilename
  258. // MINCRYPT_FILE_HANDLE : pvFile - HANDLE hFile
  259. // MINCRYPT_FILE_BLOB : pvFile - PCRYPT_DATA_BLOB pFileBlob
  260. //
  261. // Checks if the file has an embedded PKCS #7 Signed Data message containing
  262. // Indirect Data. The PKCS #7 is verified via MinCryptVerifySignedData().
  263. // The Indirect Data is parsed via MinAsn1ParseIndirectData() to get the
  264. // HashAlgId and the file hash. MinCryptHashFile() is called to hash the
  265. // file. The returned hash is compared against the Indirect Data's hash.
  266. //
  267. // The caller can request one or more signer authenticated attribute values
  268. // to be returned. The still encoded values are returned in the
  269. // caller allocated memory. The beginning of this returned memory will
  270. // be set to an array of attribute value blobs pointing to these
  271. // encoded values (CRYPT_DER_BLOB rgAttrBlob[cAttrOID]).
  272. // For performance reasons, the caller should make every attempt to allow
  273. // for a single pass call. The necessary memory size is:
  274. // (cAttrOID * sizeof(CRYPT_DER_BLOB)) +
  275. // total length of encoded attribute values.
  276. //
  277. // *pcbAttr will be updated with the number of bytes required to contain
  278. // the attribute blobs and values. If the input memory is insufficient,
  279. // ERROR_INSUFFICIENT_BUFFER will be returned if no other error.
  280. //
  281. // For a multi-valued attribute, only the first value is returned.
  282. //
  283. // If the function succeeds, the return value is ERROR_SUCCESS. Otherwise,
  284. // a nonzero error code is returned.
  285. //
  286. // Only NT, PE 32 bit file formats are supported.
  287. //--------------------------------------------------------------------------
  288. LONG
  289. WINAPI
  290. MinCryptVerifySignedFile(
  291. IN DWORD dwFileType,
  292. IN const VOID *pvFile,
  293. IN OPTIONAL DWORD cAttrOID,
  294. IN OPTIONAL CRYPT_DER_BLOB rgAttrEncodedOIDBlob[],
  295. // CRYPT_DER_BLOB rgAttrBlob[cAttrOID] header is at beginning
  296. // with the bytes pointed to immediately following
  297. OUT OPTIONAL CRYPT_DER_BLOB *rgAttrValueBlob,
  298. IN OUT OPTIONAL DWORD *pcbAttr
  299. );
  300. //+-------------------------------------------------------------------------
  301. // Verifies the hashes in the system catalogs.
  302. //
  303. // Iterates through the hashes and attempts to find the system catalog
  304. // containing it. If found, the system catalog file is verified as a
  305. // PKCS #7 Signed Data message with its signer cert verified up to a baked
  306. // in root.
  307. //
  308. // The following mscat32.dll APIs are called to find the system catalog file:
  309. // CryptCATAdminAcquireContext
  310. // CryptCATAdminReleaseContext
  311. // CryptCATAdminEnumCatalogFromHash
  312. // CryptCATAdminReleaseCatalogContext
  313. // CryptCATCatalogInfoFromContext
  314. //
  315. // If the hash was successfully verified, rglErr[] is set to ERROR_SUCCESS.
  316. // Otherwise, rglErr[] is set to a nonzero error code.
  317. //
  318. // The caller can request one or more catalog subject attribute,
  319. // extension or signer authenticated attribute values to be returned for
  320. // each hash. The still encoded values are returned in the
  321. // caller allocated memory. The beginning of this returned memory will
  322. // be set to a 2 dimensional array of attribute value blobs pointing to these
  323. // encoded values (CRYPT_DER_BLOB rgrgAttrValueBlob[cHash][cAttrOID]).
  324. // For performance reasons, the caller should make every attempt to allow
  325. // for a single pass call. The necessary memory size is:
  326. // (cHash * cAttrOID * sizeof(CRYPT_DER_BLOB)) +
  327. // total length of encoded attribute values.
  328. //
  329. // *pcbAttr will be updated with the number of bytes required to contain
  330. // the attribute blobs and values. If the input memory is insufficient,
  331. // ERROR_INSUFFICIENT_BUFFER will be returned if no other error.
  332. //
  333. // For a multi-valued attribute, only the first value is returned.
  334. //
  335. // If the function succeeds, the return value is ERROR_SUCCESS. This may
  336. // be returned for unsuccessful rglErr[] values. Otherwise,
  337. // a nonzero error code is returned.
  338. //--------------------------------------------------------------------------
  339. LONG
  340. WINAPI
  341. MinCryptVerifyHashInSystemCatalogs(
  342. IN ALG_ID HashAlgId,
  343. IN DWORD cHash,
  344. IN CRYPT_HASH_BLOB rgHashBlob[],
  345. OUT LONG rglErr[],
  346. IN OPTIONAL DWORD cAttrOID,
  347. IN OPTIONAL CRYPT_DER_BLOB rgAttrEncodedOIDBlob[],
  348. // CRYPT_DER_BLOB rgrgAttrValueBlob[cHash][cAttrOID] header is at beginning
  349. // with the bytes pointed to immediately following
  350. OUT OPTIONAL CRYPT_DER_BLOB *rgrgAttrValueBlob,
  351. IN OUT OPTIONAL DWORD *pcbAttr
  352. );
  353. #ifdef __cplusplus
  354. } // Balance extern "C" above
  355. #endif
  356. #if defined (_MSC_VER)
  357. #if ( _MSC_VER >= 800 )
  358. #if _MSC_VER >= 1200
  359. #pragma warning(pop)
  360. #else
  361. #pragma warning(default:4201)
  362. #endif
  363. #endif
  364. #endif
  365. #endif // __MINCRYPT_H__