-
Notifications
You must be signed in to change notification settings - Fork 66
ci: Add MSI certificate validation to ArtifactBuilder #1752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
74f3e1f
ci: Add MSI certificate validation to ArtifactBuilder
tippmar-nr 31bd38f
ci: Adjust conditional run logic for several jobs so they only run on…
tippmar-nr c8e0a19
chore: Added BuildTools solution, removed NuGetHelpers from FullAgent
tippmar-nr ef2c290
Added NuGetHelper build step to ArtifactBuilder job.
tippmar-nr 07c1823
Cleanup
tippmar-nr 4074e1b
Better error message in cert validation
tippmar-nr 19f5147
fix workflow yml
tippmar-nr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace ArtifactBuilder | ||
{ | ||
// based on http://www.pinvoke.net/default.aspx/wintrust.winverifytrust | ||
|
||
#region WinTrustData struct field enums | ||
enum WinTrustDataUIChoice : uint | ||
{ | ||
All = 1, | ||
None = 2, | ||
NoBad = 3, | ||
NoGood = 4 | ||
} | ||
|
||
enum WinTrustDataRevocationChecks : uint | ||
{ | ||
None = 0x00000000, | ||
WholeChain = 0x00000001 | ||
} | ||
|
||
enum WinTrustDataChoice : uint | ||
{ | ||
File = 1, | ||
Catalog = 2, | ||
Blob = 3, | ||
Signer = 4, | ||
Certificate = 5 | ||
} | ||
|
||
enum WinTrustDataStateAction : uint | ||
{ | ||
Ignore = 0x00000000, | ||
Verify = 0x00000001, | ||
Close = 0x00000002, | ||
AutoCache = 0x00000003, | ||
AutoCacheFlush = 0x00000004 | ||
} | ||
|
||
[FlagsAttribute] | ||
enum WinTrustDataProvFlags : uint | ||
{ | ||
UseIe4TrustFlag = 0x00000001, | ||
NoIe4ChainFlag = 0x00000002, | ||
NoPolicyUsageFlag = 0x00000004, | ||
RevocationCheckNone = 0x00000010, | ||
RevocationCheckEndCert = 0x00000020, | ||
RevocationCheckChain = 0x00000040, | ||
RevocationCheckChainExcludeRoot = 0x00000080, | ||
SaferFlag = 0x00000100, // Used by software restriction policies. Should not be used. | ||
HashOnlyFlag = 0x00000200, | ||
UseDefaultOsverCheck = 0x00000400, | ||
LifetimeSigningFlag = 0x00000800, | ||
CacheOnlyUrlRetrieval = 0x00001000, // affects CRL retrieval and AIA retrieval | ||
DisableMD2andMD4 = 0x00002000 // Win7 SP1+: Disallows use of MD2 or MD4 in the chain except for the root | ||
} | ||
|
||
enum WinTrustDataUIContext : uint | ||
{ | ||
Execute = 0, | ||
Install = 1 | ||
} | ||
#endregion | ||
|
||
#region WinTrust structures | ||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | ||
class WinTrustFileInfo | ||
{ | ||
UInt32 StructSize = (UInt32)Marshal.SizeOf(typeof(WinTrustFileInfo)); | ||
IntPtr pszFilePath; // required, file name to be verified | ||
IntPtr hFile = IntPtr.Zero; // optional, open handle to FilePath | ||
IntPtr pgKnownSubject = IntPtr.Zero; // optional, subject type if it is known | ||
|
||
public WinTrustFileInfo(String _filePath) | ||
{ | ||
pszFilePath = Marshal.StringToCoTaskMemAuto(_filePath); | ||
} | ||
public void Dispose() | ||
{ | ||
if (pszFilePath != IntPtr.Zero) | ||
{ | ||
Marshal.FreeCoTaskMem(pszFilePath); | ||
pszFilePath = IntPtr.Zero; | ||
} | ||
} | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | ||
class WinTrustData | ||
{ | ||
UInt32 StructSize = (UInt32)Marshal.SizeOf(typeof(WinTrustData)); | ||
IntPtr PolicyCallbackData = IntPtr.Zero; | ||
IntPtr SIPClientData = IntPtr.Zero; | ||
// required: UI choice | ||
WinTrustDataUIChoice UIChoice = WinTrustDataUIChoice.None; | ||
// required: certificate revocation check options | ||
WinTrustDataRevocationChecks RevocationChecks = WinTrustDataRevocationChecks.None; | ||
// required: which structure is being passed in? | ||
WinTrustDataChoice UnionChoice = WinTrustDataChoice.File; | ||
// individual file | ||
IntPtr FileInfoPtr; | ||
WinTrustDataStateAction StateAction = WinTrustDataStateAction.Ignore; | ||
IntPtr StateData = IntPtr.Zero; | ||
String URLReference = null; | ||
WinTrustDataProvFlags ProvFlags = WinTrustDataProvFlags.RevocationCheckChainExcludeRoot; | ||
WinTrustDataUIContext UIContext = WinTrustDataUIContext.Execute; | ||
|
||
// constructor for silent WinTrustDataChoice.File check | ||
public WinTrustData(WinTrustFileInfo _fileInfo) | ||
{ | ||
// On Win7SP1+, don't allow MD2 or MD4 signatures | ||
if ((Environment.OSVersion.Version.Major > 6) || | ||
((Environment.OSVersion.Version.Major == 6) && (Environment.OSVersion.Version.Minor > 1)) || | ||
((Environment.OSVersion.Version.Major == 6) && (Environment.OSVersion.Version.Minor == 1) && !String.IsNullOrEmpty(Environment.OSVersion.ServicePack))) | ||
{ | ||
ProvFlags |= WinTrustDataProvFlags.DisableMD2andMD4; | ||
} | ||
|
||
var wtfiData = _fileInfo; | ||
FileInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(WinTrustFileInfo))); | ||
Marshal.StructureToPtr(wtfiData, FileInfoPtr, false); | ||
} | ||
public void Dispose() | ||
{ | ||
if (FileInfoPtr != IntPtr.Zero) | ||
{ | ||
Marshal.FreeCoTaskMem(FileInfoPtr); | ||
FileInfoPtr = IntPtr.Zero; | ||
} | ||
} | ||
} | ||
#endregion | ||
|
||
enum WinVerifyTrustResult : uint | ||
{ | ||
Success = 0, | ||
ProviderUnknown = 0x800b0001, // Trust provider is not recognized on this system | ||
ActionUnknown = 0x800b0002, // Trust provider does not support the specified action | ||
SubjectFormUnknown = 0x800b0003, // Trust provider does not support the form specified for the subject | ||
SubjectNotTrusted = 0x800b0004, // Subject failed the specified verification action | ||
FileNotSigned = 0x800B0100, // TRUST_E_NOSIGNATURE - File was not signed | ||
SubjectExplicitlyDistrusted = 0x800B0111, // Signer's certificate is in the Untrusted Publishers store | ||
SignatureOrFileCorrupt = 0x80096010, // TRUST_E_BAD_DIGEST - file was probably corrupt | ||
SubjectCertExpired = 0x800B0101, // CERT_E_EXPIRED - Signer's certificate was expired | ||
SubjectCertificateRevoked = 0x800B010C, // CERT_E_REVOKED Subject's certificate was revoked | ||
UntrustedRoot = 0x800B0109 // CERT_E_UNTRUSTEDROOT - A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider. | ||
} | ||
|
||
static class SecurityHelpers | ||
{ | ||
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); | ||
// GUID of the action to perform | ||
private const string WINTRUST_ACTION_GENERIC_VERIFY_V2 = "{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}"; | ||
|
||
[DllImport("wintrust.dll", ExactSpelling = true, SetLastError = false, CharSet = CharSet.Unicode)] | ||
static extern WinVerifyTrustResult WinVerifyTrust( | ||
[In] IntPtr hwnd, | ||
[In][MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID, | ||
[In] WinTrustData pWVTData | ||
); | ||
|
||
public static bool VerifyEmbeddedSignature(string fileName) | ||
{ | ||
WinTrustFileInfo winTrustFileInfo = null; | ||
WinTrustData winTrustData = null; | ||
|
||
try | ||
{ | ||
// specify the WinVerifyTrust function/action that we want | ||
var action = new Guid(WINTRUST_ACTION_GENERIC_VERIFY_V2); | ||
|
||
// instantiate our WinTrustFileInfo and WinTrustData data structures | ||
winTrustFileInfo = new WinTrustFileInfo(fileName); | ||
winTrustData = new WinTrustData(winTrustFileInfo); | ||
|
||
var result = WinVerifyTrust(INVALID_HANDLE_VALUE, action, winTrustData); | ||
return (result == WinVerifyTrustResult.Success); | ||
} | ||
finally | ||
{ | ||
// free the locally-held unmanaged memory in the data structures | ||
winTrustFileInfo?.Dispose(); | ||
winTrustData?.Dispose(); | ||
} | ||
} | ||
|
||
//public static bool CheckFile(string filename) | ||
//{ | ||
// // check digital signature | ||
// var ret = WinTrust.VerifyEmbeddedSignature(filename); | ||
// if (!ret) return false; | ||
|
||
// // do some other checks - for example verify the subject | ||
// var cert = new X509Certificate2(filename); | ||
// return cert.Verify() && cert.Subject == "foo"; | ||
//} | ||
nrcventura marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.6.33723.286 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArtifactBuilder", "ArtifactBuilder\ArtifactBuilder.csproj", "{2FB32877-EF0C-4382-8D3C-F653F3C26A3A}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewRelic.NuGetHelper", "NewRelic.NuGetHelper\NewRelic.NuGetHelper.csproj", "{94BF8D27-2122-4573-AA79-90B977B40EF3}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{2FB32877-EF0C-4382-8D3C-F653F3C26A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{2FB32877-EF0C-4382-8D3C-F653F3C26A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{2FB32877-EF0C-4382-8D3C-F653F3C26A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{2FB32877-EF0C-4382-8D3C-F653F3C26A3A}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{94BF8D27-2122-4573-AA79-90B977B40EF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{94BF8D27-2122-4573-AA79-90B977B40EF3}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{94BF8D27-2122-4573-AA79-90B977B40EF3}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{94BF8D27-2122-4573-AA79-90B977B40EF3}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {BA603325-9FCE-400E-9852-C8D3E39A16C6} | ||
EndGlobalSection | ||
EndGlobal |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.