From c334e5539ee467c5376b08d9f35204b57d857cc7 Mon Sep 17 00:00:00 2001 From: Badre BSAILA <54767641+pedrobsaila@users.noreply.github.com> Date: Mon, 22 Nov 2021 19:03:33 +0100 Subject: [PATCH] Make S.S.C.X509Certificates compliant with interop guidelines - part 3 --- .../Interop.CryptAcquireContext_IntPtr.cs} | 9 +- .../Interop.CERT_CHAIN_ENGINE_CONFIG.cs | 28 ++++ .../Windows/Crypt32/Interop.CertChainFlags.cs | 22 +++ .../Crypt32/Interop.CertControlStore.cs | 15 ++ .../Crypt32/Interop.CertControlStoreFlags.cs | 16 ++ .../Crypt32/Interop.CertControlStoreType.cs | 13 ++ ...nterop.CertCreateCertificateChainEngine.cs | 14 ++ .../Interop.CertDeleteCertificateFromStore.cs | 14 ++ .../Interop.CertFindCertificateInStore.cs | 20 +++ .../Crypt32/Interop.CertFindExtension.cs | 14 ++ .../Windows/Crypt32/Interop.CertFindFlags.cs | 16 ++ .../Windows/Crypt32/Interop.CertFindType.cs | 18 +++ .../Interop.CertFreeCertificateChain.cs | 14 ++ .../Interop.CertFreeCertificateChainEngine.cs | 14 ++ .../Interop.CertGetCertificateChain.cs | 57 +++++++ .../Interop.CertGetIntendedKeyUsage.cs | 19 +++ .../Crypt32/Interop.CertGetValidUsages.cs | 14 ++ .../Windows/Crypt32/Interop.CertSaveStore.cs | 20 +++ .../Crypt32/Interop.CertStoreSaveAs.cs | 14 ++ .../Crypt32/Interop.CertStoreSaveTo.cs | 13 ++ .../Crypt32/Interop.CertVerifyTimeValidity.cs | 13 ++ .../Windows/Crypt32/Interop.ChainEngine.cs | 14 ++ .../Crypt32/Interop.ChainEngineConfigFlags.cs | 21 +++ ...rtificatePrivateKey_SafeNCryptKeyHandle.cs | 21 +++ ...Interop.CryptDecodeObjectPointer_IntPtr.cs | 21 +++ ...Interop.CryptDecodeObjectPointer_string.cs | 19 +++ .../Crypt32/Interop.CryptHashPublicKeyInfo.cs | 21 +++ .../Interop.CryptImportPublicKeyInfoEx2.cs | 19 +++ .../Interop.CryptImportPublicKeyInfoFlags.cs | 17 ++ .../Crypt32/Interop.X509KeyUsageFlags.cs | 25 +++ ...rtContextHandleWithKeyContainerDeletion.cs | 2 +- .../SafeHandles/SafeChainEngineHandle.cs | 42 +++++ .../Win32/SafeHandles/SafeX509ChainHandle.cs | 3 - .../Pal.Windows/CertificatePal.Import.cs | 2 +- .../Pal.Windows/CertificatePal.PrivateKey.cs | 2 +- .../Pal.Windows/CertificatePal.cs | 6 +- .../Pal.Windows/ChainPal.BuildChain.cs | 32 ++-- .../Cryptography/Pal.Windows/ChainPal.cs | 12 +- .../Cryptography/Pal.Windows/FindPal.cs | 24 +-- .../Pal.Windows/Native/Helpers.cs | 4 +- .../Pal.Windows/Native/Interop.crypt32.cs | 81 +++------- .../Pal.Windows/Native/Primitives.cs | 149 ------------------ .../Pal.Windows/Native/SafeHandles.cs | 36 ----- .../Pal.Windows/StorePal.Export.cs | 11 +- .../Pal.Windows/StorePal.Import.cs | 2 +- .../Cryptography/Pal.Windows/StorePal.cs | 5 +- .../Pal.Windows/X509Pal.CustomExtensions.cs | 2 +- .../Pal.Windows/X509Pal.PublicKey.cs | 2 +- ...urity.Cryptography.X509Certificates.csproj | 76 ++++++++- 49 files changed, 738 insertions(+), 310 deletions(-) rename src/libraries/{System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.cryptoapi.cs => Common/src/Interop/Windows/Advapi32/Interop.CryptAcquireContext_IntPtr.cs} (58%) create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_CHAIN_ENGINE_CONFIG.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertChainFlags.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStore.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreFlags.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreType.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertCreateCertificateChainEngine.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertDeleteCertificateFromStore.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindCertificateInStore.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindExtension.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindFlags.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindType.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChain.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChainEngine.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetCertificateChain.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetIntendedKeyUsage.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetValidUsages.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSaveStore.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveAs.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveTo.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertVerifyTimeValidity.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngine.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngineConfigFlags.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptAcquireCertificatePrivateKey_SafeNCryptKeyHandle.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_IntPtr.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_string.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptHashPublicKeyInfo.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoEx2.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoFlags.cs create mode 100644 src/libraries/Common/src/Interop/Windows/Crypt32/Interop.X509KeyUsageFlags.cs create mode 100644 src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeChainEngineHandle.cs rename src/libraries/{System.Security.Cryptography.X509Certificates => Common}/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs (93%) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.cryptoapi.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptAcquireContext_IntPtr.cs similarity index 58% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.cryptoapi.cs rename to src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptAcquireContext_IntPtr.cs index 0abee0170a37f..142b7ec549b85 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.cryptoapi.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.CryptAcquireContext_IntPtr.cs @@ -6,10 +6,15 @@ internal static partial class Interop { - public static partial class cryptoapi + internal static partial class Advapi32 { [GeneratedDllImport(Libraries.Advapi32, EntryPoint = "CryptAcquireContextW", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static unsafe partial bool CryptAcquireContext(out IntPtr psafeProvHandle, char* pszContainer, char* pszProvider, int dwProvType, Crypt32.CryptAcquireContextFlags dwFlags); + internal static unsafe partial bool CryptAcquireContext( + out IntPtr psafeProvHandle, + char* pszContainer, + char* pszProvider, + int dwProvType, + Interop.Crypt32.CryptAcquireContextFlags dwFlags); } } diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_CHAIN_ENGINE_CONFIG.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_CHAIN_ENGINE_CONFIG.cs new file mode 100644 index 0000000000000..7597ea150a48b --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CERT_CHAIN_ENGINE_CONFIG.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [StructLayout(LayoutKind.Sequential)] + internal struct CERT_CHAIN_ENGINE_CONFIG + { + public int cbSize; + public IntPtr hRestrictedRoot; + public IntPtr hRestrictedTrust; + public IntPtr hRestrictedOther; + public int cAdditionalStore; + public IntPtr rghAdditionalStore; + public ChainEngineConfigFlags dwFlags; + public int dwUrlRetrievalTimeout; + public int MaximumCachedCertificates; + public int CycleDetectionModulus; + public IntPtr hExclusiveRoot; + public IntPtr hExclusiveTrustedPeople; + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertChainFlags.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertChainFlags.cs new file mode 100644 index 0000000000000..748fc10013ebb --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertChainFlags.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [Flags] + internal enum CertChainFlags : int + { + None = 0x00000000, + CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE = 0x00000100, + CERT_CHAIN_DISABLE_AIA = 0x00002000, + CERT_CHAIN_REVOCATION_CHECK_END_CERT = 0x10000000, + CERT_CHAIN_REVOCATION_CHECK_CHAIN = 0x20000000, + CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x40000000, + CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY = unchecked((int)0x80000000), + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStore.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStore.cs new file mode 100644 index 0000000000000..5d3a99327a8fc --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStore.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static partial bool CertControlStore(SafeCertStoreHandle hCertStore, CertControlStoreFlags dwFlags, CertControlStoreType dwControlType, IntPtr pvCtrlPara); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreFlags.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreFlags.cs new file mode 100644 index 0000000000000..9f4baff1614f5 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreFlags.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [Flags] + internal enum CertControlStoreFlags : int + { + None = 0x00000000, + } + } +} \ No newline at end of file diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreType.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreType.cs new file mode 100644 index 0000000000000..a0f04a14d059a --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertControlStoreType.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + internal enum CertControlStoreType : int + { + CERT_STORE_CTRL_AUTO_RESYNC = 4, + } + } +} \ No newline at end of file diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertCreateCertificateChainEngine.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertCreateCertificateChainEngine.cs new file mode 100644 index 0000000000000..65bc29dfc74d9 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertCreateCertificateChainEngine.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static partial bool CertCreateCertificateChainEngine(ref CERT_CHAIN_ENGINE_CONFIG pConfig, out SafeChainEngineHandle hChainEngineHandle); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertDeleteCertificateFromStore.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertDeleteCertificateFromStore.cs new file mode 100644 index 0000000000000..df9e43148bb1e --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertDeleteCertificateFromStore.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + // Note: CertDeleteCertificateFromStore always calls CertFreeCertificateContext on pCertContext, even if an error is encountered. + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial bool CertDeleteCertificateFromStore(CERT_CONTEXT* pCertContext); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindCertificateInStore.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindCertificateInStore.cs new file mode 100644 index 0000000000000..3a5400838ca76 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindCertificateInStore.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial SafeCertContextHandle CertFindCertificateInStore( + SafeCertStoreHandle hCertStore, + CertEncodingType dwCertEncodingType, + CertFindFlags dwFindFlags, + CertFindType dwFindType, + void* pvFindPara, + CERT_CONTEXT* pPrevCertContext); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindExtension.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindExtension.cs new file mode 100644 index 0000000000000..da00ba41a3814 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindExtension.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial CERT_EXTENSION* CertFindExtension([MarshalAs(UnmanagedType.LPStr)] string pszObjId, int cExtensions, IntPtr rgExtensions); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindFlags.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindFlags.cs new file mode 100644 index 0000000000000..35d76fedd8d81 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindFlags.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [Flags] + internal enum CertFindFlags : int + { + None = 0x00000000, + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindType.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindType.cs new file mode 100644 index 0000000000000..ebb7918939559 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFindType.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + internal enum CertFindType : int + { + CERT_FIND_SUBJECT_CERT = 0x000b0000, + CERT_FIND_HASH = 0x00010000, + CERT_FIND_SUBJECT_STR = 0x00080007, + CERT_FIND_ISSUER_STR = 0x00080004, + CERT_FIND_EXISTING = 0x000d0000, + CERT_FIND_ANY = 0x00000000, + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChain.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChain.cs new file mode 100644 index 0000000000000..c92ccaf0b62a0 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChain.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static partial void CertFreeCertificateChain(IntPtr pChainContext); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChainEngine.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChainEngine.cs new file mode 100644 index 0000000000000..425dbe78c0290 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertFreeCertificateChainEngine.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32)] + internal static partial void CertFreeCertificateChainEngine(IntPtr hChainEngine); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetCertificateChain.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetCertificateChain.cs new file mode 100644 index 0000000000000..ea7f477e0321b --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetCertificateChain.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, SetLastError = true)] + internal static unsafe partial bool CertGetCertificateChain( + IntPtr hChainEngine, + SafeCertContextHandle pCertContext, + FILETIME* pTime, + SafeCertStoreHandle hStore, + ref CERT_CHAIN_PARA pChainPara, + CertChainFlags dwFlags, + IntPtr pvReserved, + out SafeX509ChainHandle ppChainContext); + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct CERT_CHAIN_PARA + { + public int cbSize; + public CERT_USAGE_MATCH RequestedUsage; + public CERT_USAGE_MATCH RequestedIssuancePolicy; + public int dwUrlRetrievalTimeout; + public int fCheckRevocationFreshnessTime; + public int dwRevocationFreshnessTime; + public FILETIME* pftCacheResync; + public int pStrongSignPara; + public int dwStrongSignFlags; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct CERT_USAGE_MATCH + { + public CertUsageMatchType dwType; + public CTL_USAGE Usage; + } + + internal enum CertUsageMatchType : int + { + USAGE_MATCH_TYPE_AND = 0x00000000, + USAGE_MATCH_TYPE_OR = 0x00000001, + } + + [StructLayout(LayoutKind.Sequential)] + internal struct CTL_USAGE + { + public int cUsageIdentifier; + public IntPtr rgpszUsageIdentifier; + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetIntendedKeyUsage.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetIntendedKeyUsage.cs new file mode 100644 index 0000000000000..ab9cb7a6d3b01 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetIntendedKeyUsage.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + // Note: It's somewhat unusual to use an API enum as a parameter type to a P/Invoke but in this case, X509KeyUsageFlags was intentionally designed as bit-wise + // identical to the wincrypt CERT_*_USAGE values. + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial bool CertGetIntendedKeyUsage( + CertEncodingType dwCertEncodingType, + CERT_INFO* pCertInfo, + out X509KeyUsageFlags pbKeyUsage, + int cbKeyUsage); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetValidUsages.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetValidUsages.cs new file mode 100644 index 0000000000000..5e4dcf1c668a9 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertGetValidUsages.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial bool CertGetValidUsages(int cCerts, ref SafeCertContextHandle rghCerts, out int cNumOIDs, void* rghOIDs, ref int pcbOIDs); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSaveStore.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSaveStore.cs new file mode 100644 index 0000000000000..56d777dd44b5d --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertSaveStore.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + public static partial bool CertSaveStore( + SafeCertStoreHandle hCertStore, + CertEncodingType dwMsgAndCertEncodingType, + CertStoreSaveAs dwSaveAs, + CertStoreSaveTo dwSaveTo, + ref DATA_BLOB pvSaveToPara, + int dwFlags); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveAs.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveAs.cs new file mode 100644 index 0000000000000..71656911cb827 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveAs.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + internal enum CertStoreSaveAs : int + { + CERT_STORE_SAVE_AS_STORE = 1, + CERT_STORE_SAVE_AS_PKCS7 = 2, + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveTo.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveTo.cs new file mode 100644 index 0000000000000..bc517d1cece07 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertStoreSaveTo.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + internal enum CertStoreSaveTo : int + { + CERT_STORE_SAVE_TO_MEMORY = 2 + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertVerifyTimeValidity.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertVerifyTimeValidity.cs new file mode 100644 index 0000000000000..5d7a09d99bbce --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CertVerifyTimeValidity.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial int CertVerifyTimeValidity(ref FILETIME pTimeToVerify, CERT_INFO* pCertInfo); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngine.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngine.cs new file mode 100644 index 0000000000000..0f5c7db4fcb8e --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngine.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + internal enum ChainEngine : int + { + HCCE_CURRENT_USER = 0x0, + HCCE_LOCAL_MACHINE = 0x1, + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngineConfigFlags.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngineConfigFlags.cs new file mode 100644 index 0000000000000..688cc717f7e91 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.ChainEngineConfigFlags.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [Flags] + internal enum ChainEngineConfigFlags : int + { + CERT_CHAIN_CACHE_END_CERT = 0x00000001, + CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL = 0x00000004, + CERT_CHAIN_USE_LOCAL_MACHINE_STORE = 0x00000008, + CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE = 0x00000010, + CERT_CHAIN_ENABLE_SHARE_STORE = 0x00000020, + CERT_CHAIN_DISABLE_AIA = 0x00002000, + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptAcquireCertificatePrivateKey_SafeNCryptKeyHandle.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptAcquireCertificatePrivateKey_SafeNCryptKeyHandle.cs new file mode 100644 index 0000000000000..24bf1859eb659 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptAcquireCertificatePrivateKey_SafeNCryptKeyHandle.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + public static partial bool CryptAcquireCertificatePrivateKey( + SafeCertContextHandle pCert, + CryptAcquireCertificatePrivateKeyFlags dwFlags, + IntPtr pvParameters, + out SafeNCryptKeyHandle phCryptProvOrNCryptKey, + out CryptKeySpec pdwKeySpec, + out bool pfCallerFreeProvOrNCryptKey); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_IntPtr.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_IntPtr.cs new file mode 100644 index 0000000000000..2a3535a5fa914 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_IntPtr.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, EntryPoint = "CryptDecodeObject", CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial bool CryptDecodeObjectPointer( + CertEncodingType dwCertEncodingType, + IntPtr lpszStructType, + byte[] pbEncoded, + int cbEncoded, + CryptDecodeObjectFlags dwFlags, + void* pvStructInfo, + ref int pcbStructInfo); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_string.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_string.cs new file mode 100644 index 0000000000000..bbe47942f3fd7 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptDecodeObjectPointer_string.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, EntryPoint = "CryptDecodeObject", CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial bool CryptDecodeObjectPointer( + CertEncodingType dwCertEncodingType, + [MarshalAs(UnmanagedType.LPStr)] string lpszStructType, + byte[] pbEncoded, int cbEncoded, + CryptDecodeObjectFlags dwFlags, + void* pvStructInfo, + ref int pcbStructInfo); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptHashPublicKeyInfo.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptHashPublicKeyInfo.cs new file mode 100644 index 0000000000000..0098accc75782 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptHashPublicKeyInfo.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static partial bool CryptHashPublicKeyInfo( + IntPtr hCryptProv, + int algId, + int dwFlags, + CertEncodingType dwCertEncodingType, + ref CERT_PUBLIC_KEY_INFO pInfo, + byte[] pbComputedHash, + ref int pcbComputedHash); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoEx2.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoEx2.cs new file mode 100644 index 0000000000000..0d0d38fd2e6e7 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoEx2.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; +using Microsoft.Win32.SafeHandles; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] + internal static unsafe partial bool CryptImportPublicKeyInfoEx2( + CertEncodingType dwCertEncodingType, + CERT_PUBLIC_KEY_INFO* pInfo, + CryptImportPublicKeyInfoFlags dwFlags, + void* pvAuxInfo, + out SafeBCryptKeyHandle phKey); + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoFlags.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoFlags.cs new file mode 100644 index 0000000000000..776c2f9c8f0f4 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.CryptImportPublicKeyInfoFlags.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [Flags] + internal enum CryptImportPublicKeyInfoFlags + { + NONE = 0, + CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG = 0x40000000, + } + } +} diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.X509KeyUsageFlags.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.X509KeyUsageFlags.cs new file mode 100644 index 0000000000000..ff5130a8b9330 --- /dev/null +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.X509KeyUsageFlags.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +internal static partial class Interop +{ + internal static partial class Crypt32 + { + [Flags] + public enum X509KeyUsageFlags + { + None = 0x0000, + EncipherOnly = 0x0001, + CrlSign = 0x0002, + KeyCertSign = 0x0004, + KeyAgreement = 0x0008, + DataEncipherment = 0x0010, + KeyEncipherment = 0x0020, + NonRepudiation = 0x0040, + DigitalSignature = 0x0080, + DecipherOnly = 0x8000, + } + } +} diff --git a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeCertContextHandleWithKeyContainerDeletion.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeCertContextHandleWithKeyContainerDeletion.cs index 503b451f26821..7488f624b90c4 100644 --- a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeCertContextHandleWithKeyContainerDeletion.cs +++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeCertContextHandleWithKeyContainerDeletion.cs @@ -68,7 +68,7 @@ internal static void DeleteKeyContainer(SafeCertContextHandle pCertContext) { Interop.Crypt32.CryptAcquireContextFlags flags = (pProvInfo->dwFlags & Interop.Crypt32.CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET) | Interop.Crypt32.CryptAcquireContextFlags.CRYPT_DELETEKEYSET; IntPtr hProv; - _ = Interop.cryptoapi.CryptAcquireContext(out hProv, pProvInfo->pwszContainerName, pProvInfo->pwszProvName, pProvInfo->dwProvType, flags); + _ = Interop.Advapi32.CryptAcquireContext(out hProv, pProvInfo->pwszContainerName, pProvInfo->pwszProvName, pProvInfo->dwProvType, flags); // Called CryptAcquireContext solely for the side effect of deleting the key containers. When called with these flags, no actual // hProv is returned (so there's nothing to clean up.) diff --git a/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeChainEngineHandle.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeChainEngineHandle.cs new file mode 100644 index 0000000000000..516a159462280 --- /dev/null +++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeChainEngineHandle.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.Win32.SafeHandles +{ + internal sealed class SafeChainEngineHandle : SafeHandleZeroOrMinusOneIsInvalid + { + public SafeChainEngineHandle() + : base(true) + { + } + + private SafeChainEngineHandle(IntPtr handle) + : base(true) + { + SetHandle(handle); + } + + public static readonly SafeChainEngineHandle MachineChainEngine = + new SafeChainEngineHandle((IntPtr)Interop.Crypt32.ChainEngine.HCCE_LOCAL_MACHINE); + + public static readonly SafeChainEngineHandle UserChainEngine = + new SafeChainEngineHandle((IntPtr)Interop.Crypt32.ChainEngine.HCCE_CURRENT_USER); + + protected sealed override bool ReleaseHandle() + { + Interop.Crypt32.CertFreeCertificateChainEngine(handle); + SetHandle(IntPtr.Zero); + return true; + } + + protected override void Dispose(bool disposing) + { + if (this != UserChainEngine && this != MachineChainEngine) + { + base.Dispose(disposing); + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs similarity index 93% rename from src/libraries/System.Security.Cryptography.X509Certificates/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs rename to src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs index 0b6968ad8e2fe..20f987f6cc053 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs +++ b/src/libraries/Common/src/Microsoft/Win32/SafeHandles/SafeX509ChainHandle.cs @@ -2,9 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Internal.Cryptography.Pal; -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; namespace Microsoft.Win32.SafeHandles { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs index bb6da361d5dd8..d9c2d1364c45c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.Import.cs @@ -139,7 +139,7 @@ private static unsafe SafeCertContextHandle GetSignerInPKCS7Store(SafeCertStoreH certInfo.SerialNumber.pbData = pCmsgSignerInfo->SerialNumber.pbData; SafeCertContextHandle? pCertContext = null; - if (!Interop.crypt32.CertFindCertificateInStore(hCertStore, CertFindType.CERT_FIND_SUBJECT_CERT, &certInfo, ref pCertContext)) + if (!Interop.crypt32.CertFindCertificateInStore(hCertStore, Interop.Crypt32.CertFindType.CERT_FIND_SUBJECT_CERT, &certInfo, ref pCertContext)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); return pCertContext; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs index 52340e8bfc38a..95210c8f2ce0b 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.PrivateKey.cs @@ -271,7 +271,7 @@ public ICertificatePal CopyWithPrivateKey(RSA rsa) int keySpec = 0; if (!Interop.crypt32.CryptAcquireCertificatePrivateKey( certificateContext, - CryptAcquireFlags.CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, + Interop.Crypt32.CryptAcquireCertificatePrivateKeyFlags.CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, IntPtr.Zero, out privateKey, out keySpec, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs index 1c17b39f594fa..65bff14b3eb59 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/CertificatePal.cs @@ -141,9 +141,9 @@ private byte[] PropagateKeyAlgorithmParametersFromChain() int cbData = 0; if (!Interop.Crypt32.CertGetCertificateContextProperty(_certContext, Interop.Crypt32.CertContextPropId.CERT_PUBKEY_ALG_PARA_PROP_ID, null, ref cbData)) { - CERT_CHAIN_PARA chainPara = default; - chainPara.cbSize = sizeof(CERT_CHAIN_PARA); - if (!Interop.crypt32.CertGetCertificateChain((IntPtr)ChainEngine.HCCE_CURRENT_USER, _certContext, null, SafeCertStoreHandle.InvalidHandle, ref chainPara, CertChainFlags.None, IntPtr.Zero, out certChainContext)) + Interop.Crypt32.CERT_CHAIN_PARA chainPara = default; + chainPara.cbSize = sizeof(Interop.Crypt32.CERT_CHAIN_PARA); + if (!Interop.Crypt32.CertGetCertificateChain((IntPtr)Interop.Crypt32.ChainEngine.HCCE_CURRENT_USER, _certContext, null, SafeCertStoreHandle.InvalidHandle, ref chainPara, Interop.Crypt32.CertChainFlags.None, IntPtr.Zero, out certChainContext)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); if (!Interop.Crypt32.CertGetCertificateContextProperty(_certContext, Interop.Crypt32.CertContextPropId.CERT_PUBKEY_ALG_PARA_PROP_ID, null, ref cbData)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs index 0c3875dca9ef9..ce38255742da7 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.BuildChain.cs @@ -40,15 +40,15 @@ internal sealed partial class ChainPal : IDisposable, IChainPal using (SafeChainEngineHandle storeHandle = GetChainEngine(trustMode, customTrustStore, useMachineContext)) using (SafeCertStoreHandle extraStoreHandle = ConvertStoreToSafeHandle(extraStore)) { - CERT_CHAIN_PARA chainPara = default; - chainPara.cbSize = Marshal.SizeOf(); + Interop.Crypt32.CERT_CHAIN_PARA chainPara = default; + chainPara.cbSize = Marshal.SizeOf(); int applicationPolicyCount; using (SafeHandle applicationPolicyOids = applicationPolicy!.ToLpstrArray(out applicationPolicyCount)) { if (!applicationPolicyOids.IsInvalid) { - chainPara.RequestedUsage.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; + chainPara.RequestedUsage.dwType = Interop.Crypt32.CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedUsage.Usage.cUsageIdentifier = applicationPolicyCount; chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = applicationPolicyOids.DangerousGetHandle(); } @@ -58,7 +58,7 @@ internal sealed partial class ChainPal : IDisposable, IChainPal { if (!certificatePolicyOids.IsInvalid) { - chainPara.RequestedIssuancePolicy.dwType = CertUsageMatchType.USAGE_MATCH_TYPE_AND; + chainPara.RequestedIssuancePolicy.dwType = Interop.Crypt32.CertUsageMatchType.USAGE_MATCH_TYPE_AND; chainPara.RequestedIssuancePolicy.Usage.cUsageIdentifier = certificatePolicyCount; chainPara.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = certificatePolicyOids.DangerousGetHandle(); } @@ -66,9 +66,9 @@ internal sealed partial class ChainPal : IDisposable, IChainPal chainPara.dwUrlRetrievalTimeout = (int)Math.Floor(timeout.TotalMilliseconds); Interop.Crypt32.FILETIME ft = Interop.Crypt32.FILETIME.FromDateTime(verificationTime); - CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag, disableAia); + Interop.Crypt32.CertChainFlags flags = MapRevocationFlags(revocationMode, revocationFlag, disableAia); SafeX509ChainHandle chain; - if (!Interop.crypt32.CertGetCertificateChain(storeHandle.DangerousGetHandle(), certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) + if (!Interop.Crypt32.CertGetCertificateChain(storeHandle.DangerousGetHandle(), certificatePal.CertContext, &ft, extraStoreHandle, ref chainPara, flags, IntPtr.Zero, out chain)) { return null; } @@ -91,8 +91,8 @@ private static SafeChainEngineHandle GetChainEngine( // Need to get a valid SafeCertStoreHandle otherwise the default stores will be trusted using (SafeCertStoreHandle customTrustStoreHandle = ConvertStoreToSafeHandle(customTrustStore, true)) { - CERT_CHAIN_ENGINE_CONFIG customChainEngine = default; - customChainEngine.cbSize = Marshal.SizeOf(); + Interop.Crypt32.CERT_CHAIN_ENGINE_CONFIG customChainEngine = default; + customChainEngine.cbSize = Marshal.SizeOf(); customChainEngine.hExclusiveRoot = customTrustStoreHandle.DangerousGetHandle(); chainEngineHandle = Interop.crypt32.CertCreateCertificateChainEngine(ref customChainEngine); } @@ -113,28 +113,28 @@ private static SafeCertStoreHandle ConvertStoreToSafeHandle(X509Certificate2Coll return ((StorePal)StorePal.LinkFromCertificateCollection(extraStore!)).SafeCertStoreHandle; } - private static CertChainFlags MapRevocationFlags( + private static Interop.Crypt32.CertChainFlags MapRevocationFlags( X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, bool disableAia) { - const CertChainFlags AiaDisabledFlags = - CertChainFlags.CERT_CHAIN_DISABLE_AIA | CertChainFlags.CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE; + const Interop.Crypt32.CertChainFlags AiaDisabledFlags = + Interop.Crypt32.CertChainFlags.CERT_CHAIN_DISABLE_AIA | Interop.Crypt32.CertChainFlags.CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE; - CertChainFlags dwFlags = disableAia ? AiaDisabledFlags : CertChainFlags.None; + Interop.Crypt32.CertChainFlags dwFlags = disableAia ? AiaDisabledFlags : Interop.Crypt32.CertChainFlags.None; if (revocationMode == X509RevocationMode.NoCheck) return dwFlags; if (revocationMode == X509RevocationMode.Offline) - dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; + dwFlags |= Interop.Crypt32.CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY; if (revocationFlag == X509RevocationFlag.EndCertificateOnly) - dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_END_CERT; + dwFlags |= Interop.Crypt32.CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_END_CERT; else if (revocationFlag == X509RevocationFlag.EntireChain) - dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CHAIN; + dwFlags |= Interop.Crypt32.CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CHAIN; else - dwFlags |= CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; + dwFlags |= Interop.Crypt32.CertChainFlags.CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; return dwFlags; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs index ff768073c643e..5b80a71eb8c48 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs @@ -36,12 +36,12 @@ public static IChainPal FromHandle(IntPtr chainContext) unsafe { - CERT_CHAIN_POLICY_PARA para = default; - para.cbSize = sizeof(CERT_CHAIN_POLICY_PARA); - para.dwFlags = (int)flags; + Interop.Crypt32.CERT_CHAIN_POLICY_PARA para = default; + para.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_PARA); + para.dwFlags = (uint)flags; - CERT_CHAIN_POLICY_STATUS status = default; - status.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS); + Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default; + status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS); if (!Interop.crypt32.CertVerifyCertificateChainPolicy(ChainPolicy.CERT_CHAIN_POLICY_BASE, _chain, ref para, ref status)) { @@ -105,7 +105,7 @@ public SafeX509ChainHandle SafeHandle public static bool ReleaseSafeX509ChainHandle(IntPtr handle) { - Interop.crypt32.CertFreeCertificateChain(handle); + Interop.Crypt32.CertFreeCertificateChain(handle); return true; } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs index b3cbcafc2faa9..4cadc49aaf2c6 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/FindPal.cs @@ -48,7 +48,7 @@ public unsafe void FindByThumbprint(byte[] thumbPrint) fixed (byte* pThumbPrint = thumbPrint) { Interop.Crypt32.DATA_BLOB blob = new Interop.Crypt32.DATA_BLOB(new IntPtr(pThumbPrint), (uint)thumbPrint.Length); - FindCore(CertFindType.CERT_FIND_HASH, &blob); + FindCore(Interop.Crypt32.CertFindType.CERT_FIND_HASH, &blob); } } @@ -56,7 +56,7 @@ public unsafe void FindBySubjectName(string subjectName) { fixed (char* pSubjectName = subjectName) { - FindCore(CertFindType.CERT_FIND_SUBJECT_STR, pSubjectName); + FindCore(Interop.Crypt32.CertFindType.CERT_FIND_SUBJECT_STR, pSubjectName); } } @@ -75,7 +75,7 @@ public unsafe void FindByIssuerName(string issuerName) { fixed (char* pIssuerName = issuerName) { - FindCore(CertFindType.CERT_FIND_ISSUER_STR, pIssuerName); + FindCore(Interop.Crypt32.CertFindType.CERT_FIND_ISSUER_STR, pIssuerName); } } @@ -129,7 +129,7 @@ private unsafe void FindByTime(DateTime dateTime, int compareResult) (fileTime, compareResult), static (state, pCertContext) => { - int comparison = Interop.crypt32.CertVerifyTimeValidity(ref state.fileTime, + int comparison = Interop.Crypt32.CertVerifyTimeValidity(ref state.fileTime, pCertContext.CertContext->pCertInfo); GC.KeepAlive(pCertContext); return comparison == state.compareResult; @@ -149,7 +149,7 @@ public unsafe void FindByTemplateName(string templateName) bool foundMatch = false; Interop.Crypt32.CERT_INFO* pCertInfo = pCertContext.CertContext->pCertInfo; { - Interop.Crypt32.CERT_EXTENSION* pV1Template = Interop.crypt32.CertFindExtension(Oids.EnrollCertTypeExtension, + Interop.Crypt32.CERT_EXTENSION* pV1Template = Interop.Crypt32.CertFindExtension(Oids.EnrollCertTypeExtension, pCertInfo->cExtension, pCertInfo->rgExtension); if (pV1Template != null) { @@ -172,7 +172,7 @@ public unsafe void FindByTemplateName(string templateName) if (!foundMatch) { - Interop.Crypt32.CERT_EXTENSION* pV2Template = Interop.crypt32.CertFindExtension(Oids.CertificateTemplate, + Interop.Crypt32.CERT_EXTENSION* pV2Template = Interop.Crypt32.CertFindExtension(Oids.CertificateTemplate, pCertInfo->cExtension, pCertInfo->rgExtension); if (pV2Template != null) { @@ -211,7 +211,7 @@ public unsafe void FindByApplicationPolicy(string oidValue) { int numOids; int cbData = 0; - if (!Interop.crypt32.CertGetValidUsages(1, ref pCertContext, out numOids, null, ref cbData)) + if (!Interop.Crypt32.CertGetValidUsages(1, ref pCertContext, out numOids, null, ref cbData)) return false; // -1 means the certificate is good for all usages. @@ -220,7 +220,7 @@ public unsafe void FindByApplicationPolicy(string oidValue) fixed (byte* pOidsPointer = new byte[cbData]) { - if (!Interop.crypt32.CertGetValidUsages(1, ref pCertContext, out numOids, pOidsPointer, ref cbData)) + if (!Interop.Crypt32.CertGetValidUsages(1, ref pCertContext, out numOids, pOidsPointer, ref cbData)) return false; IntPtr* pOids = (IntPtr*)pOidsPointer; @@ -242,7 +242,7 @@ public unsafe void FindByCertificatePolicy(string oidValue) static (oidValue, pCertContext) => { Interop.Crypt32.CERT_INFO* pCertInfo = pCertContext.CertContext->pCertInfo; - Interop.Crypt32.CERT_EXTENSION* pCertExtension = Interop.crypt32.CertFindExtension(Oids.CertPolicies, + Interop.Crypt32.CERT_EXTENSION* pCertExtension = Interop.Crypt32.CertFindExtension(Oids.CertPolicies, pCertInfo->cExtension, pCertInfo->rgExtension); if (pCertExtension == null) return false; @@ -283,7 +283,7 @@ public unsafe void FindByExtension(string oidValue) static (oidValue, pCertContext) => { Interop.Crypt32.CERT_INFO* pCertInfo = pCertContext.CertContext->pCertInfo; - Interop.Crypt32.CERT_EXTENSION* pCertExtension = Interop.crypt32.CertFindExtension(oidValue, pCertInfo->cExtension, pCertInfo->rgExtension); + Interop.Crypt32.CERT_EXTENSION* pCertExtension = Interop.Crypt32.CertFindExtension(oidValue, pCertInfo->cExtension, pCertInfo->rgExtension); GC.KeepAlive(pCertContext); return pCertExtension != null; }); @@ -329,10 +329,10 @@ public void Dispose() private unsafe void FindCore(TState state, Func filter) { - FindCore(CertFindType.CERT_FIND_ANY, null, state, filter); + FindCore(Interop.Crypt32.CertFindType.CERT_FIND_ANY, null, state, filter); } - private unsafe void FindCore(CertFindType dwFindType, void* pvFindPara, TState state = default!, Func? filter = null) + private unsafe void FindCore(Interop.Crypt32.CertFindType dwFindType, void* pvFindPara, TState state = default!, Func? filter = null) { SafeCertStoreHandle findResults = Interop.crypt32.CertOpenStore( CertStoreProvider.CERT_STORE_PROV_MEMORY, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs index 3d41a6d1e9e49..07dc27d9a39b3 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Helpers.cs @@ -123,7 +123,7 @@ public static TResult DecodeObject( { int cb = 0; - if (!Interop.crypt32.CryptDecodeObjectPointer( + if (!Interop.Crypt32.CryptDecodeObjectPointer( Interop.Crypt32.CertEncodingType.All, lpszStructType, encoded, @@ -137,7 +137,7 @@ public static TResult DecodeObject( byte* decoded = stackalloc byte[cb]; - if (!Interop.crypt32.CryptDecodeObjectPointer( + if (!Interop.Crypt32.CryptDecodeObjectPointer( Interop.Crypt32.CertEncodingType.All, lpszStructType, encoded, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs index 7d0516af4af68..8df13c01e359c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Interop.crypt32.cs @@ -87,15 +87,9 @@ public static bool CryptDecodeObject(Interop.Crypt32.CertEncodingType dwCertEnco public static unsafe bool CryptDecodeObjectPointer(Interop.Crypt32.CertEncodingType dwCertEncodingType, CryptDecodeObjectStructType lpszStructType, byte[] pbEncoded, int cbEncoded, Interop.Crypt32.CryptDecodeObjectFlags dwFlags, void* pvStructInfo, ref int pcbStructInfo) { - return CryptDecodeObjectPointer(dwCertEncodingType, (IntPtr)lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, ref pcbStructInfo); + return Interop.Crypt32.CryptDecodeObjectPointer(dwCertEncodingType, (IntPtr)lpszStructType, pbEncoded, cbEncoded, dwFlags, pvStructInfo, ref pcbStructInfo); } - [GeneratedDllImport(Libraries.Crypt32, EntryPoint = "CryptDecodeObject", CharSet = CharSet.Unicode, SetLastError = true)] - private static unsafe partial bool CryptDecodeObjectPointer(Interop.Crypt32.CertEncodingType dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, int cbEncoded, Interop.Crypt32.CryptDecodeObjectFlags dwFlags, void* pvStructInfo, ref int pcbStructInfo); - - [GeneratedDllImport(Libraries.Crypt32, EntryPoint = "CryptDecodeObject", CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial bool CryptDecodeObjectPointer(Interop.Crypt32.CertEncodingType dwCertEncodingType, [MarshalAs(UnmanagedType.LPStr)] string lpszStructType, byte[] pbEncoded, int cbEncoded, Interop.Crypt32.CryptDecodeObjectFlags dwFlags, void* pvStructInfo, ref int pcbStructInfo); - public static unsafe bool CryptEncodeObject(Interop.Crypt32.CertEncodingType dwCertEncodingType, CryptDecodeObjectStructType lpszStructType, void* pvStructInfo, byte[]? pbEncoded, ref int pcbEncoded) { return Interop.Crypt32.CryptEncodeObject(dwCertEncodingType, (IntPtr)lpszStructType, pvStructInfo, pbEncoded, ref pcbEncoded); @@ -127,9 +121,9 @@ public static unsafe byte[] EncodeObject(string lpszStructType, void* decoded) return encoded; } - internal static SafeChainEngineHandle CertCreateCertificateChainEngine(ref CERT_CHAIN_ENGINE_CONFIG config) + internal static SafeChainEngineHandle CertCreateCertificateChainEngine(ref Interop.Crypt32.CERT_CHAIN_ENGINE_CONFIG config) { - if (!CertCreateCertificateChainEngine(ref config, out SafeChainEngineHandle chainEngineHandle)) + if (!Interop.Crypt32.CertCreateCertificateChainEngine(ref config, out SafeChainEngineHandle chainEngineHandle)) { int errorCode = Marshal.GetLastWin32Error(); throw errorCode.ToCryptographicException(); @@ -138,21 +132,6 @@ internal static SafeChainEngineHandle CertCreateCertificateChainEngine(ref CERT_ return chainEngineHandle; } - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - private static partial bool CertCreateCertificateChainEngine(ref CERT_CHAIN_ENGINE_CONFIG pConfig, out SafeChainEngineHandle hChainEngineHandle); - - [GeneratedDllImport(Libraries.Crypt32)] - public static partial void CertFreeCertificateChainEngine(IntPtr hChainEngine); - - [GeneratedDllImport(Libraries.Crypt32, SetLastError = true)] - public static unsafe partial bool CertGetCertificateChain(IntPtr hChainEngine, SafeCertContextHandle pCertContext, Interop.Crypt32.FILETIME* pTime, SafeCertStoreHandle hStore, ref CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, IntPtr pvReserved, out SafeX509ChainHandle ppChainContext); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static partial bool CryptHashPublicKeyInfo(IntPtr hCryptProv, int algId, int dwFlags, Interop.Crypt32.CertEncodingType dwCertEncodingType, ref Interop.Crypt32.CERT_PUBLIC_KEY_INFO pInfo, byte[] pbComputedHash, ref int pcbComputedHash); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static partial bool CertSaveStore(SafeCertStoreHandle hCertStore, Interop.Crypt32.CertEncodingType dwMsgAndCertEncodingType, CertStoreSaveAs dwSaveAs, CertStoreSaveTo dwSaveTo, ref Interop.Crypt32.DATA_BLOB pvSaveToPara, int dwFlags); - /// /// A less error-prone wrapper for CertEnumCertificatesInStore(). /// @@ -160,52 +139,30 @@ internal static SafeChainEngineHandle CertCreateCertificateChainEngine(ref CERT_ /// the next certificate in the iteration. The final call sets pCertContext to an invalid SafeCertStoreHandle /// and returns "false" to indicate the end of the store has been reached. /// - public static unsafe bool CertFindCertificateInStore(SafeCertStoreHandle hCertStore, CertFindType dwFindType, void* pvFindPara, [NotNull] ref SafeCertContextHandle? pCertContext) + public static unsafe bool CertFindCertificateInStore(SafeCertStoreHandle hCertStore, Interop.Crypt32.CertFindType dwFindType, void* pvFindPara, [NotNull] ref SafeCertContextHandle? pCertContext) { Interop.Crypt32.CERT_CONTEXT* pPrevCertContext = pCertContext == null ? null : pCertContext.Disconnect(); - pCertContext = CertFindCertificateInStore(hCertStore, Interop.Crypt32.CertEncodingType.All, CertFindFlags.None, dwFindType, pvFindPara, pPrevCertContext); + pCertContext = Interop.Crypt32.CertFindCertificateInStore(hCertStore, Interop.Crypt32.CertEncodingType.All, Interop.Crypt32.CertFindFlags.None, dwFindType, pvFindPara, pPrevCertContext); return !pCertContext.IsInvalid; } - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - private static unsafe partial SafeCertContextHandle CertFindCertificateInStore(SafeCertStoreHandle hCertStore, Interop.Crypt32.CertEncodingType dwCertEncodingType, CertFindFlags dwFindFlags, CertFindType dwFindType, void* pvFindPara, Interop.Crypt32.CERT_CONTEXT* pPrevCertContext); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial int CertVerifyTimeValidity(ref Interop.Crypt32.FILETIME pTimeToVerify, Interop.Crypt32.CERT_INFO* pCertInfo); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial Interop.Crypt32.CERT_EXTENSION* CertFindExtension([MarshalAs(UnmanagedType.LPStr)] string pszObjId, int cExtensions, IntPtr rgExtensions); - - // Note: It's somewhat unusual to use an API enum as a parameter type to a P/Invoke but in this case, X509KeyUsageFlags was intentionally designed as bit-wise - // identical to the wincrypt CERT_*_USAGE values. - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial bool CertGetIntendedKeyUsage(Interop.Crypt32.CertEncodingType dwCertEncodingType, Interop.Crypt32.CERT_INFO* pCertInfo, out X509KeyUsageFlags pbKeyUsage, int cbKeyUsage); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial bool CertGetValidUsages(int cCerts, ref SafeCertContextHandle rghCerts, out int cNumOIDs, void* rghOIDs, ref int pcbOIDs); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static partial bool CertControlStore(SafeCertStoreHandle hCertStore, CertControlStoreFlags dwFlags, CertControlStoreType dwControlType, IntPtr pvCtrlPara); - - // Note: CertDeleteCertificateFromStore always calls CertFreeCertificateContext on pCertContext, even if an error is encountered. - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial bool CertDeleteCertificateFromStore(Interop.Crypt32.CERT_CONTEXT* pCertContext); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static partial void CertFreeCertificateChain(IntPtr pChainContext); - - public static bool CertVerifyCertificateChainPolicy(ChainPolicy pszPolicyOID, SafeX509ChainHandle pChainContext, ref CERT_CHAIN_POLICY_PARA pPolicyPara, ref CERT_CHAIN_POLICY_STATUS pPolicyStatus) + public static unsafe bool CertGetIntendedKeyUsage(Interop.Crypt32.CertEncodingType dwCertEncodingType, Interop.Crypt32.CERT_INFO* pCertInfo, out X509KeyUsageFlags pbKeyUsage, int cbKeyUsage) { - return CertVerifyCertificateChainPolicy((IntPtr)pszPolicyOID, pChainContext, ref pPolicyPara, ref pPolicyStatus); + bool result = Interop.Crypt32.CertGetIntendedKeyUsage(dwCertEncodingType, pCertInfo, out Interop.Crypt32.X509KeyUsageFlags x509KeyUsageFlags, cbKeyUsage); + pbKeyUsage = (X509KeyUsageFlags)(int)x509KeyUsageFlags; + return result; } - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - private static partial bool CertVerifyCertificateChainPolicy(IntPtr pszPolicyOID, SafeX509ChainHandle pChainContext, ref CERT_CHAIN_POLICY_PARA pPolicyPara, ref CERT_CHAIN_POLICY_STATUS pPolicyStatus); - - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static unsafe partial bool CryptImportPublicKeyInfoEx2(Interop.Crypt32.CertEncodingType dwCertEncodingType, Interop.Crypt32.CERT_PUBLIC_KEY_INFO* pInfo, CryptImportPublicKeyInfoFlags dwFlags, void* pvAuxInfo, out SafeBCryptKeyHandle phKey); + public static bool CertVerifyCertificateChainPolicy(ChainPolicy pszPolicyOID, SafeX509ChainHandle pChainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA pPolicyPara, ref Interop.Crypt32.CERT_CHAIN_POLICY_STATUS pPolicyStatus) + { + return Interop.Crypt32.CertVerifyCertificateChainPolicy((IntPtr)pszPolicyOID, pChainContext, ref pPolicyPara, ref pPolicyStatus); + } - [GeneratedDllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)] - public static partial bool CryptAcquireCertificatePrivateKey(SafeCertContextHandle pCert, CryptAcquireFlags dwFlags, IntPtr pvParameters, out SafeNCryptKeyHandle phCryptProvOrNCryptKey, out int pdwKeySpec, out bool pfCallerFreeProvOrNCryptKey); + public static bool CryptAcquireCertificatePrivateKey(SafeCertContextHandle pCert, Interop.Crypt32.CryptAcquireCertificatePrivateKeyFlags dwFlags, IntPtr pvParameters, out SafeNCryptKeyHandle phCryptProvOrNCryptKey, out int pdwKeySpec, out bool pfCallerFreeProvOrNCryptKey) + { + bool result = Interop.Crypt32.CryptAcquireCertificatePrivateKey(pCert, dwFlags, pvParameters, out phCryptProvOrNCryptKey, out Interop.Crypt32.CryptKeySpec pdwKeySpecEnum, out pfCallerFreeProvOrNCryptKey); + pdwKeySpec = (int)pdwKeySpecEnum; + return result; + } } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs index 53dbdb873fbbd..bec34b98cd60c 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/Primitives.cs @@ -21,22 +21,6 @@ internal struct CMSG_SIGNER_INFO_Partial // This is not the full definition of //... more fields follow ... } - [Flags] - internal enum CertFindFlags : int - { - None = 0x00000000, - } - - internal enum CertFindType : int - { - CERT_FIND_SUBJECT_CERT = 0x000b0000, - CERT_FIND_HASH = 0x00010000, - CERT_FIND_SUBJECT_STR = 0x00080007, - CERT_FIND_ISSUER_STR = 0x00080004, - CERT_FIND_EXISTING = 0x000d0000, - CERT_FIND_ANY = 0x00000000, - } - internal enum FormatObjectType : int { None = 0, @@ -69,58 +53,6 @@ internal enum CryptDecodeObjectStructType : int X509_CERTIFICATE_TEMPLATE = 64, } - [StructLayout(LayoutKind.Sequential)] - internal struct CTL_USAGE - { - public int cUsageIdentifier; - public IntPtr rgpszUsageIdentifier; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct CERT_USAGE_MATCH - { - public CertUsageMatchType dwType; - public CTL_USAGE Usage; - } - - internal enum CertUsageMatchType : int - { - USAGE_MATCH_TYPE_AND = 0x00000000, - USAGE_MATCH_TYPE_OR = 0x00000001, - } - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct CERT_CHAIN_PARA - { - public int cbSize; - public CERT_USAGE_MATCH RequestedUsage; - public CERT_USAGE_MATCH RequestedIssuancePolicy; - public int dwUrlRetrievalTimeout; - public int fCheckRevocationFreshnessTime; - public int dwRevocationFreshnessTime; - public Interop.Crypt32.FILETIME* pftCacheResync; - public int pStrongSignPara; - public int dwStrongSignFlags; - } - - [Flags] - internal enum CertChainFlags : int - { - None = 0x00000000, - CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE = 0x00000100, - CERT_CHAIN_DISABLE_AIA = 0x00002000, - CERT_CHAIN_REVOCATION_CHECK_END_CERT = 0x10000000, - CERT_CHAIN_REVOCATION_CHECK_CHAIN = 0x20000000, - CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x40000000, - CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY = unchecked((int)0x80000000), - } - - internal enum ChainEngine : int - { - HCCE_CURRENT_USER = 0x0, - HCCE_LOCAL_MACHINE = 0x1, - } - [StructLayout(LayoutKind.Sequential)] internal struct CERT_DSS_PARAMETERS { @@ -162,17 +94,6 @@ internal unsafe struct CERT_ENHKEY_USAGE public IntPtr* rgpszUsageIdentifier; // LPSTR* } - internal enum CertStoreSaveAs : int - { - CERT_STORE_SAVE_AS_STORE = 1, - CERT_STORE_SAVE_AS_PKCS7 = 2, - } - - internal enum CertStoreSaveTo : int - { - CERT_STORE_SAVE_TO_MEMORY = 2, - } - [StructLayout(LayoutKind.Sequential)] internal struct CERT_POLICY_INFO { @@ -204,17 +125,6 @@ internal struct CERT_TEMPLATE_EXT public int dwMinorVersion; } - [Flags] - internal enum CertControlStoreFlags : int - { - None = 0x00000000, - } - - internal enum CertControlStoreType : int - { - CERT_STORE_CTRL_AUTO_RESYNC = 4, - } - [Flags] internal enum CertTrustErrorStatus : int { @@ -335,68 +245,9 @@ internal unsafe struct CERT_CHAIN_CONTEXT public Guid ChainId; } - [StructLayout(LayoutKind.Sequential)] - internal struct CERT_CHAIN_POLICY_PARA - { - public int cbSize; - public int dwFlags; - public IntPtr pvExtraPolicyPara; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct CERT_CHAIN_POLICY_STATUS - { - public int cbSize; - public int dwError; - public IntPtr lChainIndex; - public IntPtr lElementIndex; - public IntPtr pvExtraPolicyStatus; - } - internal enum ChainPolicy : int { // Predefined verify chain policies CERT_CHAIN_POLICY_BASE = 1, } - - internal enum CryptAcquireFlags : int - { - CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG = 0x00040000, - } - - [Flags] - internal enum ChainEngineConfigFlags : int - { - CERT_CHAIN_CACHE_END_CERT = 0x00000001, - CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL = 0x00000004, - CERT_CHAIN_USE_LOCAL_MACHINE_STORE = 0x00000008, - CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE = 0x00000010, - CERT_CHAIN_ENABLE_SHARE_STORE = 0x00000020, - CERT_CHAIN_DISABLE_AIA = 0x00002000, - } - - // Windows 7 definition of the struct - [StructLayout(LayoutKind.Sequential)] - internal struct CERT_CHAIN_ENGINE_CONFIG - { - public int cbSize; - public IntPtr hRestrictedRoot; - public IntPtr hRestrictedTrust; - public IntPtr hRestrictedOther; - public int cAdditionalStore; - public IntPtr rghAdditionalStore; - public ChainEngineConfigFlags dwFlags; - public int dwUrlRetrievalTimeout; - public int MaximumCachedCertificates; - public int CycleDetectionModulus; - public IntPtr hExclusiveRoot; - public IntPtr hExclusiveTrustedPeople; - } - - [Flags] - internal enum CryptImportPublicKeyInfoFlags - { - NONE = 0, - CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG = 0x40000000, - } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs index 3d8a71f732a3e..c9cf3d62fe055 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/Native/SafeHandles.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Win32.SafeHandles; -using System; using System.Runtime.InteropServices; #pragma warning disable CA1419 // TODO https://github.com/dotnet/roslyn-analyzers/issues/5232: not intended for use with P/Invoke @@ -27,39 +26,4 @@ protected sealed override bool ReleaseHandle() return true; } } - - internal sealed class SafeChainEngineHandle : SafeHandleZeroOrMinusOneIsInvalid - { - public SafeChainEngineHandle() - : base(true) - { - } - - private SafeChainEngineHandle(IntPtr handle) - : base(true) - { - SetHandle(handle); - } - - public static readonly SafeChainEngineHandle MachineChainEngine = - new SafeChainEngineHandle((IntPtr)ChainEngine.HCCE_LOCAL_MACHINE); - - public static readonly SafeChainEngineHandle UserChainEngine = - new SafeChainEngineHandle((IntPtr)ChainEngine.HCCE_CURRENT_USER); - - protected sealed override bool ReleaseHandle() - { - Interop.crypt32.CertFreeCertificateChainEngine(handle); - SetHandle(IntPtr.Zero); - return true; - } - - protected override void Dispose(bool disposing) - { - if (this != UserChainEngine && this != MachineChainEngine) - { - base.Dispose(disposing); - } - } - } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs index a67477bb40abc..2a44fb6aba75e 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Export.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal.Native; using Microsoft.Win32.SafeHandles; using System; using System.Diagnostics; @@ -93,29 +92,29 @@ public void MoveTo(X509Certificate2Collection collection) } case X509ContentType.SerializedStore: - return SaveToMemoryStore(CertStoreSaveAs.CERT_STORE_SAVE_AS_STORE); + return SaveToMemoryStore(Interop.Crypt32.CertStoreSaveAs.CERT_STORE_SAVE_AS_STORE); case X509ContentType.Pkcs7: - return SaveToMemoryStore(CertStoreSaveAs.CERT_STORE_SAVE_AS_PKCS7); + return SaveToMemoryStore(Interop.Crypt32.CertStoreSaveAs.CERT_STORE_SAVE_AS_PKCS7); default: throw new CryptographicException(SR.Cryptography_X509_InvalidContentType); } } - private byte[] SaveToMemoryStore(CertStoreSaveAs dwSaveAs) + private byte[] SaveToMemoryStore(Interop.Crypt32.CertStoreSaveAs dwSaveAs) { unsafe { Interop.Crypt32.DATA_BLOB blob = new Interop.Crypt32.DATA_BLOB(IntPtr.Zero, 0); - if (!Interop.crypt32.CertSaveStore(_certStore, Interop.Crypt32.CertEncodingType.All, dwSaveAs, CertStoreSaveTo.CERT_STORE_SAVE_TO_MEMORY, ref blob, 0)) + if (!Interop.Crypt32.CertSaveStore(_certStore, Interop.Crypt32.CertEncodingType.All, dwSaveAs, Interop.Crypt32.CertStoreSaveTo.CERT_STORE_SAVE_TO_MEMORY, ref blob, 0)) throw Marshal.GetLastWin32Error().ToCryptographicException(); byte[] exportedData = new byte[blob.cbData]; fixed (byte* pExportedData = exportedData) { blob.pbData = new IntPtr(pExportedData); - if (!Interop.crypt32.CertSaveStore(_certStore, Interop.Crypt32.CertEncodingType.All, dwSaveAs, CertStoreSaveTo.CERT_STORE_SAVE_TO_MEMORY, ref blob, 0)) + if (!Interop.Crypt32.CertSaveStore(_certStore, Interop.Crypt32.CertEncodingType.All, dwSaveAs, Interop.Crypt32.CertStoreSaveTo.CERT_STORE_SAVE_TO_MEMORY, ref blob, 0)) throw Marshal.GetLastWin32Error().ToCryptographicException(); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs index a44b64d42cec9..ed4c5386e74bf 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.Import.cs @@ -163,7 +163,7 @@ public static IStorePal FromSystemStore(string storeName, StoreLocation storeLoc // // For compat with desktop, ignoring any failures from this call. (It is pretty unlikely to fail, in any case.) // - _ = Interop.crypt32.CertControlStore(certStore, CertControlStoreFlags.None, CertControlStoreType.CERT_STORE_CTRL_AUTO_RESYNC, IntPtr.Zero); + _ = Interop.Crypt32.CertControlStore(certStore, Interop.Crypt32.CertControlStoreFlags.None, Interop.Crypt32.CertControlStoreType.CERT_STORE_CTRL_AUTO_RESYNC, IntPtr.Zero); return new StorePal(certStore); } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs index 4a51e200d694c..47bbfe4c7988d 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/StorePal.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Internal.Cryptography.Pal.Native; using Microsoft.Win32.SafeHandles; using System; using System.Diagnostics; @@ -58,11 +57,11 @@ public void Remove(ICertificatePal certificate) SafeCertContextHandle existingCertContext = ((CertificatePal)certificate).CertContext; SafeCertContextHandle? enumCertContext = null; Interop.Crypt32.CERT_CONTEXT* pCertContext = existingCertContext.CertContext; - if (!Interop.crypt32.CertFindCertificateInStore(_certStore, CertFindType.CERT_FIND_EXISTING, pCertContext, ref enumCertContext)) + if (!Interop.crypt32.CertFindCertificateInStore(_certStore, Interop.Crypt32.CertFindType.CERT_FIND_EXISTING, pCertContext, ref enumCertContext)) return; // The certificate is not present in the store, simply return. Interop.Crypt32.CERT_CONTEXT* pCertContextToDelete = enumCertContext.Disconnect(); // CertDeleteCertificateFromContext always frees the context (even on error) - if (!Interop.crypt32.CertDeleteCertificateFromStore(pCertContextToDelete)) + if (!Interop.Crypt32.CertDeleteCertificateFromStore(pCertContextToDelete)) throw Marshal.GetLastWin32Error().ToCryptographicException(); GC.KeepAlive(existingCertContext); diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs index 763f127441568..677fb54ac35b1 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.CustomExtensions.cs @@ -224,7 +224,7 @@ public byte[] ComputeCapiSha1OfPublicKey(PublicKey key) int cb = 20; byte[] buffer = new byte[cb]; - if (!Interop.crypt32.CryptHashPublicKeyInfo(IntPtr.Zero, AlgId.CALG_SHA1, 0, Interop.Crypt32.CertEncodingType.All, ref publicKeyInfo, buffer, ref cb)) + if (!Interop.Crypt32.CryptHashPublicKeyInfo(IntPtr.Zero, AlgId.CALG_SHA1, 0, Interop.Crypt32.CertEncodingType.All, ref publicKeyInfo, buffer, ref cb)) throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); if (cb < buffer.Length) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs index 6751c910661b2..8355f6834dc45 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs @@ -134,7 +134,7 @@ private static SafeBCryptKeyHandle ImportPublicKeyInfo(SafeCertContextHandle cer { unsafe { - bool success = Interop.crypt32.CryptImportPublicKeyInfoEx2(Interop.Crypt32.CertEncodingType.X509_ASN_ENCODING, &(certContext.CertContext->pCertInfo->SubjectPublicKeyInfo), importFlags, null, out bCryptKeyHandle); + bool success = Interop.Crypt32.CryptImportPublicKeyInfoEx2(Interop.Crypt32.CertEncodingType.X509_ASN_ENCODING, &(certContext.CertContext->pCertInfo->SubjectPublicKeyInfo), importFlags, null, out bCryptKeyHandle); if (!success) throw Marshal.GetHRForLastWin32Error().ToCryptographicException(); return bCryptKeyHandle; diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj index 3783b0ca44337..3ea6525c02b41 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj @@ -130,7 +130,8 @@ - + @@ -243,7 +244,6 @@ - @@ -255,16 +255,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + +