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.

1108 lines
39 KiB

  1. #include "item.h"
  2. #define MAX_LAYERS 30
  3. extern HINSTANCE hInst;
  4. extern const BYTE RgbSHA1AlgId[] =
  5. {0x30, 0x09, 0x30, 0x07, 0x06, 0x05, 0x2B, 0x0E,
  6. 0x03, 0x02, 0x1A};
  7. extern const int CbSHA1AlgId = sizeof(RgbSHA1AlgId);
  8. byte RgbEntityId1[] = {0x1, 0x4, 0x7, 0x8, 0x10};
  9. byte RgbEntityId2[] = {0x1, 0x4, 0x7, 0x10, 0x8};
  10. const char SzPolicyRoot[] = "Software\\Microsoft\\Cryptography\\OID\\EncodingType 1\\SMimeSecurityLabel";
  11. //const char SzPolicyRoot[] = "Software\\Microsoft\\Cryptography\\SMIME\\SecurityPolicies";
  12. class CSecurityPolicy {
  13. public:
  14. DWORD dwFlags;
  15. char * szDllName;
  16. char * szPolicyOID;
  17. char * szFuncName;
  18. HMODULE hmod;
  19. PFNGetSMimePolicy pfnFuncName;
  20. ISMimePolicySimpleEdit * ppolicy;
  21. CSecurityPolicy() {
  22. szDllName = szPolicyOID = szFuncName = NULL;
  23. hmod = 0;
  24. pfnFuncName = NULL;
  25. ppolicy = NULL;
  26. dwFlags = 0;
  27. }
  28. ~CSecurityPolicy() {
  29. free(szDllName);
  30. free(szPolicyOID);
  31. free(szFuncName);
  32. if (ppolicy != NULL) ppolicy->Release();
  33. FreeLibrary(hmod);
  34. }
  35. };
  36. ////////////////////////////////////////////////////////////////////////////
  37. BOOL CALLBACK MLDataCreateDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
  38. {
  39. DWORD cb;
  40. DWORD cb2;
  41. BOOL f;
  42. SMIME_ML_EXPANSION_HISTORY mlHistory;
  43. LPBYTE pb;
  44. PSMIME_ML_EXPANSION_HISTORY pMLHistory;
  45. static PCCERT_CONTEXT pccert1 = NULL;
  46. static PCCERT_CONTEXT pccert2 = NULL;
  47. static CSignData * psd = NULL;
  48. char rgch[256];
  49. SMIME_MLDATA rgMLData[5];
  50. switch (msg) {
  51. case WM_INITDIALOG:
  52. pccert1 = NULL;
  53. pccert2 = NULL;
  54. psd = (CSignData *) lParam;
  55. #if 0
  56. psd->GetMLHistory(&pb, &cb);
  57. if (cb > 0) {
  58. f = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_MLExpansion_History,
  59. pb, cb, CRYPT_ENCODE_ALLOC_FLAG, NULL,
  60. &pMLHistory, &cb2);
  61. }
  62. #endif // 0
  63. break;
  64. case WM_COMMAND:
  65. switch (wParam) {
  66. case MAKELONG(IDC_MLC_SELECT1, BN_CLICKED):
  67. if (DoCertDialog(hdlg, "Choose ML Data Certificate",
  68. psd->GetMyStore(), &pccert1,
  69. FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
  70. GetFriendlyNameOfCertA(pccert1, rgch, sizeof(rgch));
  71. SetDlgItemText(hdlg, IDC_MLC_CERT1, rgch);
  72. }
  73. break;
  74. case MAKELONG(IDC_MLC_SELECT2, BN_CLICKED):
  75. if (DoCertDialog(hdlg, "Choose ML Data Certificate",
  76. psd->GetMyStore(), &pccert2,
  77. FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
  78. GetFriendlyNameOfCertA(pccert2, rgch, sizeof(rgch));
  79. SetDlgItemText(hdlg, IDC_MLC_CERT2, rgch);
  80. }
  81. break;
  82. case MAKELONG(IDC_MLC_ABSENT1, BN_CLICKED):
  83. case MAKELONG(IDC_MLC_NONE1, BN_CLICKED):
  84. EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES1), FALSE);
  85. break;
  86. case MAKELONG(IDC_MLC_INSTEAD1, BN_CLICKED):
  87. case MAKELONG(IDC_MLC_ALSO1, BN_CLICKED):
  88. EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES1), TRUE);
  89. break;
  90. case MAKELONG(IDC_MLC_ABSENT2, BN_CLICKED):
  91. case MAKELONG(IDC_MLC_NONE2, BN_CLICKED):
  92. EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES2), FALSE);
  93. break;
  94. case MAKELONG(IDC_MLC_INSTEAD2, BN_CLICKED):
  95. case MAKELONG(IDC_MLC_ALSO2, BN_CLICKED):
  96. EnableWindow(GetDlgItem(hdlg, IDC_MLC_NAMES2), TRUE);
  97. break;
  98. case IDOK:
  99. memset(&mlHistory, 0, sizeof(mlHistory));
  100. memset(rgMLData, 0, sizeof(rgMLData));
  101. mlHistory.cMLData = 0;
  102. mlHistory.rgMLData = rgMLData;
  103. mlHistory.cMLData = 1;
  104. if (pccert1 == NULL) {
  105. break;
  106. }
  107. if (SendDlgItemMessage(hdlg, IDC_MLC_ID1, BM_GETCHECK, 0, 0)) {
  108. rgMLData[0].dwChoice = SMIME_MLDATA_SUBJECT_KEY_IDENTIFIER;
  109. rgMLData[0].SubjectKeyIdentifier.cbData = sizeof(RgbEntityId1);
  110. rgMLData[0].SubjectKeyIdentifier.pbData = RgbEntityId1;
  111. }
  112. else {
  113. rgMLData[0].dwChoice = SMIME_MLDATA_ISSUER_SERIAL_NUMBER;
  114. rgMLData[0].u.SerialNumber = pccert1->pCertInfo->SerialNumber;
  115. rgMLData[0].u.Issuer = pccert1->pCertInfo->Issuer;
  116. }
  117. GetSystemTimeAsFileTime(&rgMLData[0].ExpansionTime);
  118. if (SendDlgItemMessage(hdlg, IDC_MLC_ABSENT1, BM_GETCHECK, 0, 0)) {
  119. rgMLData[0].dwPolicy = SMIME_MLPOLICY_NO_CHANGE;
  120. }
  121. else if (SendDlgItemMessage(hdlg, IDC_MLC_NONE1, BM_GETCHECK, 0, 0)) {
  122. rgMLData[0].dwPolicy = SMIME_MLPOLICY_NONE;
  123. }
  124. else if (SendDlgItemMessage(hdlg, IDC_MLC_INSTEAD1, BM_GETCHECK, 0, 0)) {
  125. rgMLData[0].dwPolicy = SMIME_MLPOLICY_INSTEAD_OF;
  126. if (!ParseNames(&rgMLData[0].cNames, &rgMLData[0].rgNames,
  127. hdlg, IDC_MLC_NAMES1)) {
  128. return FALSE;
  129. }
  130. }
  131. else {
  132. rgMLData[0].dwPolicy = SMIME_MLPOLICY_IN_ADDITION_TO;
  133. if (!ParseNames(&rgMLData[0].cNames, &rgMLData[0].rgNames,
  134. hdlg, IDC_MLC_NAMES1)) {
  135. return FALSE;
  136. }
  137. }
  138. if (SendDlgItemMessage(hdlg, IDC_MLC_INCLUDE2, BM_GETCHECK, 0, 0)) {
  139. mlHistory.cMLData = 2;
  140. if (pccert2 == NULL) {
  141. break;
  142. }
  143. if (SendDlgItemMessage(hdlg, IDC_MLC_ID2, BM_GETCHECK, 0, 0)) {
  144. rgMLData[1].dwChoice = SMIME_MLDATA_SUBJECT_KEY_IDENTIFIER;
  145. rgMLData[1].SubjectKeyIdentifier.cbData = sizeof(RgbEntityId2);
  146. rgMLData[1].SubjectKeyIdentifier.pbData = RgbEntityId2;
  147. }
  148. else {
  149. rgMLData[1].dwChoice = SMIME_MLDATA_ISSUER_SERIAL_NUMBER;
  150. rgMLData[1].u.SerialNumber = pccert2->pCertInfo->SerialNumber;
  151. rgMLData[1].u.Issuer = pccert2->pCertInfo->Issuer;
  152. }
  153. GetSystemTimeAsFileTime(&rgMLData[1].ExpansionTime);
  154. if (SendDlgItemMessage(hdlg, IDC_MLC_ABSENT2, BM_GETCHECK, 0, 0)) {
  155. rgMLData[1].dwPolicy = SMIME_MLPOLICY_NO_CHANGE;
  156. }
  157. else if (SendDlgItemMessage(hdlg, IDC_MLC_NONE2, BM_GETCHECK, 0, 0)) {
  158. rgMLData[1].dwPolicy = SMIME_MLPOLICY_NONE;
  159. }
  160. else if (SendDlgItemMessage(hdlg, IDC_MLC_INSTEAD2, BM_GETCHECK, 0, 0)) {
  161. rgMLData[1].dwPolicy = SMIME_MLPOLICY_INSTEAD_OF;
  162. if (!ParseNames(&rgMLData[1].cNames, &rgMLData[1].rgNames,
  163. hdlg, IDC_MLC_NAMES2)) {
  164. return FALSE;
  165. }
  166. }
  167. else {
  168. rgMLData[1].dwPolicy = SMIME_MLPOLICY_IN_ADDITION_TO;
  169. if (!ParseNames(&rgMLData[1].cNames, &rgMLData[1].rgNames,
  170. hdlg, IDC_MLC_NAMES2)) {
  171. return FALSE;
  172. }
  173. }
  174. }
  175. f = CryptEncodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_MLExpansion_History,
  176. &mlHistory, CRYPT_ENCODE_ALLOC_FLAG, NULL,
  177. &pb, &cb);
  178. if (!f) return FALSE;
  179. psd->SetMLHistory(pb, cb);
  180. case IDCANCEL:
  181. CertFreeCertificateContext(pccert1);
  182. CertFreeCertificateContext(pccert2);
  183. EndDialog(hdlg, wParam);
  184. break;
  185. default:
  186. return FALSE;
  187. }
  188. break;
  189. default:
  190. return FALSE;
  191. }
  192. return TRUE;
  193. }
  194. ////////////////////////////////////////////////////////////////////////////
  195. void InitPolicies(HWND hdlg, DWORD idc1, DWORD idc2, DWORD idc3, DWORD idc4)
  196. {
  197. DWORD cbData;
  198. DWORD cbMaxData;
  199. DWORD cval;
  200. DWORD dw;
  201. FILETIME ft;
  202. HKEY hkey;
  203. HKEY hkey2;
  204. DWORD i;
  205. DWORD i1;
  206. DWORD iSel;
  207. CSecurityPolicy * p;
  208. char * pbData = NULL;
  209. char rgch[256];
  210. if (RegOpenKey(HKEY_LOCAL_MACHINE, SzPolicyRoot, &hkey)) {
  211. return;
  212. }
  213. for (i=0; TRUE; i++) {
  214. cbData =sizeof(rgch);
  215. dw = RegEnumKeyEx(hkey, i, rgch, &cbData, NULL, NULL, NULL, &ft);
  216. if (dw != ERROR_SUCCESS) {
  217. break;
  218. }
  219. dw = RegOpenKey(hkey, rgch, &hkey2);
  220. dw = RegQueryInfoKey(hkey2, NULL, NULL, NULL, NULL, NULL, NULL, &cval,
  221. NULL, &cbMaxData, NULL, NULL);
  222. pbData = (LPSTR) malloc(cbMaxData);
  223. p = new CSecurityPolicy;
  224. p->szPolicyOID = _strdup(rgch);
  225. cbData = cbMaxData;
  226. dw = RegQueryValueEx(hkey2, "DllPath", NULL, &dw, (LPBYTE) pbData, &cbData);
  227. p->szDllName = _strdup(pbData);
  228. dw = RegQueryValueEx(hkey2, "FuncName", NULL, &dw, (LPBYTE) pbData, &cbData);
  229. if (*pbData != 0) {
  230. p->szFuncName = _strdup(pbData);
  231. }
  232. cbData = cbMaxData;
  233. dw = RegQueryValueEx(hkey2, "CommonName", NULL, &dw, (LPBYTE) pbData, &cbData);
  234. iSel = SendDlgItemMessage(hdlg, idc1, CB_ADDSTRING, 0, (LPARAM) pbData);
  235. Assert(iSel != CB_ERR);
  236. if (iSel == CB_ERR) {
  237. continue;
  238. }
  239. SendDlgItemMessage(hdlg, idc1, CB_SETITEMDATA, iSel, (LPARAM) p);
  240. free(pbData); pbData = NULL;
  241. RegCloseKey(hkey2); hkey2 = NULL;
  242. }
  243. //exit:
  244. if (pbData != NULL) free(pbData);
  245. if (hkey != NULL) RegCloseKey(hkey);
  246. if (hkey2 != NULL) RegCloseKey(hkey2);
  247. }
  248. void PolicyFillClassifications(HWND hwnd, DWORD idc1, DWORD idc2, DWORD idc3,
  249. DWORD dw)
  250. {
  251. DWORD cb;
  252. DWORD cbEncode;
  253. DWORD cbMax;
  254. DWORD cClassifications = 0;
  255. DWORD cval;
  256. DWORD dwValue;
  257. DWORD dwDefaultClassification;
  258. HRESULT hr;
  259. DWORD i;
  260. int iSel;
  261. DWORD iSetSel;
  262. CSecurityPolicy * p;
  263. LPBYTE pbEncode;
  264. DWORD * pdwClassifications = NULL;
  265. LPWSTR * pwszClassifications = NULL;
  266. WCHAR rgwch[256];
  267. iSel = SendDlgItemMessage(hwnd, IDC_SD_POLICY, CB_GETCURSEL, 0, 0);
  268. p = (CSecurityPolicy *) SendDlgItemMessage(hwnd, idc1, CB_GETITEMDATA,
  269. iSel, 0);
  270. if (((int) p) == CB_ERR) {
  271. return;
  272. }
  273. if (p->hmod == NULL) {
  274. p->hmod = LoadLibrary(p->szDllName);
  275. if (p->hmod == NULL) {
  276. return;
  277. }
  278. }
  279. if (p->pfnFuncName == NULL) {
  280. p->pfnFuncName = (PFNGetSMimePolicy) GetProcAddress(p->hmod, p->szFuncName);
  281. if (p->pfnFuncName == NULL) {
  282. return;
  283. }
  284. }
  285. if (p->ppolicy == NULL) {
  286. p->pfnFuncName(0, p->szPolicyOID, 1252, IID_ISMimePolicySimpleEdit,
  287. (LPUNKNOWN *) &p->ppolicy);
  288. }
  289. p->ppolicy->GetPolicyInfo(0, &p->dwFlags);
  290. // get the classification information.
  291. hr = p->ppolicy->GetClassifications(0, &cClassifications, &pwszClassifications,
  292. &pdwClassifications,
  293. &dwDefaultClassification);
  294. if (FAILED(hr)) {
  295. goto Error;
  296. }
  297. SendDlgItemMessage(hwnd, idc2, CB_RESETCONTENT, 0, 0);
  298. for (i=0, iSetSel = 0; i<cClassifications; i++) {
  299. iSel = SendDlgItemMessageW(hwnd, idc2, CB_ADDSTRING, 0, (LPARAM) pwszClassifications[i]);
  300. SendDlgItemMessage(hwnd, idc2, CB_SETITEMDATA, iSel, pdwClassifications[i]);
  301. if (dwDefaultClassification == pdwClassifications[i]) {
  302. iSetSel = i;
  303. }
  304. }
  305. SendDlgItemMessage(hwnd, idc2, CB_SETCURSEL, iSetSel, 0);
  306. EnableWindow(GetDlgItem(hwnd, idc3), !!(p->dwFlags & SMIME_POLICY_EDIT_UI));
  307. Error:
  308. return;
  309. }
  310. BOOL CALLBACK SignInfoDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
  311. {
  312. static CSignInfo * psi = NULL;
  313. switch (msg) {
  314. case UM_SET_DATA:
  315. psi = (CSignInfo *) lParam;
  316. SendDlgItemMessage(hdlg, IDC_SI_BLOB_SIGN, BM_SETCHECK,
  317. ((psi != NULL) && (psi->m_fBlob)), 0);
  318. break;
  319. case WM_COMMAND:
  320. switch (wParam) {
  321. case MAKELONG(IDC_SI_BLOB_SIGN, BN_CLICKED):
  322. psi->m_fBlob = SendDlgItemMessage(hdlg, IDC_SI_BLOB_SIGN,
  323. BM_GETCHECK, 0, 0);
  324. return FALSE;
  325. default:
  326. return FALSE;
  327. }
  328. break;
  329. default:
  330. return FALSE;
  331. }
  332. return TRUE;
  333. }
  334. BOOL CALLBACK SignDataDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
  335. {
  336. DWORD c;
  337. DWORD cb;
  338. DWORD cbEncode;
  339. DWORD cch;
  340. DWORD dw;
  341. BOOL f;
  342. DWORD i;
  343. CSecurityPolicy * p;
  344. LPBYTE pb;
  345. LPBYTE pbEncode;
  346. SMIME_SECURITY_LABEL * plabel;
  347. static CSignData * psd = NULL;
  348. LPWSTR psz;
  349. CHAR rgch[300];
  350. switch (msg) {
  351. case WM_INITDIALOG:
  352. InitPolicies(hdlg, IDC_SD_POLICY, IDC_SD_CLASSIFICATION,
  353. IDC_SD_PRIVACY_MARK, IDC_SD_ADVANCED);
  354. SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_SETCURSEL, 0, 0);
  355. PolicyFillClassifications(hdlg, IDC_SD_POLICY, IDC_SD_CLASSIFICATION,
  356. IDC_SD_ADVANCED, 0);
  357. break;
  358. case UM_SET_DATA:
  359. // Need to extract and build a security label
  360. if (psd != NULL) {
  361. if (SendDlgItemMessage(hdlg, IDC_SD_LABEL, BM_GETCHECK, 0, 0)) {
  362. DWORD dw;
  363. DWORD iSel;
  364. SMIME_SECURITY_LABEL label = {0};
  365. CSecurityPolicy * p;
  366. WCHAR rgwch[255];
  367. iSel = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCURSEL, 0, 0);
  368. p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
  369. CB_GETITEMDATA, iSel, 0);
  370. iSel = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETCURSEL,
  371. 0, 0);
  372. dw = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETITEMDATA,
  373. iSel, 0);
  374. rgwch[0] = 0;
  375. GetDlgItemTextW(hdlg, IDC_SD_PRIVACY_MARK, rgwch, sizeof(rgwch)/2);
  376. label.pszObjIdSecurityPolicy = p->szPolicyOID;
  377. if (dw == -1) {
  378. label.fHasClassification = FALSE;
  379. }
  380. else {
  381. label.fHasClassification = TRUE;
  382. label.dwClassification = dw;
  383. }
  384. if (rgwch[0] != 0) {
  385. label.wszPrivacyMark = rgwch;
  386. }
  387. else {
  388. label.wszPrivacyMark = NULL;
  389. }
  390. label.cCategories = 0;
  391. f = CryptEncodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_Security_Label,
  392. &label, CRYPT_ENCODE_ALLOC_FLAG, NULL,
  393. &pbEncode, &cbEncode);
  394. Assert(f);
  395. psd->SetLabel(pbEncode, cbEncode);
  396. LocalFree(pbEncode);
  397. }
  398. }
  399. // Fill in the dialog
  400. psd = (CSignData *) lParam;
  401. if ((psd != NULL) && (psd->m_pccert != NULL)) {
  402. GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
  403. SetDlgItemText(hdlg, IDC_SD_CERT_NAME, rgch);
  404. }
  405. else {
  406. SetDlgItemText(hdlg, IDC_SD_CERT_NAME, "");
  407. }
  408. SendDlgItemMessage(hdlg, IDC_SD_RECEIPT, BM_SETCHECK,
  409. ((psd != NULL) && (psd->m_fReceipt)), 0);
  410. SendDlgItemMessage(hdlg, IDC_SD_USE_SKI, BM_SETCHECK,
  411. ((psd != NULL) && (psd->m_fUseSKI)), 0);
  412. SendDlgItemMessage(hdlg, IDC_SD_MLDATA, BM_SETCHECK,
  413. ((psd != NULL) && (psd->m_fMLHistory)), 0);
  414. SendDlgItemMessage(hdlg, IDC_SD_AUTHATTRIB, BM_SETCHECK,
  415. ((psd != NULL) && (psd->m_fAuthAttrib)), 0);
  416. SendDlgItemMessage(hdlg, IDC_SD_UNAUTHATTRIB, BM_SETCHECK,
  417. ((psd != NULL) && (psd->m_fUnAuthAttrib)), 0);
  418. if (psd != NULL) {
  419. psd->GetLabel(&pbEncode, &cbEncode);
  420. SendDlgItemMessage(hdlg, IDC_SD_LABEL, BM_SETCHECK, (cbEncode > 0), 0);
  421. c = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCOUNT, 0, 0);
  422. if (cbEncode > 0) {
  423. f = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_Security_Label,
  424. pbEncode, cbEncode, CRYPT_ENCODE_ALLOC_FLAG,
  425. NULL, &plabel, &cb);
  426. Assert(f);
  427. for (i=0; i<c; i++) {
  428. p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
  429. CB_GETITEMDATA, i, 0);
  430. if (strcmp(p->szPolicyOID, plabel->pszObjIdSecurityPolicy) == 0) {
  431. break;
  432. }
  433. }
  434. Assert(i<c);
  435. if (i<c) {
  436. SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_SETCURSEL, i, 0);
  437. PolicyFillClassifications(hdlg, IDC_SD_POLICY,
  438. IDC_SD_CLASSIFICATION,
  439. IDC_SD_ADVANCED,
  440. plabel->dwClassification);
  441. }
  442. LocalFree(plabel);
  443. }
  444. else {
  445. }
  446. }
  447. break;
  448. case WM_COMMAND:
  449. switch (wParam) {
  450. case IDC_SD_CERT_CHOOSE:
  451. if (DoCertDialog(hdlg, "Choose Signing Certificate", psd->GetMyStore(),
  452. &psd->m_pccert, FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
  453. GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
  454. SetDlgItemText(hdlg, IDC_SD_CERT_NAME, rgch);
  455. }
  456. break;
  457. case MAKELONG(IDC_SD_RECEIPT, BN_CLICKED):
  458. psd->m_fReceipt = SendDlgItemMessage(hdlg, IDC_SD_RECEIPT, BM_GETCHECK,
  459. 0, 0);
  460. return FALSE;
  461. case MAKELONG(IDC_SD_USE_SKI, BN_CLICKED):
  462. psd->m_fUseSKI = SendDlgItemMessage(hdlg, IDC_SD_USE_SKI, BM_GETCHECK,
  463. 0, 0);
  464. return FALSE;
  465. case IDC_SD_DO_RECEIPT:
  466. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_RECEIPT_CREATE), hdlg,
  467. ReceiptCreateDlgProc, (LPARAM) psd);
  468. break;
  469. case IDC_SD_ADVANCED:
  470. // Query the list to get the policy module descriptor
  471. i = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCURSEL, 0, 0);
  472. p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
  473. CB_GETITEMDATA, i, 0);
  474. // Query the classification within the policy module
  475. i = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETCURSEL,
  476. 0, 0);
  477. dw = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETITEMDATA,
  478. i, 0);
  479. // Query back the privacy mark within the policy mark.
  480. cch = SendDlgItemMessage(hdlg, IDC_SD_PRIVACY_MARK, WM_GETTEXTLENGTH, 0, 0);
  481. if (cch > 0) {
  482. psz = (LPWSTR) LocalAlloc(0, cch);
  483. *psz = 0;
  484. SendDlgItemMessageW(hdlg, IDC_SD_PRIVACY_MARK, WM_GETTEXT, cch, (LPARAM) psz);
  485. }
  486. else {
  487. psz = NULL;
  488. }
  489. // If we already have a security label on this object, grab it.
  490. psd->GetLabel(&pb, &cb);
  491. if (cb > 0) {
  492. pbEncode = (LPBYTE) LocalAlloc(0, cb);
  493. memcpy(pbEncode, pb, cb);
  494. }
  495. else {
  496. pbEncode = NULL;
  497. }
  498. #if 0
  499. // Now call the advanced UI to see what it wants to do. It will return an
  500. // new receipt and we go from there
  501. if (p->ppolicy->EditUI(hdlg, &dw, &psz, &pbEncode, &cb) == S_OK) {
  502. // Put the label back on our object.
  503. psd->SetLabel(pbEncode, cb);
  504. // Put back the classification
  505. c = SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_GETCOUNT, 0, 0);
  506. for (i=0; i<c; i++) {
  507. if (dw == (DWORD) SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION,
  508. CB_GETITEMDATA, i, 0)) {
  509. SendDlgItemMessage(hdlg, IDC_SD_CLASSIFICATION, CB_SETCURSEL, i, 0);
  510. break;
  511. }
  512. }
  513. // Put back the privacy mark
  514. if (psz != NULL) {
  515. SetDlgItemTextW(hdlg, IDC_SD_PRIVACY_MARK, psz);
  516. LocalFree(psz);
  517. }
  518. else {
  519. SetDlgItemTextW(hdlg, IDC_SD_PRIVACY_MARK, L"");
  520. }
  521. }
  522. #endif // 0
  523. // Free the label as encoded, we have already saved it.
  524. if (pbEncode != NULL) {
  525. LocalFree(pbEncode);
  526. }
  527. break;
  528. case MAKELONG(IDC_SD_MLDATA, BN_CLICKED):
  529. psd->m_fMLHistory = SendDlgItemMessage(hdlg, IDC_SD_MLDATA, BM_GETCHECK,
  530. 0, 0);
  531. break;
  532. case IDC_SD_DO_MLDATA:
  533. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MLDATA_CREATE), hdlg,
  534. MLDataCreateDlgProc, (LPARAM) psd);
  535. break;
  536. case MAKELONG(IDC_SD_AUTHATTRIB, BN_CLICKED):
  537. psd->m_fAuthAttrib = SendDlgItemMessage(hdlg, IDC_SD_AUTHATTRIB, BM_GETCHECK,
  538. 0, 0);
  539. break;
  540. case IDC_SD_DO_AUTHATTRIB:
  541. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ATTRIB_CREATE), hdlg,
  542. AuthAttribCreateDlgProc, (LPARAM) psd);
  543. break;
  544. case MAKELONG(IDC_SD_UNAUTHATTRIB, BN_CLICKED):
  545. psd->m_fUnAuthAttrib = SendDlgItemMessage(hdlg, IDC_SD_UNAUTHATTRIB, BM_GETCHECK,
  546. 0, 0);
  547. break;
  548. case IDC_SD_DO_UNAUTHATTRIB:
  549. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ATTRIB_CREATE), hdlg,
  550. UnAuthAttribCreateDlgProc, (LPARAM) psd);
  551. break;
  552. default:
  553. return FALSE;
  554. }
  555. break;
  556. case WM_DESTROY:
  557. c = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCOUNT, 0, 0);
  558. for (i=0; i <c; i++) {
  559. p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
  560. CB_GETITEMDATA, i, 0);
  561. delete p;
  562. }
  563. break;
  564. default:
  565. return FALSE;
  566. }
  567. return TRUE;
  568. }
  569. BOOL CALLBACK SignDataReadDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
  570. {
  571. DWORD c;
  572. DWORD cb;
  573. DWORD cbEncode;
  574. BOOL f;
  575. DWORD i;
  576. CSecurityPolicy * p;
  577. LPBYTE pbEncode;
  578. SMIME_SECURITY_LABEL * plabel;
  579. static CSignData * psd = NULL;
  580. CHAR rgch[300];
  581. switch (msg) {
  582. case WM_INITDIALOG:
  583. break;
  584. case UM_SET_DATA:
  585. // Fill in the dialog
  586. psd = (CSignData *) lParam;
  587. if ((psd != NULL) && (psd->m_pccert != NULL)) {
  588. GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
  589. SetDlgItemText(hdlg, IDC_SDR_CERT_NAME, rgch);
  590. }
  591. else {
  592. SetDlgItemText(hdlg, IDC_SDR_CERT_NAME, "");
  593. }
  594. SendDlgItemMessage(hdlg, IDC_SDR_RECEIPT, BM_SETCHECK,
  595. ((psd != NULL) && (psd->m_fReceipt)), 0);
  596. if (psd != NULL) {
  597. psd->GetLabel(&pbEncode, &cbEncode);
  598. SendDlgItemMessage(hdlg, IDC_SD_LABEL, BM_SETCHECK, (cbEncode > 0), 0);
  599. if (cbEncode > 0) {
  600. f = CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_SMIME_Security_Label,
  601. pbEncode, cbEncode, CRYPT_ENCODE_ALLOC_FLAG,
  602. NULL, &plabel, &cb);
  603. Assert(f);
  604. c = SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_GETCOUNT, 0, 0);
  605. for (i=0; i<c; i++) {
  606. p = (CSecurityPolicy *) SendDlgItemMessage(hdlg, IDC_SD_POLICY,
  607. CB_GETITEMDATA, i, 0);
  608. if (strcmp(p->szPolicyOID, plabel->pszObjIdSecurityPolicy) == 0) {
  609. break;
  610. }
  611. }
  612. if (i<c) {
  613. SendDlgItemMessage(hdlg, IDC_SD_POLICY, CB_SETCURSEL, i, 0);
  614. PolicyFillClassifications(hdlg, IDC_SD_POLICY,
  615. IDC_SD_CLASSIFICATION,
  616. IDC_SD_ADVANCED,
  617. plabel->dwClassification);
  618. }
  619. else {
  620. SetDlgItemText(hdlg, IDC_SDR_POLICY, plabel->pszObjIdSecurityPolicy);
  621. SetDlgItemInt(hdlg, IDC_SDR_CLASSIFICATION, plabel->dwClassification, TRUE);
  622. }
  623. LocalFree(plabel);
  624. }
  625. else {
  626. }
  627. }
  628. break;
  629. case WM_COMMAND:
  630. switch (wParam) {
  631. case IDC_SD_CERT_CHOOSE:
  632. if (DoCertDialog(hdlg, "Choose Signing Certificate", psd->GetMyStore(),
  633. &psd->m_pccert, FILTER_RSA_SIGN | FILTER_DSA_SIGN)) {
  634. GetFriendlyNameOfCertA(psd->m_pccert, rgch, sizeof(rgch));
  635. SetDlgItemText(hdlg, IDC_SD_CERT_NAME, rgch);
  636. }
  637. break;
  638. case MAKELONG(IDC_SD_RECEIPT, BN_CLICKED):
  639. psd->m_fReceipt = SendDlgItemMessage(hdlg, IDC_SD_RECEIPT, BM_GETCHECK,
  640. 0, 0);
  641. return FALSE;
  642. case IDC_SD_DO_RECEIPT:
  643. // Dialog for button
  644. break;
  645. case IDM_VALIDATE:
  646. if (psd->m_pccert != NULL) {
  647. DWORD dw;
  648. HCERTSTORE hstore = NULL;
  649. HrValidateCert(psd->m_pccert, NULL, NULL, &hstore, &dw);
  650. if (hstore != NULL)
  651. if (!CertCloseStore(hstore, CERT_CLOSE_STORE_CHECK_FLAG)) {
  652. AssertSz(FALSE, "Store did not close");
  653. }
  654. }
  655. break;
  656. default:
  657. return FALSE;
  658. }
  659. break;
  660. default:
  661. return FALSE;
  662. }
  663. return TRUE;
  664. }
  665. ////////
  666. HRESULT CSignInfo::AddToMessage(DWORD * pulLayers, IMimeMessage * pmm, HWND hwnd)
  667. {
  668. HRESULT hr;
  669. CSignData * psd;
  670. DWORD count = 0;
  671. DWORD dwType = 0;
  672. HCERTSTORE hcertstore;
  673. IMimeBody * pmb = NULL;
  674. IMimeSecurity2 * psmime2 = NULL;
  675. IMimeSecurity2 * pms2 = NULL;
  676. PROPVARIANT rgpvAlgHash[MAX_LAYERS] = {0};
  677. PROPVARIANT rgpvAuthAttr[MAX_LAYERS] = {0};
  678. PCCERT_CONTEXT rgpccert[MAX_LAYERS] = {0};
  679. PROPVARIANT var;
  680. hcertstore = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, NULL,
  681. 0, NULL);
  682. if (hcertstore == NULL) {
  683. hr = E_FAIL;
  684. goto exit;
  685. }
  686. // Pull out the body interface to set security properties
  687. hr = pmm->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *) &pmb);
  688. if (FAILED(hr)) goto exit;
  689. // Find out what security already exists
  690. hr = pmb->GetOption(OID_SECURITY_TYPE, &var);
  691. if (FAILED(hr)) goto exit;
  692. dwType = var.ulVal;
  693. // if any security, then we need to push on a new layer, all previous security
  694. // is now on the "y-security" layer and not on the hbody layer
  695. if (dwType != 0) {
  696. hr = pmm->QueryInterface(IID_IMimeSecurity2, (LPVOID *) &pms2);
  697. if (FAILED(hr)) goto exit;
  698. hr = pms2->Encode(hwnd, SEF_SENDERSCERTPROVIDED |
  699. SEF_ENCRYPTWITHNOSENDERCERT);
  700. if (FAILED(hr)) goto exit;
  701. pms2->Release(); pms2 = NULL;
  702. dwType = 0;
  703. pmb->Release(); pmb = NULL;
  704. // Pull out the body interface to set security properties
  705. hr = pmm->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *) &pmb);
  706. if (FAILED(hr)) goto exit;
  707. }
  708. //
  709. hr = pmb->QueryInterface(IID_IMimeSecurity2, (LPVOID *) &psmime2);
  710. if (FAILED(hr)) goto exit;
  711. if (psmime2 != NULL) {
  712. var.vt = VT_UI4;
  713. var.ulVal = Count();
  714. hr = pmb->SetOption(OID_SECURITY_SIGNATURE_COUNT, &var);
  715. if (FAILED(hr)) goto exit;
  716. }
  717. for (psd = Head(); psd != NULL; psd = psd->Next()) {
  718. hr = psd->BuildArrays(&count, &dwType, rgpvAlgHash, rgpccert,
  719. rgpvAuthAttr, hcertstore, psmime2);
  720. if (FAILED(hr)) goto exit;
  721. }
  722. if (m_fBlob) {
  723. dwType |= MST_THIS_BLOBSIGN;
  724. }
  725. else {
  726. dwType |= MST_THIS_SIGN;
  727. }
  728. // M00HACK
  729. // hr = InsertBody(pmm, HBODY_ROOT);
  730. // if (FAILED(hr)) {
  731. // goto exit;
  732. // }
  733. // Security Type
  734. var.vt = VT_UI4;
  735. var.ulVal = dwType;
  736. hr = pmb->SetOption(OID_SECURITY_TYPE, &var);
  737. if (FAILED(hr)) goto exit;
  738. var.vt = VT_UI4;
  739. var.ulVal = (DWORD) hcertstore;
  740. hr = pmb->SetOption(OID_SECURITY_HCERTSTORE, &var);
  741. if (FAILED(hr)) goto exit;
  742. var.vt = VT_UI4;
  743. var.ulVal = count;
  744. hr = pmb->SetOption(OID_SECURITY_SIGNATURE_COUNT, &var);
  745. if (FAILED(hr)) goto exit;
  746. if (count > 1) {
  747. var.vt = (VT_VECTOR | VT_VARIANT);
  748. var.capropvar.cElems = count;
  749. var.capropvar.pElems = rgpvAlgHash;
  750. hr = pmb->SetOption(OID_SECURITY_ALG_HASH_RG, &var);
  751. if (FAILED(hr)) goto exit;
  752. var.vt = (VT_VECTOR | VT_UI4);
  753. var.caul.cElems = count;
  754. var.caul.pElems = (DWORD *) rgpccert;
  755. hr = pmb->SetOption(OID_SECURITY_CERT_SIGNING_RG, &var);
  756. if (FAILED(hr)) goto exit;
  757. if (psmime2 == NULL) {
  758. var.vt = (VT_VECTOR | VT_VARIANT);
  759. var.capropvar.cElems = count;
  760. var.capropvar.pElems = rgpvAuthAttr;
  761. hr = pmb->SetOption(OID_SECURITY_AUTHATTR_RG, &var);
  762. if (FAILED(hr)) goto exit;
  763. }
  764. }
  765. else {
  766. var.vt = VT_BLOB;
  767. memcpy(&var.blob, &rgpvAlgHash[0].blob, sizeof(var.blob));
  768. hr = pmb->SetOption(OID_SECURITY_ALG_HASH, &var);
  769. if (FAILED(hr)) goto exit;
  770. var.vt = VT_UI4;
  771. var.ulVal = (ULONG) rgpccert[0];
  772. hr = pmb->SetOption(OID_SECURITY_CERT_SIGNING, &var);
  773. if (FAILED(hr)) goto exit;
  774. if (psmime2 == NULL) {
  775. var.vt = VT_BLOB;
  776. memcpy(&var.blob, &rgpvAuthAttr[0].blob, sizeof(var.blob));
  777. hr = pmb->SetOption(OID_SECURITY_AUTHATTR, &var);
  778. if (FAILED(hr)) goto exit;
  779. }
  780. }
  781. hr = S_OK;
  782. exit:
  783. CertCloseStore(hcertstore, 0);
  784. if (pmb != NULL) pmb->Release();
  785. if (psmime2 != NULL) psmime2->Release();
  786. *pulLayers += 1;
  787. return hr;
  788. }
  789. int CSignInfo::Count() const
  790. {
  791. int count = 0;
  792. CSignData * psd;
  793. for (psd=Head(); psd != NULL; psd = psd->Next()) {
  794. count += 1;
  795. }
  796. return count;
  797. }
  798. //////////
  799. CSignData::CSignData(int state) :
  800. CItem(TYPE_SIGN_DATA, state)
  801. {
  802. m_pccert = NULL;
  803. m_ulValidity = 0;
  804. m_valLabel.cbData = 0;
  805. m_valLabel.pbData = NULL;
  806. m_fReceipt = FALSE;
  807. m_fMLHistory = FALSE;
  808. m_fAuthAttrib = FALSE;
  809. m_fUnAuthAttrib = FALSE;
  810. m_fLabel = FALSE;
  811. m_valReceipt.cbData = 0;
  812. m_valReceipt.pbData = NULL;
  813. m_valMLHistory.cbData = 0;
  814. m_valMLHistory.pbData = NULL;
  815. m_valAuthAttrib.cbData = 0;
  816. m_valAuthAttrib.pbData = NULL;
  817. m_szAuthAttribOID = NULL;
  818. m_valUnAuthAttrib.cbData = 0;
  819. m_valUnAuthAttrib.pbData = NULL;
  820. m_szUnAuthAttribOID = NULL;
  821. }
  822. HRESULT CSignData::BuildArrays(DWORD * pCount, DWORD * pdwType,
  823. PROPVARIANT * rgvHash, PCCERT_CONTEXT * rgpccert,
  824. PROPVARIANT * rgvAuthAttr, HCERTSTORE hcertstore,
  825. IMimeSecurity2 * psmime2)
  826. {
  827. CRYPT_ATTRIBUTES attrs;
  828. BOOL f;
  829. int i = *pCount;
  830. CRYPT_ATTRIBUTE rgattrs[4];
  831. PROPVARIANT var;
  832. *pdwType |= MST_THIS_SIGN;
  833. rgvHash[i].blob.pBlobData = (LPBYTE) RgbSHA1AlgId;
  834. rgvHash[i].blob.cbSize = CbSHA1AlgId;
  835. // Don't add ref the certificate -- we don't free it in the caller.
  836. rgpccert[i] = m_pccert;
  837. f = CertAddCertificateContextToStore(hcertstore, m_pccert,
  838. CERT_STORE_ADD_USE_EXISTING, NULL);
  839. Assert(f);
  840. // Setup for encoding authenticated attributes
  841. attrs.cAttr = 0;
  842. attrs.rgAttr = rgattrs;
  843. // Encode in the label
  844. if (m_valLabel.pbData != NULL) {
  845. rgattrs[attrs.cAttr].pszObjId = szOID_SMIME_Security_Label;
  846. rgattrs[attrs.cAttr].cValue = 1;
  847. rgattrs[attrs.cAttr].rgValue = &m_valLabel;
  848. if (psmime2 != NULL) {
  849. psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
  850. &rgattrs[attrs.cAttr]);
  851. }
  852. else {
  853. attrs.cAttr += 1;
  854. }
  855. }
  856. if (m_valReceipt.pbData != NULL) {
  857. rgattrs[attrs.cAttr].pszObjId = szOID_SMIME_Receipt_Request;
  858. rgattrs[attrs.cAttr].cValue = 1;
  859. rgattrs[attrs.cAttr].rgValue = &m_valReceipt;
  860. if (psmime2 != NULL) {
  861. psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
  862. &rgattrs[attrs.cAttr]);
  863. }
  864. else {
  865. attrs.cAttr += 1;
  866. }
  867. }
  868. if (m_valMLHistory.pbData != NULL) {
  869. rgattrs[attrs.cAttr].pszObjId = szOID_SMIME_MLExpansion_History;
  870. rgattrs[attrs.cAttr].cValue = 1;
  871. rgattrs[attrs.cAttr].rgValue = &m_valMLHistory;
  872. if (psmime2 != NULL) {
  873. psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
  874. &rgattrs[attrs.cAttr]);
  875. }
  876. else {
  877. attrs.cAttr += 1;
  878. }
  879. }
  880. if ((m_szAuthAttribOID != NULL) && (m_valAuthAttrib.pbData != NULL)) {
  881. rgattrs[attrs.cAttr].pszObjId = m_szAuthAttribOID;
  882. rgattrs[attrs.cAttr].cValue = 1;
  883. rgattrs[attrs.cAttr].rgValue = &m_valAuthAttrib;
  884. if (psmime2 != NULL) {
  885. psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_SIGNED,
  886. &rgattrs[attrs.cAttr]);
  887. }
  888. else {
  889. attrs.cAttr += 1;
  890. }
  891. }
  892. if (psmime2 != NULL) {
  893. if ((m_szUnAuthAttribOID != NULL) && (m_valUnAuthAttrib.pbData != NULL)) {
  894. rgattrs[attrs.cAttr].pszObjId = m_szUnAuthAttribOID;
  895. rgattrs[attrs.cAttr].cValue = 1;
  896. rgattrs[attrs.cAttr].rgValue = &m_valUnAuthAttrib;
  897. psmime2->SetAttribute(0, i, SMIME_ATTRIBUTE_SET_UNSIGNED,
  898. &rgattrs[attrs.cAttr]);
  899. }
  900. }
  901. Assert(attrs.cAttr <= sizeof(rgattrs)/sizeof(rgattrs[0]));
  902. if (attrs.cAttr > 0) {
  903. f = CryptEncodeObjectEx(X509_ASN_ENCODING, szOID_Microsoft_Attribute_Sequence,
  904. &attrs, CRYPT_ENCODE_ALLOC_FLAG, NULL,
  905. &rgvAuthAttr[i].blob.pBlobData,
  906. &rgvAuthAttr[i].blob.cbSize);
  907. Assert(f);
  908. }
  909. *pCount = i+1;
  910. return S_OK;
  911. }
  912. void CSignData::SetLabel(LPBYTE pb, DWORD cb)
  913. {
  914. if (m_valLabel.pbData != NULL) {
  915. free(m_valLabel.pbData);
  916. m_valLabel.pbData = NULL;
  917. m_valLabel.cbData = 0;
  918. }
  919. if (cb > 0) {
  920. m_valLabel.pbData = (LPBYTE) malloc(cb);
  921. memcpy(m_valLabel.pbData, pb, cb);
  922. m_valLabel.cbData = cb;
  923. }
  924. }