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.

2458 lines
73 KiB

  1. //
  2. // Certificat.cpp
  3. //
  4. #include "StdAfx.h"
  5. #include "CertWiz.h"
  6. #include "Certificat.h"
  7. #include "certutil.h"
  8. #include <malloc.h>
  9. #include "base64.h"
  10. #include "resource.h"
  11. #include <certupgr.h>
  12. #include <certca.h>
  13. #include "mru.h"
  14. #include "Shlwapi.h"
  15. #include <cryptui.h>
  16. #include <strsafe.h>
  17. // for certobj object
  18. #include "certobj.h"
  19. #include "certobj_i.c"
  20. const CLSID CLSID_CEnroll =
  21. {0x43F8F289, 0x7A20, 0x11D0, {0x8F, 0x06, 0x00, 0xC0, 0x4F, 0xC2, 0x95, 0xE1}};
  22. const IID IID_IEnroll =
  23. {0xacaa7838, 0x4585, 0x11d1, {0xab, 0x57, 0x00, 0xc0, 0x4f, 0xc2, 0x95, 0xe1}};
  24. const IID IID_ICEnroll2 =
  25. {0x704ca730, 0xc90b, 0x11d1, {0x9b, 0xec, 0x00, 0xc0, 0x4f, 0xc2, 0x95, 0xe1}};
  26. const CLSID CLSID_CCertRequest =
  27. {0x98aff3f0, 0x5524, 0x11d0, {0x88, 0x12, 0x00, 0xa0, 0xc9, 0x03, 0xb8, 0x3c}};
  28. const IID IID_ICertRequest =
  29. {0x014e4840, 0x5523, 0x11d0, {0x88, 0x12, 0x00, 0xa0, 0xc9, 0x03, 0xb8, 0x3c}};
  30. WCHAR * bstrEmpty = L"";
  31. extern CCertWizApp theApp;
  32. BOOL
  33. CCryptBlob::Resize(DWORD cb)
  34. {
  35. if (cb > GetSize())
  36. {
  37. if (NULL !=
  38. (m_blob.pbData = Realloc(m_blob.pbData, cb)))
  39. {
  40. m_blob.cbData = cb;
  41. return TRUE;
  42. }
  43. return FALSE;
  44. }
  45. return TRUE;
  46. }
  47. IMPLEMENT_DYNAMIC(CCertificate, CObject)
  48. CCertificate::CCertificate()
  49. : m_CAType(CA_OFFLINE),
  50. m_KeyLength(512),
  51. m_pPendingRequest(NULL),
  52. m_RespCertContext(NULL),
  53. m_pInstalledCert(NULL),
  54. m_pKeyRingCert(NULL),
  55. m_pEnroll(NULL),
  56. m_status_code(-1),
  57. m_CreateDirectory(FALSE),
  58. m_SGCcertificat(FALSE),
  59. m_DefaultCSP(TRUE),
  60. m_DefaultProviderType(PROV_RSA_SCHANNEL),
  61. m_ExportPFXPrivateKey(FALSE),
  62. m_CertObjInstalled(FALSE),
  63. m_OverWriteExisting(FALSE)
  64. {
  65. }
  66. CCertificate::~CCertificate()
  67. {
  68. if (m_pPendingRequest != NULL)
  69. CertFreeCertificateContext(m_pPendingRequest);
  70. if (m_RespCertContext != NULL)
  71. CertFreeCertificateContext(m_RespCertContext);
  72. if (m_pInstalledCert != NULL)
  73. CertFreeCertificateContext(m_pInstalledCert);
  74. if (m_pKeyRingCert != NULL)
  75. CertFreeCertificateContext(m_pKeyRingCert);
  76. if (m_pEnroll != NULL)
  77. m_pEnroll->Release();
  78. }
  79. const TCHAR szResponseFileName[] = _T("ResponseFileName");
  80. const TCHAR szKeyRingFileName[] = _T("KeyRingFileName");
  81. const TCHAR szRequestFileName[] = _T("RequestFileName");
  82. const TCHAR szCertificateTemplate[] = _T("CertificateTemplate");
  83. const TCHAR szState[] = _T("State");
  84. const TCHAR szStateMRU[] = _T("StateMRU");
  85. const TCHAR szLocality[] = _T("Locality");
  86. const TCHAR szLocalityMRU[] = _T("LocalityMRU");
  87. const TCHAR szOrganization[] = _T("Organization");
  88. const TCHAR szOrganizationMRU[] = _T("OrganizationMRU");
  89. const TCHAR szOrganizationUnit[] = _T("OrganizationUnit");
  90. const TCHAR szOrganizationUnitMRU[] = _T("OrganizationUnitMRU");
  91. const TCHAR szMachineNameRemote[] = _T("MachineNameRemote");
  92. const TCHAR szUserNameRemote[] = _T("UserNameRemote");
  93. const TCHAR szWebSiteInstanceNameRemote[] = _T("WebSiteInstanceNameRemote");
  94. #define QUERY_NAME(x,y)\
  95. do {\
  96. if (ERROR_SUCCESS == RegQueryValueEx(hKey, (x), NULL, &dwType, NULL, &cbData))\
  97. {\
  98. ASSERT(dwType == REG_SZ);\
  99. pName = (BYTE *)(y).GetBuffer(cbData);\
  100. RegQueryValueEx(hKey, (x), NULL, &dwType, pName, &cbData);\
  101. if (pName != NULL)\
  102. {\
  103. (y).ReleaseBuffer();\
  104. pName = NULL;\
  105. }\
  106. }\
  107. } while (0)
  108. BOOL
  109. CCertificate::Init()
  110. {
  111. ASSERT(!m_MachineName.IsEmpty());
  112. ASSERT(!m_WebSiteInstanceName.IsEmpty());
  113. // get web site description from metabase, it could be empty
  114. // do not panic in case of error
  115. if (!GetServerComment(m_MachineName, m_WebSiteInstanceName, m_FriendlyName, &m_hResult))
  116. m_hResult = S_OK;
  117. m_CommonName = m_MachineName;
  118. m_CommonName.MakeLower();
  119. m_SSLPort.Empty();
  120. m_MachineName_Remote = m_MachineName;
  121. m_WebSiteInstanceName_Remote = m_WebSiteInstanceName;
  122. HKEY hKey = theApp.RegOpenKeyWizard();
  123. DWORD dwType;
  124. DWORD cbData;
  125. if (hKey != NULL)
  126. {
  127. BYTE * pName = NULL;
  128. QUERY_NAME(szRequestFileName, m_ReqFileName);
  129. QUERY_NAME(szResponseFileName, m_RespFileName);
  130. QUERY_NAME(szKeyRingFileName, m_KeyFileName);
  131. QUERY_NAME(szMachineNameRemote, m_MachineName_Remote);
  132. QUERY_NAME(szUserNameRemote, m_UserName_Remote);
  133. QUERY_NAME(szWebSiteInstanceNameRemote, m_WebSiteInstanceName_Remote);
  134. QUERY_NAME(szCertificateTemplate, m_CertificateTemplate);
  135. QUERY_NAME(szState, m_State);
  136. QUERY_NAME(szLocality, m_Locality);
  137. QUERY_NAME(szOrganization, m_Organization);
  138. QUERY_NAME(szOrganizationUnit, m_OrganizationUnit);
  139. RegCloseKey(hKey);
  140. }
  141. #ifdef _DEBUG
  142. else
  143. {
  144. TRACE(_T("Failed to open Registry key for Wizard parameters\n"));
  145. }
  146. #endif
  147. if (m_CertificateTemplate.IsEmpty())
  148. {
  149. // User didn't defined anything -- use standard name
  150. m_CertificateTemplate = wszCERTTYPE_WEBSERVER;
  151. }
  152. // Set flag to tell if com certobj is installed
  153. m_CertObjInstalled = IsCertObjInstalled();
  154. return TRUE;
  155. }
  156. #define SAVE_NAME(x,y)\
  157. do {\
  158. if (!(y).IsEmpty())\
  159. {\
  160. VERIFY(ERROR_SUCCESS == RegSetValueEx(hKey, (x), 0, REG_SZ, \
  161. (const BYTE *)(LPCTSTR)(y), \
  162. sizeof(TCHAR) * ((y).GetLength() + 1)));\
  163. }\
  164. } while (0)
  165. BOOL
  166. CCertificate::SaveSettings()
  167. {
  168. HKEY hKey = theApp.RegOpenKeyWizard();
  169. if (hKey != NULL)
  170. {
  171. switch (GetStatusCode())
  172. {
  173. case REQUEST_NEW_CERT:
  174. case REQUEST_RENEW_CERT:
  175. SAVE_NAME(szState, m_State);
  176. AddToMRU(szStateMRU, m_State);
  177. SAVE_NAME(szLocality, m_Locality);
  178. AddToMRU(szLocalityMRU, m_Locality);
  179. SAVE_NAME(szOrganization, m_Organization);
  180. AddToMRU(szOrganizationMRU, m_Organization);
  181. SAVE_NAME(szOrganizationUnit, m_OrganizationUnit);
  182. AddToMRU(szOrganizationUnitMRU, m_OrganizationUnit);
  183. SAVE_NAME(szRequestFileName, m_ReqFileName);
  184. break;
  185. case REQUEST_PROCESS_PENDING:
  186. SAVE_NAME(szResponseFileName, m_RespFileName);
  187. break;
  188. case REQUEST_IMPORT_KEYRING:
  189. SAVE_NAME(szKeyRingFileName, m_KeyFileName);
  190. break;
  191. case REQUEST_IMPORT_CERT:
  192. case REQUEST_EXPORT_CERT:
  193. SAVE_NAME(szKeyRingFileName, m_KeyFileName);
  194. break;
  195. case REQUEST_COPY_MOVE_FROM_REMOTE:
  196. case REQUEST_COPY_MOVE_TO_REMOTE:
  197. SAVE_NAME(szKeyRingFileName, m_KeyFileName);
  198. SAVE_NAME(szMachineNameRemote, m_MachineName_Remote);
  199. SAVE_NAME(szUserNameRemote, m_UserName_Remote);
  200. SAVE_NAME(szWebSiteInstanceNameRemote, m_WebSiteInstanceName_Remote);
  201. break;
  202. default:
  203. break;
  204. }
  205. RegCloseKey(hKey);
  206. return TRUE;
  207. }
  208. #ifdef _DEBUG
  209. else
  210. {
  211. TRACE(_T("Failed to open Registry key for Wizard parameters\n"));
  212. }
  213. #endif
  214. return FALSE;
  215. }
  216. BOOL
  217. CCertificate::SetSecuritySettings()
  218. {
  219. long dwGenKeyFlags;
  220. if (SUCCEEDED(GetEnrollObject()->get_GenKeyFlags(&dwGenKeyFlags)))
  221. {
  222. dwGenKeyFlags &= 0x0000FFFF;
  223. dwGenKeyFlags |= (m_KeyLength << 16);
  224. if (m_SGCcertificat)
  225. dwGenKeyFlags |= CRYPT_SGCKEY;
  226. return (SUCCEEDED(GetEnrollObject()->put_GenKeyFlags(dwGenKeyFlags)));
  227. }
  228. return FALSE;
  229. }
  230. // defines taken from the old KeyGen utility
  231. #define MESSAGE_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----\r\n"
  232. #define MESSAGE_TRAILER "-----END NEW CERTIFICATE REQUEST-----\r\n"
  233. BOOL
  234. CCertificate::WriteRequestString(CString& request)
  235. {
  236. ASSERT(!PathIsRelative(m_ReqFileName));
  237. BOOL bRes = FALSE;
  238. try {
  239. CString strPath;
  240. strPath = m_ReqFileName;
  241. LPTSTR pPath = strPath.GetBuffer(strPath.GetLength());
  242. PathRemoveFileSpec(pPath);
  243. if (!PathIsDirectory(pPath))
  244. {
  245. if (!CreateDirectoryFromPath(strPath, NULL))
  246. {
  247. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  248. SetBodyTextID(USE_DEFAULT_CAPTION);
  249. return FALSE;
  250. }
  251. }
  252. strPath.ReleaseBuffer();
  253. HANDLE hFile = ::CreateFile(m_ReqFileName,
  254. GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  255. if (hFile != INVALID_HANDLE_VALUE)
  256. {
  257. DWORD cb = request.GetLength();
  258. char * ascii_buf = (char *) LocalAlloc(LPTR,cb);
  259. if (ascii_buf)
  260. {
  261. wcstombs(ascii_buf, request, cb);
  262. bRes = ::WriteFile(hFile, ascii_buf, cb, &cb, NULL);
  263. ::CloseHandle(hFile);
  264. LocalFree(ascii_buf);ascii_buf=NULL;
  265. }
  266. else
  267. {
  268. m_hResult = E_OUTOFMEMORY;
  269. SetBodyTextID(USE_DEFAULT_CAPTION);
  270. }
  271. }
  272. else
  273. {
  274. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  275. SetBodyTextID(USE_DEFAULT_CAPTION);
  276. }
  277. }
  278. catch (CFileException * e)
  279. {
  280. TCHAR szCause[255];
  281. e->GetErrorMessage(szCause, 255);
  282. TRACE(_T("Got CFileException with error: %s\n"), szCause);
  283. m_hResult = HRESULT_FROM_WIN32(e->m_lOsError);
  284. }
  285. catch (CException * e)
  286. {
  287. TCHAR szCause[255];
  288. e->GetErrorMessage(szCause, 255);
  289. TRACE(_T("Got CException with error: %s\n"), szCause);
  290. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  291. }
  292. return bRes;
  293. }
  294. #define HEADER_SERVER_ _T("Server:\t%s\r\n\r\n")
  295. #define HEADER_COMMON_NAME_ _T("Common-name:\t%s\r\n")
  296. #define HEADER_FRIENDLY_NAME_ _T("Friendly name:\t%s\r\n")
  297. #define HEADER_ORG_UNIT_ _T("Organization Unit:\t%s\r\n")
  298. #define HEADER_ORGANIZATION_ _T("Organization:\t%s\r\n")
  299. #define HEADER_LOCALITY_ _T("Locality:\t%s\r\n")
  300. #define HEADER_STATE_ _T("State:\t%s\r\n")
  301. #define HEADER_COUNTRY_ _T("Country:\t%s\r\n")
  302. static void WRITE_LINE(CString& str, TCHAR * format, CString& data)
  303. {
  304. CString buf;
  305. buf.Format(format, data);
  306. str += buf;
  307. }
  308. void
  309. CCertificate::DumpHeader(CString& str)
  310. {
  311. DumpOnlineHeader(str);
  312. }
  313. void
  314. CCertificate::DumpOnlineHeader(CString& str)
  315. {
  316. WRITE_LINE(str, HEADER_SERVER_, m_CommonName);
  317. WRITE_LINE(str, HEADER_FRIENDLY_NAME_, m_FriendlyName);
  318. WRITE_LINE(str, HEADER_ORG_UNIT_, m_OrganizationUnit);
  319. WRITE_LINE(str, HEADER_ORGANIZATION_, m_Organization);
  320. WRITE_LINE(str, HEADER_LOCALITY_, m_Locality);;
  321. WRITE_LINE(str, HEADER_STATE_, m_State);
  322. WRITE_LINE(str, HEADER_COUNTRY_, m_Country);
  323. }
  324. BOOL
  325. CCertificate::GetSelectedCertDescription(CERT_DESCRIPTION& cd)
  326. {
  327. BOOL bRes = FALSE;
  328. ASSERT(m_pSelectedCertHash != NULL);
  329. HCERTSTORE hStore = OpenMyStore(GetEnrollObject(), &m_hResult);
  330. if (hStore != NULL)
  331. {
  332. PCCERT_CONTEXT pCert = CertFindCertificateInStore(hStore,
  333. CRYPT_ASN_ENCODING,
  334. 0,
  335. CERT_FIND_HASH,
  336. m_pSelectedCertHash,
  337. NULL);
  338. if (pCert != NULL)
  339. {
  340. bRes = GetCertDescription(pCert, cd);
  341. CertFreeCertificateContext(pCert);
  342. }
  343. CertCloseStore(hStore, 0);
  344. }
  345. return bRes;
  346. }
  347. void CCertificate::CreateDN(CString& str)
  348. {
  349. str.Empty();
  350. // per bug 639398, should be ordered
  351. // in reverse order:C,S,L,O.OU,CN
  352. str += _T("C=") + m_Country;
  353. str += _T("\n,S=") + m_State;
  354. str += _T("\n,L=") + m_Locality;
  355. str += _T("\n,O=\"") + m_Organization + _T("\"");
  356. str += _T("\n,OU=\"") + m_OrganizationUnit + _T("\"");
  357. str += _T("\n,CN=\"") + m_CommonName + _T("\"");
  358. }
  359. PCCERT_CONTEXT
  360. CCertificate::GetPendingRequest()
  361. {
  362. if (m_pPendingRequest == NULL)
  363. {
  364. ASSERT(!m_WebSiteInstanceName.IsEmpty());
  365. m_pPendingRequest = GetPendingDummyCert(m_WebSiteInstanceName,
  366. GetEnrollObject(), &m_hResult);
  367. }
  368. return m_pPendingRequest;
  369. }
  370. PCCERT_CONTEXT
  371. CCertificate::GetInstalledCert()
  372. {
  373. if (m_pInstalledCert == NULL)
  374. {
  375. m_pInstalledCert = ::GetInstalledCert(m_MachineName,
  376. m_WebSiteInstanceName,
  377. GetEnrollObject(),
  378. &m_hResult);
  379. }
  380. return m_pInstalledCert;
  381. }
  382. PCCERT_CONTEXT
  383. CCertificate::GetPFXFileCert()
  384. {
  385. ASSERT(!m_KeyFileName.IsEmpty());
  386. ASSERT(!m_KeyPassword.IsEmpty());
  387. IIISCertObj *pTheObject = NULL;
  388. DWORD cbBinaryBufferSize = 0;
  389. char * pbBinaryBuffer = NULL;
  390. BOOL bPleaseDoCoUninit = FALSE;
  391. VARIANT_BOOL bAllowExport = VARIANT_FALSE;
  392. VARIANT_BOOL bOverWriteExisting = VARIANT_FALSE;
  393. if (m_MarkAsExportable)
  394. {
  395. bAllowExport = VARIANT_TRUE;
  396. }
  397. else
  398. {
  399. bAllowExport = VARIANT_FALSE;
  400. }
  401. if (m_OverWriteExisting)
  402. {
  403. bOverWriteExisting = VARIANT_TRUE;
  404. }
  405. else
  406. {
  407. bOverWriteExisting = VARIANT_FALSE;
  408. }
  409. if (FALSE == m_CertObjInstalled)
  410. {
  411. m_pKeyRingCert = NULL;
  412. goto GetPFXFileCert_Exit;
  413. }
  414. if (m_pKeyRingCert == NULL)
  415. {
  416. BSTR bstrFileName = SysAllocString(m_KeyFileName);
  417. LPTSTR lpTempPassword = m_KeyPassword.GetClearTextPassword();
  418. BSTR bstrFilePassword = SysAllocString(lpTempPassword);
  419. m_KeyPassword.DestroyClearTextPassword(lpTempPassword);
  420. VARIANT VtArray;
  421. m_hResult = CoInitialize(NULL);
  422. if(FAILED(m_hResult))
  423. {
  424. return NULL;
  425. }
  426. bPleaseDoCoUninit = TRUE;
  427. // this one seems to work with surrogates..
  428. m_hResult = CoCreateInstance(CLSID_IISCertObj,NULL,CLSCTX_SERVER,IID_IIISCertObj,(void **)&pTheObject);
  429. if (FAILED(m_hResult))
  430. {
  431. goto GetPFXFileCert_Exit;
  432. }
  433. // at this point we were able to instantiate the com object on the server (local or remote)
  434. m_hResult = pTheObject->ImportToCertStore(bstrFileName,bstrFilePassword,bAllowExport,bOverWriteExisting,&VtArray);
  435. if (FAILED(m_hResult))
  436. {
  437. m_pKeyRingCert = NULL;
  438. goto GetPFXFileCert_Exit;
  439. }
  440. // we have a VtArray now.
  441. // change it back to a binary blob
  442. m_hResult = HereIsVtArrayGimmieBinary(&VtArray,&cbBinaryBufferSize,&pbBinaryBuffer,FALSE);
  443. if (FAILED(m_hResult))
  444. {
  445. m_pKeyRingCert = NULL;
  446. goto GetPFXFileCert_Exit;
  447. }
  448. // we have the hash now.
  449. // we can use it to lookup the cert and get the PCCERT_CONTEXT
  450. // Get the pointer to the cert...
  451. m_pKeyRingCert = GetInstalledCertFromHash(&m_hResult,cbBinaryBufferSize,pbBinaryBuffer);
  452. }
  453. GetPFXFileCert_Exit:
  454. if (pTheObject)
  455. {
  456. pTheObject->Release();
  457. pTheObject = NULL;
  458. }
  459. if (pbBinaryBuffer)
  460. {
  461. CoTaskMemFree(pbBinaryBuffer);
  462. }
  463. if (bPleaseDoCoUninit)
  464. {
  465. CoUninitialize();
  466. }
  467. return m_pKeyRingCert;
  468. }
  469. PCCERT_CONTEXT
  470. CCertificate::GetImportCert()
  471. {
  472. // Warning: you are replacing a certificate which
  473. // is being referenced by another site. are you sure you want to do this?
  474. BOOL bOverWrite = TRUE;
  475. ASSERT(!m_KeyFileName.IsEmpty());
  476. ASSERT(!m_KeyPassword.IsEmpty());
  477. if (m_pKeyRingCert == NULL)
  478. {
  479. // See if there alrady is a certificat that we are going to over write!!!
  480. int len = m_KeyPassword.GetByteLength();
  481. char * ascii_password = (char *) LocalAlloc(LPTR,len);
  482. if (NULL != ascii_password)
  483. {
  484. size_t n;
  485. LPTSTR lpTempPassword = m_KeyPassword.GetClearTextPassword();
  486. if (lpTempPassword)
  487. {
  488. VERIFY(-1 != (n = wcstombs(ascii_password, lpTempPassword, len)));
  489. m_KeyPassword.DestroyClearTextPassword(lpTempPassword);
  490. ascii_password[n] = '\0';
  491. m_pKeyRingCert = ::ImportKRBackupToCAPIStore(
  492. (LPTSTR)(LPCTSTR)m_KeyFileName,
  493. ascii_password,
  494. _T("MY"),
  495. bOverWrite);
  496. }
  497. }
  498. if (m_pKeyRingCert == NULL)
  499. {
  500. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  501. }
  502. if (ascii_password)
  503. {
  504. SecureZeroMemory(ascii_password,len);
  505. LocalFree(ascii_password);ascii_password=NULL;
  506. }
  507. }
  508. return m_pKeyRingCert;
  509. }
  510. PCCERT_CONTEXT
  511. CCertificate::GetKeyRingCert()
  512. {
  513. ASSERT(!m_KeyFileName.IsEmpty());
  514. ASSERT(!m_KeyPassword.IsEmpty());
  515. BOOL bOverWrite = FALSE;
  516. if (m_pKeyRingCert == NULL)
  517. {
  518. int len = m_KeyPassword.GetByteLength();
  519. char * ascii_password = (char *) LocalAlloc(LPTR,len);
  520. if (NULL != ascii_password)
  521. {
  522. size_t n;
  523. LPTSTR lpTempPassword = m_KeyPassword.GetClearTextPassword();
  524. if (lpTempPassword)
  525. {
  526. VERIFY(-1 != (n = wcstombs(ascii_password, lpTempPassword, len)));
  527. m_KeyPassword.DestroyClearTextPassword(lpTempPassword);
  528. ascii_password[n] = '\0';
  529. m_pKeyRingCert = ::ImportKRBackupToCAPIStore(
  530. (LPTSTR)(LPCTSTR)m_KeyFileName,
  531. ascii_password,
  532. _T("MY"),
  533. bOverWrite);
  534. }
  535. }
  536. if (m_pKeyRingCert == NULL)
  537. {
  538. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  539. }
  540. if (ascii_password)
  541. {
  542. SecureZeroMemory(ascii_password,len);
  543. LocalFree(ascii_password);ascii_password=NULL;
  544. }
  545. }
  546. return m_pKeyRingCert;
  547. }
  548. /* INTRINSA suppress=null_pointers, uninitialized */
  549. PCCERT_CONTEXT
  550. CCertificate::GetResponseCert()
  551. {
  552. if (m_RespCertContext == NULL)
  553. {
  554. ASSERT(!m_RespFileName.IsEmpty());
  555. m_RespCertContext = GetCertContextFromPKCS7File(
  556. m_RespFileName,
  557. &GetPendingRequest()->pCertInfo->SubjectPublicKeyInfo,
  558. &m_hResult);
  559. ASSERT(SUCCEEDED(m_hResult));
  560. }
  561. return m_RespCertContext;
  562. }
  563. BOOL
  564. CCertificate::GetResponseCertDescription(CERT_DESCRIPTION& cd)
  565. {
  566. CERT_DESCRIPTION cdReq;
  567. if (GetCertDescription(GetResponseCert(), cd))
  568. {
  569. if (GetCertDescription(GetPendingRequest(), cdReq))
  570. {
  571. cd.m_FriendlyName = cdReq.m_FriendlyName;
  572. }
  573. return TRUE;
  574. }
  575. return FALSE;
  576. }
  577. /*------------------------------------------------------------------------------
  578. IsResponseInstalled
  579. Function checks if certificate from the response file
  580. m_RespFileName was istalled to some server. If possible,
  581. it returns name of this server in str.
  582. Returns FALSE if certificate is not found in MY store or
  583. if this store cannot be opened
  584. */
  585. BOOL
  586. CCertificate::IsResponseInstalled(
  587. CString& str // return server instance name (not yet implemented)
  588. )
  589. {
  590. BOOL bRes = FALSE;
  591. // get cert context from response file
  592. PCCERT_CONTEXT pContext = GetCertContextFromPKCS7File(
  593. m_RespFileName, NULL, &m_hResult);
  594. if (pContext != NULL)
  595. {
  596. HCERTSTORE hStore = OpenMyStore(GetEnrollObject(), &m_hResult);
  597. if (hStore != NULL)
  598. {
  599. PCCERT_CONTEXT pCert = NULL;
  600. while (NULL != (pCert = CertEnumCertificatesInStore(hStore, pCert)))
  601. {
  602. // do not include installed cert to the list
  603. if (CertCompareCertificate(X509_ASN_ENCODING,
  604. pContext->pCertInfo, pCert->pCertInfo))
  605. {
  606. bRes = TRUE;
  607. // Try to find, where is was installed
  608. break;
  609. }
  610. }
  611. if (pCert != NULL)
  612. CertFreeCertificateContext(pCert);
  613. }
  614. }
  615. return bRes;
  616. }
  617. BOOL
  618. CCertificate::FindInstanceNameForResponse(CString& str)
  619. {
  620. BOOL bRes = FALSE;
  621. // get cert context from response file
  622. PCCERT_CONTEXT pContext = GetCertContextFromPKCS7File(m_RespFileName, NULL, &m_hResult);
  623. if (pContext != NULL)
  624. {
  625. // find dummy cert in REQUEST store that has public key
  626. // the same as in this context
  627. PCCERT_CONTEXT pReq = GetReqCertByKey(GetEnrollObject(), &pContext->pCertInfo->SubjectPublicKeyInfo, &m_hResult);
  628. if (pReq != NULL)
  629. {
  630. // get friendly name prop from this dummy cert
  631. if (!GetFriendlyName(pReq, str, &m_hResult))
  632. {
  633. // get instance name prop from this dummy cert
  634. DWORD cb;
  635. BYTE * prop = NULL;
  636. if (CertGetCertificateContextProperty(pReq, CERTWIZ_INSTANCE_NAME_PROP_ID, NULL, &cb))
  637. {
  638. prop = (BYTE *) LocalAlloc(LPTR,cb);
  639. if (NULL != prop)
  640. {
  641. if (CertGetCertificateContextProperty(pReq, CERTWIZ_INSTANCE_NAME_PROP_ID, prop, &cb))
  642. {
  643. // decode this instance name property
  644. DWORD cbData = 0;
  645. BYTE * data = NULL;
  646. if (CryptDecodeObject(CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING,prop, cb, 0, NULL, &cbData))
  647. {
  648. data = (BYTE *) LocalAlloc(LPTR,cbData);
  649. if (NULL != data)
  650. {
  651. if (CryptDecodeObject(CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING,prop, cb, 0, data, &cbData))
  652. {
  653. CERT_NAME_VALUE * p = (CERT_NAME_VALUE *)data;
  654. CString strInstanceName = (LPCTSTR)p->Value.pbData;
  655. // now try to get comment from this server
  656. if (GetServerComment(m_MachineName, strInstanceName, str, &m_hResult))
  657. {
  658. if (str.IsEmpty())
  659. {
  660. // generate something like [Web Site #n]
  661. str.LoadString(IDS_WEB_SITE_N);
  662. int len = strInstanceName.GetLength();
  663. for (int i = len - 1, count = 0; i >= 0; i--, count++)
  664. {
  665. if (!_istdigit(strInstanceName.GetAt(i)))
  666. break;
  667. }
  668. ASSERT(count < len);
  669. AfxFormatString1(str, IDS_WEB_SITE_N, strInstanceName.Right(count));
  670. }
  671. }
  672. m_hResult = S_OK;
  673. bRes = TRUE;
  674. }
  675. if (data)
  676. {
  677. LocalFree(data);data=NULL;
  678. }
  679. }
  680. }
  681. }
  682. }
  683. }
  684. if (prop)
  685. {
  686. LocalFree(prop);prop=NULL;
  687. }
  688. }
  689. CertFreeCertificateContext(pReq);
  690. }
  691. else
  692. {
  693. // probably this request was deleted from the request store
  694. }
  695. CertFreeCertificateContext(pContext);
  696. }
  697. return bRes;
  698. }
  699. IEnroll *
  700. CCertificate::GetEnrollObject()
  701. {
  702. if (m_pEnroll == NULL)
  703. {
  704. m_hResult = CoCreateInstance(CLSID_CEnroll,
  705. NULL,
  706. CLSCTX_INPROC_SERVER,
  707. IID_IEnroll,
  708. (void **)&m_pEnroll);
  709. // now we need to change defaults for this
  710. // object to LOCAL_MACHINE
  711. if (m_pEnroll != NULL)
  712. {
  713. long dwFlags;
  714. VERIFY(SUCCEEDED(m_pEnroll->get_MyStoreFlags(&dwFlags)));
  715. dwFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK;
  716. dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
  717. // following call will change Request store flags also
  718. VERIFY(SUCCEEDED(m_pEnroll->put_MyStoreFlags(dwFlags)));
  719. VERIFY(SUCCEEDED(m_pEnroll->get_GenKeyFlags(&dwFlags)));
  720. dwFlags |= CRYPT_EXPORTABLE;
  721. VERIFY(SUCCEEDED(m_pEnroll->put_GenKeyFlags(dwFlags)));
  722. VERIFY(SUCCEEDED(m_pEnroll->put_KeySpec(AT_KEYEXCHANGE)));
  723. VERIFY(SUCCEEDED(m_pEnroll->put_ProviderType(m_DefaultProviderType)));
  724. VERIFY(SUCCEEDED(m_pEnroll->put_DeleteRequestCert(TRUE)));
  725. }
  726. }
  727. ASSERT(m_pEnroll != NULL);
  728. return m_pEnroll;
  729. }
  730. BOOL
  731. CCertificate::HasInstalledCert()
  732. {
  733. BOOL bResult = FALSE;
  734. CComAuthInfo auth;
  735. CMetaKey key(&auth,
  736. m_WebSiteInstanceName,
  737. METADATA_PERMISSION_READ,
  738. METADATA_MASTER_ROOT_HANDLE
  739. );
  740. if (key.Succeeded())
  741. {
  742. CString store_name;
  743. CBlob blob;
  744. if ( S_OK == key.QueryValue(MD_SSL_CERT_HASH, blob)
  745. && S_OK == key.QueryValue(MD_SSL_CERT_STORE_NAME, store_name)
  746. )
  747. {
  748. bResult = TRUE;
  749. }
  750. }
  751. return bResult;
  752. }
  753. HRESULT
  754. CCertificate::UninstallCert()
  755. {
  756. CComAuthInfo auth;
  757. CMetaKey key(
  758. &auth,
  759. m_WebSiteInstanceName,
  760. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  761. METADATA_MASTER_ROOT_HANDLE
  762. );
  763. if (key.Succeeded())
  764. {
  765. CString store_name;
  766. key.QueryValue(MD_SSL_CERT_STORE_NAME, store_name);
  767. if (SUCCEEDED(key.DeleteValue(MD_SSL_CERT_HASH)))
  768. {
  769. key.DeleteValue(MD_SSL_CERT_STORE_NAME);
  770. // leave this here when uninstalling certificate:
  771. // bug:612595
  772. //key.DeleteValue(MD_SECURE_BINDINGS);
  773. }
  774. }
  775. return m_hResult = key.QueryResult();
  776. }
  777. BOOL CCertificate::WriteRequestBody()
  778. {
  779. ASSERT(!m_ReqFileName.IsEmpty());
  780. HRESULT hr;
  781. BOOL bRes = FALSE;
  782. CString strDN;
  783. CreateDN(strDN);
  784. ASSERT(!strDN.IsEmpty());
  785. CString strUsage(szOID_PKIX_KP_SERVER_AUTH);
  786. CCryptBlobIMalloc request;
  787. GetEnrollObject()->put_ProviderType(m_DefaultCSP ?
  788. m_DefaultProviderType : m_CustomProviderType);
  789. if (!m_DefaultCSP)
  790. {
  791. GetEnrollObject()->put_ProviderNameWStr((LPTSTR)(LPCTSTR)m_CspName);
  792. GetEnrollObject()->put_KeySpec(AT_SIGNATURE);
  793. if (m_CustomProviderType == PROV_DH_SCHANNEL)
  794. {
  795. GetEnrollObject()->put_KeySpec(AT_SIGNATURE);
  796. }
  797. else if (m_CustomProviderType == PROV_RSA_SCHANNEL)
  798. {
  799. GetEnrollObject()->put_KeySpec(AT_KEYEXCHANGE);
  800. }
  801. }
  802. if (SUCCEEDED(hr = GetEnrollObject()->createPKCS10WStr((LPTSTR)(LPCTSTR)strDN,(LPTSTR)(LPCTSTR)strUsage,request)))
  803. {
  804. // BASE64 encode pkcs 10
  805. DWORD err, cch;
  806. char * psz = NULL;
  807. if ((err = Base64EncodeA(request.GetData(), request.GetSize(), NULL, &cch)) == ERROR_SUCCESS)
  808. {
  809. psz = (char *) LocalAlloc(LPTR, cch);
  810. if (NULL != psz)
  811. {
  812. if ((err = Base64EncodeA(request.GetData(), request.GetSize(), psz, &cch)) == ERROR_SUCCESS)
  813. {
  814. HANDLE hFile = ::CreateFile(m_ReqFileName,GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  815. if (hFile == INVALID_HANDLE_VALUE)
  816. {
  817. return FALSE;
  818. }
  819. DWORD written;
  820. ::SetFilePointer(hFile, 0, NULL, FILE_END);
  821. ::WriteFile(hFile, MESSAGE_HEADER, sizeof(MESSAGE_HEADER) - 1, &written, NULL);
  822. ::WriteFile(hFile, psz, cch, &written, NULL);
  823. ::WriteFile(hFile, MESSAGE_TRAILER, sizeof(MESSAGE_TRAILER) - 1, &written, NULL);
  824. ::CloseHandle(hFile);
  825. // get back request from encoded data
  826. PCERT_REQUEST_INFO req_info;
  827. VERIFY(GetRequestInfoFromPKCS10(request, &req_info, &m_hResult));
  828. // find dummy cert put to request store by createPKCS10 call
  829. HCERTSTORE hStore = OpenRequestStore(GetEnrollObject(), &m_hResult);
  830. if (hStore != NULL)
  831. {
  832. PCCERT_CONTEXT pDummyCert = CertFindCertificateInStore(hStore,
  833. CRYPT_ASN_ENCODING,
  834. 0,
  835. CERT_FIND_PUBLIC_KEY,
  836. (void *)&req_info->SubjectPublicKeyInfo,
  837. NULL);
  838. if (pDummyCert != NULL)
  839. {
  840. // now we need to attach web server instance name to this cert
  841. // encode string into data blob
  842. CRYPT_DATA_BLOB name;
  843. CERT_NAME_VALUE name_value;
  844. name_value.dwValueType = CERT_RDN_BMP_STRING;
  845. name_value.Value.cbData = 0;
  846. name_value.Value.pbData = (LPBYTE)(LPCTSTR)m_WebSiteInstanceName;
  847. {
  848. name.pbData = NULL;
  849. if (!CryptEncodeObject(CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING,&name_value, NULL, &name.cbData))
  850. {
  851. ASSERT(FALSE);
  852. }
  853. name.pbData = (BYTE *) LocalAlloc(LPTR,name.cbData);
  854. if (NULL == name.pbData)
  855. {
  856. ASSERT(FALSE);
  857. }
  858. if (!CryptEncodeObject(CRYPT_ASN_ENCODING, X509_UNICODE_ANY_STRING,&name_value, name.pbData, &name.cbData))
  859. {
  860. ASSERT(FALSE);
  861. }
  862. VERIFY(bRes = CertSetCertificateContextProperty(pDummyCert, CERTWIZ_INSTANCE_NAME_PROP_ID, 0, &name));
  863. if (name.pbData)
  864. {
  865. LocalFree(name.pbData);name.pbData=NULL;
  866. }
  867. }
  868. // put friendly name to dummy cert -- we will reuse it later
  869. m_FriendlyName.ReleaseBuffer();
  870. AttachFriendlyName(pDummyCert, m_FriendlyName, &m_hResult);
  871. // we also need to put some flag to show what we are waiting for:
  872. // new sertificate or renewing certificate
  873. CRYPT_DATA_BLOB flag;
  874. flag.pbData = NULL;
  875. if (!CryptEncodeObject(CRYPT_ASN_ENCODING, X509_INTEGER,&m_status_code, NULL, &flag.cbData))
  876. {
  877. ASSERT(FALSE);
  878. }
  879. flag.pbData = (BYTE *) LocalAlloc(LPTR,flag.cbData);
  880. if (NULL == flag.pbData)
  881. {
  882. ASSERT(FALSE);
  883. }
  884. if (!CryptEncodeObject(CRYPT_ASN_ENCODING, X509_INTEGER,&m_status_code, flag.pbData, &flag.cbData))
  885. {
  886. ASSERT(FALSE);
  887. }
  888. VERIFY(bRes = CertSetCertificateContextProperty(pDummyCert, CERTWIZ_REQUEST_FLAG_PROP_ID, 0, &flag));
  889. CertFreeCertificateContext(pDummyCert);
  890. if (flag.pbData)
  891. {
  892. LocalFree(flag.pbData);flag.pbData=NULL;
  893. }
  894. }
  895. CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
  896. }
  897. LocalFree(req_info);
  898. }
  899. if (psz)
  900. {
  901. LocalFree(psz);psz=NULL;
  902. }
  903. }
  904. }
  905. bRes = TRUE;
  906. }
  907. return bRes;
  908. }
  909. BOOL
  910. CCertificate::InstallResponseCert()
  911. {
  912. BOOL bRes = FALSE;
  913. CCryptBlobLocal blobRequestText;
  914. // Get all our data attached to dummy cert
  915. GetFriendlyName(GetPendingRequest(), m_FriendlyName, &m_hResult);
  916. ASSERT(!m_FriendlyName.IsEmpty());
  917. GetBlobProperty(GetPendingRequest(),
  918. CERTWIZ_REQUEST_TEXT_PROP_ID, blobRequestText, &m_hResult);
  919. ASSERT(blobRequestText.GetSize() != 0);
  920. CCryptBlobLocal hash_blob;
  921. if (::GetHashProperty(GetResponseCert(), hash_blob, &m_hResult))
  922. {
  923. if (SUCCEEDED(m_hResult = GetEnrollObject()->acceptFilePKCS7WStr(
  924. (LPTSTR)(LPCTSTR)m_RespFileName))
  925. && InstallCertByHash(hash_blob, m_MachineName, m_WebSiteInstanceName,
  926. GetEnrollObject(), &m_hResult)
  927. )
  928. {
  929. // reattach friendly name and request text to installed cert
  930. m_FriendlyName.ReleaseBuffer();
  931. AttachFriendlyName(GetInstalledCert(), m_FriendlyName, &m_hResult);
  932. bRes = CertSetCertificateContextProperty(GetInstalledCert(),
  933. CERTWIZ_REQUEST_TEXT_PROP_ID, 0, blobRequestText);
  934. }
  935. }
  936. if (!bRes)
  937. {
  938. SetBodyTextID(USE_DEFAULT_CAPTION);
  939. }
  940. #ifdef ENABLE_W3SVC_SSL_PAGE
  941. // see if the SSL attribute was set...if it was then set the SSL site for this certificate...
  942. if (!m_SSLPort.IsEmpty())
  943. {
  944. // get the port and write it to the metabase.
  945. bRes = WriteSSLPortToSite(m_MachineName,m_WebSiteInstanceName,m_SSLPort,&m_hResult);
  946. if (!bRes)
  947. {
  948. SetBodyTextID(USE_DEFAULT_CAPTION);
  949. }
  950. }
  951. #endif
  952. return bRes;
  953. }
  954. BOOL
  955. CCertificate::InstallCopyMoveFromRemote()
  956. {
  957. ASSERT(!m_KeyFileName.IsEmpty());
  958. ASSERT(!m_KeyPassword.IsEmpty());
  959. ASSERT(!m_WebSiteInstanceName.IsEmpty());
  960. BOOL bRes = FALSE;
  961. BOOL bPleaseDoCoUninit = FALSE;
  962. IIISCertObj *pTheObject = NULL;
  963. VARIANT varUserName;
  964. VARIANT varUserPassword;
  965. VARIANT * pvarUserName = &varUserName;
  966. VARIANT * pvarUserPassword = &varUserPassword;
  967. VariantInit(pvarUserName);
  968. VariantInit(pvarUserPassword);
  969. VARIANT_BOOL bAllowExport = VARIANT_FALSE;
  970. VARIANT_BOOL bOverWriteExisting = VARIANT_TRUE;
  971. if (m_MarkAsExportable)
  972. {
  973. bAllowExport = VARIANT_TRUE;
  974. }
  975. else
  976. {
  977. bAllowExport = VARIANT_FALSE;
  978. }
  979. if (FALSE == m_CertObjInstalled)
  980. {
  981. goto InstallCopyMoveFromRemote_Exit;
  982. }
  983. pvarUserName->bstrVal = SysAllocString(_T(""));
  984. pvarUserPassword->bstrVal = SysAllocString(_T(""));
  985. V_VT(pvarUserName) = VT_BSTR;
  986. V_VT(pvarUserPassword) = VT_BSTR;
  987. // set the properties to the remote server's info
  988. // when we call copy, it will connect to the
  989. // remote object and copy it back into our object
  990. // local machine
  991. BSTR bstrServerName = SysAllocString(m_MachineName);
  992. BSTR bstrUserName = SysAllocString(_T(""));
  993. BSTR bstrUserPassword = SysAllocString(_T(""));
  994. BSTR bstrInstanceName = SysAllocString(m_WebSiteInstanceName);
  995. // remote machine
  996. BSTR bstrUserName_Remote = SysAllocString(m_UserName_Remote);
  997. LPTSTR pszTempPassword = m_UserPassword_Remote.GetClearTextPassword();
  998. BSTR bstrUserPassword_Remote = SysAllocString(pszTempPassword);
  999. m_UserPassword_Remote.DestroyClearTextPassword(pszTempPassword);
  1000. BSTR bstrServerName_Remote = SysAllocString(m_MachineName_Remote);
  1001. BSTR bstrInstanceName_Remote = SysAllocString(m_WebSiteInstanceName_Remote);
  1002. m_hResult = CoInitialize(NULL);
  1003. if(FAILED(m_hResult))
  1004. {
  1005. return bRes;
  1006. }
  1007. bPleaseDoCoUninit = TRUE;
  1008. // this one seems to work with surrogates..
  1009. m_hResult = CoCreateInstance(CLSID_IISCertObj,NULL,CLSCTX_SERVER,IID_IIISCertObj,(void **)&pTheObject);
  1010. if (FAILED(m_hResult))
  1011. {
  1012. goto InstallCopyMoveFromRemote_Exit;
  1013. }
  1014. // at this point we were able to instantiate the com object on the server (local or remote)
  1015. pTheObject->put_ServerName(bstrServerName_Remote);
  1016. pTheObject->put_UserName(bstrUserName_Remote);
  1017. pTheObject->put_UserPassword(bstrUserPassword_Remote);
  1018. pTheObject->put_InstanceName(bstrInstanceName_Remote);
  1019. if (m_DeleteAfterCopy)
  1020. {
  1021. m_hResult = pTheObject->Move(bAllowExport,bOverWriteExisting,bstrServerName,bstrInstanceName,varUserName,varUserPassword);
  1022. }
  1023. else
  1024. {
  1025. m_hResult = pTheObject->Copy(bAllowExport,bOverWriteExisting,bstrServerName,bstrInstanceName,varUserName,varUserPassword);
  1026. }
  1027. if (FAILED(m_hResult))
  1028. {
  1029. goto InstallCopyMoveFromRemote_Exit;
  1030. }
  1031. bRes = TRUE;
  1032. InstallCopyMoveFromRemote_Exit:
  1033. if (pvarUserName)
  1034. {
  1035. VariantClear(pvarUserName);
  1036. }
  1037. if (pvarUserPassword)
  1038. {
  1039. VariantClear(pvarUserPassword);
  1040. }
  1041. if (!bRes)
  1042. {
  1043. SetBodyTextID(USE_DEFAULT_CAPTION);
  1044. }
  1045. if (pTheObject)
  1046. {
  1047. pTheObject->Release();
  1048. pTheObject = NULL;
  1049. }
  1050. if (bPleaseDoCoUninit)
  1051. {
  1052. CoUninitialize();
  1053. }
  1054. return bRes;
  1055. }
  1056. BOOL CCertificate::IsCertObjInstalled()
  1057. {
  1058. BOOL bReturn = FALSE;
  1059. HRESULT hRes = E_FAIL;
  1060. BOOL bPleaseDoCoUninit = FALSE;
  1061. IIISCertObj *pTheObject = NULL;
  1062. hRes = CoInitialize(NULL);
  1063. if(FAILED(hRes))
  1064. {
  1065. bReturn = FALSE;
  1066. goto IsCertObjInstalled_Exit;
  1067. }
  1068. bPleaseDoCoUninit = TRUE;
  1069. // this one seems to work with surrogates..
  1070. hRes = CoCreateInstance(CLSID_IISCertObj,NULL,CLSCTX_SERVER,IID_IIISCertObj,(void **)&pTheObject);
  1071. if (FAILED(hRes))
  1072. {
  1073. bReturn = FALSE;
  1074. goto IsCertObjInstalled_Exit;
  1075. }
  1076. if (pTheObject)
  1077. {
  1078. bReturn = TRUE;
  1079. pTheObject->Release();
  1080. pTheObject = NULL;
  1081. }
  1082. IsCertObjInstalled_Exit:
  1083. if (bPleaseDoCoUninit)
  1084. {
  1085. CoUninitialize();
  1086. }
  1087. return bReturn;
  1088. }
  1089. BOOL
  1090. CCertificate::InstallCopyMoveToRemote()
  1091. {
  1092. ASSERT(!m_KeyFileName.IsEmpty());
  1093. ASSERT(!m_KeyPassword.IsEmpty());
  1094. ASSERT(!m_WebSiteInstanceName.IsEmpty());
  1095. BOOL bRes = FALSE;
  1096. BOOL bPleaseDoCoUninit = FALSE;
  1097. IIISCertObj *pTheObject = NULL;
  1098. VARIANT varUserName_Remote;
  1099. VARIANT varUserPassword_Remote;
  1100. VARIANT * pvarUserName_Remote = &varUserName_Remote;
  1101. VARIANT * pvarUserPassword_Remote = &varUserPassword_Remote;
  1102. VariantInit(pvarUserName_Remote);
  1103. VariantInit(pvarUserPassword_Remote);
  1104. VARIANT_BOOL bAllowExport = VARIANT_FALSE;
  1105. VARIANT_BOOL bOverWriteExisting = VARIANT_TRUE;
  1106. if (m_MarkAsExportable)
  1107. {
  1108. bAllowExport = VARIANT_TRUE;
  1109. }
  1110. else
  1111. {
  1112. bAllowExport = VARIANT_FALSE;
  1113. }
  1114. if (FALSE == m_CertObjInstalled)
  1115. {
  1116. goto InstallCopyMoveToRemote_Exit;
  1117. }
  1118. pvarUserName_Remote->bstrVal = SysAllocString(m_UserName_Remote);
  1119. LPTSTR pszTempPassword = m_UserPassword_Remote.GetClearTextPassword();
  1120. pvarUserPassword_Remote->bstrVal = SysAllocString(pszTempPassword);
  1121. m_UserPassword_Remote.DestroyClearTextPassword(pszTempPassword);
  1122. V_VT(pvarUserName_Remote) = VT_BSTR;
  1123. V_VT(pvarUserPassword_Remote) = VT_BSTR;
  1124. // set the properties to the remote server's info
  1125. // when we call copy, it will connect to the
  1126. // remote object and copy it back into our object
  1127. // local machine
  1128. BSTR bstrServerName = SysAllocString(_T(""));
  1129. BSTR bstrUserName = SysAllocString(_T(""));
  1130. BSTR bstrUserPassword = SysAllocString(_T(""));
  1131. BSTR bstrInstanceName = SysAllocString(m_WebSiteInstanceName);
  1132. // remote machine
  1133. BSTR bstrServerName_Remote = SysAllocString(m_MachineName_Remote);
  1134. BSTR bstrInstanceName_Remote = SysAllocString(m_WebSiteInstanceName_Remote);
  1135. m_hResult = CoInitialize(NULL);
  1136. if(FAILED(m_hResult))
  1137. {
  1138. return bRes;
  1139. }
  1140. bPleaseDoCoUninit = TRUE;
  1141. // this one seems to work with surrogates..
  1142. m_hResult = CoCreateInstance(CLSID_IISCertObj,NULL,CLSCTX_SERVER,IID_IIISCertObj,(void **)&pTheObject);
  1143. if (FAILED(m_hResult))
  1144. {
  1145. goto InstallCopyMoveToRemote_Exit;
  1146. }
  1147. // at this point we were able to instantiate the com object on the server (local or remote)
  1148. pTheObject->put_ServerName(bstrServerName);
  1149. pTheObject->put_UserName(bstrUserName);
  1150. pTheObject->put_UserPassword(bstrUserPassword);
  1151. pTheObject->put_InstanceName(bstrInstanceName);
  1152. if (m_DeleteAfterCopy)
  1153. {
  1154. m_hResult = pTheObject->Move(bAllowExport,bOverWriteExisting,bstrServerName_Remote,bstrInstanceName_Remote,varUserName_Remote,varUserPassword_Remote);
  1155. }
  1156. else
  1157. {
  1158. m_hResult = pTheObject->Copy(bAllowExport,bOverWriteExisting,bstrServerName_Remote,bstrInstanceName_Remote,varUserName_Remote,varUserPassword_Remote);
  1159. }
  1160. if (FAILED(m_hResult))
  1161. {
  1162. goto InstallCopyMoveToRemote_Exit;
  1163. }
  1164. m_hResult = S_OK;
  1165. bRes = TRUE;
  1166. InstallCopyMoveToRemote_Exit:
  1167. if (pvarUserName_Remote)
  1168. {
  1169. VariantClear(pvarUserName_Remote);
  1170. }
  1171. if (pvarUserPassword_Remote)
  1172. {
  1173. VariantClear(pvarUserPassword_Remote);
  1174. }
  1175. if (!bRes)
  1176. {
  1177. SetBodyTextID(USE_DEFAULT_CAPTION);
  1178. }
  1179. if (pTheObject)
  1180. {
  1181. pTheObject->Release();
  1182. pTheObject = NULL;
  1183. }
  1184. if (bPleaseDoCoUninit)
  1185. {
  1186. CoUninitialize();
  1187. }
  1188. return bRes;
  1189. }
  1190. // We don't have initial request for KeyRing certificate, therefore we will
  1191. // not be able to renew this certificate
  1192. //
  1193. BOOL
  1194. CCertificate::InstallExportPFXCert()
  1195. {
  1196. ASSERT(!m_KeyFileName.IsEmpty());
  1197. ASSERT(!m_KeyPassword.IsEmpty());
  1198. ASSERT(!m_WebSiteInstanceName.IsEmpty());
  1199. BOOL bRes = FALSE;
  1200. BOOL bPleaseDoCoUninit = FALSE;
  1201. IIISCertObj *pTheObject = NULL;
  1202. VARIANT_BOOL bExportThePrivateKeyToo = VARIANT_FALSE;
  1203. if (m_ExportPFXPrivateKey)
  1204. {
  1205. bExportThePrivateKeyToo = VARIANT_TRUE;
  1206. }
  1207. else
  1208. {
  1209. bExportThePrivateKeyToo = VARIANT_FALSE;
  1210. }
  1211. if (FALSE == m_CertObjInstalled)
  1212. {
  1213. goto InstallExportPFXCert_Exit;
  1214. }
  1215. // since this is the local machine
  1216. // make sure all this stuff is not set.
  1217. BSTR bstrServerName = SysAllocString(_T(""));
  1218. BSTR bstrUserName = SysAllocString(_T(""));
  1219. BSTR bstrUserPassword = SysAllocString(_T(""));
  1220. // create bstrs for these member cstrings
  1221. BSTR bstrFileName = SysAllocString(m_KeyFileName);
  1222. LPTSTR lpTempPassword = m_KeyPassword.GetClearTextPassword();
  1223. BSTR bstrFilePassword = SysAllocString(lpTempPassword);
  1224. m_KeyPassword.DestroyClearTextPassword(lpTempPassword);
  1225. BSTR bstrInstanceName = SysAllocString(m_WebSiteInstanceName);
  1226. m_hResult = CoInitialize(NULL);
  1227. if(FAILED(m_hResult))
  1228. {
  1229. return bRes;
  1230. }
  1231. bPleaseDoCoUninit = TRUE;
  1232. // this one seems to work with surrogates..
  1233. m_hResult = CoCreateInstance(CLSID_IISCertObj,NULL,CLSCTX_SERVER,IID_IIISCertObj,(void **)&pTheObject);
  1234. if (FAILED(m_hResult))
  1235. {
  1236. goto InstallExportPFXCert_Exit;
  1237. }
  1238. // at this point we were able to instantiate the com object on the server (local or remote)
  1239. pTheObject->put_ServerName(bstrServerName);
  1240. pTheObject->put_UserName(bstrUserName);
  1241. pTheObject->put_UserPassword(bstrUserPassword);
  1242. pTheObject->put_InstanceName(bstrInstanceName);
  1243. m_hResult = pTheObject->Export(bstrFileName,bstrFilePassword,bExportThePrivateKeyToo,VARIANT_FALSE,VARIANT_FALSE);
  1244. if (FAILED(m_hResult))
  1245. {
  1246. goto InstallExportPFXCert_Exit;
  1247. }
  1248. m_hResult = S_OK;
  1249. bRes = TRUE;
  1250. InstallExportPFXCert_Exit:
  1251. if (!bRes)
  1252. {
  1253. SetBodyTextID(USE_DEFAULT_CAPTION);
  1254. }
  1255. if (pTheObject)
  1256. {
  1257. pTheObject->Release();
  1258. pTheObject = NULL;
  1259. }
  1260. if (bPleaseDoCoUninit)
  1261. {
  1262. CoUninitialize();
  1263. }
  1264. return bRes;
  1265. }
  1266. //
  1267. BOOL
  1268. CCertificate::InstallImportPFXCert()
  1269. {
  1270. BOOL bRes = FALSE;
  1271. CCryptBlobLocal hash_blob;
  1272. if (::GetHashProperty(GetImportCert(), hash_blob, &m_hResult))
  1273. {
  1274. HRESULT hr;
  1275. CString name;
  1276. ::GetFriendlyName(GetImportCert(), name, &hr);
  1277. if (CRYPT_E_NOT_FOUND == hr || name.IsEmpty())
  1278. {
  1279. CERT_DESCRIPTION desc;
  1280. if (GetCertDescription(GetImportCert(), desc))
  1281. {
  1282. bRes = AttachFriendlyName(GetImportCert(), desc.m_CommonName, &hr);
  1283. }
  1284. }
  1285. ASSERT(bRes);
  1286. bRes = InstallCertByHash(hash_blob, m_MachineName, m_WebSiteInstanceName,
  1287. GetEnrollObject(), &m_hResult);
  1288. }
  1289. if (!bRes)
  1290. {
  1291. SetBodyTextID(USE_DEFAULT_CAPTION);
  1292. }
  1293. #ifdef ENABLE_W3SVC_SSL_PAGE
  1294. // see if the SSL attribute was set...if it was then set the SSL site for this certificate...
  1295. if (!m_SSLPort.IsEmpty())
  1296. {
  1297. // get the port and write it to the metabase.
  1298. bRes = WriteSSLPortToSite(m_MachineName,m_WebSiteInstanceName,m_SSLPort,&m_hResult);
  1299. if (!bRes)
  1300. {
  1301. SetBodyTextID(USE_DEFAULT_CAPTION);
  1302. }
  1303. }
  1304. #endif
  1305. return bRes;
  1306. }
  1307. // We don't have initial request for KeyRing certificate, therefore we will
  1308. // not be able to renew this certificate
  1309. //
  1310. BOOL
  1311. CCertificate::InstallKeyRingCert()
  1312. {
  1313. BOOL bRes = FALSE;
  1314. CCryptBlobLocal hash_blob;
  1315. if (::GetHashProperty(GetKeyRingCert(), hash_blob, &m_hResult))
  1316. {
  1317. HRESULT hr;
  1318. CString name;
  1319. ::GetFriendlyName(GetKeyRingCert(), name, &hr);
  1320. if (CRYPT_E_NOT_FOUND == hr || name.IsEmpty())
  1321. {
  1322. CERT_DESCRIPTION desc;
  1323. if (GetCertDescription(GetKeyRingCert(), desc))
  1324. {
  1325. bRes = AttachFriendlyName(GetKeyRingCert(), desc.m_CommonName, &hr);
  1326. }
  1327. }
  1328. ASSERT(bRes);
  1329. bRes = InstallCertByHash(hash_blob, m_MachineName, m_WebSiteInstanceName,
  1330. GetEnrollObject(), &m_hResult);
  1331. }
  1332. if (!bRes)
  1333. {
  1334. SetBodyTextID(USE_DEFAULT_CAPTION);
  1335. }
  1336. #ifdef ENABLE_W3SVC_SSL_PAGE
  1337. // see if the SSL attribute was set...if it was then set the SSL site for this certificate...
  1338. if (!m_SSLPort.IsEmpty())
  1339. {
  1340. // get the port and write it to the metabase.
  1341. bRes = WriteSSLPortToSite(m_MachineName,m_WebSiteInstanceName,m_SSLPort,&m_hResult);
  1342. if (!bRes)
  1343. {
  1344. SetBodyTextID(USE_DEFAULT_CAPTION);
  1345. }
  1346. }
  1347. #endif
  1348. return bRes;
  1349. }
  1350. // Instead of renewal we create new certificate based on parameters
  1351. // from the current one. After creation we install this certificate in place
  1352. // of current one and deleting the old one from store. Even if IIS has an
  1353. // opened SSL connection it should get a notification and update the certificate
  1354. // data.
  1355. //
  1356. BOOL
  1357. CCertificate::SubmitRenewalRequest()
  1358. {
  1359. BOOL bRes = LoadRenewalData();
  1360. if (bRes)
  1361. {
  1362. bRes = SetSecuritySettings();
  1363. if (bRes)
  1364. {
  1365. PCCERT_CONTEXT pCurrent = GetInstalledCert();
  1366. m_pInstalledCert = NULL;
  1367. if (bRes = SubmitRequest())
  1368. {
  1369. CertDeleteCertificateFromStore(pCurrent);
  1370. }
  1371. }
  1372. }
  1373. return bRes;
  1374. }
  1375. BOOL CCertificate::SubmitRequest()
  1376. {
  1377. ASSERT(!m_ConfigCA.IsEmpty());
  1378. BOOL bRes = FALSE;
  1379. ICertRequest * pRequest = NULL;
  1380. if (SUCCEEDED(m_hResult = CoCreateInstance(CLSID_CCertRequest, NULL,
  1381. CLSCTX_INPROC_SERVER, IID_ICertRequest, (void **)&pRequest)))
  1382. {
  1383. CString strDN;
  1384. CreateDN(strDN);
  1385. BSTR request = NULL;
  1386. if (SUCCEEDED(m_hResult = CreateRequest_Base64(
  1387. (BSTR)(LPCTSTR)strDN,
  1388. GetEnrollObject(),
  1389. m_DefaultCSP ? NULL : (LPTSTR)(LPCTSTR)m_CspName,
  1390. m_DefaultCSP ? m_DefaultProviderType : m_CustomProviderType,
  1391. &request)))
  1392. {
  1393. ASSERT(pRequest != NULL);
  1394. CString attrib;
  1395. GetCertificateTemplate(attrib);
  1396. LONG disp;
  1397. m_hResult = pRequest->Submit(CR_IN_BASE64 | CR_IN_PKCS10,
  1398. request,
  1399. (BSTR)(LPCTSTR)attrib,
  1400. (LPTSTR)(LPCTSTR)m_ConfigCA,
  1401. &disp);
  1402. if (FAILED(m_hResult))
  1403. {
  1404. IISDebugOutput(_T("Submit request returned HRESULT 0x%x; Disposition %x\n"), m_hResult, disp);
  1405. }
  1406. if (SUCCEEDED(m_hResult))
  1407. {
  1408. if (disp == CR_DISP_ISSUED)
  1409. {
  1410. BSTR bstrOutCert = NULL;
  1411. if (SUCCEEDED(m_hResult =
  1412. pRequest->GetCertificate(CR_OUT_BASE64 /*| CR_OUT_CHAIN */, &bstrOutCert)))
  1413. {
  1414. CRYPT_DATA_BLOB blob;
  1415. blob.cbData = SysStringByteLen(bstrOutCert);
  1416. blob.pbData = (BYTE *)bstrOutCert;
  1417. m_hResult = GetEnrollObject()->acceptPKCS7Blob(&blob);
  1418. if (SUCCEEDED(m_hResult))
  1419. {
  1420. PCCERT_CONTEXT pContext = GetCertContextFromPKCS7(blob.pbData, blob.cbData,
  1421. NULL, &m_hResult);
  1422. ASSERT(pContext != NULL);
  1423. if (pContext != NULL)
  1424. {
  1425. BYTE HashBuffer[40]; // give it some extra size
  1426. DWORD dwHashSize = sizeof(HashBuffer);
  1427. if (CertGetCertificateContextProperty(pContext,
  1428. CERT_SHA1_HASH_PROP_ID,
  1429. (VOID *) HashBuffer,
  1430. &dwHashSize))
  1431. {
  1432. CRYPT_HASH_BLOB hash_blob = {dwHashSize, HashBuffer};
  1433. if (!(bRes = InstallHashToMetabase(&hash_blob,
  1434. m_MachineName,
  1435. m_WebSiteInstanceName,
  1436. &m_hResult)))
  1437. {
  1438. SetBodyTextID(IDS_CERT_INSTALLATION_FAILURE);
  1439. }
  1440. }
  1441. CertFreeCertificateContext(pContext);
  1442. }
  1443. // now put extra properties to the installed cert
  1444. if (NULL != (pContext = GetInstalledCert()))
  1445. {
  1446. if (!(bRes = AttachFriendlyName(pContext, m_FriendlyName, &m_hResult)))
  1447. {
  1448. SetBodyTextID(IDS_CERT_INSTALLATION_FAILURE);
  1449. }
  1450. }
  1451. }
  1452. if (bstrOutCert){SysFreeString(bstrOutCert);}
  1453. }
  1454. }
  1455. else
  1456. {
  1457. switch (disp)
  1458. {
  1459. case CR_DISP_INCOMPLETE:
  1460. case CR_DISP_ERROR:
  1461. case CR_DISP_DENIED:
  1462. case CR_DISP_ISSUED_OUT_OF_BAND:
  1463. case CR_DISP_UNDER_SUBMISSION:
  1464. {
  1465. BOOL bFailedToGetMsg = TRUE;
  1466. HRESULT hrLastStatus = 0;
  1467. if (SUCCEEDED(pRequest ->GetLastStatus(&hrLastStatus)))
  1468. {
  1469. LPTSTR lpBuffer = NULL;
  1470. DWORD cChars = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  1471. NULL,
  1472. hrLastStatus,
  1473. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  1474. (LPTSTR)&lpBuffer, 0, NULL);
  1475. if (cChars != 0)
  1476. {
  1477. CString csTemp = lpBuffer;
  1478. SetBodyTextString(csTemp);
  1479. bFailedToGetMsg = FALSE;
  1480. }
  1481. if (lpBuffer ) {LocalFree (lpBuffer);}
  1482. m_hResult = hrLastStatus;
  1483. }
  1484. if (TRUE == bFailedToGetMsg)
  1485. {
  1486. BSTR bstr = NULL;
  1487. if (SUCCEEDED(pRequest->GetDispositionMessage(&bstr)))
  1488. {
  1489. SetBodyTextString(CString(bstr));
  1490. if (bstr) {SysFreeString(bstr);}
  1491. }
  1492. m_hResult = E_FAIL;
  1493. }
  1494. }
  1495. break;
  1496. default:
  1497. SetBodyTextID(IDS_INTERNAL_ERROR);
  1498. break;
  1499. }
  1500. }
  1501. }
  1502. else // !SUCCEEDED
  1503. {
  1504. // clear out any error IDs and strings
  1505. // we will use default processing of m_hResult
  1506. SetBodyTextID(USE_DEFAULT_CAPTION);
  1507. }
  1508. if (request){SysFreeString(request);}
  1509. }
  1510. else
  1511. {
  1512. // CreateRequest_Base64 failed.
  1513. // likely with "NTE_BAD_ALGID _HRESULT_TYPEDEF_(0x80090008L)"
  1514. BOOL bFailedToGetMsg = TRUE;
  1515. HRESULT hrLastStatus = m_hResult;
  1516. LPTSTR lpBuffer = NULL;
  1517. DWORD cChars = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  1518. NULL,
  1519. hrLastStatus,
  1520. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  1521. (LPTSTR)&lpBuffer, 0, NULL);
  1522. if (cChars != 0)
  1523. {
  1524. if (lpBuffer)
  1525. {
  1526. CString csTemp = lpBuffer;
  1527. if (!csTemp.IsEmpty())
  1528. {
  1529. SetBodyTextString(csTemp);
  1530. }
  1531. bFailedToGetMsg = FALSE;
  1532. }
  1533. }
  1534. if (lpBuffer ) {LocalFree (lpBuffer);}
  1535. }
  1536. pRequest->Release();
  1537. }
  1538. IISDebugOutput(_T("SubmitRequest:end:hres=0x%x;\n"), m_hResult);
  1539. return bRes;
  1540. }
  1541. BOOL
  1542. CCertificate::PrepareRequestString(CString& request_text, CCryptBlob& request_blob)
  1543. {
  1544. BOOL bRet = FALSE;
  1545. CString strDN;
  1546. TCHAR szUsage[] = _T(szOID_PKIX_KP_SERVER_AUTH);
  1547. DWORD err, cch;
  1548. char * psz = NULL;
  1549. if (m_status_code == REQUEST_RENEW_CERT)
  1550. {
  1551. if (FALSE == LoadRenewalData())
  1552. {return FALSE;}
  1553. if (FALSE == SetSecuritySettings())
  1554. {return FALSE;}
  1555. }
  1556. CreateDN(strDN);
  1557. ASSERT(!strDN.IsEmpty());
  1558. GetEnrollObject()->put_ProviderType(m_DefaultCSP ? m_DefaultProviderType : m_CustomProviderType);
  1559. if (!m_DefaultCSP)
  1560. {
  1561. GetEnrollObject()->put_ProviderNameWStr((LPTSTR)(LPCTSTR)m_CspName);
  1562. // We are supporting only these two types of CSP, it is pretty safe to
  1563. // have just two options, because we are using the same two types when
  1564. // we are populating CSP selection list.
  1565. if (m_CustomProviderType == PROV_DH_SCHANNEL)
  1566. {
  1567. GetEnrollObject()->put_KeySpec(AT_SIGNATURE);
  1568. }
  1569. else if (m_CustomProviderType == PROV_RSA_SCHANNEL)
  1570. {
  1571. GetEnrollObject()->put_KeySpec(AT_KEYEXCHANGE);
  1572. }
  1573. }
  1574. if (FAILED(m_hResult = GetEnrollObject()->createPKCS10WStr((LPTSTR)(LPCTSTR)strDN, szUsage, request_blob)))
  1575. {
  1576. SetBodyTextID(USE_DEFAULT_CAPTION);
  1577. return FALSE;
  1578. }
  1579. // BASE64 encode pkcs 10
  1580. if (ERROR_SUCCESS != (err = Base64EncodeA(request_blob.GetData(), request_blob.GetSize(), NULL, &cch)))
  1581. {
  1582. return FALSE;
  1583. }
  1584. bRet = FALSE;
  1585. psz = (char *) LocalAlloc(LPTR,cch+1);
  1586. if (NULL == psz)
  1587. {
  1588. goto PrepareRequestString_Exit;
  1589. }
  1590. if (ERROR_SUCCESS != (err = Base64EncodeA(request_blob.GetData(), request_blob.GetSize(), psz, &cch)))
  1591. {
  1592. goto PrepareRequestString_Exit;
  1593. }
  1594. psz[cch] = '\0';
  1595. request_text = MESSAGE_HEADER;
  1596. request_text += psz;
  1597. request_text += MESSAGE_TRAILER;
  1598. bRet = TRUE;
  1599. PrepareRequestString_Exit:
  1600. if (psz)
  1601. {LocalFree(psz);psz=NULL;}
  1602. return bRet;
  1603. }
  1604. BOOL
  1605. CCertificate::PrepareRequest()
  1606. {
  1607. BOOL bRes = FALSE;
  1608. CString request_text;
  1609. CCryptBlobIMalloc request_blob;
  1610. if (PrepareRequestString(request_text, request_blob))
  1611. {
  1612. if (WriteRequestString(request_text))
  1613. {
  1614. CCryptBlobLocal name_blob, request_store_blob, status_blob;
  1615. // prepare data we want to attach to dummy request
  1616. if ( EncodeString(m_WebSiteInstanceName, name_blob, &m_hResult)
  1617. && EncodeInteger(m_status_code, status_blob, &m_hResult)
  1618. )
  1619. {
  1620. // get back request from encoded data
  1621. PCERT_REQUEST_INFO pReqInfo;
  1622. bRes = GetRequestInfoFromPKCS10(request_blob, &pReqInfo, &m_hResult);
  1623. if (bRes)
  1624. {
  1625. // find dummy cert put to request store by createPKCS10 call
  1626. HCERTSTORE hStore = OpenRequestStore(GetEnrollObject(), &m_hResult);
  1627. if (hStore != NULL)
  1628. {
  1629. PCCERT_CONTEXT pDummyCert = CertFindCertificateInStore(hStore,
  1630. CRYPT_ASN_ENCODING,
  1631. 0,
  1632. CERT_FIND_PUBLIC_KEY,
  1633. (void *)&pReqInfo->SubjectPublicKeyInfo,
  1634. NULL);
  1635. if (pDummyCert != NULL)
  1636. {
  1637. if ( CertSetCertificateContextProperty(pDummyCert,
  1638. CERTWIZ_INSTANCE_NAME_PROP_ID, 0, name_blob)
  1639. && CertSetCertificateContextProperty(pDummyCert,
  1640. CERTWIZ_REQUEST_FLAG_PROP_ID, 0, status_blob)
  1641. // put friendly name to dummy cert -- we will reuse it later
  1642. && AttachFriendlyName(pDummyCert, m_FriendlyName, &m_hResult)
  1643. )
  1644. {
  1645. bRes = TRUE;
  1646. // put certificate text to the clipboard
  1647. if (OpenClipboard(GetFocus()))
  1648. {
  1649. size_t len = request_text.GetLength() + 1;
  1650. HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len);
  1651. LPSTR pMem = (LPSTR)GlobalLock(hMem);
  1652. if (pMem != NULL)
  1653. {
  1654. wcstombs(pMem, request_text, len);
  1655. GlobalUnlock(hMem);
  1656. SetClipboardData(CF_TEXT, hMem);
  1657. }
  1658. CloseClipboard();
  1659. }
  1660. }
  1661. else
  1662. {
  1663. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  1664. }
  1665. CertFreeCertificateContext(pDummyCert);
  1666. }
  1667. CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
  1668. }
  1669. LocalFree(pReqInfo);
  1670. }
  1671. }
  1672. }
  1673. }
  1674. if (!bRes)
  1675. SetBodyTextID(USE_DEFAULT_CAPTION);
  1676. return bRes;
  1677. }
  1678. BOOL CCertificate::LoadRenewalData()
  1679. {
  1680. // we need to obtain data from the installed cert
  1681. CERT_DESCRIPTION desc;
  1682. BOOL res = FALSE;
  1683. DWORD cbData;
  1684. BYTE * pByte = NULL;
  1685. DWORD len = 0;
  1686. PCCERT_CONTEXT pCertTemp = GetInstalledCert();
  1687. if (!pCertTemp)
  1688. {
  1689. res = FALSE;
  1690. goto ErrorExit;
  1691. }
  1692. if (!GetCertDescription(pCertTemp, desc))
  1693. {
  1694. res = FALSE;
  1695. goto ErrorExit;
  1696. }
  1697. m_CommonName = desc.m_CommonName;
  1698. m_FriendlyName = desc.m_FriendlyName;
  1699. m_Country = desc.m_Country;
  1700. m_State = desc.m_State;
  1701. m_Locality = desc.m_Locality;
  1702. m_Organization = desc.m_Organization;
  1703. m_OrganizationUnit = desc.m_OrganizationUnit;
  1704. len = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &pCertTemp->pCertInfo->SubjectPublicKeyInfo);
  1705. if (len == 0)
  1706. {
  1707. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  1708. goto ErrorExit;
  1709. }
  1710. m_KeyLength = len;
  1711. // compare property value
  1712. if (!CertGetCertificateContextProperty(pCertTemp, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData))
  1713. {
  1714. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  1715. goto ErrorExit;
  1716. }
  1717. pByte = (BYTE *)LocalAlloc(LPTR,cbData);
  1718. if (NULL == pByte)
  1719. {
  1720. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  1721. goto ErrorExit;
  1722. }
  1723. if (!CertGetCertificateContextProperty(pCertTemp, CERT_KEY_PROV_INFO_PROP_ID, pByte, &cbData))
  1724. {
  1725. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  1726. goto ErrorExit;
  1727. }
  1728. else
  1729. {
  1730. CRYPT_KEY_PROV_INFO * pProvInfo = (CRYPT_KEY_PROV_INFO *)pByte;
  1731. if (pProvInfo->dwProvType != m_DefaultProviderType)
  1732. {
  1733. m_DefaultCSP = FALSE;
  1734. m_CustomProviderType = pProvInfo->dwProvType;
  1735. m_CspName = pProvInfo->pwszProvName;
  1736. }
  1737. CArray<LPCSTR, LPCSTR> uses;
  1738. uses.Add(szOID_SERVER_GATED_CRYPTO);
  1739. uses.Add(szOID_SGC_NETSCAPE);
  1740. m_SGCcertificat = FALSE;
  1741. INT iEnhancedKeyUsage = ContainsKeyUsageProperty(pCertTemp, uses, &m_hResult);
  1742. switch (iEnhancedKeyUsage)
  1743. {
  1744. case 0:
  1745. {
  1746. // BUG:683489:remove check for basic constraint "subjecttype=ca"
  1747. // Per bug 683489, accept it
  1748. m_SGCcertificat = TRUE;
  1749. /*
  1750. // check other stuff
  1751. if (DID_NOT_FIND_CONSTRAINT == CheckCertConstraints(pCertTemp) || FOUND_CONSTRAINT == CheckCertConstraints(pCertTemp))
  1752. {
  1753. // it's good
  1754. m_SGCcertificat = TRUE;
  1755. }
  1756. */
  1757. break;
  1758. }
  1759. case 1:
  1760. // This Cert has the uses we want...
  1761. m_SGCcertificat = TRUE;
  1762. break;
  1763. case 2:
  1764. // This Cert does not have the uses we want...
  1765. // skip this cert
  1766. break;
  1767. default:
  1768. // should never get here.
  1769. break;
  1770. }
  1771. res = TRUE;
  1772. }
  1773. ErrorExit:
  1774. if (pByte)
  1775. {
  1776. LocalFree(pByte);pByte=NULL;
  1777. }
  1778. return res;
  1779. }
  1780. #if 0
  1781. BOOL
  1782. CCertificate::WriteRenewalRequest()
  1783. {
  1784. BOOL bRes = FALSE;
  1785. if (GetInstalledCert() != NULL)
  1786. {
  1787. BSTR bstrRequest;
  1788. if ( SUCCEEDED(m_hResult = GetEnrollObject()->put_RenewalCertificate(GetInstalledCert()))
  1789. && SUCCEEDED(m_hResult = CreateRequest_Base64(bstrEmpty,
  1790. GetEnrollObject(),
  1791. m_DefaultCSP ? NULL : (LPTSTR)(LPCTSTR)m_CspName,
  1792. m_DefaultCSP ? m_DefaultProviderType : m_CustomProviderType,
  1793. &bstrRequest))
  1794. )
  1795. {
  1796. CString str = MESSAGE_HEADER;
  1797. str += bstrRequest;
  1798. str += MESSAGE_TRAILER;
  1799. if (WriteRequestString(str))
  1800. {
  1801. CCryptBlobLocal name_blob, status_blob;
  1802. CCryptBlobIMalloc request_blob;
  1803. request_blob.Set(SysStringLen(bstrRequest), (BYTE *)bstrRequest);
  1804. // prepare data we want to attach to dummy request
  1805. if ( EncodeString(m_WebSiteInstanceName, name_blob, &m_hResult)
  1806. && EncodeInteger(m_status_code, status_blob, &m_hResult)
  1807. )
  1808. {
  1809. // get back request from encoded data
  1810. PCERT_REQUEST_INFO req_info;
  1811. if (GetRequestInfoFromPKCS10(request_blob, &req_info, &m_hResult))
  1812. {
  1813. // find dummy cert put to request store by createPKCS10 call
  1814. HCERTSTORE hStore = OpenRequestStore(GetEnrollObject(), &m_hResult);
  1815. if (hStore != NULL)
  1816. {
  1817. PCCERT_CONTEXT pDummyCert = CertFindCertificateInStore(hStore,
  1818. CRYPT_ASN_ENCODING,
  1819. 0,
  1820. CERT_FIND_PUBLIC_KEY,
  1821. (void *)&req_info->SubjectPublicKeyInfo,
  1822. NULL);
  1823. if (pDummyCert != NULL)
  1824. {
  1825. if ( CertSetCertificateContextProperty(pDummyCert,
  1826. CERTWIZ_INSTANCE_NAME_PROP_ID, 0, name_blob)
  1827. && CertSetCertificateContextProperty(pDummyCert,
  1828. CERTWIZ_REQUEST_FLAG_PROP_ID, 0, status_blob)
  1829. // put friendly name to dummy cert -- we will reuse it later
  1830. && AttachFriendlyName(pDummyCert, m_FriendlyName, &m_hResult)
  1831. )
  1832. {
  1833. bRes = TRUE;
  1834. }
  1835. else
  1836. {
  1837. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  1838. }
  1839. CertFreeCertificateContext(pDummyCert);
  1840. }
  1841. CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
  1842. }
  1843. LocalFree(req_info);
  1844. }
  1845. }
  1846. }
  1847. }
  1848. }
  1849. return bRes;
  1850. }
  1851. #endif
  1852. CCertDescList::~CCertDescList()
  1853. {
  1854. POSITION pos = GetHeadPosition();
  1855. while (pos != NULL)
  1856. {
  1857. CERT_DESCRIPTION * pDesc = GetNext(pos);
  1858. if (pDesc)
  1859. {
  1860. if (pDesc->m_phash)
  1861. {
  1862. LocalFree(pDesc->m_phash);
  1863. pDesc->m_phash = NULL;
  1864. }
  1865. delete pDesc;
  1866. pDesc = NULL;
  1867. }
  1868. }
  1869. }
  1870. BOOL
  1871. CCertificate::GetCertDescription(PCCERT_CONTEXT pCert,
  1872. CERT_DESCRIPTION& desc)
  1873. {
  1874. BOOL bRes = FALSE;
  1875. DWORD cb;
  1876. UINT i, j;
  1877. CERT_NAME_INFO * pNameInfo = NULL;
  1878. desc.m_CommonName = _T("");
  1879. desc.m_FriendlyName = _T("");
  1880. desc.m_Country = _T("");
  1881. desc.m_State = _T("");
  1882. desc.m_Locality = _T("");
  1883. desc.m_Organization = _T("");
  1884. desc.m_OrganizationUnit = _T("");
  1885. desc.m_CAName = _T("");
  1886. desc.m_ExpirationDate = _T("");
  1887. desc.m_Usage = _T("");
  1888. desc.m_AltSubject = _T("");
  1889. desc.m_phash = NULL;
  1890. desc.m_hash_length = 0;
  1891. if (pCert == NULL)
  1892. goto ErrExit;
  1893. if ( !CryptDecodeObject(X509_ASN_ENCODING, X509_UNICODE_NAME,
  1894. pCert->pCertInfo->Subject.pbData,
  1895. pCert->pCertInfo->Subject.cbData,
  1896. 0, NULL, &cb))
  1897. {
  1898. goto ErrExit;
  1899. }
  1900. pNameInfo = (CERT_NAME_INFO *) LocalAlloc(LPTR,cb);
  1901. if (NULL == pNameInfo)
  1902. {
  1903. goto ErrExit;
  1904. }
  1905. if (!CryptDecodeObject(X509_ASN_ENCODING, X509_UNICODE_NAME,
  1906. pCert->pCertInfo->Subject.pbData,
  1907. pCert->pCertInfo->Subject.cbData,
  1908. 0,
  1909. pNameInfo, &cb))
  1910. {
  1911. goto ErrExit;
  1912. }
  1913. for (i = 0; i < pNameInfo->cRDN; i++)
  1914. {
  1915. CERT_RDN rdn = pNameInfo->rgRDN[i];
  1916. for (j = 0; j < rdn.cRDNAttr; j++)
  1917. {
  1918. CERT_RDN_ATTR attr = rdn.rgRDNAttr[j];
  1919. if (strcmp(attr.pszObjId, szOID_COMMON_NAME) == 0)
  1920. {
  1921. FormatRdnAttr(desc.m_CommonName, attr.dwValueType, attr.Value, FALSE);
  1922. }
  1923. else if (strcmp(attr.pszObjId, szOID_COUNTRY_NAME) == 0)
  1924. {
  1925. FormatRdnAttr(desc.m_Country, attr.dwValueType, attr.Value, TRUE);
  1926. }
  1927. else if (strcmp(attr.pszObjId, szOID_LOCALITY_NAME) == 0)
  1928. {
  1929. FormatRdnAttr(desc.m_Locality, attr.dwValueType, attr.Value, TRUE);
  1930. }
  1931. else if (strcmp(attr.pszObjId, szOID_STATE_OR_PROVINCE_NAME) == 0)
  1932. {
  1933. FormatRdnAttr(desc.m_State, attr.dwValueType, attr.Value, TRUE);
  1934. }
  1935. else if (strcmp(attr.pszObjId, szOID_ORGANIZATION_NAME) == 0)
  1936. {
  1937. FormatRdnAttr(desc.m_Organization, attr.dwValueType, attr.Value, TRUE);
  1938. }
  1939. else if (strcmp(attr.pszObjId, szOID_ORGANIZATIONAL_UNIT_NAME) == 0)
  1940. {
  1941. if(!lstrlen(desc.m_OrganizationUnit)) // WinSE 30339
  1942. FormatRdnAttr(desc.m_OrganizationUnit, attr.dwValueType, attr.Value, TRUE);
  1943. }
  1944. }
  1945. }
  1946. // issued to
  1947. if (!GetNameString(pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, desc.m_CAName, &m_hResult))
  1948. {
  1949. goto ErrExit;
  1950. }
  1951. // expiration date
  1952. if (!FormatDateString(desc.m_ExpirationDate, pCert->pCertInfo->NotAfter, FALSE, FALSE))
  1953. {
  1954. goto ErrExit;
  1955. }
  1956. // purpose
  1957. if (!FormatEnhancedKeyUsageString(desc.m_Usage, pCert, FALSE, FALSE, &m_hResult))
  1958. {
  1959. // According to local experts, we should also use certs without this property set
  1960. //ASSERT(FALSE);
  1961. //goto ErrExit;
  1962. }
  1963. // friendly name
  1964. if (!GetFriendlyName(pCert, desc.m_FriendlyName, &m_hResult))
  1965. {
  1966. desc.m_FriendlyName.LoadString(IDS_FRIENDLYNAME_NONE);
  1967. }
  1968. // get the alternate subject name if subject is empty
  1969. // will use this as display only if subject name does not exist.
  1970. if (desc.m_CommonName.IsEmpty())
  1971. {
  1972. TCHAR * pwszOut = NULL;
  1973. GetAlternateSubjectName(pCert,&pwszOut);
  1974. if (pwszOut)
  1975. {
  1976. desc.m_AltSubject = pwszOut;
  1977. LocalFree(pwszOut);pwszOut = NULL;
  1978. }
  1979. }
  1980. bRes = TRUE;
  1981. ErrExit:
  1982. if (pNameInfo)
  1983. {
  1984. LocalFree(pNameInfo);pNameInfo=NULL;
  1985. }
  1986. return bRes;
  1987. }
  1988. int
  1989. CCertificate::MyStoreCertCount()
  1990. {
  1991. int count = 0;
  1992. HCERTSTORE hStore = OpenMyStore(GetEnrollObject(), &m_hResult);
  1993. if (hStore != NULL)
  1994. {
  1995. PCCERT_CONTEXT pCert = NULL;
  1996. CArray<LPCSTR, LPCSTR> uses;
  1997. uses.Add(szOID_PKIX_KP_SERVER_AUTH);
  1998. uses.Add(szOID_SERVER_GATED_CRYPTO);
  1999. uses.Add(szOID_SGC_NETSCAPE);
  2000. INT iEnhancedKeyUsage = 0;
  2001. while (NULL != (pCert = CertEnumCertificatesInStore(hStore, pCert)))
  2002. {
  2003. // do not include installed cert to the list
  2004. if ( GetInstalledCert() != NULL
  2005. && CertCompareCertificate(X509_ASN_ENCODING,
  2006. GetInstalledCert()->pCertInfo, pCert->pCertInfo)
  2007. )
  2008. {
  2009. continue;
  2010. }
  2011. //If no EKU, look at basic constraints:
  2012. //If we do not have basic constraints, do display it in the list to pick web server certs from
  2013. //If we do have basic constraints with Subject Type =CA, don't display it in the list to pick web server certs from (this will filter out CA certs)
  2014. //If we do have basic constraints with SubectType !=CA, do display it in the list to pick web server certs from
  2015. iEnhancedKeyUsage = ContainsKeyUsageProperty(pCert, uses, &m_hResult);
  2016. switch (iEnhancedKeyUsage)
  2017. {
  2018. case 0:
  2019. {
  2020. // BUG:683489:remove check for basic constraint "subjecttype=ca"
  2021. // Per bug 683489, accept it
  2022. /*
  2023. // check other stuff
  2024. if (DID_NOT_FIND_CONSTRAINT == CheckCertConstraints(pCert) || FOUND_CONSTRAINT == CheckCertConstraints(pCert))
  2025. {
  2026. // add it up.
  2027. }
  2028. else if (FOUND_CONSTRAINT_BUT_THIS_IS_A_CA_OR_ITS_NOT_AN_END_ENTITY == CheckCertConstraints(pCert))
  2029. {
  2030. // skip this cert
  2031. continue;
  2032. }
  2033. else
  2034. {
  2035. // skip this cert
  2036. continue;
  2037. }
  2038. */
  2039. break;
  2040. }
  2041. case 1:
  2042. // This Cert has the uses we want...
  2043. break;
  2044. case 2:
  2045. // This Cert does not have the uses we want...
  2046. // skip this cert
  2047. continue;
  2048. break;
  2049. default:
  2050. // should never get here.
  2051. continue;
  2052. break;
  2053. }
  2054. count++;
  2055. }
  2056. if (pCert != NULL)
  2057. CertFreeCertificateContext(pCert);
  2058. VERIFY(CertCloseStore(hStore, 0));
  2059. }
  2060. return count;
  2061. }
  2062. BOOL
  2063. CCertificate::GetCertDescList(CCertDescList& list)
  2064. {
  2065. ASSERT(list.GetCount() == 0);
  2066. BOOL bRes = FALSE;
  2067. // we are looking to MY store only
  2068. HCERTSTORE hStore = OpenMyStore(GetEnrollObject(), &m_hResult);
  2069. if (hStore != NULL)
  2070. {
  2071. PCCERT_CONTEXT pCert = NULL;
  2072. // do not include certs with improper usage
  2073. CArray<LPCSTR, LPCSTR> uses;
  2074. uses.Add(szOID_PKIX_KP_SERVER_AUTH);
  2075. uses.Add(szOID_SERVER_GATED_CRYPTO);
  2076. uses.Add(szOID_SGC_NETSCAPE);
  2077. INT iEnhancedKeyUsage = 0;
  2078. while (NULL != (pCert = CertEnumCertificatesInStore(hStore, pCert)))
  2079. {
  2080. // do not include installed cert to the list
  2081. if ( GetInstalledCert() != NULL
  2082. && CertCompareCertificate(X509_ASN_ENCODING,
  2083. GetInstalledCert()->pCertInfo, pCert->pCertInfo)
  2084. )
  2085. {
  2086. continue;
  2087. }
  2088. //If no EKU, look at basic constraints:
  2089. //If we do not have basic constraints, do display it in the list to pick web server certs from
  2090. //If we do have basic constraints with Subject Type =CA, don't display it in the list to pick web server certs from (this will filter out CA certs)
  2091. //If we do have basic constraints with SubectType !=CA, do display it in the list to pick web server certs from
  2092. iEnhancedKeyUsage = ContainsKeyUsageProperty(pCert, uses, &m_hResult);
  2093. switch (iEnhancedKeyUsage)
  2094. {
  2095. case 0:
  2096. {
  2097. // BUG:683489:remove check for basic constraint "subjecttype=ca"
  2098. // Per bug 683489, display it in the list
  2099. /*
  2100. // check other stuff
  2101. if (DID_NOT_FIND_CONSTRAINT == CheckCertConstraints(pCert) || FOUND_CONSTRAINT == CheckCertConstraints(pCert))
  2102. {
  2103. // it's okay, add it to the list
  2104. }
  2105. else
  2106. {
  2107. if (SUCCEEDED(m_hResult) || m_hResult == CRYPT_E_NOT_FOUND)
  2108. continue;
  2109. else
  2110. goto ErrExit;
  2111. }
  2112. */
  2113. break;
  2114. }
  2115. case 1:
  2116. // This Cert has the uses we want...
  2117. break;
  2118. case 2:
  2119. // This Cert does not have the uses we want...
  2120. // skip this cert
  2121. continue;
  2122. break;
  2123. default:
  2124. // should never get here.
  2125. continue;
  2126. break;
  2127. }
  2128. CERT_DESCRIPTION * pDesc = new CERT_DESCRIPTION;
  2129. pDesc->m_hash_length = CERT_HASH_LENGTH;
  2130. if (!GetCertDescription(pCert, *pDesc))
  2131. {
  2132. delete pDesc;
  2133. if (m_hResult == CRYPT_E_NOT_FOUND)
  2134. continue;
  2135. goto ErrExit;
  2136. }
  2137. // Get the size we need to allocate...
  2138. pDesc->m_hash_length = 0;
  2139. pDesc->m_phash = NULL;
  2140. if (CertGetCertificateContextProperty(pCert,
  2141. CERT_SHA1_HASH_PROP_ID,
  2142. (VOID *)NULL,
  2143. &pDesc->m_hash_length))
  2144. {
  2145. pDesc->m_phash = (BYTE *) LocalAlloc(LPTR,pDesc->m_hash_length);
  2146. if (pDesc->m_phash)
  2147. {
  2148. if (!CertGetCertificateContextProperty(pCert,
  2149. CERT_SHA1_HASH_PROP_ID,
  2150. (VOID *)pDesc->m_phash,
  2151. &pDesc->m_hash_length))
  2152. {
  2153. if (pDesc->m_phash)
  2154. {
  2155. LocalFree(pDesc->m_phash);
  2156. }
  2157. delete pDesc;
  2158. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  2159. goto ErrExit;
  2160. }
  2161. }
  2162. else
  2163. {
  2164. delete pDesc;
  2165. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  2166. goto ErrExit;
  2167. }
  2168. }
  2169. else
  2170. {
  2171. delete pDesc;
  2172. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  2173. goto ErrExit;
  2174. }
  2175. list.AddTail(pDesc);
  2176. }
  2177. bRes = TRUE;
  2178. ErrExit:
  2179. if (pCert != NULL)
  2180. CertFreeCertificateContext(pCert);
  2181. VERIFY(CertCloseStore(hStore, 0));
  2182. }
  2183. return bRes;
  2184. }
  2185. BOOL
  2186. CCertificate::ReplaceInstalled()
  2187. {
  2188. // Current cert will be left in the store for next use
  2189. // Selected cert will be installed instead
  2190. return InstallSelectedCert();
  2191. }
  2192. BOOL
  2193. CCertificate::CancelRequest()
  2194. {
  2195. // we are just removing dummy cert from the REQUEST store
  2196. if (NULL != GetPendingRequest())
  2197. {
  2198. BOOL bRes = CertDeleteCertificateFromStore(GetPendingRequest());
  2199. if (!bRes)
  2200. {
  2201. m_hResult = HRESULT_FROM_WIN32(GetLastError());
  2202. SetBodyTextID(USE_DEFAULT_CAPTION);
  2203. }
  2204. else
  2205. m_pPendingRequest = NULL;
  2206. return bRes;
  2207. }
  2208. return FALSE;
  2209. }
  2210. BOOL
  2211. CCertificate::InstallSelectedCert()
  2212. {
  2213. BOOL bRes = FALSE;
  2214. HRESULT hr;
  2215. // local authorities required that cert should have some
  2216. // friendly name. We will put common name when friendly name is not available
  2217. HCERTSTORE hStore = OpenMyStore(GetEnrollObject(), &hr);
  2218. if (hStore != NULL)
  2219. {
  2220. PCCERT_CONTEXT pCert = CertFindCertificateInStore(hStore,
  2221. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  2222. 0, CERT_FIND_HASH,
  2223. (LPVOID)m_pSelectedCertHash,
  2224. NULL);
  2225. if (pCert != NULL)
  2226. {
  2227. CString name;
  2228. ::GetFriendlyName(pCert, name, &hr);
  2229. if (CRYPT_E_NOT_FOUND == hr || name.IsEmpty())
  2230. {
  2231. CERT_DESCRIPTION desc;
  2232. if (GetCertDescription(pCert, desc))
  2233. {
  2234. bRes = AttachFriendlyName(pCert, desc.m_CommonName, &hr);
  2235. }
  2236. }
  2237. }
  2238. VERIFY(CertCloseStore(hStore, 0));
  2239. }
  2240. // we are just rewriting current settings
  2241. // current cert will be left in MY store
  2242. bRes = ::InstallCertByHash(m_pSelectedCertHash,
  2243. m_MachineName,
  2244. m_WebSiteInstanceName,
  2245. GetEnrollObject(),
  2246. &m_hResult);
  2247. if (!bRes)
  2248. {
  2249. SetBodyTextID(USE_DEFAULT_CAPTION);
  2250. }
  2251. #ifdef ENABLE_W3SVC_SSL_PAGE
  2252. // see if the SSL attribute was set...if it was then set the SSL site for this certificate...
  2253. if (!m_SSLPort.IsEmpty())
  2254. {
  2255. // get the port and write it to the metabase.
  2256. bRes = WriteSSLPortToSite(m_MachineName,m_WebSiteInstanceName,m_SSLPort,&m_hResult);
  2257. if (!bRes)
  2258. {
  2259. SetBodyTextID(USE_DEFAULT_CAPTION);
  2260. }
  2261. }
  2262. #endif
  2263. return bRes;
  2264. }