From 34b34ff8478beabc09a7f10d808f4ce3788176ed Mon Sep 17 00:00:00 2001 From: Paul Higinbotham Date: Tue, 20 Jun 2017 15:08:45 -0700 Subject: [PATCH 1/2] Fixed missing functionality to add timestamper cert for the newer catalog signing APIs --- .../security/Authenticode.cs | 114 +++++++++++------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/src/System.Management.Automation/security/Authenticode.cs b/src/System.Management.Automation/security/Authenticode.cs index e8ed6e1dc75..f2de4fb9a3a 100644 --- a/src/System.Management.Automation/security/Authenticode.cs +++ b/src/System.Management.Automation/security/Authenticode.cs @@ -363,10 +363,23 @@ private static Signature GetSignatureFromCatalog(string filename) DWORD error = GetErrorFromSignatureState(sigInfo.nSignatureState); X509Certificate2 cert = null; + if (ppCertContext != IntPtr.Zero) { cert = new X509Certificate2(ppCertContext); - signature = new Signature(filename, error, cert); + + // Get the time stamper certificate if available + IntPtr pProvSigner = IntPtr.Zero; + X509Certificate2 timestamperCert = null; + TryGetProviderSigner(phStateData, ref pProvSigner, ref timestamperCert); + if (timestamperCert != null) + { + signature = new Signature(filename, error, cert, timestamperCert); + } + else + { + signature = new Signature(filename, error, cert); + } switch (sigInfo.nSignatureType) { @@ -578,70 +591,81 @@ private static Signature GetSignatureFromWintrustData( DWORD error, NativeMethods.WINTRUST_DATA wtd) { + s_tracer.WriteLine("GetSignatureFromWintrustData: error: {0}", error); + Signature signature = null; - X509Certificate2 signerCert = null; + IntPtr pProvSigner = IntPtr.Zero; X509Certificate2 timestamperCert = null; + if (TryGetProviderSigner(wtd.hWVTStateData, ref pProvSigner, ref timestamperCert)) + { + // + // get cert of the signer + // + X509Certificate2 signerCert = GetCertFromChain(pProvSigner); - s_tracer.WriteLine("GetSignatureFromWintrustData: error: {0}", error); + if (signerCert != null) + { + if (timestamperCert != null) + { + signature = new Signature(filePath, + error, + signerCert, + timestamperCert); + } + else + { + signature = new Signature(filePath, + error, + signerCert); + } + + signature.SignatureType = SignatureType.Authenticode; + } + } + + Diagnostics.Assert(((error == 0) && (signature != null)) || (error != 0), "GetSignatureFromWintrustData: general crypto failure"); + + if ((signature == null) && (error != 0)) + { + signature = new Signature(filePath, error); + } + + return signature; + } + [ArchitectureSensitive] + private static bool TryGetProviderSigner(IntPtr wvtStateData, ref IntPtr pProvSigner, ref X509Certificate2 timestamperCert) + { // The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be // able to see that. #pragma warning disable 56523 IntPtr pProvData = - NativeMethods.WTHelperProvDataFromStateData(wtd.hWVTStateData); + NativeMethods.WTHelperProvDataFromStateData(wvtStateData); #pragma warning enable 56523 if (pProvData != IntPtr.Zero) { - IntPtr pProvSigner = + pProvSigner = NativeMethods.WTHelperGetProvSignerFromChain(pProvData, 0, 0, 0); + if (pProvSigner != IntPtr.Zero) { - // - // get cert of the signer - // - signerCert = GetCertFromChain(pProvSigner); - - if (signerCert != null) + NativeMethods.CRYPT_PROVIDER_SGNR provSigner = + (NativeMethods.CRYPT_PROVIDER_SGNR) + ClrFacade.PtrToStructure(pProvSigner); + if (provSigner.csCounterSigners == 1) { - NativeMethods.CRYPT_PROVIDER_SGNR provSigner = - (NativeMethods.CRYPT_PROVIDER_SGNR) - ClrFacade.PtrToStructure(pProvSigner); - if (provSigner.csCounterSigners == 1) - { - // - // time stamper cert available - // - timestamperCert = GetCertFromChain(provSigner.pasCounterSigners); - } - - if (timestamperCert != null) - { - signature = new Signature(filePath, - error, - signerCert, - timestamperCert); - } - else - { - signature = new Signature(filePath, - error, - signerCert); - } - - signature.SignatureType = SignatureType.Authenticode; + // + // time stamper cert available + // + timestamperCert = GetCertFromChain(provSigner.pasCounterSigners); } - } - } - Diagnostics.Assert(((error == 0) && (signature != null)) || (error != 0), "GetSignatureFromWintrustData: general crypto failure"); - - if ((signature == null) && (error != 0)) - { - signature = new Signature(filePath, error); + return true; + } } - return signature; + return false; } [ArchitectureSensitive] From 0c663b422f74291cf7c862ef3c3448374441fe9e Mon Sep 17 00:00:00 2001 From: Paul Higinbotham Date: Thu, 22 Jun 2017 16:23:22 -0700 Subject: [PATCH 2/2] Code review changes --- .../security/Authenticode.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/System.Management.Automation/security/Authenticode.cs b/src/System.Management.Automation/security/Authenticode.cs index f2de4fb9a3a..e6a5168b73d 100644 --- a/src/System.Management.Automation/security/Authenticode.cs +++ b/src/System.Management.Automation/security/Authenticode.cs @@ -369,9 +369,7 @@ private static Signature GetSignatureFromCatalog(string filename) cert = new X509Certificate2(ppCertContext); // Get the time stamper certificate if available - IntPtr pProvSigner = IntPtr.Zero; - X509Certificate2 timestamperCert = null; - TryGetProviderSigner(phStateData, ref pProvSigner, ref timestamperCert); + TryGetProviderSigner(phStateData, out IntPtr pProvSigner, out X509Certificate2 timestamperCert); if (timestamperCert != null) { signature = new Signature(filename, error, cert, timestamperCert); @@ -594,9 +592,7 @@ private static Signature GetSignatureFromWintrustData( s_tracer.WriteLine("GetSignatureFromWintrustData: error: {0}", error); Signature signature = null; - IntPtr pProvSigner = IntPtr.Zero; - X509Certificate2 timestamperCert = null; - if (TryGetProviderSigner(wtd.hWVTStateData, ref pProvSigner, ref timestamperCert)) + if (TryGetProviderSigner(wtd.hWVTStateData, out IntPtr pProvSigner, out X509Certificate2 timestamperCert)) { // // get cert of the signer @@ -634,8 +630,11 @@ private static Signature GetSignatureFromWintrustData( } [ArchitectureSensitive] - private static bool TryGetProviderSigner(IntPtr wvtStateData, ref IntPtr pProvSigner, ref X509Certificate2 timestamperCert) + private static bool TryGetProviderSigner(IntPtr wvtStateData, out IntPtr pProvSigner, out X509Certificate2 timestamperCert) { + pProvSigner = IntPtr.Zero; + timestamperCert = null; + // The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be // able to see that. #pragma warning disable 56523