Ejemplo n.º 1
0
static HRESULT ExecuteCertificateOperation(
	__in MSIHANDLE hInstall,
	__in SCA_ACTION saAction,
	__in DWORD dwStoreLocation
	)
{
	//AssertSz(FALSE, "Debug ExecuteCertificateOperation() here.");
	Assert(saAction & SCA_ACTION_INSTALL || saAction & SCA_ACTION_UNINSTALL);

	HRESULT hr = S_OK;
	LPWSTR pwzCaData = NULL;
	LPWSTR pwz;
	LPWSTR pwzName = NULL;
	LPWSTR pwzStore = NULL;
	int iAttributes = 0;
	LPWSTR pwzPFXPassword = NULL;
	LPWSTR pwzFilePath = NULL;
	BYTE* pbData = NULL;
	DWORD cbData = 0;

	HCERTSTORE hCertStore = NULL;

	hr = WcaGetProperty(L"CustomActionData", &pwzCaData);
	ExitOnFailure(hr, "Failed to get CustomActionData");

	WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %S", pwzCaData);

	pwz = pwzCaData;
	hr = WcaReadStringFromCaData(&pwz, &pwzName);
	ExitOnFailure(hr, "Failed to parse certificate name.");
	hr = WcaReadStringFromCaData(&pwz, &pwzStore);
	ExitOnFailure(hr, "Failed to parse CustomActionData, StoreName");
	hr = WcaReadIntegerFromCaData(&pwz, &iAttributes);
	ExitOnFailure(hr, "Failed to parse certificate attribute");
	if (SCA_ACTION_INSTALL == saAction) // install operations need more data
	{
		if (iAttributes & SCA_CERT_INSTALLED_FILE_PATH)
		{
			hr = WcaReadStringFromCaData(&pwz, &pwzFilePath);
			ExitOnFailure(hr, "Failed to parse path to certficate file.");

			hr = FileReadUntil(&pbData, &cbData, pwzFilePath, SIXTY_FOUR_MEG);
			ExitOnFailure(hr, "Failed to read certificate from file path.");
		}
		else
		{
			hr = WcaReadStreamFromCaData(&pwz, &pbData, (DWORD_PTR*)&cbData);
			ExitOnFailure(hr, "Failed to parse certficate stream.");
		}

		hr = WcaReadStringFromCaData(&pwz, &pwzPFXPassword);
		ExitOnFailure(hr, "Failed to parse certificate password.");
	}

	// Open the right store.
	hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation, pwzStore);
	MessageExitOnNullWithLastError1(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store: %S", pwzStore);

	if (SCA_ACTION_INSTALL == saAction) // install operations need more data
	{
		hr = InstallCertificate(hCertStore, (dwStoreLocation == CERT_SYSTEM_STORE_CURRENT_USER), pwzName, pbData, cbData, pwzPFXPassword);
		ExitOnFailure(hr, "Failed to install certificate.");
	}
	else
	{
		Assert(SCA_ACTION_UNINSTALL == saAction);

		hr = UninstallCertificate(hCertStore, pwzName);
		ExitOnFailure(hr, "Failed to uninstall certificate.");
	}

LExit:
	if (hCertStore)
	{
		::CertCloseStore(hCertStore, 0);
	}

	ReleaseMem(pbData);
	ReleaseStr(pwzFilePath);
	ReleaseStr(pwzPFXPassword);
	ReleaseStr(pwzStore);
	ReleaseStr(pwzName);
	ReleaseStr(pwzCaData);
	return hr;
}
Ejemplo n.º 2
0
static HRESULT ExecuteCertificateOperation(
    __in MSIHANDLE hInstall,
    __in SCA_ACTION saAction,
    __in DWORD dwStoreLocation
    )
{
    //AssertSz(FALSE, "Debug ExecuteCertificateOperation() here.");
    Assert(saAction & SCA_ACTION_INSTALL || saAction & SCA_ACTION_UNINSTALL);

    HRESULT hr = S_OK;
    LPWSTR pwzCaData = NULL;
    LPWSTR pwz;
    LPWSTR pwzName = NULL;
    LPWSTR pwzStore = NULL;
    int iAttributes = 0;
    LPWSTR pwzPFXPassword = NULL;
    LPWSTR pwzFilePath = NULL;
    BYTE* pbData = NULL;
    DWORD cbData = 0;
    DWORD cbPFXPassword = 0;

    BOOL fUserStoreLocation = (CERT_SYSTEM_STORE_CURRENT_USER == dwStoreLocation);
    HCERTSTORE hCertStore = NULL;

    hr = WcaGetProperty(L"CustomActionData", &pwzCaData);
    ExitOnFailure(hr, "Failed to get CustomActionData");

    WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzCaData);

    pwz = pwzCaData;
    hr = WcaReadStringFromCaData(&pwz, &pwzName);
    ExitOnFailure(hr, "Failed to parse certificate name.");
    hr = WcaReadStringFromCaData(&pwz, &pwzStore);
    ExitOnFailure(hr, "Failed to parse CustomActionData, StoreName");
    hr = WcaReadIntegerFromCaData(&pwz, &iAttributes);
    ExitOnFailure(hr, "Failed to parse certificate attribute");
    if (SCA_ACTION_INSTALL == saAction) // install operations need more data
    {
        hr = WcaReadStreamFromCaData(&pwz, &pbData, (DWORD_PTR*)&cbData);
        ExitOnFailure(hr, "Failed to parse certificate stream.");

        hr = WcaReadStringFromCaData(&pwz, &pwzPFXPassword);
        ExitOnFailure(hr, "Failed to parse certificate password.");
    }

    // Open the right store.
    hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, dwStoreLocation, pwzStore);
    MessageExitOnNullWithLastError1(hCertStore, hr, msierrCERTFailedOpen, "Failed to open certificate store: %ls", pwzStore);

    if (SCA_ACTION_INSTALL == saAction) // install operations need more data
    {
        // Uninstall existing versions of this package.  Ignore any failures
        // This is needed to clean up the private key of a cert when we replace an existing cert
        // CertAddCertificateContextToStore(CERT_STORE_ADD_REPLACE_EXISTING) does not remove the private key if the cert is replaced
        UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName);

        hr = InstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName, pbData, cbData, pwzPFXPassword);
        ExitOnFailure(hr, "Failed to install certificate.");
    }
    else
    {
        Assert(SCA_ACTION_UNINSTALL == saAction);

        hr = UninstallCertificatePackage(hCertStore, fUserStoreLocation, pwzName);
        ExitOnFailure(hr, "Failed to uninstall certificate.");
    }

LExit:
    if (NULL != pwzPFXPassword && SUCCEEDED(StrSize(pwzPFXPassword, &cbPFXPassword)))
    {
        SecureZeroMemory(pwzPFXPassword, cbPFXPassword);
    }

    if (hCertStore)
    {
        if (!::CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG))
        {
            WcaLog(LOGMSG_VERBOSE, "Cert store was closed but not all resources were freed.  Error 0x%x", GetLastError());
        }
    }

    ReleaseMem(pbData);
    ReleaseStr(pwzFilePath);
    ReleaseStr(pwzPFXPassword);
    ReleaseStr(pwzStore);
    ReleaseStr(pwzName);
    ReleaseStr(pwzCaData);
    return hr;
}