mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Remove undocumented certificate Win32 APIs (#3818)
The code paths deleted where using the undocumented Win32 APIs on WIn8 and newer for the following purposes: * Faster filtering * Getting two properties (left empty on Win7 and below) * Logging using Certificate components when a cert is deleted or copied. After the change, all the code uses public APIs. Filtering is done in PowerShell using existing code. I don't believe the logging is needed.
This commit is contained in:
committed by
Dongbo Wang
parent
7517004052
commit
3496136999
@@ -15,6 +15,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Management.Automation.Provider;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Globalization;
|
||||
@@ -154,134 +155,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the Certificate Provider dynamic parameters.
|
||||
///
|
||||
/// We only support one dynamic parameter for Win 7 and earlier:
|
||||
/// CodeSigningCert
|
||||
/// If provided, we only return certificates valid for signing code or
|
||||
/// scripts.
|
||||
///
|
||||
/// For Win 8 and later, we also support:
|
||||
/// SSLServerAuthentication
|
||||
/// If provided, only return certificates valid for server authentication.
|
||||
///
|
||||
/// DnsName
|
||||
/// If provided, only return certificates matching the supplied DNS Name.
|
||||
///
|
||||
/// Eku
|
||||
/// If provided, only return certificates containing all of the OIDs
|
||||
/// supplied.
|
||||
///
|
||||
/// ExpiringInDays
|
||||
/// If provided, only return certificates expiring within the specified
|
||||
/// number of days.
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
internal sealed class CertificateProviderDynamicParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// switch that controls whether we only return
|
||||
/// code signing certs.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public SwitchParameter CodeSigningCert
|
||||
{
|
||||
get { return _codeSigningCert; }
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method is used by command line processing")]
|
||||
set
|
||||
{ _codeSigningCert = value; }
|
||||
}
|
||||
private SwitchParameter _codeSigningCert = new SwitchParameter();
|
||||
|
||||
/// <summary>
|
||||
/// switch that controls whether we only return
|
||||
/// data encipherment certs.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public SwitchParameter DocumentEncryptionCert
|
||||
{
|
||||
get { return _documentEncryptionCert; }
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method is used by command line processing")]
|
||||
set
|
||||
{ _documentEncryptionCert = value; }
|
||||
}
|
||||
private SwitchParameter _documentEncryptionCert = new SwitchParameter();
|
||||
|
||||
/// <summary>
|
||||
/// switch that controls whether we only return
|
||||
/// code signing certs.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public SwitchParameter SSLServerAuthentication
|
||||
{
|
||||
get { return _sslServerAuthentication; }
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method is used by command line processing")]
|
||||
set
|
||||
{ _sslServerAuthentication = value; }
|
||||
}
|
||||
|
||||
private SwitchParameter _sslServerAuthentication = new SwitchParameter();
|
||||
|
||||
/// <summary>
|
||||
/// string to filter certs by DNSName
|
||||
/// Expected content is a single DNS Name that may start and/or end
|
||||
/// with '*': "contoso.com" or "*toso.c*"
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public DnsNameRepresentation DnsName
|
||||
{
|
||||
get { return _dnsName; }
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method is used by command line processing")]
|
||||
set
|
||||
{ _dnsName = value; }
|
||||
}
|
||||
|
||||
private DnsNameRepresentation _dnsName;
|
||||
|
||||
/// <summary>
|
||||
/// string to filter certs by EKU
|
||||
/// Expected content is one or more OID strings:
|
||||
/// "1.3.6.1.5.5.7.3.1", etc.
|
||||
/// For a cert to match, it must be valid for all listed OIDs.
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public string[] Eku
|
||||
{
|
||||
get { return _eku; }
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method is used by command line processing")]
|
||||
set
|
||||
{ _eku = value; }
|
||||
}
|
||||
|
||||
private string[] _eku = null;
|
||||
|
||||
/// <summary>
|
||||
/// string to filter certs by the number of valid days
|
||||
/// Expected content is a non-negative integer.
|
||||
/// "0" matches all certs that have already expired.
|
||||
/// "1" matches all certs that are currently valid and will expire
|
||||
/// by midnight tonight (local time).
|
||||
/// </summary>
|
||||
[Parameter()]
|
||||
public int ExpiringInDays
|
||||
{
|
||||
get { return _expiringInDays; }
|
||||
|
||||
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "This method is used by command line processing")]
|
||||
set
|
||||
{ _expiringInDays = value; }
|
||||
}
|
||||
|
||||
private int _expiringInDays = -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the Certificate Provider remove-item dynamic parameters.
|
||||
///
|
||||
@@ -351,42 +224,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the safe handle class for native cert store handles,
|
||||
/// HCERTSTORE.
|
||||
/// </summary>
|
||||
internal sealed class CertificateFilterHandle : SafeHandle
|
||||
{
|
||||
public CertificateFilterHandle() : base(IntPtr.Zero, true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
bool fResult = false;
|
||||
|
||||
if (IntPtr.Zero != handle)
|
||||
{
|
||||
Security.NativeMethods.CCFindCertificateFreeFilter(handle);
|
||||
handle = IntPtr.Zero;
|
||||
fResult = true;
|
||||
}
|
||||
return fResult;
|
||||
}
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get { return handle; }
|
||||
set { handle = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the Certificate Provider store handle class
|
||||
/// </summary>
|
||||
@@ -477,25 +314,8 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
}
|
||||
|
||||
public IntPtr GetFirstCert(
|
||||
CertificateFilterInfo filter)
|
||||
public IntPtr GetFirstCert()
|
||||
{
|
||||
_filterHandle = null;
|
||||
if (DownLevelHelper.NativeFilteringSupported() && filter != null)
|
||||
{
|
||||
IntPtr hFilter = IntPtr.Zero;
|
||||
|
||||
_filterHandle = new CertificateFilterHandle();
|
||||
int hr = Security.NativeMethods.CCFindCertificateBuildFilter(
|
||||
filter.FilterString,
|
||||
ref hFilter);
|
||||
if (hr != Security.NativeConstants.S_OK)
|
||||
{
|
||||
_filterHandle = null;
|
||||
throw new System.ComponentModel.Win32Exception(hr);
|
||||
}
|
||||
_filterHandle.Handle = hFilter;
|
||||
}
|
||||
return GetNextCert(IntPtr.Zero);
|
||||
}
|
||||
|
||||
@@ -508,19 +328,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
}
|
||||
if (Valid)
|
||||
{
|
||||
if (_filterHandle != null)
|
||||
{
|
||||
certContext = Security.NativeMethods.CCFindCertificateFromFilter(
|
||||
_storeHandle.Handle,
|
||||
_filterHandle.Handle,
|
||||
certContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
certContext = Security.NativeMethods.CertEnumCertificatesInStore(
|
||||
_storeHandle.Handle,
|
||||
certContext);
|
||||
}
|
||||
certContext = Security.NativeMethods.CertEnumCertificatesInStore(
|
||||
_storeHandle.Handle,
|
||||
certContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -635,7 +445,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
private X509StoreLocation _storeLocation = null;
|
||||
private string _storeName = null;
|
||||
private CertificateStoreHandle _storeHandle = null;
|
||||
private CertificateFilterHandle _filterHandle = null;
|
||||
private bool _valid = false;
|
||||
private bool _open = false;
|
||||
}
|
||||
@@ -1233,7 +1042,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
if (store != null)
|
||||
{
|
||||
store.Open(IncludeArchivedCerts());
|
||||
IntPtr certContext = store.GetFirstCert(null);
|
||||
IntPtr certContext = store.GetFirstCert();
|
||||
if (IntPtr.Zero != certContext)
|
||||
{
|
||||
store.FreeCert(certContext);
|
||||
@@ -1944,7 +1753,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
//
|
||||
// enumerate over each cert and remove it
|
||||
//
|
||||
IntPtr certContext = store.GetFirstCert(null);
|
||||
IntPtr certContext = store.GetFirstCert();
|
||||
while (IntPtr.Zero != certContext)
|
||||
{
|
||||
X509Certificate2 cert = new X509Certificate2(certContext);
|
||||
@@ -2092,10 +1901,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
CommitUserDS(context.hCertStore);
|
||||
}
|
||||
|
||||
if (DownLevelHelper.LogCertChangeSupported())
|
||||
{
|
||||
Security.NativeMethods.LogCertDelete(fMachine, cert.Handle);
|
||||
}
|
||||
//TODO: Log Cert Delete
|
||||
|
||||
//delete private key
|
||||
if (fDeleteKey && fHasPrivateKey)
|
||||
@@ -2173,18 +1979,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
if (DownLevelHelper.LogCertChangeSupported())
|
||||
{
|
||||
bool fMachine = store.Location.Location == StoreLocation.LocalMachine;
|
||||
|
||||
if (cert.HasPrivateKey &&
|
||||
String.Equals(store.StoreName, "MY", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Security.NativeMethods.LogCertCopy(fMachine, cert.Handle);
|
||||
}
|
||||
|
||||
Security.NativeMethods.LogCertDelete(fMachine, cert.Handle);
|
||||
}
|
||||
//TODO: log cert move
|
||||
}
|
||||
|
||||
//commit the change to physical store
|
||||
@@ -2499,14 +2294,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
///
|
||||
protected override object GetItemDynamicParameters(string path)
|
||||
{
|
||||
if (DownLevelHelper.NativeFilteringSupported())
|
||||
{
|
||||
return new CertificateProviderDynamicParameters();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CertificateProviderCodeSigningDynamicParameters();
|
||||
}
|
||||
return new CertificateProviderCodeSigningDynamicParameters();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2531,14 +2319,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </returns>
|
||||
protected override object GetChildItemsDynamicParameters(string path, bool recurse)
|
||||
{
|
||||
if (DownLevelHelper.NativeFilteringSupported())
|
||||
{
|
||||
return new CertificateProviderDynamicParameters();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CertificateProviderCodeSigningDynamicParameters();
|
||||
}
|
||||
return new CertificateProviderCodeSigningDynamicParameters();
|
||||
}
|
||||
|
||||
#endregion DriveCmdletProvider overrides
|
||||
@@ -2718,7 +2499,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
//
|
||||
// enumerate over each cert and return it (or its name)
|
||||
//
|
||||
IntPtr certContext = store.GetFirstCert(filter);
|
||||
IntPtr certContext = store.GetFirstCert();
|
||||
|
||||
while (IntPtr.Zero != certContext)
|
||||
{
|
||||
@@ -2952,62 +2733,14 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
if (DynamicParameters != null)
|
||||
{
|
||||
if (DownLevelHelper.NativeFilteringSupported())
|
||||
CertificateProviderCodeSigningDynamicParameters dp =
|
||||
DynamicParameters as CertificateProviderCodeSigningDynamicParameters;
|
||||
if (dp != null)
|
||||
{
|
||||
CertificateProviderDynamicParameters dp =
|
||||
DynamicParameters as CertificateProviderDynamicParameters;
|
||||
if (dp != null)
|
||||
if (dp.CodeSigningCert)
|
||||
{
|
||||
bool filterSpecified = false;
|
||||
|
||||
filter = new CertificateFilterInfo();
|
||||
if (dp.CodeSigningCert)
|
||||
{
|
||||
filter.Purpose = CertificatePurpose.CodeSigning;
|
||||
filterSpecified = true;
|
||||
}
|
||||
if (dp.DocumentEncryptionCert)
|
||||
{
|
||||
filter.Purpose = CertificatePurpose.DocumentEncryption;
|
||||
filterSpecified = true;
|
||||
}
|
||||
if (dp.SSLServerAuthentication)
|
||||
{
|
||||
filter.SSLServerAuthentication = true;
|
||||
filterSpecified = true;
|
||||
}
|
||||
if (dp.DnsName.Punycode != null)
|
||||
{
|
||||
filter.DnsName = dp.DnsName.Punycode;
|
||||
filterSpecified = true;
|
||||
}
|
||||
if (dp.Eku != null)
|
||||
{
|
||||
filter.Eku = dp.Eku;
|
||||
filterSpecified = true;
|
||||
}
|
||||
if (dp.ExpiringInDays >= 0)
|
||||
{
|
||||
filter.ExpiringInDays = dp.ExpiringInDays;
|
||||
filterSpecified = true;
|
||||
}
|
||||
if (!filterSpecified)
|
||||
{
|
||||
filter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CertificateProviderCodeSigningDynamicParameters dp =
|
||||
DynamicParameters as CertificateProviderCodeSigningDynamicParameters;
|
||||
if (dp != null)
|
||||
{
|
||||
if (dp.CodeSigningCert)
|
||||
{
|
||||
filter = new CertificateFilterInfo();
|
||||
filter.Purpose = CertificatePurpose.CodeSigning;
|
||||
}
|
||||
filter.Purpose = CertificatePurpose.CodeSigning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3541,33 +3274,20 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </summary>
|
||||
public EnhancedKeyUsageProperty(X509Certificate2 cert)
|
||||
{
|
||||
if (DownLevelHelper.NativeFilteringSupported())
|
||||
foreach (X509Extension extension in cert.Extensions)
|
||||
{
|
||||
Collection<string> ekuCollection = System.Management.Automation.Internal.SecuritySupport.GetCertEKU(cert);
|
||||
|
||||
foreach (string oidString in ekuCollection)
|
||||
// Filter to the OID for EKU
|
||||
if (extension.Oid.Value == "2.5.29.37")
|
||||
{
|
||||
if (!String.IsNullOrEmpty(oidString))
|
||||
X509EnhancedKeyUsageExtension ext = extension as X509EnhancedKeyUsageExtension;
|
||||
if(ext != null)
|
||||
{
|
||||
IntPtr stringAnsi = (IntPtr)Marshal.StringToHGlobalAnsi(oidString);
|
||||
|
||||
EnhancedKeyUsageRepresentation ekuString;
|
||||
IntPtr oidPtr = Security.NativeMethods.CryptFindOIDInfo(
|
||||
Security.NativeConstants.CRYPT_OID_INFO_OID_KEY,
|
||||
stringAnsi,
|
||||
0);
|
||||
if (oidPtr != IntPtr.Zero)
|
||||
OidCollection oids = ext.EnhancedKeyUsages;
|
||||
foreach (Oid oid in oids)
|
||||
{
|
||||
Security.NativeMethods.CRYPT_OID_INFO oidInfo =
|
||||
ClrFacade.PtrToStructure<Security.NativeMethods.CRYPT_OID_INFO>(oidPtr);
|
||||
ekuString = new EnhancedKeyUsageRepresentation(oidInfo.pwszName, oidString);
|
||||
EnhancedKeyUsageRepresentation ekuString = new EnhancedKeyUsageRepresentation(oid.FriendlyName, oid.Value);
|
||||
_ekuList.Add(ekuString);
|
||||
}
|
||||
else //if oidInfo is not available
|
||||
{
|
||||
ekuString = new EnhancedKeyUsageRepresentation(null, oidString);
|
||||
}
|
||||
|
||||
_ekuList.Add(ekuString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3581,6 +3301,9 @@ namespace Microsoft.PowerShell.Commands
|
||||
public sealed class DnsNameProperty
|
||||
{
|
||||
private List<DnsNameRepresentation> _dnsList = new List<DnsNameRepresentation>();
|
||||
private System.Globalization.IdnMapping idnMapping = new System.Globalization.IdnMapping();
|
||||
private const string dnsNamePrefix = "DNS Name=";
|
||||
private const string distinguishedNamePrefix = "CN=";
|
||||
|
||||
/// <summary>
|
||||
/// get property of DnsNameList
|
||||
@@ -3598,81 +3321,65 @@ namespace Microsoft.PowerShell.Commands
|
||||
/// </summary>
|
||||
public DnsNameProperty(X509Certificate2 cert)
|
||||
{
|
||||
if (DownLevelHelper.NativeFilteringSupported())
|
||||
string name;
|
||||
string unicodeName;
|
||||
DnsNameRepresentation dnsName;
|
||||
_dnsList = new List<DnsNameRepresentation>();
|
||||
|
||||
// extract DNS name from subject distinguish name
|
||||
// if it exists and does not contain a comma
|
||||
// a comma, indicates it is not a DNS name
|
||||
if(cert.Subject.StartsWith(distinguishedNamePrefix, System.StringComparison.InvariantCultureIgnoreCase) &&
|
||||
cert.Subject.IndexOf(",",System.StringComparison.InvariantCulture)==-1)
|
||||
{
|
||||
if (cert != null)
|
||||
{
|
||||
//need to get subject alternative name from the certificate context
|
||||
_dnsList = GetCertNames(
|
||||
cert.Handle,
|
||||
Security.NativeMethods.AltNameType.CERT_ALT_NAME_DNS_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper function for CCGetCertNameList and CCFreeStringArray
|
||||
private List<DnsNameRepresentation> GetCertNames(IntPtr certHandle, Security.NativeMethods.AltNameType nameType)
|
||||
{
|
||||
DWORD cPunycodeName;
|
||||
IntPtr papwszPunycodeNames = IntPtr.Zero;
|
||||
IntPtr papwszUnicodeNames = IntPtr.Zero;
|
||||
List<DnsNameRepresentation> names = new List<DnsNameRepresentation>();
|
||||
int hr;
|
||||
|
||||
if (certHandle != IntPtr.Zero)
|
||||
{
|
||||
hr = Security.NativeMethods.CCGetCertNameList(
|
||||
certHandle,
|
||||
nameType,
|
||||
0, // no conversion to Unicode
|
||||
out cPunycodeName,
|
||||
out papwszPunycodeNames);
|
||||
if (hr != Security.NativeConstants.S_OK)
|
||||
{
|
||||
if (hr != Security.NativeMethods.CRYPT_E_NOT_FOUND)
|
||||
{
|
||||
throw Marshal.GetExceptionForHR(hr);
|
||||
}
|
||||
cPunycodeName = 0;
|
||||
}
|
||||
|
||||
name = cert.Subject.Substring(distinguishedNamePrefix.Length);
|
||||
try
|
||||
{
|
||||
if (0 < cPunycodeName)
|
||||
{
|
||||
DWORD cUnicodeName;
|
||||
unicodeName = idnMapping.GetUnicode(name);
|
||||
}
|
||||
catch(System.ArgumentException)
|
||||
{
|
||||
// The name is not valid punyCode, assume it's valid ascii.
|
||||
unicodeName = name;
|
||||
}
|
||||
|
||||
hr = Security.NativeMethods.CCGetCertNameList(
|
||||
certHandle,
|
||||
nameType,
|
||||
Security.NativeMethods.CryptDecodeFlags.CRYPT_DECODE_ENABLE_IA5CONVERSION_FLAG,
|
||||
out cUnicodeName,
|
||||
out papwszUnicodeNames);
|
||||
if (hr != Security.NativeConstants.S_OK)
|
||||
dnsName = new DnsNameRepresentation(name,unicodeName);
|
||||
_dnsList.Add(dnsName);
|
||||
}
|
||||
|
||||
foreach (X509Extension extension in cert.Extensions)
|
||||
{
|
||||
// Filter to the OID for Subject Alternative Name
|
||||
if (extension.Oid.Value == "2.5.29.17")
|
||||
{
|
||||
string[] names = extension.Format(true).Split(Environment.NewLine);
|
||||
foreach(string nameLine in names)
|
||||
{
|
||||
// Get the part after 'DNS Name='
|
||||
if(nameLine.StartsWith(dnsNamePrefix, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
throw Marshal.GetExceptionForHR(hr);
|
||||
}
|
||||
if (cPunycodeName != cUnicodeName)
|
||||
{
|
||||
throw Marshal.GetExceptionForHR(
|
||||
Security.NativeMethods.E_INVALID_DATA);
|
||||
}
|
||||
for (int i = 0; i < cPunycodeName; i++)
|
||||
{
|
||||
names.Add(new DnsNameRepresentation(
|
||||
Marshal.PtrToStringUni(Marshal.ReadIntPtr(papwszPunycodeNames, i * Marshal.SizeOf(papwszPunycodeNames))),
|
||||
Marshal.PtrToStringUni(Marshal.ReadIntPtr(papwszUnicodeNames, i * Marshal.SizeOf(papwszUnicodeNames)))));
|
||||
name = nameLine.Substring(dnsNamePrefix.Length);
|
||||
try
|
||||
{
|
||||
unicodeName = idnMapping.GetUnicode(name);
|
||||
}
|
||||
catch(System.ArgumentException)
|
||||
{
|
||||
// The name is not valid punyCode, assume it's valid ascii.
|
||||
unicodeName = name;
|
||||
}
|
||||
|
||||
dnsName = new DnsNameRepresentation(name,unicodeName);
|
||||
|
||||
// Only add the name if it is not the same as an existing name.
|
||||
if(!_dnsList.Contains(dnsName))
|
||||
{
|
||||
_dnsList.Add(dnsName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Security.NativeMethods.CCFreeStringArray(papwszPunycodeNames);
|
||||
Security.NativeMethods.CCFreeStringArray(papwszUnicodeNames);
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3689,9 +3396,6 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
if (!s_isWin8Set)
|
||||
{
|
||||
#if CORECLR
|
||||
s_isWin8 = true;
|
||||
#else
|
||||
System.OperatingSystem osInfo = System.Environment.OSVersion;
|
||||
PlatformID platform = osInfo.Platform;
|
||||
Version version = osInfo.Version;
|
||||
@@ -3702,44 +3406,12 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
s_isWin8 = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_isWin8Set = true;
|
||||
}
|
||||
return s_isWin8;
|
||||
}
|
||||
|
||||
private static bool s_nativeFilteringSet = false;
|
||||
private static bool s_nativeFiltering = false;
|
||||
|
||||
internal static bool NativeFilteringSupported()
|
||||
{
|
||||
if (!s_nativeFilteringSet)
|
||||
{
|
||||
if (IsWin8AndAbove() && Security.NativeMethods.IsSystem32DllPresent("certca.dll"))
|
||||
{
|
||||
s_nativeFiltering = true;
|
||||
}
|
||||
s_nativeFilteringSet = true;
|
||||
}
|
||||
return s_nativeFiltering;
|
||||
}
|
||||
|
||||
private static bool s_logChangesSet = false;
|
||||
private static bool s_logChanges = false;
|
||||
|
||||
internal static bool LogCertChangeSupported()
|
||||
{
|
||||
if (!s_logChangesSet)
|
||||
{
|
||||
if (IsWin8AndAbove() && Security.NativeMethods.IsSystem32DllPresent("certenroll.dll"))
|
||||
{
|
||||
s_logChanges = true;
|
||||
}
|
||||
s_logChangesSet = true;
|
||||
}
|
||||
return s_logChanges;
|
||||
}
|
||||
|
||||
internal static bool TrustedIssuerSupported()
|
||||
{
|
||||
return IsWin8AndAbove();
|
||||
|
||||
@@ -1453,59 +1453,6 @@ namespace System.Management.Automation.Security
|
||||
CRYPT_DECODE_ENABLE_UTF8PERCENT_FLAG = 0x04000000,
|
||||
CRYPT_DECODE_ENABLE_IA5CONVERSION_FLAG = (CRYPT_DECODE_ENABLE_PUNYCODE_FLAG | CRYPT_DECODE_ENABLE_UTF8PERCENT_FLAG),
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// certca.dll stuff
|
||||
//
|
||||
|
||||
[DllImport("certca.dll")]
|
||||
internal static extern
|
||||
int CCFindCertificateBuildFilter(
|
||||
[MarshalAsAttribute(UnmanagedType.LPWStr)]
|
||||
string filter,
|
||||
ref IntPtr certFilter);
|
||||
|
||||
[DllImport("certca.dll")]
|
||||
internal static extern
|
||||
void CCFindCertificateFreeFilter(
|
||||
IntPtr certFilter);
|
||||
|
||||
|
||||
[DllImport("certca.dll")]
|
||||
internal static extern
|
||||
IntPtr CCFindCertificateFromFilter(
|
||||
IntPtr storeHandle,
|
||||
IntPtr certFilter,
|
||||
IntPtr prevCertContext);
|
||||
|
||||
[DllImport("certca.dll")]
|
||||
internal static extern
|
||||
int // HRESULT
|
||||
CCGetCertNameList(
|
||||
IntPtr certContext,
|
||||
AltNameType dwAltNameChoice,
|
||||
CryptDecodeFlags dwFlags,
|
||||
out DWORD cName,
|
||||
out IntPtr papwszName);
|
||||
|
||||
[DllImport("certca.dll")]
|
||||
internal static extern
|
||||
void CCFreeStringArray(IntPtr papwsz);
|
||||
}
|
||||
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
// HRESULT LogCertDelete(")
|
||||
// __in bool fMachine,")
|
||||
// __in PCCERT_CONTEXT pCertContext)
|
||||
[DllImport("certenroll.dll")]
|
||||
internal static extern int LogCertDelete(bool fMachine, IntPtr pCertContext);
|
||||
|
||||
// HRESULT LogCertCopy(")
|
||||
// __in bool fMachine,")
|
||||
// __in PCCERT_CONTEXT pCertContext)
|
||||
[DllImport("certenroll.dll")]
|
||||
internal static extern int LogCertCopy(bool fMachine, IntPtr pCertContext);
|
||||
}
|
||||
|
||||
#region Check_UI_Allowed
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
# The import and table creation work on non-windows, but are currently not needed
|
||||
if($IsWindows)
|
||||
{
|
||||
Import-Module (Join-Path -Path $PSScriptRoot 'certificateCommon.psm1') -Force
|
||||
|
||||
$currentUserMyLocations = @(
|
||||
@{path = 'Cert:\CurrentUser\my'}
|
||||
@{path = 'cert:\currentuser\my'}
|
||||
@{path = 'Microsoft.PowerShell.Security\Certificate::CurrentUser\My'}
|
||||
@{path = 'Microsoft.PowerShell.Security\certificate::currentuser\my'}
|
||||
)
|
||||
|
||||
$testLocations = @(
|
||||
@{path = 'cert:\'}
|
||||
@{path = 'CERT:\'}
|
||||
@{path = 'Microsoft.PowerShell.Security\Certificate::'}
|
||||
)
|
||||
}
|
||||
|
||||
# Add CurrentUserMyLocations to TestLocations
|
||||
foreach($location in $currentUserMyLocations)
|
||||
{
|
||||
$testLocations += $location
|
||||
}
|
||||
|
||||
Describe "Certificate Provider tests" -Tags "CI" {
|
||||
BeforeAll{
|
||||
if(!$IsWindows)
|
||||
{
|
||||
# Skip for non-Windows platforms
|
||||
$defaultParamValues = $PSdefaultParameterValues.Clone()
|
||||
$PSdefaultParameterValues = @{ "it:skip" = $true }
|
||||
}
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
if(!$IsWindows)
|
||||
{
|
||||
$PSdefaultParameterValues = $defaultParamValues
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-Item tests" {
|
||||
it "Should be able to get a certificate store, path: <path>" -TestCases $testLocations {
|
||||
param([string] $path)
|
||||
$expectedResolvedPath = Resolve-Path -LiteralPath $path
|
||||
$result = Get-Item -LiteralPath $path
|
||||
$result | should not be null
|
||||
$result | ForEach-Object {
|
||||
$resolvedPath = Resolve-Path $_.PSPath
|
||||
$resolvedPath.Provider | should be $expectedResolvedPath.Provider
|
||||
$resolvedPath.ProviderPath.TrimStart('\') | should be $expectedResolvedPath.ProviderPath.TrimStart('\')
|
||||
}
|
||||
}
|
||||
it "Should return two items at the root of the provider" {
|
||||
(Get-Item -Path cert:\*).Count | should be 2
|
||||
}
|
||||
it "Should be able to get multiple items explictly" {
|
||||
(get-item cert:\LocalMachine , cert:\CurrentUser).Count | should be 2
|
||||
}
|
||||
it "Should return PathNotFound when getting a non-existant certificate store" {
|
||||
{Get-Item cert:\IDONTEXIST -ErrorAction Stop} | ShouldBeErrorId "PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand"
|
||||
}
|
||||
it "Should return PathNotFound when getting a non-existant certificate" {
|
||||
{Get-Item cert:\currentuser\my\IDONTEXIST -ErrorAction Stop} | ShouldBeErrorId "PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand"
|
||||
}
|
||||
}
|
||||
Context "Get-ChildItem tests"{
|
||||
it "should be able to get a container using a wildcard" {
|
||||
(Get-ChildItem Cert:\CurrentUser\M?).PSPath | should be 'Microsoft.PowerShell.Security\Certificate::CurrentUser\My'
|
||||
}
|
||||
it "Should return two items at the root of the provider" {
|
||||
(Get-ChildItem -Path cert:\).Count | should be 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Certificate Provider tests" -Tags "Feature" {
|
||||
BeforeAll{
|
||||
if($IsWindows)
|
||||
{
|
||||
Install-TestCertificates
|
||||
Push-Location Cert:\
|
||||
}
|
||||
else
|
||||
{
|
||||
# Skip for non-Windows platforms
|
||||
$defaultParamValues = $PSdefaultParameterValues.Clone()
|
||||
$PSdefaultParameterValues = @{ "it:skip" = $true }
|
||||
}
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
if($IsWindows)
|
||||
{
|
||||
Remove-TestCertificates
|
||||
Pop-Location
|
||||
}
|
||||
else
|
||||
{
|
||||
$PSdefaultParameterValues = $defaultParamValues
|
||||
}
|
||||
}
|
||||
|
||||
Context "Get-Item tests" {
|
||||
it "Should be able to get certifate by path: <path>" -TestCases $currentUserMyLocations {
|
||||
param([string] $path)
|
||||
$expectedThumbprint = (Get-GoodCertificateObject).Thumbprint
|
||||
$leafPath = Join-Path -Path $path -ChildPath $expectedThumbprint
|
||||
$cert = (Get-item -LiteralPath $leafPath)
|
||||
$cert | should not be null
|
||||
$cert.Thumbprint | should be $expectedThumbprint
|
||||
}
|
||||
it "Should be able to get DnsNameList of certifate by path: <path>" -TestCases $currentUserMyLocations {
|
||||
param([string] $path)
|
||||
$expectedThumbprint = (Get-GoodCertificateObject).Thumbprint
|
||||
$expectedName = (Get-GoodCertificateObject).DnsNameList[0].Unicode
|
||||
$expectedEncodedName = (Get-GoodCertificateObject).DnsNameList[0].Punycode
|
||||
$leafPath = Join-Path -Path $path -ChildPath $expectedThumbprint
|
||||
$cert = (Get-item -LiteralPath $leafPath)
|
||||
$cert | should not be null
|
||||
$cert.DnsNameList | should not be null
|
||||
$cert.DnsNameList.Count | should be 1
|
||||
$cert.DnsNameList[0].Unicode | should be $expectedName
|
||||
$cert.DnsNameList[0].Punycode | should be $expectedEncodedName
|
||||
}
|
||||
it "Should be able to get DNSNameList of certifate by path: <path>" -TestCases $currentUserMyLocations {
|
||||
param([string] $path)
|
||||
$expectedThumbprint = (Get-GoodCertificateObject).Thumbprint
|
||||
$expectedOid = (Get-GoodCertificateObject).EnhancedKeyUsageList[0].ObjectId
|
||||
$leafPath = Join-Path -Path $path -ChildPath $expectedThumbprint
|
||||
$cert = (Get-item -LiteralPath $leafPath)
|
||||
$cert | should not be null
|
||||
$cert.EnhancedKeyUsageList | should not be null
|
||||
$cert.EnhancedKeyUsageList.Count | should be 1
|
||||
$cert.EnhancedKeyUsageList[0].ObjectId.Length | should not be 0
|
||||
$cert.EnhancedKeyUsageList[0].ObjectId | should be $expectedOid
|
||||
}
|
||||
it "Should filter to codesign certificates" {
|
||||
$allCerts = get-item cert:\CurrentUser\My\*
|
||||
$codeSignCerts = get-item cert:\CurrentUser\My\* -CodeSigningCert
|
||||
$codeSignCerts | should not be null
|
||||
$allCerts | should not be null
|
||||
$nonCodeSignCertCount = $allCerts.Count - $codeSignCerts.Count
|
||||
$nonCodeSignCertCount | should not be 0
|
||||
}
|
||||
it "Should be able to exclude by thumbprint" {
|
||||
$allCerts = get-item cert:\CurrentUser\My\*
|
||||
$testThumbprint = (Get-GoodCertificateObject).Thumbprint
|
||||
$allCertsExceptOne = (Get-Item "cert:\currentuser\my\*" -Exclude $testThumbprint)
|
||||
$allCerts | should not be null
|
||||
$allCertsExceptOne | should not be null
|
||||
$countDifference = $allCerts.Count - $allCertsExceptOne.Count
|
||||
$countDifference | should be 1
|
||||
}
|
||||
}
|
||||
Context "Get-ChildItem tests"{
|
||||
it "Should filter to codesign certificates" {
|
||||
$allCerts = get-ChildItem cert:\CurrentUser\My
|
||||
$codeSignCerts = get-ChildItem cert:\CurrentUser\My -CodeSigningCert
|
||||
$codeSignCerts | should not be null
|
||||
$allCerts | should not be null
|
||||
$nonCodeSignCertCount = $allCerts.Count - $codeSignCerts.Count
|
||||
$nonCodeSignCertCount | should not be 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,96 +1,9 @@
|
||||
|
||||
Function Create-GoodCertificate
|
||||
{
|
||||
$dataEnciphermentCert = "
|
||||
MIIKYAIBAzCCCiAGCSqGSIb3DQEHAaCCChEEggoNMIIKCTCCBgoGCSqGSIb3DQEHAaCCBfsEggX3
|
||||
MIIF8zCCBe8GCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAgPOFDMBkCffQIC
|
||||
B9AEggTYjY55RrmAhdj1grENxXjiPrVNdS++pb5UOn3M7O78BR0U1i2h5zvjkPjOwdLoOCbq5pgg
|
||||
F0PKaMjHVu8EoZxSqsib17ptR5Rx5N23hseuJUzS8fTAHiBet9payNOJlPfkpuqMfQEmCAo9gAPz
|
||||
w4RiyZNOA3NhxkfGl9yU4O9GSEr2koWKCUoCNelkIXVbkV728L7zSiWRSqRb7V4QJAtwtgPLTbl/
|
||||
zo2SFhdNAGPeXbcOsKCv9trhuxPZ0FH4fukbXkHs0I3b5mYgMUI5Mds7UwT3wCtz+Ev9pLbmYN8X
|
||||
NfH0tAK8ZGnQS1GcI4xCMEM8T9Tx3uwWY4arvRM3GTLwyt8JZEVZNTuYL9A9+RyeiO5d5xEKG8H4
|
||||
snOCoTriT45tdl8hzMBCdc3jWxWiydmNRw47irifv5BX7BK/6FLAxkMRwACAxNO63ezG/OxuDDEz
|
||||
ml+KzeZNvr4u4mTBcgZ49vMSyfRt/my+5+iLnSMGp4Rt0uix8489wctkxGlgyXGk23pA4Cj4hq/6
|
||||
txopcl2gHn+DAFrHIgLg4JR8lcuOzBw8nFOrhK7iR9aMK21apxwImIaDCKJ1grOfbuElq4pkMpov
|
||||
SltJe00WB94o69LibOg5LqpTrHW2/DY951sIgElF83FdUBhoZHasfCme/RxgliQf3QHedmENXSjr
|
||||
8R8PAWX4wC0ZZVC0qcq5XP0PkwtuDKmfqq69R32nmBzpRrfypm9S+PfsYZeCeuROh6YKQ0ZBMnLb
|
||||
8Y9povpXh0lYwVLuPanvAFiCT4vI7oRd1Mg1Zr9ZooMFAVomall1UnQQ29fvsoADjEDcPymVT80o
|
||||
kTkw3NXnTX6fGZ94Eh0KZcuMgjTqIO3OKpH0lcaSBxlES4V0sO/mwP4ULy8l3dcnn440Nei33VDo
|
||||
B7n2jhjJl/HvtltfEEEw1DW9AWDvkJDp878sD6VoyQZehvvxBNT0FwMr20TbVKeAGxf9n+xJ9Alo
|
||||
VUS3qE7XnpxAAAR5L2OG+tMd4dyDSge1qrkVNZ3/uUzKKCZei2P7ICR9cX1FRsmcINdNfydIA2cA
|
||||
Pmeq+UkRdqsJxt1NSK5bLvMM4EHRQZMMbXVKxxJ+kQDrzfQtERFPyd3Hdm2F4T/JXUQ+PrTQnRqY
|
||||
LruTAiZfxygZuFrxJnNTRydRdbEaTAtMjFCMRFZ2wctJsgCb3yN9tt0JDYxIvm0MSehXiF+sCrl4
|
||||
yZvvUzJqrgppHRTBR4Sao+MZ/rJ30vVU19Q3oBi9ikTqDY+4SrHsp5Y4llnsbrz0Web+h2jLvyJz
|
||||
LgKuqs87qHhToVMLuULy/HLqY3m661EMwNqh5D76gSFI+TP2/rzT5mVOGglahFoc848o4cshtPWE
|
||||
9MjAkDfsMbIfeKH3uh3D+eBIxYmZ5Cq2aHzqdQ0pU/nDNX7BDjC3E80VcQnXx4U6tRsQHsGtbcld
|
||||
MFTp0yHJ2KLkz+inH3WPy/lYuVZ0QJe+LqvGt+bt1DgQmLBMD9WLFML3d0TtkuY3RhD5Y0wr2zt9
|
||||
tT6WVTn8Hob1cJns4N7tDEr8Q3TdIar0I5Bzj3qoesJt+4lxwnVdUA1bNJ2zxXIkDfX/MTB464FI
|
||||
2g9uhUs3lIOEiCjeJCwBebgZa1HlfhyCRu0E7fnNnKLaGWRs8LVy7MZIfe1kJoDVgTGB3TATBgkq
|
||||
hkiG9w0BCRUxBgQEAQAAADBdBgkrBgEEAYI3EQExUB5OAE0AaQBjAHIAbwBzAG8AZgB0ACAAUwB0
|
||||
AHIAbwBuAGcAIABDAHIAeQBwAHQAbwBnAHIAYQBwAGgAaQBjACAAUAByAG8AdgBpAGQAZQByMGcG
|
||||
CSqGSIb3DQEJFDFaHlgAQwBlAHIAdABSAGUAcQAtAGEAYgA5AGUAZgA3AGYAOAAtAGUAYwA2AGEA
|
||||
LQA0ADUAMwA4AC0AOQA4AGQAOAAtADAAYQA4AGUAYwA4ADUAOQBkADkAMgAxMIID9wYJKoZIhvcN
|
||||
AQcGoIID6DCCA+QCAQAwggPdBgkqhkiG9w0BBwEwHAYKKoZIhvcNAQwBBjAOBAiYL6rZmAGN9QIC
|
||||
B9CAggOw8eaNgIqx26SlOBKKQZ5O7NDZQHbytHTWn4ifNhVFUkbuaj22/VnYOFB9//8BLY6t0Dvw
|
||||
X6wqXSMnbr1jOuUYaFdJzOBZBsYQfFTfoJ4iOb2jwwIpZSgTHeqgXbvnI7MIxauu6F4UseWVxt3u
|
||||
ZhHjEZQjKWeC5mNCb6wX0IOQk96n1RJnJ3v1D4Q5YrVekOVq70VhRNtLOZMkrJV7vDMNlUYXD69D
|
||||
PbcyPajVvETq0W98YNKB89oNwFWuKoMLNPWmSwIfn10oSEtybNEEr2IVgCBt2w2eb+nIDuA3c/Rc
|
||||
qKPXwVGMzoUyAiGwTcueCdMRmiuQAuKCUyi9P/JqeIbgHtg15nAoGtw+l4MsFXfdMJjTCDd0WYff
|
||||
l9ipaNnw8erCPquD0+wXeMnNivXaFzu2+CGwCSwbDl2M49HAQdtpKhNj5jKJBEP1GRQIk173gbEZ
|
||||
n69IXUCsf0GDZiZVNbAQHBOuRoEHpBhendFgTJFAU2LDHlmV6OA0LYHaSn7CP/vOXOhWXJ1yGL2p
|
||||
SeUepciwQV7sOHqDExWY82fd1kHSHcgCAkWLSSdIPlWhyeqjC1agSP6b74VK8uLRPkin5F9wGIPi
|
||||
ewe/LsW3PTtDkDnj3DiSioKlQRUUxVxzi5qPBs+7vJEhbuO7UhtsMCWeUygDbw6n8BKan4w9iLhx
|
||||
7/z6zVvQmLnK4HZChTPFuThRy1NctupoX7nE+CDgyhcmryaTDXohkviMWl4Od+8uGh8Quv2bHk6Y
|
||||
UnFqNB/hSqYMkTuMLH4F9sVzoQEsYu96CDwbQaggbLMnPtmHKsPtzdnWQnys+oGT4uD8vl9xFdEW
|
||||
AZdestrxbDK0La0AgGszUE+6B/GtOs2pv0fMXXYV2h+dAlwfz7oLxzm9E+SFgzviL+6PuI9fDHNd
|
||||
pWeq/Rr5OpFb3rSotGTl84aIjk3hPd3uHujPQh8GO2EQ5k6p6ukk+a7gOUB+pH8fHihFl5L7pI0z
|
||||
yRp0FvbZo//hmACYMvINoy2EQxjYLh7QLeE4qEr8bkzJVgEURUvcUpyHFJT6PGzUMqGx/Wjh2jJc
|
||||
HfEDPMUDoTE/QRzLW7XrmQgJIRuHgPI/cqmOyvpEvuwdRhYyHEKktRO3tGjeflohDCyDW9bxOaJV
|
||||
ZP64KBordM28ZHCQbnSdU0I5us6qiFX2PiLlBzRMH2ftUNMYReioqZyR+Xv5wjaoydV3//BDMH8M
|
||||
1lh9GazUO8+OtzQEH0jiBi6ctlzFT8nNI2C+cOB9S3yMAjCEQa8wNzAfMAcGBSsOAwIaBBR96vF2
|
||||
OksttXT1kXf+aez9EzDlsgQU4ck78h0WTy01zHLwSKNWK4wFFQM=
|
||||
"
|
||||
|
||||
$dataEnciphermentCert = $dataEnciphermentCert -replace '\s',''
|
||||
$certBytes = [Convert]::FromBase64String($dataEnciphermentCert)
|
||||
$certLocation = Join-Path $TestDrive "ProtectedEventLogging.pfx"
|
||||
[IO.File]::WriteAllBytes($certLocation, $certBytes)
|
||||
|
||||
return $certLocation
|
||||
}
|
||||
|
||||
Function Create-BadCertificate
|
||||
{
|
||||
$codeSigningCert = "
|
||||
MIIDAjCCAeqgAwIBAgIQW/oHcNaftoFGOYb4w5A0JTANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQD
|
||||
DA5DTVNUZXN0QmFkQ2VydDAeFw0xNzAzMDcwNjEyMDNaFw0xODAzMDcwNjMyMDNaMBkxFzAVBgNV
|
||||
BAMMDkNNU1Rlc3RCYWRDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAogOnCBPp
|
||||
xCQXvCJOe4KUXrTL5hwzKSV/mA4pF/kWCVLseWkeTzll+02S0SzMR1oqyxGZOU+KiakmH8sIxDpS
|
||||
pBpYi3R+JtaUYeK7IwvM7yMgxzYbVUFupNXDIdFcgd7FwX4R9wJGwd/hEw5fe+ua96G6bBlfQC8j
|
||||
I8iHfqHZ2GmssIuSt72WhT6tKZhPJIMjwmKaB8j/gm6EC7eH83wNmVW/ss2AsG5cMT0Zmk2vkXPd
|
||||
7rVYbAh9WcvxYzTYZLsPkXx/s6uanLo7pBPMqQ8fgImSXiD5EBO9d6SzqoagoAkH/l3oKCUztsqU
|
||||
PAfTu1aTAYRW5O26AcICTbIYOMkDMQIDAQABo0YwRDAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAww
|
||||
CgYIKwYBBQUHAwMwHQYDVR0OBBYEFLSLHDqLWoDBj0j/UavIf0hAHZ2YMA0GCSqGSIb3DQEBCwUA
|
||||
A4IBAQB7GJ3ykI07k2D1mfiQ10+Xse4b6KXylbzYfJ1k3K0NEBwT7H/lhMu4yz95A7pXU41yKKVE
|
||||
OzmpX8QGyczRM269+WpUvVOXwudQL7s/JFeZyEhxPYRP0JC8U9rur1iJeULvsPZJU2kGeLceTl7k
|
||||
psuZeHouYeNuFeeKR66GcHKzqm+5odAJBxjQ/iGP+CVfNVX56Abhu8mXX6sFiorrBSV/NzPThqja
|
||||
mtsMC3Fq53xANMjFT4kUqMtK+oehPf0+0jHHra4hpCVZ2KoPLLPxpJPko8hUO5LxATLU+UII7w3c
|
||||
nMbw+XY4C8xdDnHfS6mF+Hol98dURB/MC/x3sZ3gSjKo
|
||||
"
|
||||
|
||||
$codeSigningCert = $codeSigningCert -replace '\s',''
|
||||
$certBytes = [Convert]::FromBase64String($codeSigningCert)
|
||||
$certLocation = Join-Path $TestDrive "CMSTestBadCert"
|
||||
[IO.File]::WriteAllBytes($certLocation, $certBytes)
|
||||
|
||||
return $certLocation
|
||||
}
|
||||
|
||||
Import-Module (Join-Path -Path $PSScriptRoot 'certificateCommon.psm1') -Force
|
||||
|
||||
Describe "CmsMessage cmdlets and Get-PfxCertificate basic tests" -Tags "CI" {
|
||||
|
||||
BeforeAll {
|
||||
$certLocation = Create-GoodCertificate
|
||||
$certLocation = New-GoodCertificate
|
||||
$certLocation | Should Not BeNullOrEmpty | Out-Null
|
||||
}
|
||||
|
||||
@@ -148,62 +61,23 @@ Describe "CmsMessage cmdlets and Get-PfxCertificate basic tests" -Tags "CI" {
|
||||
|
||||
Describe "CmsMessage cmdlets thorough tests" -Tags "Feature" {
|
||||
|
||||
BeforeAll {
|
||||
if ($IsWindows)
|
||||
BeforeAll{
|
||||
if($IsWindows)
|
||||
{
|
||||
$certLocation = Create-GoodCertificate
|
||||
$certLocation | Should Not BeNullOrEmpty | Out-Null
|
||||
|
||||
$badCertLocation = Create-BadCertificate
|
||||
$badCertLocation | Should Not BeNullOrEmpty | Out-Null
|
||||
|
||||
if ($IsCoreCLR)
|
||||
{
|
||||
# PKI module is not available for PowerShell Core, so we need to use Windows PowerShell to import the cert
|
||||
$fullPowerShell = Join-Path "$env:SystemRoot" "System32\WindowsPowerShell\v1.0\powershell.exe"
|
||||
|
||||
try {
|
||||
$modulePathCopy = $env:PSModulePath
|
||||
$env:PSModulePath = $null
|
||||
|
||||
$command = @"
|
||||
Import-PfxCertificate $certLocation -CertStoreLocation cert:\CurrentUser\My | % PSPath
|
||||
Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | % PSPath
|
||||
"@
|
||||
$certPaths = & $fullPowerShell -NoProfile -NonInteractive -Command $command
|
||||
$certPaths.Count | Should Be 2 | Out-Null
|
||||
|
||||
$importedCert = Get-ChildItem $certPaths[0]
|
||||
$testBadCert = Get-ChildItem $certPaths[1]
|
||||
} finally {
|
||||
$env:PSModulePath = $modulePathCopy
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$importedCert = Import-PfxCertificate $certLocation -CertStoreLocation cert:\CurrentUser\My
|
||||
$testBadCert = Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My
|
||||
}
|
||||
Install-TestCertificates
|
||||
}
|
||||
else
|
||||
{
|
||||
# Skip for non-Windows platforms
|
||||
$defaultParamValues = $PSdefaultParameterValues.Clone()
|
||||
$PSdefaultParameterValues = @{ "it:skip" = $true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AfterAll {
|
||||
if ($IsWindows)
|
||||
if($IsWindows)
|
||||
{
|
||||
if ($importedCert)
|
||||
{
|
||||
Remove-Item (Join-Path Cert:\CurrentUser\My $importedCert.Thumbprint) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($testBadCert)
|
||||
{
|
||||
Remove-Item (Join-Path Cert:\CurrentUser\My $testBadCert.Thumbprint) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Remove-TestCertificates
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -246,7 +120,7 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
|
||||
It "Verify wildcarded recipient resolution by path [Decryption]" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] ($certLocation + "*")
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] ((Get-GoodCertificateLocation) + "*")
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
# Should have resolved single cert
|
||||
@@ -255,7 +129,7 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
|
||||
It "Verify wildcarded recipient resolution by path [Encryption]" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] ($certLocation + "*")
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] ((Get-GoodCertificateLocation) + "*")
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
@@ -264,9 +138,9 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
It "Verify resolution by directory" {
|
||||
$protectedEventLoggingCertPath = Join-Path $TestDrive ProtectedEventLoggingDir
|
||||
$null = New-Item -ItemType Directory $protectedEventLoggingCertPath -Force
|
||||
Copy-Item $certLocation $protectedEventLoggingCertPath
|
||||
Copy-Item $certLocation (Join-Path $protectedEventLoggingCertPath "SecondCert.pfx")
|
||||
Copy-Item $certLocation (Join-Path $protectedEventLoggingCertPath "ThirdCert.pfx")
|
||||
Copy-Item (Get-GoodCertificateLocation) $protectedEventLoggingCertPath
|
||||
Copy-Item (Get-GoodCertificateLocation) (Join-Path $protectedEventLoggingCertPath "SecondCert.pfx")
|
||||
Copy-Item (Get-GoodCertificateLocation) (Join-Path $protectedEventLoggingCertPath "ThirdCert.pfx")
|
||||
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $protectedEventLoggingCertPath
|
||||
@@ -277,21 +151,21 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
|
||||
It "Verify resolution by thumbprint" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $importedCert.Thumbprint
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] (Get-GoodCertificateObject).Thumbprint
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
# "Should have certs from thumbprint in 'My' store"
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
$recipient.Certificates[0].Thumbprint | Should Be $importedCert.Thumbprint
|
||||
$recipient.Certificates[0].Thumbprint | Should Be (Get-GoodCertificateObject).Thumbprint
|
||||
}
|
||||
|
||||
It "Verify resolution by subject name" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $importedCert.Subject
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] (Get-GoodCertificateObject).Subject
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
$recipient.Certificates[0].Thumbprint | Should Be $importedCert.Thumbprint
|
||||
$recipient.Certificates[0].Thumbprint | Should Be (Get-GoodCertificateObject).Thumbprint
|
||||
}
|
||||
|
||||
It "Verify error when no cert found in encryption for encryption" {
|
||||
@@ -314,7 +188,7 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
|
||||
It "Verify error when encrypting to wrong cert" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $testBadCert.Thumbprint
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] (Get-BadCertificateObject).Thumbprint
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$errors.Count | Should Be 1
|
||||
@@ -346,17 +220,17 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
$encryptedPath = $tempPath + ".encrypted.txt"
|
||||
"Hello World","How are you?" | Set-Content $tempPath
|
||||
|
||||
Protect-CmsMessage -Path $tempPath -To $certLocation -OutFile $encryptedPath
|
||||
Protect-CmsMessage -Path $tempPath -To (Get-GoodCertificateLocation) -OutFile $encryptedPath
|
||||
|
||||
$message = Get-CmsMessage -LiteralPath $encryptedPath
|
||||
$message.Recipients.Count | Should Be 1
|
||||
$message.Recipients[0].IssuerName | Should Be "CN=MyDataEnciphermentCert"
|
||||
|
||||
$expected = "Hello World" + [System.Environment]::NewLine + "How are you?" + [System.Environment]::NewLine
|
||||
$decrypted = $message | Unprotect-CmsMessage -To $certLocation
|
||||
$decrypted = $message | Unprotect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
$decrypted | Should Be $expected
|
||||
|
||||
$decrypted = Unprotect-CmsMessage -Path $encryptedPath -To $certLocation
|
||||
$decrypted = Unprotect-CmsMessage -Path $encryptedPath -To (Get-GoodCertificateLocation)
|
||||
$decrypted | Should Be $expected
|
||||
} finally {
|
||||
Remove-Item $tempPath, $encryptedPath -Force -ErrorAction SilentlyContinue
|
||||
@@ -367,7 +241,7 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
try {
|
||||
$randomNum = Get-Random -Minimum 1000 -Maximum 9999
|
||||
$tempPath = Join-Path $TestDrive "$randomNum-Path-Test-File"
|
||||
"Hello World" | Protect-CmsMessage -To $certLocation -OutFile $tempPath
|
||||
"Hello World" | Protect-CmsMessage -To (Get-GoodCertificateLocation) -OutFile $tempPath
|
||||
|
||||
# Decrypt using $importedCert in the Cert store
|
||||
$decrypted = Unprotect-CmsMessage -Path $tempPath
|
||||
@@ -411,11 +285,11 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
}
|
||||
|
||||
It "Verify Unprotect-CmsMessage lets you include context" {
|
||||
$protected = "Hello World" | Protect-CmsMessage -To $certLocation
|
||||
$protected = "Hello World" | Protect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
$adjustedProtected = "Pre content" + [System.Environment]::NewLine + $protected + [System.Environment]::NewLine + "Post content"
|
||||
|
||||
$decryptedNoContext = $adjustedProtected | Unprotect-CmsMessage -To $certLocation
|
||||
$decryptedWithContext = $adjustedProtected | Unprotect-CmsMessage -To $certLocation -IncludeContext
|
||||
$decryptedNoContext = $adjustedProtected | Unprotect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
$decryptedWithContext = $adjustedProtected | Unprotect-CmsMessage -To (Get-GoodCertificateLocation) -IncludeContext
|
||||
|
||||
$decryptedNoContext | Should Be "Hello World"
|
||||
|
||||
@@ -424,16 +298,16 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
}
|
||||
|
||||
It "Verify Unprotect-CmsMessage treats event logs as a first class citizen" {
|
||||
$protected = "Encrypted Message1","Encrypted Message2" | Protect-CmsMessage -To $certLocation
|
||||
$protected = "Encrypted Message1","Encrypted Message2" | Protect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
$virtualEventLog = Get-WinEvent Microsoft-Windows-PowerShell/Operational -MaxEvents 1
|
||||
$savedId = $virtualEventLog.Id
|
||||
$virtualEventLog.Message = $protected
|
||||
|
||||
$expected = "Encrypted Message1" + [System.Environment]::NewLine + "Encrypted Message2"
|
||||
$decrypted = $virtualEventLog | Unprotect-CmsMessage -To $certLocation
|
||||
$decrypted = $virtualEventLog | Unprotect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
$decrypted | Should Be $expected
|
||||
|
||||
$processed = $virtualEventLog | Unprotect-CmsMessage -To $certLocation -IncludeContext
|
||||
$processed = $virtualEventLog | Unprotect-CmsMessage -To (Get-GoodCertificateLocation) -IncludeContext
|
||||
$processed.Id | Should Be $savedId
|
||||
$processed.Message | Should Be $expected
|
||||
}
|
||||
@@ -451,8 +325,8 @@ Import-Certificate $badCertLocation -CertStoreLocation Cert:\CurrentUser\My | %
|
||||
}
|
||||
|
||||
It "Verify protect message using OutString" {
|
||||
$protected = Get-Process -Id $pid | Protect-CmsMessage -To $certLocation
|
||||
$decrypted = $protected | Unprotect-CmsMessage -To $certLocation
|
||||
$protected = Get-Process -Id $pid | Protect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
$decrypted = $protected | Unprotect-CmsMessage -To (Get-GoodCertificateLocation)
|
||||
# Should have had PID in output
|
||||
$decrypted | Should Match $pid
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
Function New-GoodCertificate
|
||||
{
|
||||
$dataEnciphermentCert = "
|
||||
MIIKYAIBAzCCCiAGCSqGSIb3DQEHAaCCChEEggoNMIIKCTCCBgoGCSqGSIb3DQEHAaCCBfsEggX3
|
||||
MIIF8zCCBe8GCyqGSIb3DQEMCgECoIIE/jCCBPowHAYKKoZIhvcNAQwBAzAOBAgPOFDMBkCffQIC
|
||||
B9AEggTYjY55RrmAhdj1grENxXjiPrVNdS++pb5UOn3M7O78BR0U1i2h5zvjkPjOwdLoOCbq5pgg
|
||||
F0PKaMjHVu8EoZxSqsib17ptR5Rx5N23hseuJUzS8fTAHiBet9payNOJlPfkpuqMfQEmCAo9gAPz
|
||||
w4RiyZNOA3NhxkfGl9yU4O9GSEr2koWKCUoCNelkIXVbkV728L7zSiWRSqRb7V4QJAtwtgPLTbl/
|
||||
zo2SFhdNAGPeXbcOsKCv9trhuxPZ0FH4fukbXkHs0I3b5mYgMUI5Mds7UwT3wCtz+Ev9pLbmYN8X
|
||||
NfH0tAK8ZGnQS1GcI4xCMEM8T9Tx3uwWY4arvRM3GTLwyt8JZEVZNTuYL9A9+RyeiO5d5xEKG8H4
|
||||
snOCoTriT45tdl8hzMBCdc3jWxWiydmNRw47irifv5BX7BK/6FLAxkMRwACAxNO63ezG/OxuDDEz
|
||||
ml+KzeZNvr4u4mTBcgZ49vMSyfRt/my+5+iLnSMGp4Rt0uix8489wctkxGlgyXGk23pA4Cj4hq/6
|
||||
txopcl2gHn+DAFrHIgLg4JR8lcuOzBw8nFOrhK7iR9aMK21apxwImIaDCKJ1grOfbuElq4pkMpov
|
||||
SltJe00WB94o69LibOg5LqpTrHW2/DY951sIgElF83FdUBhoZHasfCme/RxgliQf3QHedmENXSjr
|
||||
8R8PAWX4wC0ZZVC0qcq5XP0PkwtuDKmfqq69R32nmBzpRrfypm9S+PfsYZeCeuROh6YKQ0ZBMnLb
|
||||
8Y9povpXh0lYwVLuPanvAFiCT4vI7oRd1Mg1Zr9ZooMFAVomall1UnQQ29fvsoADjEDcPymVT80o
|
||||
kTkw3NXnTX6fGZ94Eh0KZcuMgjTqIO3OKpH0lcaSBxlES4V0sO/mwP4ULy8l3dcnn440Nei33VDo
|
||||
B7n2jhjJl/HvtltfEEEw1DW9AWDvkJDp878sD6VoyQZehvvxBNT0FwMr20TbVKeAGxf9n+xJ9Alo
|
||||
VUS3qE7XnpxAAAR5L2OG+tMd4dyDSge1qrkVNZ3/uUzKKCZei2P7ICR9cX1FRsmcINdNfydIA2cA
|
||||
Pmeq+UkRdqsJxt1NSK5bLvMM4EHRQZMMbXVKxxJ+kQDrzfQtERFPyd3Hdm2F4T/JXUQ+PrTQnRqY
|
||||
LruTAiZfxygZuFrxJnNTRydRdbEaTAtMjFCMRFZ2wctJsgCb3yN9tt0JDYxIvm0MSehXiF+sCrl4
|
||||
yZvvUzJqrgppHRTBR4Sao+MZ/rJ30vVU19Q3oBi9ikTqDY+4SrHsp5Y4llnsbrz0Web+h2jLvyJz
|
||||
LgKuqs87qHhToVMLuULy/HLqY3m661EMwNqh5D76gSFI+TP2/rzT5mVOGglahFoc848o4cshtPWE
|
||||
9MjAkDfsMbIfeKH3uh3D+eBIxYmZ5Cq2aHzqdQ0pU/nDNX7BDjC3E80VcQnXx4U6tRsQHsGtbcld
|
||||
MFTp0yHJ2KLkz+inH3WPy/lYuVZ0QJe+LqvGt+bt1DgQmLBMD9WLFML3d0TtkuY3RhD5Y0wr2zt9
|
||||
tT6WVTn8Hob1cJns4N7tDEr8Q3TdIar0I5Bzj3qoesJt+4lxwnVdUA1bNJ2zxXIkDfX/MTB464FI
|
||||
2g9uhUs3lIOEiCjeJCwBebgZa1HlfhyCRu0E7fnNnKLaGWRs8LVy7MZIfe1kJoDVgTGB3TATBgkq
|
||||
hkiG9w0BCRUxBgQEAQAAADBdBgkrBgEEAYI3EQExUB5OAE0AaQBjAHIAbwBzAG8AZgB0ACAAUwB0
|
||||
AHIAbwBuAGcAIABDAHIAeQBwAHQAbwBnAHIAYQBwAGgAaQBjACAAUAByAG8AdgBpAGQAZQByMGcG
|
||||
CSqGSIb3DQEJFDFaHlgAQwBlAHIAdABSAGUAcQAtAGEAYgA5AGUAZgA3AGYAOAAtAGUAYwA2AGEA
|
||||
LQA0ADUAMwA4AC0AOQA4AGQAOAAtADAAYQA4AGUAYwA4ADUAOQBkADkAMgAxMIID9wYJKoZIhvcN
|
||||
AQcGoIID6DCCA+QCAQAwggPdBgkqhkiG9w0BBwEwHAYKKoZIhvcNAQwBBjAOBAiYL6rZmAGN9QIC
|
||||
B9CAggOw8eaNgIqx26SlOBKKQZ5O7NDZQHbytHTWn4ifNhVFUkbuaj22/VnYOFB9//8BLY6t0Dvw
|
||||
X6wqXSMnbr1jOuUYaFdJzOBZBsYQfFTfoJ4iOb2jwwIpZSgTHeqgXbvnI7MIxauu6F4UseWVxt3u
|
||||
ZhHjEZQjKWeC5mNCb6wX0IOQk96n1RJnJ3v1D4Q5YrVekOVq70VhRNtLOZMkrJV7vDMNlUYXD69D
|
||||
PbcyPajVvETq0W98YNKB89oNwFWuKoMLNPWmSwIfn10oSEtybNEEr2IVgCBt2w2eb+nIDuA3c/Rc
|
||||
qKPXwVGMzoUyAiGwTcueCdMRmiuQAuKCUyi9P/JqeIbgHtg15nAoGtw+l4MsFXfdMJjTCDd0WYff
|
||||
l9ipaNnw8erCPquD0+wXeMnNivXaFzu2+CGwCSwbDl2M49HAQdtpKhNj5jKJBEP1GRQIk173gbEZ
|
||||
n69IXUCsf0GDZiZVNbAQHBOuRoEHpBhendFgTJFAU2LDHlmV6OA0LYHaSn7CP/vOXOhWXJ1yGL2p
|
||||
SeUepciwQV7sOHqDExWY82fd1kHSHcgCAkWLSSdIPlWhyeqjC1agSP6b74VK8uLRPkin5F9wGIPi
|
||||
ewe/LsW3PTtDkDnj3DiSioKlQRUUxVxzi5qPBs+7vJEhbuO7UhtsMCWeUygDbw6n8BKan4w9iLhx
|
||||
7/z6zVvQmLnK4HZChTPFuThRy1NctupoX7nE+CDgyhcmryaTDXohkviMWl4Od+8uGh8Quv2bHk6Y
|
||||
UnFqNB/hSqYMkTuMLH4F9sVzoQEsYu96CDwbQaggbLMnPtmHKsPtzdnWQnys+oGT4uD8vl9xFdEW
|
||||
AZdestrxbDK0La0AgGszUE+6B/GtOs2pv0fMXXYV2h+dAlwfz7oLxzm9E+SFgzviL+6PuI9fDHNd
|
||||
pWeq/Rr5OpFb3rSotGTl84aIjk3hPd3uHujPQh8GO2EQ5k6p6ukk+a7gOUB+pH8fHihFl5L7pI0z
|
||||
yRp0FvbZo//hmACYMvINoy2EQxjYLh7QLeE4qEr8bkzJVgEURUvcUpyHFJT6PGzUMqGx/Wjh2jJc
|
||||
HfEDPMUDoTE/QRzLW7XrmQgJIRuHgPI/cqmOyvpEvuwdRhYyHEKktRO3tGjeflohDCyDW9bxOaJV
|
||||
ZP64KBordM28ZHCQbnSdU0I5us6qiFX2PiLlBzRMH2ftUNMYReioqZyR+Xv5wjaoydV3//BDMH8M
|
||||
1lh9GazUO8+OtzQEH0jiBi6ctlzFT8nNI2C+cOB9S3yMAjCEQa8wNzAfMAcGBSsOAwIaBBR96vF2
|
||||
OksttXT1kXf+aez9EzDlsgQU4ck78h0WTy01zHLwSKNWK4wFFQM=
|
||||
"
|
||||
|
||||
$dataEnciphermentCert = $dataEnciphermentCert -replace '\s',''
|
||||
$certBytes = [Convert]::FromBase64String($dataEnciphermentCert)
|
||||
$certLocation = Join-Path $TestDrive "ProtectedEventLogging.pfx"
|
||||
[IO.File]::WriteAllBytes($certLocation, $certBytes)
|
||||
|
||||
return $certLocation
|
||||
}
|
||||
|
||||
Function New-BadCertificate
|
||||
{
|
||||
$codeSigningCert = "
|
||||
MIIDAjCCAeqgAwIBAgIQW/oHcNaftoFGOYb4w5A0JTANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQD
|
||||
DA5DTVNUZXN0QmFkQ2VydDAeFw0xNzAzMDcwNjEyMDNaFw0xODAzMDcwNjMyMDNaMBkxFzAVBgNV
|
||||
BAMMDkNNU1Rlc3RCYWRDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAogOnCBPp
|
||||
xCQXvCJOe4KUXrTL5hwzKSV/mA4pF/kWCVLseWkeTzll+02S0SzMR1oqyxGZOU+KiakmH8sIxDpS
|
||||
pBpYi3R+JtaUYeK7IwvM7yMgxzYbVUFupNXDIdFcgd7FwX4R9wJGwd/hEw5fe+ua96G6bBlfQC8j
|
||||
I8iHfqHZ2GmssIuSt72WhT6tKZhPJIMjwmKaB8j/gm6EC7eH83wNmVW/ss2AsG5cMT0Zmk2vkXPd
|
||||
7rVYbAh9WcvxYzTYZLsPkXx/s6uanLo7pBPMqQ8fgImSXiD5EBO9d6SzqoagoAkH/l3oKCUztsqU
|
||||
PAfTu1aTAYRW5O26AcICTbIYOMkDMQIDAQABo0YwRDAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAww
|
||||
CgYIKwYBBQUHAwMwHQYDVR0OBBYEFLSLHDqLWoDBj0j/UavIf0hAHZ2YMA0GCSqGSIb3DQEBCwUA
|
||||
A4IBAQB7GJ3ykI07k2D1mfiQ10+Xse4b6KXylbzYfJ1k3K0NEBwT7H/lhMu4yz95A7pXU41yKKVE
|
||||
OzmpX8QGyczRM269+WpUvVOXwudQL7s/JFeZyEhxPYRP0JC8U9rur1iJeULvsPZJU2kGeLceTl7k
|
||||
psuZeHouYeNuFeeKR66GcHKzqm+5odAJBxjQ/iGP+CVfNVX56Abhu8mXX6sFiorrBSV/NzPThqja
|
||||
mtsMC3Fq53xANMjFT4kUqMtK+oehPf0+0jHHra4hpCVZ2KoPLLPxpJPko8hUO5LxATLU+UII7w3c
|
||||
nMbw+XY4C8xdDnHfS6mF+Hol98dURB/MC/x3sZ3gSjKo
|
||||
"
|
||||
|
||||
$codeSigningCert = $codeSigningCert -replace '\s',''
|
||||
$certBytes = [Convert]::FromBase64String($codeSigningCert)
|
||||
$certLocation = Join-Path $TestDrive "CMSTestBadCert"
|
||||
[IO.File]::WriteAllBytes($certLocation, $certBytes)
|
||||
|
||||
return $certLocation
|
||||
}
|
||||
|
||||
function Install-TestCertificates
|
||||
{
|
||||
$script:certLocation = New-GoodCertificate
|
||||
$script:certLocation | Should Not BeNullOrEmpty | Out-Null
|
||||
|
||||
$script:badCertLocation = New-BadCertificate
|
||||
$script:badCertLocation | Should Not BeNullOrEmpty | Out-Null
|
||||
|
||||
if ($IsCoreCLR -and $IsWindows)
|
||||
{
|
||||
# PKI module is not available for PowerShell Core, so we need to use Windows PowerShell to import the cert
|
||||
$fullPowerShell = Join-Path "$env:SystemRoot" "System32\WindowsPowerShell\v1.0\powershell.exe"
|
||||
|
||||
try {
|
||||
$modulePathCopy = $env:PSModulePath
|
||||
$env:PSModulePath = $null
|
||||
|
||||
$command = @"
|
||||
Import-PfxCertificate $script:certLocation -CertStoreLocation cert:\CurrentUser\My | % PSPath
|
||||
Import-Certificate $script:badCertLocation -CertStoreLocation Cert:\CurrentUser\My | % PSPath
|
||||
"@
|
||||
$certPaths = & $fullPowerShell -NoProfile -NonInteractive -Command $command
|
||||
$certPaths.Count | Should Be 2 | Out-Null
|
||||
|
||||
$script:importedCert = Get-ChildItem $certPaths[0]
|
||||
$script:testBadCert = Get-ChildItem $certPaths[1]
|
||||
} finally {
|
||||
$env:PSModulePath = $modulePathCopy
|
||||
}
|
||||
}
|
||||
elseif($IsWindows)
|
||||
{
|
||||
$script:importedCert = Import-PfxCertificate $script:certLocation -CertStoreLocation cert:\CurrentUser\My
|
||||
$script:testBadCert = Import-Certificate $script:badCertLocation -CertStoreLocation Cert:\CurrentUser\My
|
||||
}
|
||||
else {
|
||||
throw 'Not supported on non-windows platforms'
|
||||
}
|
||||
}
|
||||
|
||||
function Get-GoodCertificateLocation
|
||||
{
|
||||
return $script:certLocation
|
||||
}
|
||||
|
||||
function Get-GoodCertificateObject
|
||||
{
|
||||
return $script:importedCert
|
||||
}
|
||||
|
||||
function Get-BadCertificateObject
|
||||
{
|
||||
return $script:testBadCert
|
||||
}
|
||||
|
||||
function Remove-TestCertificates
|
||||
{
|
||||
if($IsWindows)
|
||||
{
|
||||
if ($script:importedCert)
|
||||
{
|
||||
Remove-Item (Join-Path Cert:\CurrentUser\My $script:importedCert.Thumbprint) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
if ($script:testBadCert)
|
||||
{
|
||||
Remove-Item (Join-Path Cert:\CurrentUser\My $script:testBadCert.Thumbprint) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw 'Not supported on non-windows platforms'
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user