mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Port CmsMessage cmdlets and Get-PfxCertificate to powershell core (#3224)
This commit is contained in:
@@ -47,19 +47,13 @@
|
||||
"define": [ "CORECLR" ],
|
||||
"compile": {
|
||||
"exclude": [
|
||||
"security/CertificateCommands.cs",
|
||||
"security/CmsCommands.cs",
|
||||
"singleshell/installer/MshSecurityMshSnapin.cs",
|
||||
|
||||
"gen/CertificateCommands.cs",
|
||||
"gen/CmsCommands.cs",
|
||||
"gen/SecurityMshSnapinResources.cs"
|
||||
]
|
||||
},
|
||||
"embed": {
|
||||
"exclude": [
|
||||
"resources/CertificateCommands.resx",
|
||||
"resources/CmsCommands.resx",
|
||||
"resources/SecurityMshSnapinResources.resx"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -212,26 +212,20 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
private static X509Certificate2 GetCertFromPfxFile(string path)
|
||||
{
|
||||
X509Certificate2 cert = new X509Certificate2();
|
||||
|
||||
cert.Import(path);
|
||||
|
||||
X509Certificate2 cert = new X509Certificate2(path);
|
||||
return cert;
|
||||
}
|
||||
|
||||
private static X509Certificate2 GetCertFromPfxFile(string path, SecureString password)
|
||||
{
|
||||
X509Certificate2 cert = new X509Certificate2();
|
||||
|
||||
//
|
||||
// NTRAID#DevDiv Bugs-33007-2004/7/08-kumarp
|
||||
// the following will not be required once X509Certificate2.Import()
|
||||
// accepts a SecureString
|
||||
//
|
||||
string clearTextPassword = SecurityUtils.GetStringFromSecureString(password);
|
||||
|
||||
cert.Import(path, clearTextPassword, X509KeyStorageFlags.DefaultKeySet);
|
||||
|
||||
string clearTextPassword = Utils.GetStringFromSecureString(password);
|
||||
|
||||
var cert = new X509Certificate2(path, clearTextPassword, X509KeyStorageFlags.DefaultKeySet);
|
||||
return cert;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,19 +3,14 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Text;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Management.Automation.Security;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
@@ -279,7 +274,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
if (_contentBuffer.Length > 0)
|
||||
{
|
||||
_contentBuffer.Append(Environment.NewLine);
|
||||
_contentBuffer.Append(System.Environment.NewLine);
|
||||
}
|
||||
|
||||
_contentBuffer.Append(Content);
|
||||
@@ -456,7 +451,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
if (_contentBuffer.Length > 0)
|
||||
{
|
||||
_contentBuffer.Append(Environment.NewLine);
|
||||
_contentBuffer.Append(System.Environment.NewLine);
|
||||
}
|
||||
|
||||
_contentBuffer.Append(Content);
|
||||
|
||||
@@ -5,21 +5,9 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using Microsoft.PowerShell.Commands;
|
||||
using System.Management.Automation.Host;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Security;
|
||||
using System.Security.Principal;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using DWORD = System.UInt32;
|
||||
using BOOL = System.UInt32;
|
||||
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
||||
|
||||
namespace Microsoft.PowerShell
|
||||
{
|
||||
@@ -47,44 +35,6 @@ namespace Microsoft.PowerShell
|
||||
return size;
|
||||
}
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// throw if file is smaller than 4 bytes in length
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="filePath"> path to file </param>
|
||||
///
|
||||
/// <returns> Does not return a value </returns>
|
||||
///
|
||||
/// <remarks> </remarks>
|
||||
///
|
||||
internal static void CheckIfFileSmallerThan4Bytes(string filePath)
|
||||
{
|
||||
if (GetFileSize(filePath) < 4)
|
||||
{
|
||||
string message =
|
||||
StringUtil.Format(
|
||||
UtilsStrings.FileSmallerThan4Bytes,
|
||||
new object[] { filePath }
|
||||
);
|
||||
|
||||
throw PSTraceSource.NewArgumentException(message, "path");
|
||||
/*
|
||||
// 2004/10/22-JonN The above form of the constructor
|
||||
// no longer exists. This should probably be as below,
|
||||
// however I have not tested this. This method is not
|
||||
// used so I have removed it.
|
||||
throw PSTraceSource.NewArgumentException(
|
||||
"path",
|
||||
"Utils",
|
||||
"FileSmallerThan4Bytes",
|
||||
filePath
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// present a prompt for a SecureString data
|
||||
/// </summary>
|
||||
@@ -109,74 +59,6 @@ namespace Microsoft.PowerShell
|
||||
return ss;
|
||||
}
|
||||
|
||||
#if !CORECLR
|
||||
/// <summary>
|
||||
/// get plain text string from a SecureString
|
||||
///
|
||||
/// This function will not be required once all of the methods
|
||||
/// that we call accept a SecureString. The list below has
|
||||
/// classes/methods that will be changed to accept a SecureString
|
||||
/// after Whidbey beta1
|
||||
///
|
||||
/// -- X509Certificate2.Import (String, String, X509KeyStorageFlags)
|
||||
/// (DCR #33007 in the DevDiv Schedule db)
|
||||
///
|
||||
/// -- NetworkCredential(string, string);
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="ss"> input data </param>
|
||||
///
|
||||
/// <returns> a string representing clear-text equivalent of ss </returns>
|
||||
///
|
||||
/// <remarks> </remarks>
|
||||
///
|
||||
[ArchitectureSensitive]
|
||||
internal static string GetStringFromSecureString(SecureString ss)
|
||||
{
|
||||
IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(ss);
|
||||
string s = Marshal.PtrToStringUni(p);
|
||||
|
||||
Marshal.ZeroFreeGlobalAllocUnicode(p);
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// display sec-desc of a file
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="sd"> file security descriptor </param>
|
||||
///
|
||||
/// <returns> Does not return a value </returns>
|
||||
///
|
||||
/// <remarks> </remarks>
|
||||
///
|
||||
internal static void ShowFileSd(FileSecurity sd)
|
||||
{
|
||||
string userName = null;
|
||||
FileSystemRights rights = 0;
|
||||
AccessControlType aceType = 0;
|
||||
|
||||
rules = sd.GetAccessRules(true, false, typeof(NTAccount));
|
||||
|
||||
foreach (FileSystemAccessRule r in rules)
|
||||
{
|
||||
userName = r.IdentityReference.ToString();
|
||||
aceType = r.AccessControlType;
|
||||
rights = r.FileSystemRights;
|
||||
|
||||
Console.WriteLine("{0} : {1} : {2}",
|
||||
userName,
|
||||
aceType.ToString(),
|
||||
rights.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
||||
@@ -7,7 +7,7 @@ ModuleVersion="3.0.0.0"
|
||||
PowerShellVersion="3.0"
|
||||
AliasesToExport = @()
|
||||
FunctionsToExport = @()
|
||||
CmdletsToExport="Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "ConvertFrom-SecureString", "ConvertTo-SecureString"
|
||||
CmdletsToExport="Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "ConvertFrom-SecureString", "ConvertTo-SecureString", "Get-PfxCertificate"
|
||||
NestedModules="Microsoft.PowerShell.Security.dll"
|
||||
HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390786'
|
||||
}
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
@{
|
||||
GUID="A94C8C7E-9810-47C0-B8AF-65089C13A35A"
|
||||
Author="Microsoft Corporation"
|
||||
CompanyName="Microsoft Corporation"
|
||||
Copyright="© Microsoft Corporation. All rights reserved."
|
||||
ModuleVersion="3.0.0.0"
|
||||
PowerShellVersion="3.0"
|
||||
AliasesToExport = @()
|
||||
FunctionsToExport = @()
|
||||
CmdletsToExport="Get-Acl", "Set-Acl", "Get-Credential", "Get-ExecutionPolicy", "Set-ExecutionPolicy", "Get-AuthenticodeSignature", "Set-AuthenticodeSignature", "ConvertFrom-SecureString", "ConvertTo-SecureString", "New-FileCatalog" , "Test-FileCatalog"
|
||||
NestedModules="Microsoft.PowerShell.Security.dll"
|
||||
HelpInfoURI = 'https://go.microsoft.com/fwlink/?linkid=390786'
|
||||
}
|
||||
@@ -793,31 +793,6 @@ namespace System.Management.Automation
|
||||
|
||||
#endregion PSTransaction
|
||||
|
||||
#region CMS
|
||||
|
||||
internal static class CmsUtils
|
||||
{
|
||||
internal static string BEGIN_CERTIFICATE_SIGIL = "-----BEGIN CERTIFICATE-----";
|
||||
internal static string END_CERTIFICATE_SIGIL = "-----END CERTIFICATE-----";
|
||||
|
||||
internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipients, SessionState sessionState, out ErrorRecord error)
|
||||
{
|
||||
throw new NotImplementedException("CmsUtils.Encrypt(...) is not implemented in CoreCLR powershell.");
|
||||
}
|
||||
|
||||
internal static string GetAsciiArmor(byte[] bytes)
|
||||
{
|
||||
throw new NotImplementedException("CmsUtils.GetAsciiArmor(...) is not implemented in CoreCLR powershell.");
|
||||
}
|
||||
|
||||
internal static byte[] RemoveAsciiArmor(string actualContent, string beginMarker, string endMarker, out int startIndex, out int endIndex)
|
||||
{
|
||||
throw new NotImplementedException("CmsUtils.RemoveAsciiArmor(...) is not implemented in CoreCLR powershell.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion CMS
|
||||
|
||||
#region ApartmentState
|
||||
|
||||
internal enum ApartmentState
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
"System.Reflection.Emit.Lightweight": "4.3.0",
|
||||
"System.Security.AccessControl": "4.3.0",
|
||||
"System.Security.Cryptography.Algorithms": "4.3.0",
|
||||
"System.Security.Cryptography.Pkcs": "4.3.0",
|
||||
"System.Security.Cryptography.X509Certificates": "4.3.0",
|
||||
"System.Threading.Thread": "4.3.0",
|
||||
"System.Threading.Tasks.Parallel": "4.3.0",
|
||||
|
||||
@@ -1012,17 +1012,11 @@ namespace Microsoft.PowerShell.Commands
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
#if !CORECLR
|
||||
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
|
||||
/// <summary>
|
||||
/// Utility class for CMS (Cryptographic Message Syntax) related operations
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The namespace 'System.Security.Cryptography.Pkcs' is not available in CoreCLR,
|
||||
/// so the Cryptographic Message Syntax (CMS) will not be supported on OneCore PS.
|
||||
/// </remarks>
|
||||
internal static class CmsUtils
|
||||
{
|
||||
internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipients, SessionState sessionState, out ErrorRecord error)
|
||||
@@ -1086,8 +1080,7 @@ namespace System.Management.Automation
|
||||
StringBuilder output = new StringBuilder();
|
||||
output.AppendLine(BEGIN_CMS_SIGIL);
|
||||
|
||||
string encodedString = Convert.ToBase64String(
|
||||
bytes, Base64FormattingOptions.InsertLineBreaks);
|
||||
string encodedString = ClrFacade.ToBase64StringWithLineBreaks(bytes);
|
||||
output.AppendLine(encodedString);
|
||||
output.Append(END_CMS_SIGIL);
|
||||
|
||||
@@ -1131,8 +1124,6 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Represents a message recipient for the Cms cmdlets.
|
||||
/// </summary>
|
||||
@@ -1271,7 +1262,7 @@ namespace System.Management.Automation
|
||||
return;
|
||||
}
|
||||
|
||||
List<X509Certificate2> certificatesToProcess = new List<X509Certificate2>(); ;
|
||||
List<X509Certificate2> certificatesToProcess = new List<X509Certificate2>();
|
||||
try
|
||||
{
|
||||
X509Certificate2 newCertificate = new X509Certificate2(messageBytes);
|
||||
|
||||
@@ -661,6 +661,36 @@ namespace System.Management.Automation
|
||||
|
||||
#region Misc
|
||||
|
||||
/// <summary>
|
||||
/// Facade for Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks)
|
||||
/// Inserts line breaks after every 76 characters in the string representation.
|
||||
/// </summary>
|
||||
internal static string ToBase64StringWithLineBreaks(byte[] bytes)
|
||||
{
|
||||
#if CORECLR
|
||||
// Inserts line breaks after every 76 characters in the string representation.
|
||||
string encodedRawString = Convert.ToBase64String(bytes);
|
||||
if (encodedRawString.Length <= 76)
|
||||
return encodedRawString;
|
||||
|
||||
StringBuilder builder = new StringBuilder(encodedRawString.Length);
|
||||
int index = 0, remainingLen = encodedRawString.Length;
|
||||
while (remainingLen > 76)
|
||||
{
|
||||
builder.Append(encodedRawString, index, 76);
|
||||
builder.Append(System.Environment.NewLine);
|
||||
|
||||
index += 76;
|
||||
remainingLen -= 76;
|
||||
}
|
||||
|
||||
builder.Append(encodedRawString, index, remainingLen);
|
||||
return builder.ToString();
|
||||
#else
|
||||
return Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Facade for RemotingServices.IsTransparentProxy(object)
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,421 @@
|
||||
|
||||
Function Create-TestCertificate
|
||||
{
|
||||
$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
|
||||
}
|
||||
|
||||
|
||||
Describe "CmsMessage cmdlets and Get-PfxCertificate basic tests" -Tags "CI" {
|
||||
|
||||
BeforeAll {
|
||||
$certLocation = Create-TestCertificate
|
||||
$certLocation | Should Not BeNullOrEmpty | Out-Null
|
||||
}
|
||||
|
||||
It "Verify Get-PfxCertificate -FilePath" {
|
||||
$cert = Get-PfxCertificate -FilePath $certLocation
|
||||
$cert.Subject | Should Be "CN=MyDataEnciphermentCert"
|
||||
}
|
||||
|
||||
It "Verify Get-PfxCertificate -LiteralPath" {
|
||||
$cert = Get-PfxCertificate -LiteralPath $certLocation
|
||||
$cert.Subject | Should Be "CN=MyDataEnciphermentCert"
|
||||
}
|
||||
|
||||
It "Verify Get-PfxCertificate positional argument" {
|
||||
$cert = Get-PfxCertificate $certLocation
|
||||
$cert.Subject | Should Be "CN=MyDataEnciphermentCert"
|
||||
}
|
||||
|
||||
It "Verify CMS message recipient resolution by path" -Skip:(!$IsWindows) {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $certLocation
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
$recipient.Certificates[0].Subject | Should Match 'CN=MyDataEnciphermentCert'
|
||||
}
|
||||
|
||||
It "Verify CMS message recipient resolution by cert" -Skip:(!$IsWindows) {
|
||||
$errors = $null
|
||||
$cert = Get-PfxCertificate $certLocation
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $cert
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
$recipient.Certificates[0].Subject | Should Match 'CN=MyDataEnciphermentCert'
|
||||
}
|
||||
|
||||
It "Verify a CMS message can be protected / unprotected" -Skip:(!$IsWindows) {
|
||||
$protected = "Hello World","How are you?" | Protect-CmsMessage -To $certLocation
|
||||
$protected.IndexOf("-----BEGIN CMS-----") | Should Be 0
|
||||
|
||||
$message = $protected | Get-CmsMessage
|
||||
$message.Recipients.Count | Should Be 1
|
||||
$message.Recipients[0].IssuerName | Should Be "CN=MyDataEnciphermentCert"
|
||||
|
||||
$expected = "Hello World" + [System.Environment]::NewLine + "How are you?"
|
||||
$decrypted = $message | Unprotect-CmsMessage -To $certLocation
|
||||
$decrypted | Should Be $expected
|
||||
|
||||
$decrypted = $protected | Unprotect-CmsMessage -To $certLocation
|
||||
$decrypted | Should Be $expected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Describe "CmsMessage cmdlets thorough tests" -Tags "Feature" {
|
||||
|
||||
BeforeAll {
|
||||
if ($IsWindows)
|
||||
{
|
||||
$certLocation = Create-TestCertificate
|
||||
$certLocation | 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
|
||||
|
||||
$importedCertPath = & $fullPowerShell -NoProfile -NonInteractive `
|
||||
-Command "Import-PfxCertificate $certLocation -CertStoreLocation cert:\CurrentUser\My | % PSPath"
|
||||
$importedCert = Get-ChildItem $importedCertPath
|
||||
} finally {
|
||||
$env:PSMODULEPATH = $modulePathCopy
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$importedCert = Import-PfxCertificate $certLocation -CertStoreLocation cert:\CurrentUser\My
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# Skip for non-Windows platforms
|
||||
$defaultParamValues = $PSdefaultParameterValues.Clone()
|
||||
$PSdefaultParameterValues = @{ "it:skip" = $true }
|
||||
}
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
if ($IsWindows)
|
||||
{
|
||||
if ($importedCert)
|
||||
{
|
||||
Remove-Item (Join-Path Cert:\CurrentUser\My $importedCert.Thumbprint) -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$PSdefaultParameterValues = $defaultParamValues
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify message recipient resolution by Base64Cert" {
|
||||
$certContent = "
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIQRTsRwsx0LZBHrx9z5Dag2zANBgkqhkiG9w0BAQUFADAh
|
||||
MR8wHQYDVQQDDBZNeURhdGFFbmNpcGhlcm1lbnRDZXJ0MCAXDTE0MDcyNTIyMjkz
|
||||
OVoYDzMwMTQwNzI1MjIzOTM5WjAhMR8wHQYDVQQDDBZNeURhdGFFbmNpcGhlcm1l
|
||||
bnRDZXJ0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3SuShUvnRqn
|
||||
tYOIouJdP3wPZ5rtDi2KYPurpngGNZjM0EGDTrnhmEAI8DL4Kp6n/zz1mYVoX73+
|
||||
6uCpZX/13VDXg1neebJ261XpBX6FzxtclIQr8ywdUtrEgCnUAhgqgvO1Wwm4ogNR
|
||||
tWGCGkmlnqyaoV1j/V4KSn4WvKqSUIOZm0umGCTtNAJ6VtdpYO+uxxnRAapPUCY+
|
||||
qQ7DFzTUECIo1lMlBcuMiXj6NSFr4/D7ltkZ27jCdsZmzI7ZvRnDlfSYTPQnAO/E
|
||||
0uYn9uyKY/xfngWkUX/pe+j+10Lm1ypbASrj2Ezgf0KeZRXBwqKUOLhKheEmBJ18
|
||||
rLV27qwHeQIDAQABo4GOMIGLMA4GA1UdDwEB/wQEAwIEMDAUBgNVHSUEDTALBgkr
|
||||
BgEEAYI3UAEwRAYJKoZIhvcNAQkPBDcwNTAOBggqhkiG9w0DAgICAIAwDgYIKoZI
|
||||
hvcNAwQCAgCAMAcGBSsOAwIHMAoGCCqGSIb3DQMHMB0GA1UdDgQWBBRIyIzwInLJ
|
||||
3B+FajVUFMACf1hrxjANBgkqhkiG9w0BAQUFAAOCAQEAfFt4rmUmWfCbbwi2mCrZ
|
||||
Osq0lfVNUiZ+iLlEKga4VAI3sJZRtErnVM70eXUt7XpRaOdIfxjuXFpsgc37KyLi
|
||||
ByCORLuRC0itZVs3aba48opfMDXivxBy0ngqCPPLQsyaN9K7WnpvYV1QxiudYwwU
|
||||
8U5rFmzlwNLvc3XiyoGWaVZluk2DIJawQ5QYAU9/NMBBCbPHjTG7k0l4cpcEC+Ex
|
||||
od3RlO6/MOYuK2WB4VTxKsV80EdA3ljlu7Td8P4movnrbB4rG4wpCpk05eREkg/5
|
||||
Y54Ilo9m5OSAWtdx4yfS779eebLgUs3P+dk6EKwovXMokVveZA8cenIp3QkqSpeT
|
||||
cQ==
|
||||
-----END CERTIFICATE-----
|
||||
"
|
||||
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $certContent
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
$recipient.Certificates[0].Subject | Should Match 'CN=MyDataEnciphermentCert'
|
||||
}
|
||||
|
||||
It "Verify wildcarded recipient resolution by path [Decryption]" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] ($certLocation + "*")
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
# Should have resolved single cert
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
}
|
||||
|
||||
It "Verify wildcarded recipient resolution by path [Encryption]" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] ($certLocation + "*")
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $protectedEventLoggingCertPath
|
||||
$recipient.Resolve($executionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
}
|
||||
|
||||
It "Verify resolution by thumbprint" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $importedCert.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
|
||||
}
|
||||
|
||||
It "Verify resolution by subject name" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $importedCert.Subject
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
$recipient.Certificates.Count | Should Be 1
|
||||
$recipient.Certificates[0].Thumbprint | Should Be $importedCert.Thumbprint
|
||||
}
|
||||
|
||||
It "Verify error when no cert found in encryption for encryption" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] "SomeCertificateThatDoesNotExist*"
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$errors.Count | Should Be 1
|
||||
$errors[0].FullyQualifiedErrorId | Should Be "NoCertificateFound"
|
||||
}
|
||||
|
||||
It "Verify error when encrypting to non-wildcarded identifier for decryption" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] "SomeCertificateThatDoesNotExist"
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
$errors.Count | Should Be 1
|
||||
$errors[0].FullyQualifiedErrorId | Should Be "NoCertificateFound"
|
||||
}
|
||||
|
||||
It "Verify error when encrypting to wrong cert" {
|
||||
$errors = $null
|
||||
$goodCerts = @(Get-ChildItem Cert:\currentuser\My -DocumentEncryptionCert | ForEach-Object Thumbprint)
|
||||
$badCert = Get-ChildItem Cert:\currentuser\My | ? { $_.Thumbprint -notin $goodCerts } | Select -First 1
|
||||
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] $badCert.Thumbprint
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Encryption", [ref] $errors)
|
||||
|
||||
$errors.Count | Should Be 1
|
||||
$errors[0].FullyQualifiedErrorId | Should Be "CertificateCannotBeUsedForEncryption"
|
||||
}
|
||||
|
||||
It "Verify no error when encrypting to wildcarded identifier for decryption" {
|
||||
$errors = $null
|
||||
$recipient = [System.Management.Automation.CmsMessageRecipient] "SomeCertificateThatDoesNotExist*"
|
||||
$recipient.Resolve($ExecutionContext.SessionState, "Decryption", [ref] $errors)
|
||||
|
||||
$errors | Should Be $null
|
||||
$recipient.Certificates.Count | Should Be 0
|
||||
}
|
||||
|
||||
It "Verify Protect-CmsMessage emits recipient errors" {
|
||||
try {
|
||||
"Hello World" | Protect-CmsMessage -To "SomeThumbprintThatDoesNotExist" -ErrorAction Stop
|
||||
throw "No Exception!"
|
||||
} catch {
|
||||
$_.FullyQualifiedErrorId | Should Be "NoCertificateFound,Microsoft.PowerShell.Commands.ProtectCmsMessageCommand"
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify CmsMessage cmdlets works with paths" {
|
||||
try {
|
||||
$randomNum = Get-Random -Minimum 1000 -Maximum 9999
|
||||
$tempPath = Join-Path $TestDrive "$randomNum-Path-Test-File"
|
||||
$encryptedPath = $tempPath + ".encrypted.txt"
|
||||
"Hello World","How are you?" | Set-Content $tempPath
|
||||
|
||||
Protect-CmsMessage -Path $tempPath -To $certLocation -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 | Should Be $expected
|
||||
|
||||
$decrypted = Unprotect-CmsMessage -Path $encryptedPath -To $certLocation
|
||||
$decrypted | Should Be $expected
|
||||
} finally {
|
||||
Remove-Item $tempPath, $encryptedPath -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify Unprotect-CmsMessage works with local store" {
|
||||
try {
|
||||
$randomNum = Get-Random -Minimum 1000 -Maximum 9999
|
||||
$tempPath = Join-Path $TestDrive "$randomNum-Path-Test-File"
|
||||
"Hello World" | Protect-CmsMessage -To $certLocation -OutFile $tempPath
|
||||
|
||||
# Decrypt using $importedCert in the Cert store
|
||||
$decrypted = Unprotect-CmsMessage -Path $tempPath
|
||||
$decrypted | Should Be "Hello World"
|
||||
} finally {
|
||||
Remove-Item $tempPath -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify Unprotect-CmsMessage emits recipient errors" {
|
||||
try {
|
||||
"" | Unprotect-CmsMessage -To "SomeThumbprintThatDoesNotExist" -IncludeContext -ErrorAction Stop
|
||||
throw "No Exception!"
|
||||
} catch {
|
||||
$_.FullyQualifiedErrorId | Should Be "NoCertificateFound,Microsoft.PowerShell.Commands.UnprotectCmsMessageCommand"
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify failure to extract Ascii armor generates an error [Unprotect-CmsMessage]" {
|
||||
try {
|
||||
"Hello World" | Unprotect-CmsMessage -ErrorAction Stop
|
||||
throw "No Exception!"
|
||||
} catch {
|
||||
$_.FullyQualifiedErrorId | Should Be "InputContainedNoEncryptedContentIncludeContext,Microsoft.PowerShell.Commands.UnprotectCmsMessageCommand"
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify failure to extract Ascii armor generates an error [Get-CmsMessage]" {
|
||||
try {
|
||||
"Hello World" | Get-CmsMessage -ErrorAction Stop
|
||||
throw "No Exception!"
|
||||
} catch {
|
||||
$_.FullyQualifiedErrorId | Should Be "InputContainedNoEncryptedContent,Microsoft.PowerShell.Commands.GetCmsMessageCommand"
|
||||
}
|
||||
}
|
||||
|
||||
It "Verify 'Unprotect-CmsMessage -IncludeContext' with no encrypted input" {
|
||||
# Should have round-tripped content
|
||||
$result = "Hello World" | Unprotect-CmsMessage -IncludeContext
|
||||
$result | Should Be "Hello World"
|
||||
}
|
||||
|
||||
It "Verify Unprotect-CmsMessage lets you include context" {
|
||||
$protected = "Hello World" | Protect-CmsMessage -To $certLocation
|
||||
$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 | Should Be "Hello World"
|
||||
|
||||
$expected = "Pre content" + [System.Environment]::NewLine + "Hello World" + [System.Environment]::NewLine + "Post content"
|
||||
$decryptedWithContext | Should Be $expected
|
||||
}
|
||||
|
||||
It "Verify Unprotect-CmsMessage treats event logs as a first class citizen" {
|
||||
$protected = "Encrypted Message1","Encrypted Message2" | Protect-CmsMessage -To $certLocation
|
||||
$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 | Should Be $expected
|
||||
|
||||
$processed = $virtualEventLog | Unprotect-CmsMessage -To $certLocation -IncludeContext
|
||||
$processed.Id | Should Be $savedId
|
||||
$processed.Message | Should Be $expected
|
||||
}
|
||||
|
||||
It "Verify -DocumentEncryptionCert parameter works" {
|
||||
$foundCerts = Get-ChildItem Cert:\CurrentUser -Recurse -DocumentEncryptionCert
|
||||
|
||||
# Validate they all match the EKU
|
||||
$correctMatching = $foundCerts | ? {
|
||||
($_.EnhancedKeyUsageList.Count -gt 0) -and
|
||||
($_.EnhancedKeyUsageList[0].ObjectId -eq '1.3.6.1.4.1.311.80.1')
|
||||
}
|
||||
# "All Document Encryption Cert should have had correct EKU"
|
||||
@($foundCerts).Count | Should Be @($correctMatching).Count
|
||||
}
|
||||
|
||||
It "Verify protect message using OutString" {
|
||||
$protected = Get-Process -Id $pid | Protect-CmsMessage -To $certLocation
|
||||
$decrypted = $protected | Unprotect-CmsMessage -To $certLocation
|
||||
# Should have had PID in output
|
||||
$decrypted | Should Match $pid
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user