Source code of Windows XP (NT5)
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.

439 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: ACRSLast.cpp
  7. //
  8. // Contents: Implementation of Auto Cert Request Wizard Completion Page
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include <gpedit.h>
  13. #include "ACRSLast.h"
  14. #include "ACRSPSht.h"
  15. #include "storegpe.h"
  16. USE_HANDLE_MACROS("CERTMGR(ACRSLast.cpp)")
  17. #ifdef _DEBUG
  18. #ifndef ALPHA
  19. #define new DEBUG_NEW
  20. #endif
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. // Gross
  25. #define MAX_GPE_NAME_SIZE 40
  26. /////////////////////////////////////////////////////////////////////////////
  27. // ACRSCompletionPage property page
  28. IMPLEMENT_DYNCREATE (ACRSCompletionPage, CWizard97PropertyPage)
  29. ACRSCompletionPage::ACRSCompletionPage () : CWizard97PropertyPage (ACRSCompletionPage::IDD)
  30. {
  31. //{{AFX_DATA_INIT(ACRSCompletionPage)
  32. // NOTE: the ClassWizard will add member initialization here
  33. //}}AFX_DATA_INIT
  34. InitWizard97 (TRUE);
  35. }
  36. ACRSCompletionPage::~ACRSCompletionPage ()
  37. {
  38. }
  39. void ACRSCompletionPage::DoDataExchange (CDataExchange* pDX)
  40. {
  41. CWizard97PropertyPage::DoDataExchange (pDX);
  42. //{{AFX_DATA_MAP(ACRSCompletionPage)
  43. DDX_Control (pDX, IDC_CHOICES_LIST, m_choicesList);
  44. DDX_Control (pDX, IDC_BOLD_STATIC, m_staticBold);
  45. //}}AFX_DATA_MAP
  46. }
  47. BEGIN_MESSAGE_MAP(ACRSCompletionPage, CWizard97PropertyPage)
  48. //{{AFX_MSG_MAP(ACRSCompletionPage)
  49. // NOTE: the ClassWizard will add DDX and DDV calls here
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // ACRSCompletionPage message handlers
  54. BOOL ACRSCompletionPage::OnInitDialog ()
  55. {
  56. CWizard97PropertyPage::OnInitDialog ();
  57. m_staticBold.SetFont (&GetBigBoldFont ());
  58. // Set up columns in list view
  59. int colWidths[NUM_COLS] = {150, 200};
  60. VERIFY (m_choicesList.InsertColumn (COL_OPTION, L"",
  61. LVCFMT_LEFT, colWidths[COL_OPTION], COL_OPTION) != -1);
  62. VERIFY (m_choicesList.InsertColumn (COL_VALUE, L"",
  63. LVCFMT_LEFT, colWidths[COL_VALUE], COL_VALUE) != -1);
  64. return TRUE; // return TRUE unless you set the focus to a control
  65. // EXCEPTION: OCX Property Pages should return FALSE
  66. }
  67. BOOL ACRSCompletionPage::OnSetActive ()
  68. {
  69. BOOL bResult = CWizard97PropertyPage::OnSetActive ();
  70. if ( bResult )
  71. {
  72. // Remove all items then repopulate.
  73. ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
  74. ASSERT (pSheet);
  75. if ( pSheet )
  76. {
  77. // If edit mode and nothing changed, show disabled finish
  78. if ( pSheet->GetACR () && !pSheet->m_bEditModeDirty )
  79. GetParent ()->PostMessage (PSM_SETWIZBUTTONS, 0, PSWIZB_DISABLEDFINISH | PSWIZB_BACK);
  80. else
  81. GetParent ()->PostMessage (PSM_SETWIZBUTTONS, 0, PSWIZB_FINISH | PSWIZB_BACK);
  82. if ( pSheet->IsDirty () )
  83. pSheet->MarkAsClean ();
  84. VERIFY (m_choicesList.DeleteAllItems ());
  85. CString text;
  86. LV_ITEM lvItem;
  87. int iItem = 0;
  88. // Display cert type selection
  89. VERIFY (text.LoadString (IDS_CERTIFICATE_TYPE_COLUMN_NAME));
  90. ::ZeroMemory (&lvItem, sizeof (lvItem));
  91. lvItem.mask = LVIF_TEXT;
  92. lvItem.iItem = iItem;
  93. lvItem.iSubItem = COL_OPTION;
  94. lvItem.pszText = (LPWSTR) (LPCWSTR) text;
  95. VERIFY (-1 != m_choicesList.InsertItem (&lvItem));
  96. WCHAR** pawszPropertyValue = 0;
  97. HRESULT hResult = ::CAGetCertTypeProperty (pSheet->m_selectedCertType,
  98. CERTTYPE_PROP_FRIENDLY_NAME,
  99. &pawszPropertyValue);
  100. ASSERT (SUCCEEDED (hResult));
  101. if ( SUCCEEDED (hResult) )
  102. {
  103. if ( pawszPropertyValue[0] )
  104. {
  105. VERIFY (m_choicesList.SetItemText (iItem, COL_VALUE,
  106. *pawszPropertyValue));
  107. }
  108. VERIFY (SUCCEEDED (::CAFreeCertTypeProperty (
  109. pSheet->m_selectedCertType, pawszPropertyValue)));
  110. }
  111. iItem++;
  112. // Display CA selection
  113. VERIFY (text.LoadString (IDS_CERTIFICATE_AUTHORITIES));
  114. ::ZeroMemory (&lvItem, sizeof (lvItem));
  115. lvItem.mask = LVIF_TEXT;
  116. lvItem.iSubItem = COL_OPTION;
  117. POSITION pos = 0;
  118. HCAINFO hCAInfo = 0;
  119. for (pos = pSheet->m_caInfoList.GetHeadPosition (); pos;)
  120. {
  121. lvItem.iItem = iItem;
  122. lvItem.pszText = (LPWSTR) (LPCWSTR) text;
  123. VERIFY (-1 != m_choicesList.InsertItem (&lvItem));
  124. hCAInfo = pSheet->m_caInfoList.GetNext (pos);
  125. ASSERT (hCAInfo);
  126. if ( hCAInfo )
  127. {
  128. hResult = ::CAGetCAProperty (hCAInfo, CA_PROP_DISPLAY_NAME,
  129. &pawszPropertyValue);
  130. ASSERT (SUCCEEDED (hResult));
  131. if ( SUCCEEDED (hResult) )
  132. {
  133. if ( pawszPropertyValue[0] )
  134. {
  135. VERIFY (m_choicesList.SetItemText (iItem, COL_VALUE,
  136. *pawszPropertyValue));
  137. }
  138. VERIFY (SUCCEEDED (::CAFreeCAProperty (hCAInfo, pawszPropertyValue)));
  139. }
  140. }
  141. text = L" "; // only the first one has text in it
  142. iItem++;
  143. }
  144. }
  145. }
  146. return bResult;
  147. }
  148. BOOL ACRSCompletionPage::OnWizardFinish ()
  149. {
  150. BOOL bResult = TRUE;
  151. HRESULT hResult = S_OK;
  152. CWaitCursor waitCursor;
  153. ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
  154. ASSERT (pSheet);
  155. if ( pSheet )
  156. {
  157. // If edit mode and nothing changed, just return
  158. if ( pSheet->GetACR () && !pSheet->m_bEditModeDirty )
  159. {
  160. ASSERT (0);
  161. return FALSE;
  162. }
  163. PCTL_ENTRY pCTLEntry = NULL;
  164. DWORD cCTLEntry = 0;
  165. hResult = GetCTLEntry (&cCTLEntry, &pCTLEntry);
  166. if ( SUCCEEDED (hResult) )
  167. {
  168. BYTE *pbEncodedCTL = NULL;
  169. DWORD cbEncodedCTL = 0;
  170. hResult = MakeCTL (cCTLEntry, pCTLEntry, &pbEncodedCTL, &cbEncodedCTL);
  171. if ( SUCCEEDED (hResult) )
  172. {
  173. bResult = pSheet->m_pCertStore->AddEncodedCTL (
  174. X509_ASN_ENCODING,
  175. pbEncodedCTL, cbEncodedCTL,
  176. CERT_STORE_ADD_REPLACE_EXISTING,
  177. NULL);
  178. if ( !bResult )
  179. {
  180. DWORD dwErr = GetLastError ();
  181. hResult = HRESULT_FROM_WIN32 (dwErr);
  182. DisplaySystemError (m_hWnd, dwErr);
  183. }
  184. }
  185. if (pbEncodedCTL)
  186. ::LocalFree (pbEncodedCTL);
  187. }
  188. if (pCTLEntry)
  189. ::LocalFree (pCTLEntry);
  190. }
  191. if ( SUCCEEDED (hResult) )
  192. bResult = CWizard97PropertyPage::OnWizardFinish ();
  193. else
  194. bResult = FALSE;
  195. return bResult;
  196. }
  197. HRESULT ACRSCompletionPage::GetCTLEntry (OUT DWORD *pcCTLEntry, OUT PCTL_ENTRY *ppCTLEntry)
  198. {
  199. HRESULT hResult = S_OK;
  200. ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
  201. ASSERT (pSheet);
  202. if ( pSheet )
  203. {
  204. const size_t HASH_SIZE = 20;
  205. DWORD cCA = (DWORD)pSheet->m_caInfoList.GetCount ();
  206. PCTL_ENTRY pCTLEntry = (PCTL_ENTRY) ::LocalAlloc (LPTR,
  207. (sizeof (CTL_ENTRY) + HASH_SIZE) *cCA);
  208. if ( pCTLEntry )
  209. {
  210. PBYTE pbHash = (PBYTE) (pCTLEntry + cCA);
  211. HCAINFO hCAInfo = NULL;
  212. PCCERT_CONTEXT pCertContext = NULL;
  213. DWORD cbHash = HASH_SIZE;
  214. DWORD iCA = 0;
  215. for (POSITION pos = pSheet->m_caInfoList.GetHeadPosition (); pos;)
  216. {
  217. hCAInfo = pSheet->m_caInfoList.GetNext (pos);
  218. ASSERT (hCAInfo);
  219. if ( hCAInfo )
  220. {
  221. hResult = ::CAGetCACertificate (hCAInfo, &pCertContext);
  222. ASSERT (SUCCEEDED (hResult));
  223. if ( SUCCEEDED (hResult) )
  224. {
  225. cbHash = HASH_SIZE;
  226. if (::CertGetCertificateContextProperty (pCertContext,
  227. CERT_SHA1_HASH_PROP_ID,
  228. pbHash,
  229. &cbHash))
  230. {
  231. pCTLEntry[iCA].SubjectIdentifier.cbData = cbHash;
  232. pCTLEntry[iCA].SubjectIdentifier.pbData = pbHash;
  233. pbHash += cbHash;
  234. ::CertFreeCertificateContext (pCertContext);
  235. iCA++;
  236. }
  237. else
  238. {
  239. DWORD dwErr = GetLastError ();
  240. hResult = HRESULT_FROM_WIN32 (dwErr);
  241. DisplaySystemError (m_hWnd, dwErr);
  242. break;
  243. }
  244. }
  245. else
  246. break;
  247. }
  248. }
  249. if ( SUCCEEDED (hResult) )
  250. {
  251. *pcCTLEntry = cCA;
  252. *ppCTLEntry = pCTLEntry;
  253. }
  254. else
  255. {
  256. if (pCTLEntry)
  257. ::LocalFree (pCTLEntry);
  258. }
  259. }
  260. else
  261. {
  262. hResult = E_OUTOFMEMORY;
  263. }
  264. }
  265. return hResult;
  266. }
  267. HRESULT ACRSCompletionPage::MakeCTL (
  268. IN DWORD cCTLEntry,
  269. IN PCTL_ENTRY pCTLEntry,
  270. OUT BYTE **ppbEncodedCTL,
  271. OUT DWORD *pcbEncodedCTL)
  272. {
  273. HRESULT hResult = S_OK;
  274. ACRSWizardPropertySheet* pSheet = reinterpret_cast <ACRSWizardPropertySheet*> (m_pWiz);
  275. ASSERT (pSheet);
  276. if ( pSheet )
  277. {
  278. PCERT_EXTENSIONS pCertExtensions = NULL;
  279. hResult = ::CAGetCertTypeExtensions (pSheet->m_selectedCertType, &pCertExtensions);
  280. ASSERT (SUCCEEDED (hResult));
  281. if ( SUCCEEDED (hResult) )
  282. {
  283. CMSG_SIGNED_ENCODE_INFO SignerInfo;
  284. memset (&SignerInfo, 0, sizeof (SignerInfo));
  285. CTL_INFO CTLInfo;
  286. memset (&CTLInfo, 0, sizeof (CTLInfo));
  287. WCHAR** pawszPropName = 0;
  288. ZeroMemory(&CTLInfo, sizeof(CTLInfo));
  289. // set up the CTL info
  290. CTLInfo.dwVersion = sizeof (CTLInfo);
  291. CTLInfo.SubjectUsage.cUsageIdentifier = 1;
  292. hResult = ::CAGetCertTypeProperty (pSheet->m_selectedCertType,
  293. CERTTYPE_PROP_DN, &pawszPropName);
  294. ASSERT (SUCCEEDED (hResult));
  295. if ( SUCCEEDED (hResult) && pawszPropName[0] )
  296. {
  297. LPSTR psz = szOID_AUTO_ENROLL_CTL_USAGE;
  298. WCHAR pwszGPEName[MAX_GPE_NAME_SIZE];
  299. IGPEInformation *pGPEInfo = pSheet->m_pCertStore->GetGPEInformation();
  300. ZeroMemory(pwszGPEName, MAX_GPE_NAME_SIZE*sizeof (WCHAR));
  301. CTLInfo.ListIdentifier.cbData = (DWORD) (sizeof (WCHAR) * (wcslen (pawszPropName[0]) + 1));
  302. if(pGPEInfo)
  303. {
  304. pGPEInfo->GetName(pwszGPEName, sizeof(pwszGPEName)/sizeof(pwszGPEName[0]));
  305. CTLInfo.ListIdentifier.cbData += (DWORD) (sizeof(WCHAR)*(wcslen(pwszGPEName)+1));
  306. }
  307. CTLInfo.ListIdentifier.pbData = (PBYTE)LocalAlloc(LPTR, CTLInfo.ListIdentifier.cbData);
  308. if(CTLInfo.ListIdentifier.pbData == NULL)
  309. {
  310. hResult = E_OUTOFMEMORY;
  311. }
  312. if(pwszGPEName[0])
  313. {
  314. wcscpy((LPWSTR)CTLInfo.ListIdentifier.pbData, pwszGPEName);
  315. wcscat((LPWSTR)CTLInfo.ListIdentifier.pbData, L"|");
  316. }
  317. wcscat((LPWSTR)CTLInfo.ListIdentifier.pbData, pawszPropName[0]);
  318. CTLInfo.SubjectUsage.rgpszUsageIdentifier = &psz;
  319. ::GetSystemTimeAsFileTime (&CTLInfo.ThisUpdate);
  320. CTLInfo.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
  321. CTLInfo.cCTLEntry = cCTLEntry;
  322. CTLInfo.rgCTLEntry = pCTLEntry;
  323. // UNDONE - add the cert type extension
  324. // add all the reg info as an extension
  325. CTLInfo.cExtension = pCertExtensions->cExtension;
  326. CTLInfo.rgExtension = pCertExtensions->rgExtension;
  327. // encode the CTL
  328. *pcbEncodedCTL = 0;
  329. SignerInfo.cbSize = sizeof (SignerInfo);
  330. if ( ::CryptMsgEncodeAndSignCTL (PKCS_7_ASN_ENCODING,
  331. &CTLInfo, &SignerInfo, 0,
  332. NULL, pcbEncodedCTL) )
  333. {
  334. *ppbEncodedCTL = (BYTE*) ::LocalAlloc (LPTR, *pcbEncodedCTL);
  335. if ( *ppbEncodedCTL )
  336. {
  337. if (!::CryptMsgEncodeAndSignCTL (PKCS_7_ASN_ENCODING,
  338. &CTLInfo, &SignerInfo, 0,
  339. *ppbEncodedCTL, pcbEncodedCTL))
  340. {
  341. DWORD dwErr = GetLastError ();
  342. hResult = HRESULT_FROM_WIN32 (dwErr);
  343. DisplaySystemError (m_hWnd, dwErr);
  344. }
  345. }
  346. else
  347. {
  348. hResult = E_OUTOFMEMORY;
  349. }
  350. }
  351. else
  352. {
  353. DWORD dwErr = GetLastError ();
  354. hResult = HRESULT_FROM_WIN32 (dwErr);
  355. DisplaySystemError (m_hWnd, dwErr);
  356. }
  357. VERIFY (SUCCEEDED (::CAFreeCertTypeProperty (
  358. pSheet->m_selectedCertType, pawszPropName)));
  359. }
  360. if(CTLInfo.ListIdentifier.pbData)
  361. {
  362. ::LocalFree(CTLInfo.ListIdentifier.pbData);
  363. }
  364. }
  365. if (pCertExtensions)
  366. ::LocalFree (pCertExtensions);
  367. }
  368. return hResult;
  369. }