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.

348 lines
13 KiB

  1. /*
  2. ** s m i m e . h
  3. **
  4. ** Purpose: class for cryptographically enhanced mail.
  5. **
  6. ** Owner: t-erikne
  7. ** Created: 8/27/96
  8. **
  9. ** Copyright (C) Microsoft Corp. 1996-1998
  10. */
  11. #ifndef __SMIME_H
  12. #define __SMIME_H
  13. #include <mimeole.h>
  14. #ifndef __WINCRYPT_H__
  15. #include "wincrypt.h"
  16. #endif
  17. #ifdef SMIME_V3
  18. // #include "..\ess\essout.h"
  19. #endif // SMIME_V3
  20. #define szOID_INFOSEC_keyExchangeAlgorithm "2.16.840.1.101.2.1.1.22"
  21. #include "capitype.h"
  22. #include "cryptdbg.h"
  23. // WinCrypt.h helper
  24. #define DOUTL_SMIME CRYPT_LEVEL
  25. class CCAPIStm;
  26. extern CRYPT_ENCODE_PARA CryptEncodeAlloc;
  27. extern CRYPT_DECODE_PARA CryptDecodeAlloc;
  28. #ifdef MAC
  29. /*
  30. ** An array of function pointers, needed because we dynalink to
  31. ** CRYPT32.DLL. Note that not all of the crypto functions come
  32. ** from this DLL. I also use functions from ADVAPI32: the CAPI 1
  33. ** functions. These are not represented in this table and do not
  34. ** need to use GetProcAddress.
  35. ** Typedefs come from capitype.h, local to our project.
  36. */
  37. typedef struct tagCAPIfuncs {
  38. CERTENUMCERTIFICATESINSTORE *EnumCerts;
  39. CERTNAMETOSTRA *CertNameToStr;
  40. } CAPIfuncs, *PCAPIfuncs;
  41. #endif // MAC
  42. /////////////////////////////////////////////////////////////////////////////
  43. //
  44. // Structure definitions
  45. //
  46. typedef enum {
  47. ENCRYPT_ITEM_TRANSPORT = 1,
  48. ENCRYPT_ITEM_AGREEMENT = 2,
  49. ENCRYPT_ITEM_MAILLIST = 3
  50. } ENCRYPT_ITEM_TYPE;
  51. typedef struct tagEncryptItem {
  52. DWORD dwTagType;
  53. union {
  54. struct {
  55. BLOB blobAlg;
  56. DWORD cCert;
  57. PCCERT_CONTEXT * rgpccert;
  58. } Transport;
  59. struct {
  60. BLOB blobAlg;
  61. DWORD cCert;
  62. PCCERT_CONTEXT * rgpccert;
  63. PCCERT_CONTEXT pccertSender;
  64. } Agreement;
  65. struct {
  66. BLOB blobAlg; // AlgId + AuxInfo
  67. BLOB blobKeyId; // Data_Blob KeyID
  68. FILETIME date; // Date
  69. BLOB blobOctet; // Other attribute (oid, any)
  70. #ifdef SMIME_V3
  71. HCRYPTPROV hprov; // hprov
  72. HCRYPTKEY hkey; // hkey
  73. #else // !SMIME_V3
  74. BLOB blobKeyMaterial;
  75. #endif // SMIME_V3
  76. } MailList;
  77. };
  78. } EncryptItem;
  79. typedef struct tagEncryptItems {
  80. DWORD cItems;
  81. EncryptItem * rgItems;
  82. } EncryptItems;
  83. //
  84. // Notes about the [directions]
  85. // [sgn] - signing -- in for sign ops
  86. // [ver] - verification -- out for sign ops
  87. // [enc] - encryption -- in for encrypt ops
  88. // [dec] - decryption -- out for encrypt ops
  89. // [in] = [sgn,enc]
  90. // [out] = [ver,dec]
  91. //
  92. typedef struct {
  93. DWORD ulValidity; // Validity bits for each signature
  94. PCCERT_CONTEXT pccert; // Signer certificate
  95. BLOB blobHashAlg; // Hash algorithm for signer
  96. BLOB blobAuth; // authenticated attributes
  97. BLOB blobUnauth; // unauthenticated attributes
  98. #ifdef SMIME_V3
  99. BLOB blobReceipt; // Receipt to be returned
  100. BLOB blobHash; // Hash of message
  101. #endif // SMIME_V3
  102. } SignerData;
  103. class CSECURITY_LAYER_DATA : public IUnknown
  104. {
  105. friend class CSMime; // Allow CSMime access to our private data
  106. friend class CCAPIStm; // Allow CCAPIStm access to our private data
  107. public:
  108. CSECURITY_LAYER_DATA(void);
  109. ~CSECURITY_LAYER_DATA(void);
  110. // --------------------------------------------------------------------
  111. // IUnknown
  112. // --------------------------------------------------------------------
  113. STDMETHODIMP QueryInterface(REFIID, LPVOID *);
  114. STDMETHODIMP_(ULONG) AddRef(void);
  115. STDMETHODIMP_(ULONG) Release(void);
  116. //private: // private data
  117. DWORD m_cRef;
  118. DWORD m_dwMsgEnhancement; // sign? encrypt?
  119. BOOL m_fCertInLayer; // TRUE if there is a cert included in this layer
  120. // The following elements exist one for each signer on the current layer
  121. DWORD m_cSigners; // Count of signers
  122. SignerData * m_rgSigners; // Signer Data
  123. // The following items exist to encrypt the current layer
  124. DWORD m_cEncryptItems; // Encrypt Item count
  125. #ifdef SMIME_V3
  126. CRYPT_ALGORITHM_IDENTIFIER m_ContentEncryptAlgorithm; // Content AlgId
  127. void * m_pvEncryptAuxInfo; // Aux info
  128. CMSG_RECIPIENT_ENCODE_INFO * m_rgRecipientInfo; // Array of Recpient Infos
  129. CRYPT_DATA_BLOB m_blobUnprotectAttrs; // Unprotected attributes
  130. HCERTSTORE m_hstoreEncrypt; // Encrypt cert store
  131. #else // !SMIME_V3
  132. EncryptItem * m_rgEncryptItems; // count of Encrypt Items
  133. #endif // SMIME_V3
  134. // The following items exists for a decrypted message
  135. DWORD m_ulDecValidity;
  136. BLOB m_blobDecAlg; // Decryption Algorithm
  137. PCCERT_CONTEXT m_pccertDecrypt; // Decryption Certificate
  138. // These are items common to both encryption and signing
  139. HCERTSTORE m_hcertstor; // message cert store
  140. // Cert Bag for signing
  141. // Originator Info for encryption
  142. //
  143. CSECURITY_LAYER_DATA * m_psldInner; // down link
  144. CSECURITY_LAYER_DATA * m_psldOuter; // up link
  145. };
  146. typedef class CSECURITY_LAYER_DATA SECURITY_LAYER_DATA;
  147. typedef SECURITY_LAYER_DATA * PSECURITY_LAYER_DATA;
  148. // -------------------------------------------------------------------
  149. // SMIMEINFO:
  150. // bidirectional communication struct for passing parameter
  151. // info to/from the en/decode functions
  152. //
  153. // dwMsgEnhancement [inout]
  154. // fCertWithMsg [ver]
  155. // ulMsgValidity [out]
  156. // ietRequested [in]
  157. // -------------------------------------------------------------------
  158. struct SMIMEINFOtag { // si
  159. DWORD dwMsgEnhancement;
  160. PSECURITY_LAYER_DATA psldLayers; // outermost layer
  161. PSECURITY_LAYER_DATA psldEncrypt; // encryption layer
  162. PSECURITY_LAYER_DATA psldInner; // innermost layer
  163. ULONG cStores; // size of rgStores
  164. HCERTSTORE * rgStores; // array of cert stores
  165. BOOL fCertWithMsg;
  166. ULONG ulMsgValidity;
  167. ENCODINGTYPE ietRequested;
  168. HCRYPTPROV hProv;
  169. #ifdef SMIME_V3
  170. LPSTR pszInnerContent; // Inner content (NULL ->> id-data)
  171. DWORD cbInnerContent; // Inner content size if != id-data
  172. LPWSTR pwszKeyPrompt; // Key password prompt
  173. #endif // SMIME_V3
  174. };
  175. typedef struct SMIMEINFOtag SMIMEINFO;
  176. typedef SMIMEINFO *PSMIMEINFO;
  177. typedef const SMIMEINFO *PCSMIMEINFO;
  178. /////////////////////////////////////////////////////////////////////////////
  179. //
  180. // Class begins
  181. //
  182. class CSMime :
  183. public IMimeSecurity
  184. {
  185. public:
  186. //
  187. // ctor and dtor
  188. //
  189. CSMime(void);
  190. ~CSMime();
  191. //
  192. // IUnknown methods
  193. //
  194. STDMETHODIMP QueryInterface(REFIID, LPVOID *);
  195. STDMETHODIMP_(ULONG) AddRef(void);
  196. STDMETHODIMP_(ULONG) Release(void);
  197. //
  198. // IMimeSecurity methods
  199. //
  200. STDMETHODIMP InitNew();
  201. STDMETHODIMP CheckInit();
  202. STDMETHODIMP EncodeMessage(IMimeMessageTree *const pTree, DWORD dwFlags);
  203. STDMETHODIMP DecodeMessage(IMimeMessageTree *const pTree, DWORD dwFlags);
  204. STDMETHODIMP EncodeBody(IMimeMessageTree *const pTree, HBODY hEncodeRoot, DWORD dwFlags);
  205. STDMETHODIMP DecodeBody(IMimeMessageTree *const pTree, HBODY hDecodeRoot, DWORD dwFlags);
  206. STDMETHODIMP EnumCertificates(HCAPICERTSTORE hc, DWORD dwUsage, PCX509CERT pPrev, PCX509CERT *pCert);
  207. STDMETHODIMP GetCertificateName(const PCX509CERT pX509Cert, const CERTNAMETYPE cn, LPSTR *ppszName);
  208. STDMETHODIMP GetMessageType(const HWND hwndParent, IMimeBody *const pBody, DWORD *const pdwSecType);
  209. STDMETHODIMP GetCertData(const PCX509CERT pX509Cert, const CERTDATAID dataid, LPPROPVARIANT pValue);
  210. // Other methods
  211. HRESULT EncodeMessage2(IMimeMessageTree * const pTree, DWORD dwFlags,
  212. HWND hwnd);
  213. HRESULT DecodeMessage2(IMimeMessageTree * const pTree, DWORD dwFlags,
  214. HWND hwnd, IMimeSecurityCallback * pCallback);
  215. HRESULT EncodeBody2(IMimeMessageTree *const pTree, HBODY hEncodeRoot,
  216. DWORD dwFlags, HWND hwnd);
  217. HRESULT DecodeBody2(IMimeMessageTree *const pTree, HBODY hDecodeRoot,
  218. DWORD dwFlags, SMIMEINFO * psiOuterOp, HWND hwnd,
  219. IMimeSecurityCallback * pCallback);
  220. //
  221. // Implementation methods
  222. //
  223. static void UnloadAll(void);
  224. static HRESULT HrGetCertsFromThumbprints(THUMBBLOB *const rgThumbprint, X509CERTRESULT *const pResults);
  225. static HRESULT StaticGetMessageType(HWND hwndParent, IMimeBody *const pBody, DWORD *const pdwSecType);
  226. protected:
  227. static HRESULT StaticCheckInit();
  228. struct CERTARRAY {
  229. DWORD cCerts;
  230. PCCERT_CONTEXT *rgpCerts;
  231. };
  232. typedef CERTARRAY *PCERTARRAY;
  233. typedef const CERTARRAY *PCCERTARRAY;
  234. HRESULT DecodeBody (IMimeMessageTree *const pTree, HBODY hDecodeRoot, DWORD dwFlags, SMIMEINFO * psiOuterOp);
  235. HRESULT HrEncodeOpaque (SMIMEINFO *const psi, IMimeMessageTree *pTree, HBODY hEncodeRoot, IMimeBody *pEncodeRoot, LPSTREAM lpstmOut, HWND hwnd);
  236. HRESULT HrDecodeOpaque (DWORD dwFlags, SMIMEINFO *const psi, IMimeBody *const pBody, IStream *const pstmOut, HWND hwnd, IMimeSecurityCallback * pCallback);
  237. HRESULT HrEncodeClearSigned (SMIMEINFO *const psi, IMimeMessageTree *const pTree, const HBODY hEncodeRoot, IMimeBody *const pEncodeRoot, LPSTREAM lpstmOut, BOOL fCommit, HWND hwnd);
  238. HRESULT HrDecodeClearSigned (DWORD dwFlags, SMIMEINFO *const psi, IMimeMessageTree *const pTree, const HBODY hData, const HBODY hSig, HWND hwnd, IMimeSecurityCallback * pCallback);
  239. static BOOL FSign(const DWORD dwAction)
  240. { return BOOL(dwAction & MST_SIGN_MASK); }
  241. static BOOL FClearSign(const DWORD dwAction)
  242. { return (FSign(dwAction) && !(dwAction & MST_BLOB_FLAG)); }
  243. static BOOL FEncrypt(const DWORD dwAction)
  244. { return BOOL(dwAction & MST_ENCRYPT_MASK); }
  245. static HRESULT HrGetNeededAddresses(const DWORD dwTypes, IMimeMessageTree *pTree, IMimeAddressTable **ppAdrTable, IMimeEnumAddressTypes **ppEnum);
  246. static HRESULT HrGetCertificates(IMimeAddressTable *const pAdrTable, IMimeEnumAddressTypes *pEnum, const DWORD dwType, const BOOL fAlreadyHaveSendersCert, CERTARRAY *rgCerts);
  247. static HRESULT HrGetThumbprints(IMimeEnumAddressTypes *pEnum, const ITHUMBPRINTTYPE ittType, THUMBBLOB *const rgThumbprint);
  248. static HRESULT HrGenerateCertsStatus(X509CERTRESULT *pResults, IMimeAddressTable *const pAdrTable, IMimeEnumAddressTypes *const pEnum, const BOOL fIgnoreSenderError);
  249. HRESULT HrFindUsableCert(HCERTSTORE hCertStore, BYTE dwKeySpec, PCCERT_CONTEXT pPrevCert, PCCERT_CONTEXT *ppCert);
  250. static HRESULT OptionsToSMIMEINFO(BOOL fEncode, IMimeMessageTree *const pmm, IMimeBody *pBody, SMIMEINFO *psi);
  251. static HRESULT SMIMEINFOToOptions(IMimeMessageTree *const pTree, const SMIMEINFO *psi, HBODY hBody);
  252. static HRESULT MergeSMIMEINFO( SMIMEINFO * psiOut, SMIMEINFO * psiInner);
  253. static void FreeSMIMEINFO(SMIMEINFO *psi);
  254. #ifdef DEBUG
  255. void DumpAlgorithms();
  256. #endif
  257. private:
  258. static HRESULT HrInitCAPI();
  259. static void UnloadCAPI();
  260. static HRESULT CAPISTMtoSMIMEINFO(CCAPIStm *pcapistm, SMIMEINFO *psi);
  261. static void MergeSMIMEINFOs(const SMIMEINFO *const psiOuter, SMIMEINFO *const psiInner);
  262. UINT m_cRef;
  263. CRITICAL_SECTION m_cs;
  264. #ifdef MAC
  265. static CAPIfuncs ms_CAPI;
  266. static LPCSTR ms_rgszFuncNames[];
  267. #endif // MAC
  268. };
  269. inline BOOL IsOpaqueSecureContentType(IMimePropertySet *pSet)
  270. {
  271. return (
  272. S_OK == pSet->IsContentType(STR_CNT_APPLICATION, STR_SUB_XPKCS7MIME) ||
  273. S_OK == pSet->IsContentType(STR_CNT_APPLICATION, STR_SUB_PKCS7MIME));
  274. }
  275. inline BOOL IsSecureContentType(IMimePropertySet *pSet)
  276. {
  277. return (
  278. S_OK == pSet->IsContentType(STR_CNT_MULTIPART, STR_SUB_SIGNED) ||
  279. IsOpaqueSecureContentType(pSet));
  280. }
  281. BOOL IsSMimeProtocol(LPMIMEPROPERTYSET lpPropSet);
  282. #ifdef SMIME_V3
  283. void FreeRecipientInfoContent(PCMS_RECIPIENT_INFO pRecipInfo);
  284. HRESULT HrCopyOID(LPCSTR psz, LPSTR * ppsz);
  285. HRESULT HrCopyCryptDataBlob(const CRYPT_DATA_BLOB * pblobSrc, PCRYPT_DATA_BLOB pblobDst);
  286. HRESULT HrCopyCryptBitBlob(const CRYPT_BIT_BLOB * pblobSrc, PCRYPT_BIT_BLOB pblobDst);
  287. HRESULT HrCopyCryptAlgorithm(const CRYPT_ALGORITHM_IDENTIFIER * pAlgSrc,
  288. PCRYPT_ALGORITHM_IDENTIFIER pAlgDst);
  289. HRESULT HrCopyCertId(const CERT_ID * pcertidSrc, PCERT_ID pcertidDst);
  290. #endif // SMIME_V3
  291. #endif // _SMIME_H