aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.Burn
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.Burn')
-rw-r--r--src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs11
-rw-r--r--src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs1
-rw-r--r--src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs32
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs2
-rw-r--r--src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs34
-rw-r--r--src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs158
-rw-r--r--src/WixToolset.Core.Burn/VerifyInterop.cs66
7 files changed, 2 insertions, 302 deletions
diff --git a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index 2c8231f8..dea1f47d 100644
--- a/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -340,15 +340,6 @@ namespace WixToolset.Core.Burn
340 command.Execute(); 340 command.Execute();
341 } 341 }
342 342
343 // If catalog files exist, non-embedded payloads should validate with the catalogs.
344 var catalogs = section.Symbols.OfType<WixBundleCatalogSymbol>().ToList();
345
346 if (catalogs.Count > 0)
347 {
348 var command = new VerifyPayloadsWithCatalogCommand(this.Messaging, catalogs, payloadSymbols.Values);
349 command.Execute();
350 }
351
352 if (this.Messaging.EncounteredError) 343 if (this.Messaging.EncounteredError)
353 { 344 {
354 return; 345 return;
@@ -456,7 +447,7 @@ namespace WixToolset.Core.Burn
456 { 447 {
457 var executableName = Path.GetFileName(this.OutputPath); 448 var executableName = Path.GetFileName(this.OutputPath);
458 449
459 var command = new CreateBurnManifestCommand(this.Messaging, this.BackendExtensions, executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, orderedSearches, catalogs, this.IntermediateFolder); 450 var command = new CreateBurnManifestCommand(this.Messaging, this.BackendExtensions, executableName, section, bundleSymbol, containers, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, orderedSearches, this.IntermediateFolder);
460 command.Execute(); 451 command.Execute();
461 452
462 manifestPath = command.OutputPath; 453 manifestPath = command.OutputPath;
diff --git a/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs b/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
index 24a4ae67..93a1a0bc 100644
--- a/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
+++ b/src/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs
@@ -63,7 +63,6 @@ namespace WixToolset.Core.Burn.Bind
63 case SymbolDefinitionType.WixBootstrapperApplication: 63 case SymbolDefinitionType.WixBootstrapperApplication:
64 case SymbolDefinitionType.WixBootstrapperApplicationDll: 64 case SymbolDefinitionType.WixBootstrapperApplicationDll:
65 case SymbolDefinitionType.WixBundle: 65 case SymbolDefinitionType.WixBundle:
66 case SymbolDefinitionType.WixBundleCatalog:
67 case SymbolDefinitionType.WixBundleContainer: 66 case SymbolDefinitionType.WixBundleContainer:
68 case SymbolDefinitionType.WixBundleCustomDataAttribute: 67 case SymbolDefinitionType.WixBundleCustomDataAttribute:
69 case SymbolDefinitionType.WixBundleExePackage: 68 case SymbolDefinitionType.WixBundleExePackage:
diff --git a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 6eafcdd9..d12f00d1 100644
--- a/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -18,7 +18,7 @@ namespace WixToolset.Core.Burn.Bundles
18 18
19 internal class CreateBurnManifestCommand 19 internal class CreateBurnManifestCommand
20 { 20 {
21 public CreateBurnManifestCommand(IMessaging messaging, IEnumerable<IBurnBackendExtension> backendExtensions, string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, IEnumerable<ISearchFacade> orderedSearches, IEnumerable<WixBundleCatalogSymbol> catalogs, string intermediateFolder) 21 public CreateBurnManifestCommand(IMessaging messaging, IEnumerable<IBurnBackendExtension> backendExtensions, string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable<WixBundleContainerSymbol> containers, WixChainSymbol chainSymbol, IEnumerable<PackageFacade> orderedPackages, IEnumerable<WixBundleRollbackBoundarySymbol> boundaries, IEnumerable<WixBundlePayloadSymbol> uxPayloads, Dictionary<string, WixBundlePayloadSymbol> allPayloadsById, IEnumerable<ISearchFacade> orderedSearches, string intermediateFolder)
22 { 22 {
23 this.Messaging = messaging; 23 this.Messaging = messaging;
24 this.BackendExtensions = backendExtensions; 24 this.BackendExtensions = backendExtensions;
@@ -32,7 +32,6 @@ namespace WixToolset.Core.Burn.Bundles
32 this.UXContainerPayloads = uxPayloads; 32 this.UXContainerPayloads = uxPayloads;
33 this.Payloads = allPayloadsById; 33 this.Payloads = allPayloadsById;
34 this.OrderedSearches = orderedSearches; 34 this.OrderedSearches = orderedSearches;
35 this.Catalogs = catalogs;
36 this.IntermediateFolder = intermediateFolder; 35 this.IntermediateFolder = intermediateFolder;
37 } 36 }
38 37
@@ -62,8 +61,6 @@ namespace WixToolset.Core.Burn.Bundles
62 61
63 private IEnumerable<WixBundlePayloadSymbol> UXContainerPayloads { get; } 62 private IEnumerable<WixBundlePayloadSymbol> UXContainerPayloads { get; }
64 63
65 private IEnumerable<WixBundleCatalogSymbol> Catalogs { get; }
66
67 private string IntermediateFolder { get; } 64 private string IntermediateFolder { get; }
68 65
69 public void Execute() 66 public void Execute()
@@ -179,18 +176,6 @@ namespace WixToolset.Core.Burn.Bundles
179 176
180 writer.WriteEndElement(); // </UX> 177 writer.WriteEndElement(); // </UX>
181 178
182 // write the catalog elements
183 if (this.Catalogs.Any())
184 {
185 foreach (var catalog in this.Catalogs)
186 {
187 writer.WriteStartElement("Catalog");
188 writer.WriteAttributeString("Id", catalog.Id.Id);
189 writer.WriteAttributeString("Payload", catalog.PayloadRef);
190 writer.WriteEndElement();
191 }
192 }
193
194 foreach (var container in this.Containers) 179 foreach (var container in this.Containers)
195 { 180 {
196 if (!String.IsNullOrEmpty(container.WorkingPath) && BurnConstants.BurnUXContainerName != container.Id.Id) 181 if (!String.IsNullOrEmpty(container.WorkingPath) && BurnConstants.BurnUXContainerName != container.Id.Id)
@@ -698,16 +683,6 @@ namespace WixToolset.Core.Burn.Bundles
698 writer.WriteAttributeString("LayoutOnly", "yes"); 683 writer.WriteAttributeString("LayoutOnly", "yes");
699 } 684 }
700 685
701 if (!String.IsNullOrEmpty(payload.PublicKey))
702 {
703 writer.WriteAttributeString("CertificateRootPublicKeyIdentifier", payload.PublicKey);
704 }
705
706 if (!String.IsNullOrEmpty(payload.Thumbprint))
707 {
708 writer.WriteAttributeString("CertificateRootThumbprint", payload.Thumbprint);
709 }
710
711 switch (payload.Packaging) 686 switch (payload.Packaging)
712 { 687 {
713 case PackagingType.Embedded: // this means it's in a container. 688 case PackagingType.Embedded: // this means it's in a container.
@@ -742,11 +717,6 @@ namespace WixToolset.Core.Burn.Bundles
742 writer.WriteAttributeString("SourcePath", payload.Name); 717 writer.WriteAttributeString("SourcePath", payload.Name);
743 break; 718 break;
744 } 719 }
745
746 if (!String.IsNullOrEmpty(payload.CatalogRef))
747 {
748 writer.WriteAttributeString("Catalog", payload.CatalogRef);
749 }
750 } 720 }
751 721
752 private string ResolveUrl(string url, string fallbackUrl, string packageId, string payloadId, string fileName) 722 private string ResolveUrl(string url, string fallbackUrl, string packageId, string payloadId, string fileName)
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
index 7adbfcfd..e13561bc 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
@@ -406,7 +406,6 @@ namespace WixToolset.Core.Burn.Bundles
406 PackageRef = packagePayload.PackageRef, 406 PackageRef = packagePayload.PackageRef,
407 ContainerRef = packagePayload.ContainerRef, 407 ContainerRef = packagePayload.ContainerRef,
408 ContentFile = true, 408 ContentFile = true,
409 EnableSignatureValidation = packagePayload.EnableSignatureValidation,
410 Packaging = packagePayload.Packaging, 409 Packaging = packagePayload.Packaging,
411 ParentPackagePayloadRef = packagePayload.Id.Id, 410 ParentPackagePayloadRef = packagePayload.Id.Id,
412 }); 411 });
@@ -484,7 +483,6 @@ namespace WixToolset.Core.Burn.Bundles
484 PackageRef = packagePayload.PackageRef, 483 PackageRef = packagePayload.PackageRef,
485 ContainerRef = packagePayload.ContainerRef, 484 ContainerRef = packagePayload.ContainerRef,
486 ContentFile = true, 485 ContentFile = true,
487 EnableSignatureValidation = packagePayload.EnableSignatureValidation,
488 Packaging = packagePayload.Packaging, 486 Packaging = packagePayload.Packaging,
489 ParentPackagePayloadRef = packagePayload.Id.Id, 487 ParentPackagePayloadRef = packagePayload.Id.Id,
490 }); 488 });
diff --git a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
index 69c4d7c2..8811c301 100644
--- a/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
+++ b/src/WixToolset.Core.Burn/Bundles/ProcessPayloadsCommand.cs
@@ -6,9 +6,6 @@ namespace WixToolset.Core.Burn.Bundles
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Diagnostics; 7 using System.Diagnostics;
8 using System.IO; 8 using System.IO;
9 using System.Security.Cryptography;
10 using System.Security.Cryptography.X509Certificates;
11 using System.Text;
12 using WixToolset.Data; 9 using WixToolset.Data;
13 using WixToolset.Data.Burn; 10 using WixToolset.Data.Burn;
14 using WixToolset.Data.Symbols; 11 using WixToolset.Data.Symbols;
@@ -123,37 +120,6 @@ namespace WixToolset.Core.Burn.Bundles
123 payload.FileSize = (int)fileInfo.Length; 120 payload.FileSize = (int)fileInfo.Length;
124 121
125 payload.Hash = BundleHashAlgorithm.Hash(fileInfo); 122 payload.Hash = BundleHashAlgorithm.Hash(fileInfo);
126
127 // Try to get the certificate if the payload is a signed file and we're not suppressing signature validation.
128 if (payload.EnableSignatureValidation)
129 {
130 X509Certificate2 certificate = null;
131 try
132 {
133 certificate = new X509Certificate2(fileInfo.FullName);
134 }
135 catch (CryptographicException) // we don't care about non-signed files.
136 {
137 }
138
139 // If there is a certificate, remember its hashed public key identifier and thumbprint.
140 if (null != certificate)
141 {
142 byte[] publicKeyIdentifierHash = new byte[128];
143 uint publicKeyIdentifierHashSize = (uint)publicKeyIdentifierHash.Length;
144
145 Native.NativeMethods.HashPublicKeyInfo(certificate.Handle, publicKeyIdentifierHash, ref publicKeyIdentifierHashSize);
146
147 var sb = new StringBuilder(((int)publicKeyIdentifierHashSize + 1) * 2);
148 for (var i = 0; i < publicKeyIdentifierHashSize; ++i)
149 {
150 sb.AppendFormat("{0:X2}", publicKeyIdentifierHash[i]);
151 }
152
153 payload.PublicKey = sb.ToString();
154 payload.Thumbprint = certificate.Thumbprint;
155 }
156 }
157 } 123 }
158 else 124 else
159 { 125 {
diff --git a/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs b/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs
deleted file mode 100644
index e7c97ea7..00000000
--- a/src/WixToolset.Core.Burn/Bundles/VerifyPayloadsWithCatalogCommand.cs
+++ /dev/null
@@ -1,158 +0,0 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core.Burn.Bundles
4{
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 using System.Runtime.InteropServices;
10 using System.Text;
11 using WixToolset.Data;
12 using WixToolset.Data.Symbols;
13 using WixToolset.Extensibility.Services;
14
15 internal class VerifyPayloadsWithCatalogCommand
16 {
17 public VerifyPayloadsWithCatalogCommand(IMessaging messaging, IEnumerable<WixBundleCatalogSymbol> catalogs, IEnumerable<WixBundlePayloadSymbol> payloads)
18 {
19 this.Messaging = messaging;
20 this.Catalogs = catalogs;
21 this.Payloads = payloads;
22 }
23
24 private IMessaging Messaging { get; }
25
26 private IEnumerable<WixBundleCatalogSymbol> Catalogs { get; }
27
28 private IEnumerable<WixBundlePayloadSymbol> Payloads { get; }
29
30 public void Execute()
31 {
32 var catalogIdsWithPaths = this.Catalogs
33 .Join(this.Payloads,
34 catalog => catalog.PayloadRef,
35 payload => payload.Id.Id,
36 (catalog, payload) => new CatalogIdWithPath() { Id = catalog.Id.Id, FullPath = Path.GetFullPath(payload.SourceFile.Path) })
37 .ToList();
38
39 foreach (var payloadInfo in this.Payloads)
40 {
41 // Payloads that are not embedded should be verfied.
42 if (String.IsNullOrEmpty(payloadInfo.EmbeddedId))
43 {
44 var sourceFile = payloadInfo.SourceFile.Path;
45 var validated = false;
46
47 foreach (var catalog in catalogIdsWithPaths)
48 {
49 if (!validated)
50 {
51 // Get the file hash
52 uint cryptHashSize = 20;
53 byte[] cryptHashBytes = new byte[cryptHashSize];
54 int error;
55 using (var payloadStream = File.OpenRead(sourceFile))
56 {
57 // Get the file handle
58 var fileHandle = payloadStream.SafeFileHandle.DangerousGetHandle();
59
60 // 20 bytes is usually the hash size. Future hashes may be bigger
61 if (!VerifyInterop.CryptCATAdminCalcHashFromFileHandle(fileHandle, ref cryptHashSize, cryptHashBytes, 0))
62 {
63 error = Marshal.GetLastWin32Error();
64
65 if (VerifyInterop.ErrorInsufficientBuffer == error)
66 {
67 error = 0;
68 cryptHashBytes = new byte[cryptHashSize];
69 if (!VerifyInterop.CryptCATAdminCalcHashFromFileHandle(fileHandle, ref cryptHashSize, cryptHashBytes, 0))
70 {
71 error = Marshal.GetLastWin32Error();
72 }
73 }
74
75 if (0 != error)
76 {
77 this.Messaging.Write(ErrorMessages.CatalogFileHashFailed(sourceFile, error));
78 }
79 }
80 }
81
82 VerifyInterop.WinTrustCatalogInfo catalogData = new VerifyInterop.WinTrustCatalogInfo();
83 VerifyInterop.WinTrustData trustData = new VerifyInterop.WinTrustData();
84 try
85 {
86 // Create WINTRUST_CATALOG_INFO structure
87 catalogData.cbStruct = (uint)Marshal.SizeOf(catalogData);
88 catalogData.cbCalculatedFileHash = cryptHashSize;
89 catalogData.pbCalculatedFileHash = Marshal.AllocCoTaskMem((int)cryptHashSize);
90 Marshal.Copy(cryptHashBytes, 0, catalogData.pbCalculatedFileHash, (int)cryptHashSize);
91
92 var hashString = new StringBuilder();
93 foreach (var hashByte in cryptHashBytes)
94 {
95 hashString.Append(hashByte.ToString("X2"));
96 }
97 catalogData.pcwszMemberTag = hashString.ToString();
98
99 // The file names need to be lower case for older OSes
100 catalogData.pcwszMemberFilePath = sourceFile.ToLowerInvariant();
101 catalogData.pcwszCatalogFilePath = catalog.FullPath.ToLowerInvariant();
102
103 // Create WINTRUST_DATA structure
104 trustData.cbStruct = (uint)Marshal.SizeOf(trustData);
105 trustData.dwUIChoice = VerifyInterop.WTD_UI_NONE;
106 trustData.fdwRevocationChecks = VerifyInterop.WTD_REVOKE_NONE;
107 trustData.dwUnionChoice = VerifyInterop.WTD_CHOICE_CATALOG;
108 trustData.dwStateAction = VerifyInterop.WTD_STATEACTION_VERIFY;
109 trustData.dwProvFlags = VerifyInterop.WTD_REVOCATION_CHECK_NONE;
110
111 // Create the structure pointers for unmanaged
112 trustData.pCatalog = Marshal.AllocCoTaskMem(Marshal.SizeOf(catalogData));
113 Marshal.StructureToPtr(catalogData, trustData.pCatalog, false);
114
115 // Call WinTrustVerify to validate the file with the catalog
116 IntPtr noWindow = new IntPtr(-1);
117 Guid verifyGuid = new Guid(VerifyInterop.GenericVerify2);
118 long verifyResult = VerifyInterop.WinVerifyTrust(noWindow, ref verifyGuid, ref trustData);
119 if (0 == verifyResult)
120 {
121 payloadInfo.CatalogRef = catalog.Id;
122 validated = true;
123 break;
124 }
125 }
126 finally
127 {
128 // Free the structure memory
129 if (IntPtr.Zero != trustData.pCatalog)
130 {
131 Marshal.FreeCoTaskMem(trustData.pCatalog);
132 }
133
134 if (IntPtr.Zero != catalogData.pbCalculatedFileHash)
135 {
136 Marshal.FreeCoTaskMem(catalogData.pbCalculatedFileHash);
137 }
138 }
139 }
140 }
141
142 // Error message if the file was not validated by one of the catalogs
143 if (!validated)
144 {
145 this.Messaging.Write(ErrorMessages.CatalogVerificationFailed(sourceFile));
146 }
147 }
148 }
149 }
150
151 private class CatalogIdWithPath
152 {
153 public string Id { get; set; }
154
155 public string FullPath { get; set; }
156 }
157 }
158}
diff --git a/src/WixToolset.Core.Burn/VerifyInterop.cs b/src/WixToolset.Core.Burn/VerifyInterop.cs
deleted file mode 100644
index f021f1d0..00000000
--- a/src/WixToolset.Core.Burn/VerifyInterop.cs
+++ /dev/null
@@ -1,66 +0,0 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset
4{
5 using System;
6 using System.Runtime.InteropServices;
7
8 internal class VerifyInterop
9 {
10 internal const string GenericVerify2 = "00AAC56B-CD44-11d0-8CC2-00C04FC295EE";
11 internal const uint WTD_UI_NONE = 2;
12 internal const uint WTD_REVOKE_NONE = 0;
13 internal const uint WTD_CHOICE_CATALOG = 2;
14 internal const uint WTD_STATEACTION_VERIFY = 1;
15 internal const uint WTD_REVOCATION_CHECK_NONE = 0x10;
16 internal const int ErrorInsufficientBuffer = 122;
17
18 [StructLayout(LayoutKind.Sequential)]
19 internal struct WinTrustData
20 {
21 internal uint cbStruct;
22 internal IntPtr pPolicyCallbackData;
23 internal IntPtr pSIPClientData;
24 internal uint dwUIChoice;
25 internal uint fdwRevocationChecks;
26 internal uint dwUnionChoice;
27 internal IntPtr pCatalog;
28 internal uint dwStateAction;
29 internal IntPtr hWVTStateData;
30 [MarshalAs(UnmanagedType.LPWStr)]
31 internal string pwszURLReference;
32 internal uint dwProvFlags;
33 internal uint dwUIContext;
34 }
35
36 [StructLayout(LayoutKind.Sequential)]
37 internal struct WinTrustCatalogInfo
38 {
39 internal uint cbStruct;
40 internal uint dwCatalogVersion;
41 [MarshalAs(UnmanagedType.LPWStr)]
42 internal string pcwszCatalogFilePath;
43 [MarshalAs(UnmanagedType.LPWStr)]
44 internal string pcwszMemberTag;
45 [MarshalAs(UnmanagedType.LPWStr)]
46 internal string pcwszMemberFilePath;
47 internal IntPtr hMemberFile;
48 internal IntPtr pbCalculatedFileHash;
49 internal uint cbCalculatedFileHash;
50 internal IntPtr pcCatalogContext;
51 }
52
53 [DllImport("wintrust.dll", SetLastError = true)]
54 internal static extern long WinVerifyTrust(IntPtr windowHandle, ref Guid actionGuid, ref WinTrustData trustData);
55
56 [DllImport("wintrust.dll", SetLastError = true)]
57 [return: MarshalAs(UnmanagedType.Bool)]
58 internal static extern bool CryptCATAdminCalcHashFromFileHandle(
59 IntPtr fileHandle,
60 [In, Out]
61 ref uint hashSize,
62 [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
63 byte[] hashBytes,
64 uint flags);
65 }
66}