PowerShell/test/powershell/Modules/Microsoft.PowerShell.Security/CmsMessage2.Tests.ps1

178 lines
7.8 KiB
PowerShell

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
using namespace System.Security.Cryptography.X509Certificates
using namespace System.Security.Cryptography
function New-CmsRecipient {
[CmdletBinding(SupportsShouldProcess = $true)]
[OutputType([System.Security.Cryptography.X509Certificates.X509Certificate2])]
param([String]$Name, [Switch]$Invalid, [String]$OutPfxFile)
$hash = [HashAlgorithmName]::SHA256
$pad = [RSASignaturePadding]::Pkcs1
$oids = [OidCollection]::new()
$oids.Add("1.3.6.1.4.1.311.80.1") | Out-Null
$ext1 = [X509KeyUsageExtension]::new([X509KeyUsageFlags]::DataEncipherment, $false)
$ext2 = [X509EnhancedKeyUsageExtension]::new($oids, $false)
$req = ([CertificateRequest]::new("CN=$Name", ([RSA]::Create(2048)), $hash, $pad))
if (!$Invalid) { ($ext1, $ext2).ForEach( { $req.CertificateExtensions.Add($_) }) }
$certTmp = $req.CreateSelfSigned([datetime]::Now.AddDays(-1), [datetime]::Now.AddDays(365))
$certBytes = $certTmp.Export([X509ContentType]::Pfx, "tmp")
[X509KeyStorageFlags[]]$flags = "PersistKeySet", "Exportable"
$cert = [X509Certificate2]::new($certBytes, "tmp", $flags)
if ($OutPfxFile) {
$outfile = New-Item $OutPfxFile -Force
[System.IO.File]::WriteAllBytes($outfile.FullName, $cert.Export([X509ContentType]::Pfx))
}
return $cert
}
Describe "CmsMessage cmdlets using X509 cert" -Tags "CI" {
BeforeAll {
Setup -Dir "certDir"
Setup -File "vc1.pfx"
Setup -File "vc2.pfx"
Setup -File "certDir/vc3.pfx"
Setup -File "message.txt" -Content "test"
$file1 = "TestDrive:\vc1.pfx"
$file2 = "TestDrive:\vc2.pfx"
$messageFile = "TestDrive:\message.txt"
$cipherFile = "TestDrive:\cipher.txt"
$vc1 = New-CmsRecipient "ValidCms1" -OutPfxFile $file1
$vc2 = New-CmsRecipient "ValidCms2" -OutPfxFile $file2
$vc3 = New-CmsRecipient "ValidCms22" -OutPfxFile "TestDrive:\certDir\vc3.pfx"
$ic = New-CmsRecipient "InvalidCms" -Invalid -OutPfxFile "TestDrive:\ic.pfx"
$store = [X509Store]::new("My", [StoreLocation]::CurrentUser)
$store.Open("ReadWrite")
if (!$IsMacOS) {
$store.Add($vc1)
$store.Add($vc2)
$store.Add($vc3)
}
$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-----
"
}
It "Cert Store: Encrypt/Decrypt using Subject" {
"test" | Protect-CmsMessage -To $vc1.Subject | Unprotect-CmsMessage | Should -BeExactly "test"
"test" | Protect-CmsMessage -To $vc1.Subject, $vc2.Subject | Unprotect-CmsMessage | Should -BeExactly "test"
}
It "Cert Store: Subject with wildcard (returns single cert)" {
"test" | Protect-CmsMessage -To "*dCms1" | Unprotect-CmsMessage | Should -BeExactly "test"
}
It "Cert Store: Subject with wrong wildcard (returns multiple certs)" {
{ "test" | Protect-CmsMessage -To "*ValidCms*" -ErrorAction Stop } | Should -Throw -ErrorId 'IdentifierMustReferenceSingleCertificate'
}
It "Cert Store: Encrypt/Decrypt using Thumbprint" {
"test" | Protect-CmsMessage -To $vc1.Thumbprint | Unprotect-CmsMessage | Should -BeExactly "test"
"test" | Protect-CmsMessage -To $vc1.Thumbprint, $vc2.Thumbprint | Unprotect-CmsMessage | Should -BeExactly "test"
}
It "Cert Store: Encrypt/Decrypt subject and thumbprint" {
"test" | Protect-CmsMessage -To $vc1.Thumbprint, $vc2.Subject | Unprotect-CmsMessage | Should -BeExactly "test"
}
It "Cert Store: removing test certificates" {
$store.Remove($vc1)
$store.Remove($vc2)
$store.Remove($vc3)
if ($IsMacOS) {
$store.Remove($ic)
}
$store.Certificates.Find("FindByThumbprint", $vc1.Thumbprint, $false).Count | Should -BeExactly 0
$store.Certificates.Find("FindByThumbprint", $vc2.Thumbprint, $false).Count | Should -BeExactly 0
$store.Certificates.Find("FindByThumbprint", $vc3.Thumbprint, $false).Count | Should -BeExactly 0
$store.Certificates.Find("FindByThumbprint", $ic.Thumbprint, $false).Count | Should -BeExactly 0
}
It "Encrypting with X509Cert" {
"test" | Protect-CmsMessage -To $vc1 | Should -BeLike '-----BEGIN CMS*'
}
It "Encrypting with base64 string" {
"test" | Protect-CmsMessage -To $certContent | Should -BeLike '-----BEGIN CMS*'
}
It "Encrypting with multiple X509Cert" {
"test" | Protect-CmsMessage -To $vc1, $vc2 | Should -BeLike '-----BEGIN CMS*'
}
It "Decrypt with X509Cert" {
"test" | Protect-CmsMessage -To $vc1 | Unprotect-CmsMessage -To $vc1 | Should -BeExactly "test"
}
It "Decrypt with multiple X509Cert" {
"test" | Protect-CmsMessage -To $vc1, $vc2 | Unprotect-CmsMessage -To $vc1, $vc2 | Should -BeExactly "test"
}
It "Encrypt with invalid cert" {
{ "test" | Protect-CmsMessage -To $ic -ErrorAction Stop } | Should -Throw -ErrorId 'CertificateCannotBeUsedForEncryption'
}
It "Encrypt with valid and invalid" {
{ "test" | Protect-CmsMessage -To $vc1, $vc2, $ic -ErrorAction Stop } | Should -Throw -ErrorId 'CertificateCannotBeUsedForEncryption'
}
It "Encrypt/Decrypt from file" {
Protect-CmsMessage -Path $messageFile -To $vc1 -OutFile $cipherFile
$msg = Unprotect-CmsMessage -To $vc1 -Path $cipherFile
$msg | Should -BeExactly "test"
}
It "Get-CmsMessage from content" {
("test" | Protect-CmsMessage -To $vc1 | Get-CmsMessage).Content | Should -BeLike '-----BEGIN CMS*'
}
It "Get-CmsMessage from file" {
(Get-CmsMessage -Path $cipherFile).Content | Should -BeLike '-----BEGIN CMS*'
}
It "Encrypt With Single File" {
"test" | Protect-CmsMessage -To $file1 | Unprotect-CmsMessage -To $file1 | Should -BeExactly "test"
}
It "Encrypt With Multiple Files" {
$msg = "test" | Protect-CmsMessage -To $file1, $file2
($msg | Unprotect-CmsMessage -To $file1) | Should -BeExactly "test"
($msg | Unprotect-CmsMessage -To $file2) | Should -BeExactly "test"
}
It "Encrypt/Decrypt with Directory" {
"test" | Protect-CmsMessage -To "TestDrive:\certDir" | Unprotect-CmsMessage -To "TestDrive:\certDir" | Should -BeExactly "test"
}
It "Decrypt with multiple files" {
"test" | Protect-CmsMessage -To $vc1 | Unprotect-CmsMessage -To $file1, $file2 | Should -BeExactly "test"
}
AfterAll {
$store.Dispose()
}
}