178 lines
7.8 KiB
PowerShell
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()
|
|
}
|
|
}
|