mirror of https://github.com/ansible/ansible.git
win_certificate_store: added new module (#33980)
* win_certificate_store: added new module * added warning about become or credssp for pfxpull/34596/head
parent
34206a0402
commit
b2a415daae
@ -0,0 +1,252 @@
|
|||||||
|
#!powershell
|
||||||
|
# This file is part of Ansible
|
||||||
|
|
||||||
|
# Copyright: (c) 2017, Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
#Requires -Module Ansible.ModuleUtils.Legacy
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$store_name_values = ([System.Security.Cryptography.X509Certificates.StoreName]).GetEnumValues()
|
||||||
|
$store_location_values = ([System.Security.Cryptography.X509Certificates.StoreLocation]).GetEnumValues()
|
||||||
|
|
||||||
|
$params = Parse-Args $args -supports_check_mode $true
|
||||||
|
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
|
||||||
|
|
||||||
|
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent", "exported", "present"
|
||||||
|
$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty ($state -eq "present" -or $state -eq "exported")
|
||||||
|
$thumbprint = Get-AnsibleParam -obj $params -name "thumbprint" -type "str" -failifempty ($state -eq "exported")
|
||||||
|
$store_name = Get-AnsibleParam -obj $params -name "store_name" -type "str" -default "My" -validateset $store_name_values
|
||||||
|
$store_location = Get-AnsibleParam -obj $params -name "store_location" -type "str" -default "LocalMachine" -validateset $store_location_values
|
||||||
|
$password = Get-AnsibleParam -obj $params -name "password" -type "str"
|
||||||
|
$key_exportable = Get-AnsibleParam -obj $params -name "key_exportable" -type "bool" -default $true
|
||||||
|
$key_storage = Get-AnsibleParam -obj $param -name "key_storage" -type "str" -default "default" -validateset "default", "machine", "user"
|
||||||
|
$file_type = Get-AnsibleParam -obj $params -name "file_type" -type "str" -default "der" -validateset "der", "pem", "pkcs12"
|
||||||
|
|
||||||
|
$result = @{
|
||||||
|
changed = $false
|
||||||
|
thumbprints = @()
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-CertFile($path, $password, $key_exportable, $key_storage) {
|
||||||
|
# parses a certificate file and returns X509Certificate2Collection
|
||||||
|
if (-not (Test-Path -Path $path -PathType Leaf)) {
|
||||||
|
Fail-Json -obj $result -message "File at '$path' either does not exist or is not a file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# must set at least the PersistKeySet flag so that the PrivateKey
|
||||||
|
# is stored in a permanent container and not deleted once the handle
|
||||||
|
# is gone.
|
||||||
|
$store_flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet
|
||||||
|
|
||||||
|
$key_storage = $key_storage.substring(0,1).ToUpper() + $key_storage.substring(1).ToLower()
|
||||||
|
$store_flags = $store_flags -bor [Enum]::Parse([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags], "$($key_storage)KeySet")
|
||||||
|
if ($key_exportable) {
|
||||||
|
$store_flags = $store_flags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: If I'm feeling adventurours, write code to parse PKCS#12 PEM encoded
|
||||||
|
# file as .NET does not have an easy way to import this
|
||||||
|
$certs = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2Collection
|
||||||
|
|
||||||
|
try {
|
||||||
|
$certs.Import($path, $password, $store_flags)
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to load cert from file: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
return $certs
|
||||||
|
}
|
||||||
|
|
||||||
|
Function New-CertFile($cert, $path, $type, $password) {
|
||||||
|
$content_type = switch ($type) {
|
||||||
|
"pem" { [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert }
|
||||||
|
"der" { [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert }
|
||||||
|
"pkcs12" { [System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12 }
|
||||||
|
}
|
||||||
|
if ($type -eq "pkcs12") {
|
||||||
|
$missing_key = $false
|
||||||
|
if ($cert.PrivateKey -eq $null) {
|
||||||
|
$missing_key = $true
|
||||||
|
} elseif ($cert.PrivateKey.CspKeyContainerInfo.Exportable -eq $false) {
|
||||||
|
$missing_key = $true
|
||||||
|
}
|
||||||
|
if ($missing_key) {
|
||||||
|
Fail-Json -obj $result -message "Cannot export cert with key as PKCS12 when the key is not marked as exportable or not accesible by the current user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Test-Path -Path $path) {
|
||||||
|
Remove-Item -Path $path -Force
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$cert_bytes = $cert.Export($content_type, $password)
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to export certificate as bytes: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Need to manually handle a PEM file
|
||||||
|
if ($type -eq "pem") {
|
||||||
|
$cert_content = "-----BEGIN CERTIFICATE-----`r`n"
|
||||||
|
$base64_string = [System.Convert]::ToBase64String($cert_bytes, [System.Base64FormattingOptions]::InsertLineBreaks)
|
||||||
|
$cert_content += $base64_string
|
||||||
|
$cert_content += "`r`n-----END CERTIFICATE-----"
|
||||||
|
$file_encoding = [System.Text.Encoding]::ASCII
|
||||||
|
$cert_bytes = $file_encoding.GetBytes($cert_content)
|
||||||
|
} elseif ($type -eq "pkcs12") {
|
||||||
|
$result.key_exported = $false
|
||||||
|
if ($cert.PrivateKey -ne $null) {
|
||||||
|
$result.key_exportable = $cert.PrivateKey.CspKeyContainerInfo.Exportable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $check_mode) {
|
||||||
|
try {
|
||||||
|
[System.IO.File]::WriteAllBytes($path, $cert_bytes)
|
||||||
|
} catch [System.ArgumentNullException] {
|
||||||
|
Fail-Json -obj $result -message "Failed to write cert to file, cert was null: $($_.Exception.Message)"
|
||||||
|
} catch [System.IO.IOException] {
|
||||||
|
Fail-Json -obj $result -message "Failed to write cert to file due to IO exception: $($_.Exception.Message)"
|
||||||
|
} catch [System.UnauthorizedAccessException, System>Security.SecurityException] {
|
||||||
|
Fail-Json -obj $result -message "Failed to write cert to file due to permission: $($_.Exception.Message)"
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to write cert to file: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-CertFileType($path, $password) {
|
||||||
|
$certs = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2Collection
|
||||||
|
try {
|
||||||
|
$certs.Import($path, $password, 0)
|
||||||
|
} catch [System.Security.Cryptography.CryptographicException] {
|
||||||
|
# the file is a pkcs12 we just had the wrong password
|
||||||
|
return "pkcs12"
|
||||||
|
} catch {
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
$file_contents = Get-Content -Path $path -Raw
|
||||||
|
if ($file_contents.StartsWith("-----BEGIN CERTIFICATE-----")) {
|
||||||
|
return "pem"
|
||||||
|
} elseif ($file_contents.StartsWith("-----BEGIN PKCS7-----")) {
|
||||||
|
return "pkcs7-ascii"
|
||||||
|
} elseif ($certs.Count -gt 1) {
|
||||||
|
# multiple certs must be pkcs7
|
||||||
|
return "pkcs7-binary"
|
||||||
|
} elseif ($certs[0].HasPrivateKey) {
|
||||||
|
return "pkcs12"
|
||||||
|
} elseif ($path.EndsWith(".pfx") -or $path.EndsWith(".p12")) {
|
||||||
|
# no way to differenciate a pfx with a der file so we must rely on the
|
||||||
|
# extension
|
||||||
|
return "pkcs12"
|
||||||
|
} else {
|
||||||
|
return "der"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$store_name = [System.Security.Cryptography.X509Certificates.StoreName]::$store_name
|
||||||
|
$store_location = [System.Security.Cryptography.X509Certificates.Storelocation]::$store_location
|
||||||
|
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location
|
||||||
|
try {
|
||||||
|
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
|
||||||
|
} catch [System.Security.Cryptography.CryptographicException] {
|
||||||
|
Fail-Json -obj $result -message "Unable to open the store as it is not readable: $($_.Exception.Message)"
|
||||||
|
} catch [System.Security.SecurityException] {
|
||||||
|
Fail-Json -obj $result -message "Unable to open the store with the current permissions: $($_.Exception.Message)"
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Unable to open the store: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
$store_certificates = $store.Certificates
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($state -eq "absent") {
|
||||||
|
$cert_thumbprints = @()
|
||||||
|
|
||||||
|
if ($path -ne $null) {
|
||||||
|
$certs = Get-CertFile -path $path -password $password -key_exportable $key_exportable -key_storage $key_storage
|
||||||
|
foreach ($cert in $certs) {
|
||||||
|
$cert_thumbprints += $cert.Thumbprint
|
||||||
|
}
|
||||||
|
} elseif ($thumbprint -ne $null) {
|
||||||
|
$cert_thumbprints += $thumbprint
|
||||||
|
} else {
|
||||||
|
Fail-Json -obj $result -message "Either path or thumbprint must be set when state=absent"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($cert_thumbprint in $cert_thumbprints) {
|
||||||
|
$result.thumbprints += $cert_thumbprint
|
||||||
|
$found_certs = $store_certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $cert_thumbprint, $false)
|
||||||
|
if ($found_certs.Count -gt 0) {
|
||||||
|
foreach ($found_cert in $found_certs) {
|
||||||
|
try {
|
||||||
|
if (-not $check_mode) {
|
||||||
|
$store.Remove($found_cert)
|
||||||
|
}
|
||||||
|
} catch [System.Security.SecurityException] {
|
||||||
|
Fail-Json -obj $result -message "Unable to remove cert with thumbprint '$cert_thumbprint' with the current permissions: $($_.Exception.Message)"
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Unable to remove cert with thumbprint '$cert_thumbprint': $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif ($state -eq "exported") {
|
||||||
|
# TODO: Add support for PKCS7 and exporting a cert chain
|
||||||
|
$result.thumbprints += $thumbprint
|
||||||
|
$export = $true
|
||||||
|
if (Test-Path -Path $path -PathType Container) {
|
||||||
|
Fail-Json -obj $result -message "Cannot export cert to path '$path' as it is a directory"
|
||||||
|
} elseif (Test-Path -Path $path -PathType Leaf) {
|
||||||
|
$actual_cert_type = Get-CertFileType -path $path -password $password
|
||||||
|
if ($actual_cert_type -eq $file_type) {
|
||||||
|
try {
|
||||||
|
$certs = Get-CertFile -path $path -password $password -key_exportable $key_exportable -key_storage $key_storage
|
||||||
|
} catch {
|
||||||
|
# failed to load the file so we set the thumbprint to something
|
||||||
|
# that will fail validation
|
||||||
|
$certs = @{Thumbprint = $null}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($certs.Thumbprint -eq $thumbprint) {
|
||||||
|
$export = $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($export) {
|
||||||
|
$found_certs = $store_certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $thumbprint, $false)
|
||||||
|
if ($found_certs.Count -ne 1) {
|
||||||
|
Fail-Json -obj $result -message "Found $($found_certs.Count) certs when only expecting 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
New-CertFile -cert $found_certs -path $path -type $file_type -password $password
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$certs = Get-CertFile -path $path -password $password -key_exportable $key_exportable -key_storage $key_storage
|
||||||
|
foreach ($cert in $certs) {
|
||||||
|
$result.thumbprints += $cert.Thumbprint
|
||||||
|
$found_certs = $store_certificates.Find([System.Security.Cryptography.X509Certificates.X509FindType]::FindByThumbprint, $cert.Thumbprint, $false)
|
||||||
|
if ($found_certs.Count -eq 0) {
|
||||||
|
try {
|
||||||
|
if (-not $check_mode) {
|
||||||
|
$store.Add($cert)
|
||||||
|
}
|
||||||
|
} catch [System.Security.Cryptography.CryptographicException] {
|
||||||
|
Fail-Json -obj $result -message "Unable to import certificate with thumbprint '$($cert.Thumbprint)' with the current permissions: $($_.Exception.Message)"
|
||||||
|
} catch {
|
||||||
|
Fail-Json -obj $result -message "Unable to import certificate with thumbprint '$($cert.Thumbprint)': $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
$store.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit-Json -obj $result
|
@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# This file is part of Ansible
|
||||||
|
|
||||||
|
# Copyright (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
|
||||||
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'}
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
---
|
||||||
|
module: win_certificate_store
|
||||||
|
version_added: '2.5'
|
||||||
|
short_description: Manages the certificate store
|
||||||
|
description:
|
||||||
|
- Used to import/export and remove certificates and keys from the local
|
||||||
|
certificate store.
|
||||||
|
- This module is not used to create certificates and will only manage existing
|
||||||
|
certs as a file or in the store.
|
||||||
|
- It can be used to import PEM, DER, P7B, PKCS12 (PFX) certificates and export
|
||||||
|
PEM, DER and PKCS12 certificates.
|
||||||
|
options:
|
||||||
|
state:
|
||||||
|
description:
|
||||||
|
- If C(present), will ensure that the certificate at I(path) is imported
|
||||||
|
into the certificate store specified.
|
||||||
|
- If C(absent), will ensure that the certificate specified by I(thumbprint)
|
||||||
|
or the thumbprint of the cert at I(path) is removed from the store
|
||||||
|
specified.
|
||||||
|
- If C(exported), will ensure the file at I(path) is a certificate
|
||||||
|
specified by I(thumbprint).
|
||||||
|
- When exporting a certificate, if I(path) is a directory then the module
|
||||||
|
will fail, otherwise the file will be replaced if needed.
|
||||||
|
default: present
|
||||||
|
choices:
|
||||||
|
- present
|
||||||
|
- absent
|
||||||
|
- exported
|
||||||
|
path:
|
||||||
|
description:
|
||||||
|
- The path to a certificate file.
|
||||||
|
- This is required when I(state) is C(present) or C(exported).
|
||||||
|
- When I(state) is C(absent) and I(thumbprint) is not specified, the
|
||||||
|
thumbprint is derived from the certificate at this path.
|
||||||
|
thumbprint:
|
||||||
|
description:
|
||||||
|
- The thumbprint as a hex string to either export or remove.
|
||||||
|
- See the examples for how to specify the thumbprint.
|
||||||
|
store_name:
|
||||||
|
description:
|
||||||
|
- The store name to use when importing a certificate or searching for a
|
||||||
|
certificate.
|
||||||
|
default: My
|
||||||
|
choices:
|
||||||
|
- AddressBook
|
||||||
|
- AuthRoot
|
||||||
|
- CertificateAuthority
|
||||||
|
- Disallowed
|
||||||
|
- My
|
||||||
|
- Root
|
||||||
|
- TrustedPeople
|
||||||
|
- TrustedPublisher
|
||||||
|
store_location:
|
||||||
|
description:
|
||||||
|
- The store location to use when importing a certificate or searching for a
|
||||||
|
certificate.
|
||||||
|
default: LocalMachine
|
||||||
|
choices:
|
||||||
|
- CurrentUser
|
||||||
|
- LocalMachine
|
||||||
|
password:
|
||||||
|
description:
|
||||||
|
- The password of the pkcs12 certificate key.
|
||||||
|
- This is used when reading a pkcs12 certificate file or the password to
|
||||||
|
set when C(state=exported) and C(file_type=pkcs12).
|
||||||
|
- If the pkcs12 file has no password set or no password should be set on
|
||||||
|
the exported file, do not set this option.
|
||||||
|
key_exportable:
|
||||||
|
description:
|
||||||
|
- Whether to allow the private key to be exported.
|
||||||
|
- If C(no), then this module and other process will only be able to export
|
||||||
|
the certificate and the private key cannot be exported.
|
||||||
|
- Used when C(state=present) only.
|
||||||
|
type: bool
|
||||||
|
default: 'yes'
|
||||||
|
key_storage:
|
||||||
|
description:
|
||||||
|
- Specifies where Windows will store the private key when it is imported.
|
||||||
|
- When set to C(default), the default option as set by Windows is used.
|
||||||
|
- When set to C(machine), the key is stored in a path accessible by various
|
||||||
|
users.
|
||||||
|
- When set to C(user), the key is stored in a path only accessible by the
|
||||||
|
current user.
|
||||||
|
- Used when C(state=present) only and cannot be changed once imported.
|
||||||
|
- See U(https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keystorageflags.aspx)
|
||||||
|
for more details.
|
||||||
|
choices:
|
||||||
|
- default
|
||||||
|
- machine
|
||||||
|
- user
|
||||||
|
default: default
|
||||||
|
file_type:
|
||||||
|
description:
|
||||||
|
- The file type to export the certificate as when C(state=exported).
|
||||||
|
- C(der) is a binary ASN.1 encoded file.
|
||||||
|
- C(pem) is a base64 encoded file of a der file in the OpenSSL form.
|
||||||
|
- C(pkcs12) (also known as pfx) is a binary container that contains both
|
||||||
|
the certificate and private key unlike the other options.
|
||||||
|
- When C(pkcs12) is set and the private key is not exportable or accessible
|
||||||
|
by the current user, it will throw an exception.
|
||||||
|
choices:
|
||||||
|
- der
|
||||||
|
- pem
|
||||||
|
- pkcs12
|
||||||
|
default: der
|
||||||
|
notes:
|
||||||
|
- Some actions on PKCS12 certificates and keys may fail with the error
|
||||||
|
C(the specified network password is not correct), either use CredSSP or
|
||||||
|
Kerberos with credential delegation, or use C(become) to bypass these
|
||||||
|
restrictions.
|
||||||
|
- The certificates must be located on the Windows host to be set with I(path).
|
||||||
|
author:
|
||||||
|
- Jordan Borean (@jborean93)
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
- name: import a certificate
|
||||||
|
win_certificate_store:
|
||||||
|
path: C:\temp\cert.pem
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: import pfx certificate that is password protected
|
||||||
|
win_certificate_store:
|
||||||
|
path: C:\temp\cert.pfx
|
||||||
|
state: present
|
||||||
|
password: VeryStrongPasswordHere!
|
||||||
|
become: yes
|
||||||
|
become_method: runas
|
||||||
|
|
||||||
|
- name: import pfx certificate without password and set private key as un-exportable
|
||||||
|
win_certificate_store:
|
||||||
|
path: C:\temp\cert.pfx
|
||||||
|
state: present
|
||||||
|
key_exportable: no
|
||||||
|
# usually you don't set this here but it is for illustrative purposes
|
||||||
|
vars:
|
||||||
|
ansible_winrm_transport: credssp
|
||||||
|
|
||||||
|
- name: remove a certificate based on file thumbprint
|
||||||
|
win_certificate_store:
|
||||||
|
path: C:\temp\cert.pem
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: remove a certificate based on thumbprint
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: BD7AF104CF1872BDB518D95C9534EA941665FD27
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: remove certificate based on thumbprint is CurrentUser/TrustedPublishers store
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: BD7AF104CF1872BDB518D95C9534EA941665FD27
|
||||||
|
state: absent
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPublisher
|
||||||
|
|
||||||
|
- name: export certificate as der encoded file
|
||||||
|
win_certificate_store:
|
||||||
|
path: C:\temp\cert.cer
|
||||||
|
state: exported
|
||||||
|
file_type: der
|
||||||
|
|
||||||
|
- name: export certificate and key as pfx encoded file
|
||||||
|
win_certificate_store:
|
||||||
|
path: C:\temp\cert.pfx
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
password: AnotherStrongPass!
|
||||||
|
become: yes
|
||||||
|
become_method: runas
|
||||||
|
become_user: SYSTEM
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
thumbprints:
|
||||||
|
description: A list of certificate thumbprints that were touched by the
|
||||||
|
module.
|
||||||
|
returned: success
|
||||||
|
type: list
|
||||||
|
sample: ["BC05633694E675449136679A658281F17A191087"]
|
||||||
|
'''
|
@ -0,0 +1 @@
|
|||||||
|
windows/ci/group3
|
@ -0,0 +1,4 @@
|
|||||||
|
win_cert_dir: '{{win_output_dir}}\win_certificate'
|
||||||
|
key_password: password
|
||||||
|
subj_thumbprint: 'BD7AF104CF1872BDB518D95C9534EA941665FD27'
|
||||||
|
root_thumbprint: 'BC05633694E675449136679A658281F17A191087'
|
@ -0,0 +1,20 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDKDCCAhCgAwIBAgIJAP1vIdGgMJv/MA0GCSqGSIb3DQEBCwUAMCgxGTAXBgNV
|
||||||
|
BAMMEHJvb3QuYW5zaWJsZS5jb20xCzAJBgNVBAYTAlVTMCAXDTE3MTIxNTA4Mzkz
|
||||||
|
MloYDzIwODYwMTAyMDgzOTMyWjAoMRkwFwYDVQQDDBByb290LmFuc2libGUuY29t
|
||||||
|
MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmq
|
||||||
|
YT8eZY6rFQKnmScUGnnUH1tLQ+3WQpfKiWygCUSb1CNqO3J1u3pGMEqYM58LK4Kr
|
||||||
|
Mpskv7K1tCV/EMZqGTqXAIfSLy9umlb/9C3AhL9thBPn5I9dam/EmrIZktI9/w5Y
|
||||||
|
wBXn4toe+OopA3QkMQh9BUjUCPb9fdOI+ir7OGFZMmxXmiM64+BEeywM2oSGsdZ9
|
||||||
|
5hU378UBu2IX4+OAV8Fbr2l6VW+Fxg/tKIOo6Bs46Pa4EZgtemOqs3kxYBOltBTb
|
||||||
|
vFcLsLa4KYVu5Ge5YfB0Axfaem7PoP8IlMs8gxyojZ/r0o5hzxUcYlL/h8GeeoLW
|
||||||
|
PFFdiAS+UgxWINOqNXMCAwEAAaNTMFEwHQYDVR0OBBYEFLp9k4LmOnAR4ROrqhb+
|
||||||
|
CFdbk2+oMB8GA1UdIwQYMBaAFLp9k4LmOnAR4ROrqhb+CFdbk2+oMA8GA1UdEwEB
|
||||||
|
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGksycHsjGbXfWfuhQh+CvXk/A2v
|
||||||
|
MoNgiHtNMTGliVNgoVp1B1rj4x9xyZ8YrO8GAmv8jaCwCShd0B5Ul4aZVk1wglVv
|
||||||
|
lFAwb4IAZN9jv9+fw5BRzQ2tLhkVWIEwx6pZkhGhhjBvMaplLN5JwBtsdZorFbm7
|
||||||
|
wuKiUKcFAM28acoOhCmOhgyNNBZpZn5wXaQDY43AthJOhitAV7vph4MPUkwIJnOh
|
||||||
|
MA5GJXEqS58TE9z9pkhQnn9598G8tmOXyA2erAoM9JAXM3EYHxVpoHBb9QRj6WAw
|
||||||
|
XVBo6qRXkwjNEM5CbnD4hVIBsdkOGsDrgd4Q5izQZ3x+jFNkdL/zPsXjJFw=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEAyaphPx5ljqsVAqeZJxQaedQfW0tD7dZCl8qJbKAJRJvUI2o7
|
||||||
|
cnW7ekYwSpgznwsrgqsymyS/srW0JX8QxmoZOpcAh9IvL26aVv/0LcCEv22EE+fk
|
||||||
|
j11qb8SashmS0j3/DljAFefi2h746ikDdCQxCH0FSNQI9v1904j6Kvs4YVkybFea
|
||||||
|
Izrj4ER7LAzahIax1n3mFTfvxQG7Yhfj44BXwVuvaXpVb4XGD+0og6joGzjo9rgR
|
||||||
|
mC16Y6qzeTFgE6W0FNu8VwuwtrgphW7kZ7lh8HQDF9p6bs+g/wiUyzyDHKiNn+vS
|
||||||
|
jmHPFRxiUv+HwZ56gtY8UV2IBL5SDFYg06o1cwIDAQABAoIBAFRpZNsutgPJyLmb
|
||||||
|
vZeF6q8kAxwLnRtom+c9d9hoBHkbYOiSBuAaN6cuyffvTWw9GLFRR5V5BGSheg5X
|
||||||
|
6YWj03uayTYQ3H9WJHRWHrcn5mjaRnaukhUQXQT7nmT+H16xZJl0vLJupZ33aOla
|
||||||
|
0X9DxuJusk+RsU7xPEHXDCABl8/m7v3cFttUBughGBG5oDuzKlFbhXPwA8/yeJ1v
|
||||||
|
qdXKxENi9HO4X5fH1l0vFNIhEqvUVKjw/AzapYtr+bv1wssoNAzvhT7CFa2GjPQ0
|
||||||
|
Ibcq3+RxyAN4iQVITy86Yl4LW1jLx63wbg9q1WG/ca9K/OEAuT7ebJNeMYmM+kf7
|
||||||
|
sf6A8wECgYEA+nnLJ4QtANtAs6nmDC106DTx1cOf3Yq9JOAvmGLomF/8SrUzZbXM
|
||||||
|
F+JcZcttXuuFIFcZD0K7fFP9sx2ITH//BS5V0B0x7Z2olWexVjR6/5pOVFPu19ow
|
||||||
|
tyDCNi5BlTPbvSr/fAxjmO9SgVTb8oG66i4mi0Xn5bp1E441KdvNsHECgYEAzhz/
|
||||||
|
+SjFJlJcGNvMmgfAbfv6McUv7TKrPIvVkA++Gi5QdqJjkuzL1uTfgWIY/9iDByMd
|
||||||
|
W36rFTkYrw6LTMF2dkMjul72Kkco3UExSzOmF4lFmCt3DZW6a6CExKpwk4kF2RnX
|
||||||
|
GRD0FoZZown3RbPHi9rsWxjyVy/yKGwnvXYndiMCgYEA6rnIUDfllK/jansFQtQ2
|
||||||
|
goVbPGAfKJYjurL852mJX4JUBA7bI63CnX9b52lEDXfZQf1dVpfK6zAqx/gdCtPI
|
||||||
|
QSqy8FzrtSnSGnEaFxcHTRFl5lDhuxaWIIdqeSvP+eqnOhdZZP6XN3LPdrP3isNY
|
||||||
|
Tq0BIfNY5khd/v19hMSfdYECgYBQ8h6tMY/LrwiwUpIV4/l0uELYDQL3erC5RImI
|
||||||
|
3EXiblH3ZWsJpqmfKZ+FZos+3z8GLIo5BpQV76h8B5A5grkNVOzRIr42eF/aFOJR
|
||||||
|
EGWoVKbaTiehVC40WoQJ4I35wxRi4L0TAQ97USQe3akY3LP/fujYFgIGr7PAoEkz
|
||||||
|
JRX2VQKBgQDir8/a3FZVo6nYI8zIhBz8xqZJIgvlYQqiQFFwADu5eNPMvNIaVy+6
|
||||||
|
7HKibGM2jPkuS2KHdc8WUp8IrRRMui04qE7kRxVu41QXEBfPiDvrvAQf8SfJe631
|
||||||
|
XvYeZr7HKY4NI5J0ENcb54d7DLQ8a1/wL/GeLVrfUWG35Ra5MW57Og==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC0TCCAbkCCQC/MtOBa1UDpzANBgkqhkiG9w0BAQsFADAoMRkwFwYDVQQDDBBy
|
||||||
|
b290LmFuc2libGUuY29tMQswCQYDVQQGEwJVUzAgFw0xNzEyMTUwODU2MzBaGA8y
|
||||||
|
MDg2MDEwMjA4NTYzMFowKzEcMBoGA1UEAwwTc3ViamVjdC5hbnNpYmxlLmNvbTEL
|
||||||
|
MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDszqdF
|
||||||
|
So3GlVP1xUnN4bSPrFRFiOl/Mqup0Zn5UJJUR9wLnRD+OLcq7kKin6hYqozSu7cC
|
||||||
|
+BnWQoq7vGSSNVqv7BqFMwzGJt9IBUQv0UqIQkA/duUdKdAiMn2PQRsNDnkWEbTj
|
||||||
|
4xsitItVNv84cDG0lkZBYyTgfyZlZLZWplkpUQkrZhoFCekZRJ+ODrqNW3W560rr
|
||||||
|
OUIh+HiQeBqocat6OdxgICBqpUh8EVo1iha3DXjGN08q5utg6gmbIl2VBaVJjfyd
|
||||||
|
wnUSqHylJwh6WCIEh+HXsn4ndfNWSN/fDqvi5I10V1j6Zos7yqQf8qAezUAm6eSq
|
||||||
|
hLgZz0odq9DsO4HHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFK5mVIJ2D+kI0kk
|
||||||
|
sxnW4ibWFjzlYFYPYrZg+2JFIVTbKBg1YzyhuIKm0uztqRxQq5iLn/C/uponHoqF
|
||||||
|
7KDQI37KAJIQdgSva+mEuO9bZAXg/eegail2hN6np7HjOKlPu23s40dAbFrbcOWP
|
||||||
|
VbsBEPDP0HLv6OgbQWzNlE9HO1b7pX6ozk3q4ULO7IR85P6OHYsBBThL+qsOTzg/
|
||||||
|
gVknuB9+n9hgNqZcAcXBLDetOM9aEmYJCGk0enYP5UGLYpseE+rTXFbRuHTPr1o6
|
||||||
|
e8BetiSWS/wcrV4ZF5qr9NiYt5eD6JzTB5Rn5awxxj0FwMtrBu003lLQUWxsuTzz
|
||||||
|
35/RLY4=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEA7M6nRUqNxpVT9cVJzeG0j6xURYjpfzKrqdGZ+VCSVEfcC50Q
|
||||||
|
/ji3Ku5Cop+oWKqM0ru3AvgZ1kKKu7xkkjVar+wahTMMxibfSAVEL9FKiEJAP3bl
|
||||||
|
HSnQIjJ9j0EbDQ55FhG04+MbIrSLVTb/OHAxtJZGQWMk4H8mZWS2VqZZKVEJK2Ya
|
||||||
|
BQnpGUSfjg66jVt1uetK6zlCIfh4kHgaqHGrejncYCAgaqVIfBFaNYoWtw14xjdP
|
||||||
|
KubrYOoJmyJdlQWlSY38ncJ1Eqh8pScIelgiBIfh17J+J3XzVkjf3w6r4uSNdFdY
|
||||||
|
+maLO8qkH/KgHs1AJunkqoS4Gc9KHavQ7DuBxwIDAQABAoIBAQDfjqBfS+jYZrUi
|
||||||
|
uqPYV5IMaNYN5xj4Wi+xXA0OT0A1jLlxxU/7kDNrtg72U9+sBSZ483nstag+nAc5
|
||||||
|
ALu5Q+FfX3gR84XFs4DrDv22XtEMHe9leqsFgynYfu4GRaJyCw3JBeJNmWNOuj8n
|
||||||
|
rYn4EAL8xzmAFUcFIURwSEnTN6vI0cS09nQukz+9CIBuGr7TPMET8YlATDJcH+Ua
|
||||||
|
EGZ9MAFXdKF6adC2nrCVBDNr8mUEpK1XdQcPH2bvcTuZ3Jj5AF2rOrcHq4FZUm97
|
||||||
|
8PaMH6Sarxhwl+ycwrKbU5aEzUYTk67k0V6m9lyvH9z3O3Y84Tr3cZZ5WxdnG6Ri
|
||||||
|
72MFlfgRAoGBAP8wA+KWJ/ttmEXAoSX4J2fPl7X1RhR+1zPNdLY7iX0uNstL8IFH
|
||||||
|
vUN9JHi1Tr7llav+2bUTOu2EMDVmDWZH0s/qKOn+GmqIQLp0441fVAiamTcgwGKE
|
||||||
|
Wwsu4dg10IJ9akHIIbrILT0CvRcIRf67EYLBj3ZwfR+wF1ncefbsxWA9AoGBAO2P
|
||||||
|
qGMn+yrIi5DZF23x6iD2Y7bIdlUmqIqwb99XhW+3YJmRuh1EuN6XP2bIveRa9xvm
|
||||||
|
Q7bbcQM0Yv2c7eTyxpzz2I4bmnccVbs6M1VhtkyQEy5+X5yOl9wnitaaUrbWFy/w
|
||||||
|
kDPuISjLl3xDlxd6dbjf70fkG5oogx5c5toEyWZTAoGAK1CHGErMdozfr9dGgx9f
|
||||||
|
8Or3oVcEki4FcTGKgfQRHkJd4pv9MrRul6oCKsr7lsN5aDxVz7p34iDx3d54n8fJ
|
||||||
|
LKleUHllGngOJJf6l+B6bwtuvkC85vv4SCmpA/3+amfHRWsm7oFTzGtOlT4+Q0KV
|
||||||
|
clBQfZYSZvKIxCP8P8ForzECgYEAjDOad1qjOy68X7Ifx71cJjQDyV4pqDt2gNN8
|
||||||
|
Ut1+XN5m3ntI0fk6+fNdcbXLjDe7WvXcxNBhtDh4q6CwLcyyNvMavVPBJ8bLOgIx
|
||||||
|
RZSzWCA3kdr3ZpgpO78Ci4DsjAdyC9L36A4D9+Wf87CYPT0CuSdAOrd/Ks36BDNj
|
||||||
|
8wucKQ0CgYAaRwQ18nkemrpQ/+EQgEWnWfqgB+6T4ygZ4ZTym0FAtG7CdLxvCi8V
|
||||||
|
toyn+zi+yFTRFXHDmvg9HLIIMK/hRQjgc8Ns5nDwgQlGwCZTvjVbD4anCr1IWuky
|
||||||
|
owvxKWsHseNilKrnAk2maQxrrrpSk8QWrp2CFw04LsWGTxtFvstBmg==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
dependencies:
|
||||||
|
- prepare_win_tests
|
@ -0,0 +1,121 @@
|
|||||||
|
### keys in files/ have been generated with
|
||||||
|
# generate root private key
|
||||||
|
# openssl genrsa -aes256 -out enckey.pem 2048
|
||||||
|
# openssl rsa -in envkey.pem -out root-key.pem
|
||||||
|
#
|
||||||
|
# generate root certificate
|
||||||
|
# openssl req -x509 -key root-key.pem -days 24855 -out root-vert.pem -subj "/CN=root.ansible.com/C=US"
|
||||||
|
#
|
||||||
|
# generate subject private key
|
||||||
|
# openssl genrsa -aes256 -out enckey.pem 2048
|
||||||
|
# openssl rsa -in enckey.pem -out subj-key.pem
|
||||||
|
#
|
||||||
|
# generate subject certificate
|
||||||
|
# openssl req -new -key subj-key.pem -out cert.csr -subj "/CN=subject.ansible.com/C=US"
|
||||||
|
# openssl x509 -req -in cert.csr -CA root-cert.pem -CAkey root-key.pem -CAcreateserial -out subj-cert.pem -days 24855
|
||||||
|
###
|
||||||
|
---
|
||||||
|
- name: ensure test dir is present
|
||||||
|
win_file:
|
||||||
|
path: '{{win_cert_dir}}\exported'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: ensure certificates are removed from store before test
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{item}}'
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- '{{subj_thumbprint}}'
|
||||||
|
- '{{root_thumbprint}}'
|
||||||
|
|
||||||
|
- name: ensure certificates are removed from custom store before test
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{item}}'
|
||||||
|
state: absent
|
||||||
|
store_name: TrustedPeople
|
||||||
|
store_location: CurrentUser
|
||||||
|
with_items:
|
||||||
|
- '{{subj_thumbprint}}'
|
||||||
|
- '{{root_thumbprint}}'
|
||||||
|
|
||||||
|
# these files are created on the fly so we don't store binary in the git repo
|
||||||
|
- name: create PKCS12 without password
|
||||||
|
command: 'openssl pkcs12 -export -out subj-cert-without-pass.pfx -inkey subj-key.pem -in subj-cert.pem -passout pass:'
|
||||||
|
args:
|
||||||
|
chdir: '{{role_path}}/files'
|
||||||
|
delegate_to: localhost
|
||||||
|
run_once: yes
|
||||||
|
|
||||||
|
- name: create PKCS12 with password
|
||||||
|
command: 'openssl pkcs12 -export -out subj-cert-with-pass.pfx -inkey subj-key.pem -in subj-cert.pem -passout pass:{{key_password}}'
|
||||||
|
args:
|
||||||
|
chdir: '{{role_path}}/files'
|
||||||
|
delegate_to: localhost
|
||||||
|
run_once: yes
|
||||||
|
|
||||||
|
- name: create DER encoded cert
|
||||||
|
command: openssl x509 -outform der -in subj-cert.pem -out subj-cert.cer
|
||||||
|
args:
|
||||||
|
chdir: '{{role_path}}/files'
|
||||||
|
delegate_to: localhost
|
||||||
|
run_once: yes
|
||||||
|
|
||||||
|
- name: create PEM encoded PKCS7 file
|
||||||
|
command: openssl crl2pkcs7 -nocrl -certfile subj-cert.pem -certfile root-cert.pem -out chain.pem
|
||||||
|
args:
|
||||||
|
chdir: '{{role_path}}/files'
|
||||||
|
delegate_to: localhost
|
||||||
|
run_once: yes
|
||||||
|
|
||||||
|
- name: create DER encoded PKCS7 file
|
||||||
|
command: openssl crl2pkcs7 -nocrl -certfile subj-cert.pem -certfile root-cert.pem -out chain.p7b -outform der
|
||||||
|
args:
|
||||||
|
chdir: '{{role_path}}/files'
|
||||||
|
delegate_to: localhost
|
||||||
|
run_once: yes
|
||||||
|
|
||||||
|
- name: copy across test cert files
|
||||||
|
win_copy:
|
||||||
|
src: files/
|
||||||
|
dest: '{{win_cert_dir}}'
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: run tests
|
||||||
|
include_tasks: test.yml
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: ensure generated keys are deleted
|
||||||
|
file:
|
||||||
|
path: '{{role_path}}/files/{{item}}'
|
||||||
|
state: absent
|
||||||
|
delegate_to: localhost
|
||||||
|
run_once: yes
|
||||||
|
with_items:
|
||||||
|
- subj-cert-with-pass.pfx
|
||||||
|
- subj-cert-without-pass.pfx
|
||||||
|
- subj-cert.cer
|
||||||
|
- chain.pem
|
||||||
|
- chain.p7b
|
||||||
|
|
||||||
|
- name: ensure certificates are removed from store after test
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{item}}'
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- '{{subj_thumbprint}}'
|
||||||
|
- '{{root_thumbprint}}'
|
||||||
|
|
||||||
|
- name: ensure certificates are removed from custom store after test
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{item}}'
|
||||||
|
state: absent
|
||||||
|
store_name: TrustedPeople
|
||||||
|
store_location: CurrentUser
|
||||||
|
with_items:
|
||||||
|
- '{{subj_thumbprint}}'
|
||||||
|
- '{{root_thumbprint}}'
|
||||||
|
|
||||||
|
- name: ensure test dir is deleted
|
||||||
|
win_file:
|
||||||
|
path: '{{win_cert_dir}}'
|
||||||
|
state: absent
|
@ -0,0 +1,801 @@
|
|||||||
|
---
|
||||||
|
- name: fail with invalid store location
|
||||||
|
win_certificate_store:
|
||||||
|
state: present
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.pem'
|
||||||
|
store_location: FakeLocation
|
||||||
|
register: fail_fake_location
|
||||||
|
failed_when: "fail_fake_location.msg != 'Get-AnsibleParam: Argument store_location needs to be one of CurrentUser,LocalMachine but was FakeLocation.'"
|
||||||
|
|
||||||
|
- name: fail with invalid store name
|
||||||
|
win_certificate_store:
|
||||||
|
state: present
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.pem'
|
||||||
|
store_name: FakeName
|
||||||
|
register: fail_fake_name
|
||||||
|
failed_when: "fail_fake_name.msg != 'Get-AnsibleParam: Argument store_name needs to be one of AddressBook,AuthRoot,CertificateAuthority,Disallowed,My,Root,TrustedPeople,TrustedPublisher but was FakeName.'"
|
||||||
|
|
||||||
|
- name: fail when state=present and no path is set
|
||||||
|
win_certificate_store:
|
||||||
|
state: present
|
||||||
|
register: fail_present_no_path
|
||||||
|
failed_when: "fail_present_no_path.msg != 'Get-AnsibleParam: Missing required argument: path'"
|
||||||
|
|
||||||
|
- name: fail when state=exported and no path is set
|
||||||
|
win_certificate_store:
|
||||||
|
state: exported
|
||||||
|
thumbprint: ABC
|
||||||
|
register: fail_export_no_path
|
||||||
|
failed_when: "fail_export_no_path.msg != 'Get-AnsibleParam: Missing required argument: path'"
|
||||||
|
|
||||||
|
- name: fail when state=exported and no thumbprint is set
|
||||||
|
win_certificate_store:
|
||||||
|
state: exported
|
||||||
|
path: '{{win_cert_dir}}'
|
||||||
|
register: fail_export_no_thumbprint
|
||||||
|
failed_when: "fail_export_no_thumbprint.msg != 'Get-AnsibleParam: Missing required argument: thumbprint'"
|
||||||
|
|
||||||
|
- name: fail to export thumbprint when path is a dir
|
||||||
|
win_certificate_store:
|
||||||
|
state: exported
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
path: '{{win_cert_dir}}'
|
||||||
|
register: fail_export_path_is_dir
|
||||||
|
failed_when: fail_export_path_is_dir.msg != "Cannot export cert to path '" + win_cert_dir + "' as it is a directory"
|
||||||
|
|
||||||
|
- name: fail when state=absent and not path or thumbprint is set
|
||||||
|
win_certificate_store:
|
||||||
|
state: absent
|
||||||
|
register: fail_absent_no_path_or_thumbprint
|
||||||
|
failed_when: fail_absent_no_path_or_thumbprint.msg != 'Either path or thumbprint must be set when state=absent'
|
||||||
|
|
||||||
|
- name: import pem certificate (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.pem'
|
||||||
|
state: present
|
||||||
|
register: import_pem_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of import pem certificate (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pem_result_check
|
||||||
|
|
||||||
|
- name: assert results of import pem certificate (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pem_check is changed
|
||||||
|
- import_pem_check.thumbprints == [subj_thumbprint]
|
||||||
|
- import_pem_result_check.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import pem certificate
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.pem'
|
||||||
|
state: present
|
||||||
|
register: import_pem
|
||||||
|
|
||||||
|
- name: get result of import pem certificate
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pem_result
|
||||||
|
|
||||||
|
- name: assert results of import pem certificate
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pem is changed
|
||||||
|
- import_pem.thumbprints == [subj_thumbprint]
|
||||||
|
- import_pem_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: import pem certificate (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.pem'
|
||||||
|
state: present
|
||||||
|
register: import_pem_again
|
||||||
|
|
||||||
|
- name: assert results of import pem certificate (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not import_pem_again is changed
|
||||||
|
|
||||||
|
- name: remove certificate based on thumbprint (check)
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: absent
|
||||||
|
register: remove_thumbprint_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of remove certificate based on thumbprint (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: remove_thumbprint_result_check
|
||||||
|
|
||||||
|
- name: assert results of remove certificate based on thumbprint (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_thumbprint_check is changed
|
||||||
|
- remove_thumbprint_check.thumbprints == [subj_thumbprint]
|
||||||
|
- remove_thumbprint_result_check.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: remove certificate based on thumbprint
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: absent
|
||||||
|
register: remove_thumbprint
|
||||||
|
|
||||||
|
- name: get result of remove certificate based on thumbprint
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: remove_thumbprint_result
|
||||||
|
|
||||||
|
- name: assert results of remove certificate based on thumbprint
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_thumbprint is changed
|
||||||
|
- remove_thumbprint.thumbprints == [subj_thumbprint]
|
||||||
|
- remove_thumbprint_result.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: remove certificate based on thumbprint (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: absent
|
||||||
|
register: remove_thumbprint_again
|
||||||
|
|
||||||
|
- name: assert results of remove certificate based on thumbprint (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not remove_thumbprint_again is changed
|
||||||
|
|
||||||
|
- name: import der certificate (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.cer'
|
||||||
|
state: present
|
||||||
|
register: import_der_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of import der certificate (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_der_result_check
|
||||||
|
|
||||||
|
- name: assert results of import der certificate (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_der_check is changed
|
||||||
|
- import_der_check.thumbprints == [subj_thumbprint]
|
||||||
|
- import_der_result_check.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import der certificate
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.cer'
|
||||||
|
state: present
|
||||||
|
register: import_der
|
||||||
|
|
||||||
|
- name: get result of import der certificate
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_der_result
|
||||||
|
|
||||||
|
- name: assert results of import der certificate
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_der is changed
|
||||||
|
- import_der.thumbprints == [subj_thumbprint]
|
||||||
|
- import_der_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: import der certificate (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.cer'
|
||||||
|
state: present
|
||||||
|
register: import_der_again
|
||||||
|
|
||||||
|
- name: assert results of import der certificate (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not import_der_again is changed
|
||||||
|
|
||||||
|
- name: remove certificate based on path (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.cer'
|
||||||
|
state: absent
|
||||||
|
register: remove_path_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of remove certificate based on path (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: remove_path_result_check
|
||||||
|
|
||||||
|
- name: assert results of remove certificate based on path (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_path_check is changed
|
||||||
|
- remove_path_check.thumbprints == [subj_thumbprint]
|
||||||
|
- remove_path_result_check.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: remove certificate based on path
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.cer'
|
||||||
|
state: absent
|
||||||
|
register: remove_path
|
||||||
|
|
||||||
|
- name: get result of remove certificate based on path
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: remove_path_result
|
||||||
|
|
||||||
|
- name: assert results of remove certificate based on path
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_path is changed
|
||||||
|
- remove_path.thumbprints == [subj_thumbprint]
|
||||||
|
- remove_path_result.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: remove certificate based on path (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert.cer'
|
||||||
|
state: absent
|
||||||
|
register: remove_path_again
|
||||||
|
|
||||||
|
- name: assert results of remove certificate based on path (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not remove_path_again is changed
|
||||||
|
|
||||||
|
- name: import PEM encoded p7b chain (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\chain.pem'
|
||||||
|
state: present
|
||||||
|
register: import_pem_p7b_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of subj in p7b chain (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pem_p7b_subj_result_check
|
||||||
|
|
||||||
|
- name: get result of root in p7b chain (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pem_p7b_root_result_check
|
||||||
|
|
||||||
|
- name: assert results of import PEM encoded p7b chain (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pem_p7b_check is changed
|
||||||
|
- import_pem_p7b_check.thumbprints|count == 2
|
||||||
|
- subj_thumbprint in import_pem_p7b_check.thumbprints
|
||||||
|
- root_thumbprint in import_pem_p7b_check.thumbprints
|
||||||
|
- import_pem_p7b_subj_result_check.stdout_lines[0] == "False"
|
||||||
|
- import_pem_p7b_root_result_check.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import PEM encoded p7b chain
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\chain.pem'
|
||||||
|
state: present
|
||||||
|
register: import_pem_p7b
|
||||||
|
|
||||||
|
- name: get result of subj in p7b chain
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pem_p7b_subj_result
|
||||||
|
|
||||||
|
- name: get result of root in p7b chain
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pem_p7b_root_result
|
||||||
|
|
||||||
|
- name: assert results of import PEM encoded p7b chain
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pem_p7b is changed
|
||||||
|
- import_pem_p7b.thumbprints|count == 2
|
||||||
|
- subj_thumbprint in import_pem_p7b.thumbprints
|
||||||
|
- root_thumbprint in import_pem_p7b.thumbprints
|
||||||
|
- import_pem_p7b_subj_result.stdout_lines[0] == "True"
|
||||||
|
- import_pem_p7b_root_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: import PEM encoded p7b chain (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\chain.pem'
|
||||||
|
state: present
|
||||||
|
register: import_pem_p7b_again
|
||||||
|
|
||||||
|
- name: assert results of import PEM encoded p7b chain (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not import_pem_p7b_again is changed
|
||||||
|
|
||||||
|
- name: remove p7b chain certs
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{item}}'
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- '{{subj_thumbprint}}'
|
||||||
|
- '{{root_thumbprint}}'
|
||||||
|
|
||||||
|
- name: import DER encoded p7b chain into custom store (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\chain.p7b'
|
||||||
|
state: present
|
||||||
|
store_name: TrustedPeople
|
||||||
|
store_location: CurrentUser
|
||||||
|
register: import_der_p7b_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of subj in p7b chain in custom store (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_der_p7b_subj_result_check
|
||||||
|
|
||||||
|
- name: get result of root in p7b chain in custom store (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_der_p7b_root_result_check
|
||||||
|
|
||||||
|
- name: assert results of import DER encoded p7b chain into custom store (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_der_p7b_check is changed
|
||||||
|
- import_der_p7b_check.thumbprints|count == 2
|
||||||
|
- subj_thumbprint in import_der_p7b_check.thumbprints
|
||||||
|
- root_thumbprint in import_der_p7b_check.thumbprints
|
||||||
|
- import_der_p7b_subj_result_check.stdout_lines[0] == "False"
|
||||||
|
- import_der_p7b_root_result_check.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import DER encoded p7b chain into custom store
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\chain.p7b'
|
||||||
|
state: present
|
||||||
|
store_name: TrustedPeople
|
||||||
|
store_location: CurrentUser
|
||||||
|
register: import_der_p7b
|
||||||
|
|
||||||
|
- name: get result of subj in p7b chain in custom store
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_der_p7b_subj_result
|
||||||
|
|
||||||
|
- name: get result of root in p7b chain in custom store
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{root_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_der_p7b_root_result
|
||||||
|
|
||||||
|
- name: assert results of import DER encoded p7b chain into custom store
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_der_p7b is changed
|
||||||
|
- import_der_p7b.thumbprints|count == 2
|
||||||
|
- subj_thumbprint in import_der_p7b.thumbprints
|
||||||
|
- root_thumbprint in import_der_p7b.thumbprints
|
||||||
|
- import_der_p7b_root_result.stdout_lines[0] == "True"
|
||||||
|
- import_der_p7b_root_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: import DER encoded p7b chain into custom store (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\chain.p7b'
|
||||||
|
state: present
|
||||||
|
store_name: TrustedPeople
|
||||||
|
store_location: CurrentUser
|
||||||
|
register: import_der_p7b_again
|
||||||
|
|
||||||
|
- name: assert results of import DER encoded p7b chain into custom store (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not import_der_p7b_again is changed
|
||||||
|
|
||||||
|
- name: remove p7b chain certs from custom store
|
||||||
|
win_certificate_store:
|
||||||
|
thumbprint: '{{item}}'
|
||||||
|
state: absent
|
||||||
|
store_name: TrustedPeople
|
||||||
|
store_location: CurrentUser
|
||||||
|
with_items:
|
||||||
|
- '{{subj_thumbprint}}'
|
||||||
|
- '{{root_thumbprint}}'
|
||||||
|
|
||||||
|
- name: import pfx without password and non exportable (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-without-pass.pfx'
|
||||||
|
state: present
|
||||||
|
key_exportable: no
|
||||||
|
vars: &become_vars
|
||||||
|
ansible_become: yes
|
||||||
|
ansible_become_method: runas
|
||||||
|
ansible_become_user: '{{ansible_user}}'
|
||||||
|
ansible_become_pass: '{{ansible_password}}'
|
||||||
|
register: import_pfx_without_pass_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get results of import pfx without password and non exportable (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pfx_without_pass_result_check
|
||||||
|
|
||||||
|
- name: assert results of import pfx without password and non exportable (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pfx_without_pass_check is changed
|
||||||
|
- import_pfx_without_pass_check.thumbprints == [subj_thumbprint]
|
||||||
|
- import_pfx_without_pass_result_check.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import pfx without password and non exportable
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-without-pass.pfx'
|
||||||
|
state: present
|
||||||
|
key_exportable: no
|
||||||
|
vars: *become_vars
|
||||||
|
register: import_pfx_without_pass
|
||||||
|
|
||||||
|
- name: get results of import pfx without password and non exportable
|
||||||
|
win_shell: (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }).PrivateKey.CspKeyContainerInfo.Exportable
|
||||||
|
vars: *become_vars
|
||||||
|
register: import_pfx_without_pass_result
|
||||||
|
|
||||||
|
- name: assert results of import pfx without password and non exportable
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pfx_without_pass is changed
|
||||||
|
- import_pfx_without_pass.thumbprints == [subj_thumbprint]
|
||||||
|
- import_pfx_without_pass_result.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import pfx without password and non exportable (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-without-pass.pfx'
|
||||||
|
state: present
|
||||||
|
key_exportable: no
|
||||||
|
vars: *become_vars
|
||||||
|
register: import_pfx_without_pass_again
|
||||||
|
|
||||||
|
- name: assert results of import pfx without password and non exportable (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not import_pfx_without_pass_again is changed
|
||||||
|
|
||||||
|
- name: fail import pfx with password and none set
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-with-pass.pfx'
|
||||||
|
state: present
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
register: fail_import_pfx_with_password
|
||||||
|
failed_when: "'Failed to load cert from file' not in fail_import_pfx_with_password.msg and 'The specified network password is not correct' not in fail_import_pfx_with_password.msg"
|
||||||
|
|
||||||
|
- name: import pfx with password (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-with-pass.pfx'
|
||||||
|
state: present
|
||||||
|
password: '{{key_password}}'
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
register: import_pfx_with_pass_check
|
||||||
|
vars: *become_vars
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get results of import pfx with password (check)
|
||||||
|
win_shell: if (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }) { $true } else { $false }
|
||||||
|
register: import_pfx_with_pass_result_check
|
||||||
|
|
||||||
|
- name: assert results of import pfx with password (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pfx_with_pass_check is changed
|
||||||
|
- import_pfx_with_pass_check.thumbprints == [subj_thumbprint]
|
||||||
|
- import_pfx_with_pass_result_check.stdout_lines[0] == "False"
|
||||||
|
|
||||||
|
- name: import pfx with password
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-with-pass.pfx'
|
||||||
|
state: present
|
||||||
|
password: '{{key_password}}'
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
vars: *become_vars
|
||||||
|
register: import_pfx_with_pass
|
||||||
|
|
||||||
|
- name: get results of import pfx with password
|
||||||
|
win_shell: (Get-ChildItem -Path Cert:\CurrentUser\TrustedPeople | Where-Object { $_.Thumbprint -eq "{{subj_thumbprint}}" }).PrivateKey.CspKeyContainerInfo.Exportable
|
||||||
|
vars: *become_vars
|
||||||
|
register: import_pfx_with_pass_result
|
||||||
|
|
||||||
|
- name: assert results of import pfx with password
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- import_pfx_with_pass is changed
|
||||||
|
- import_pfx_with_pass.thumbprints == [subj_thumbprint]
|
||||||
|
- import_pfx_with_pass_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: import pfx with password (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\subj-cert-with-pass.pfx'
|
||||||
|
state: present
|
||||||
|
password: '{{key_password}}'
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
vars: *become_vars
|
||||||
|
register: import_pfx_with_pass_again
|
||||||
|
|
||||||
|
- name: assert results of import pfx with password (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not import_pfx_with_pass_again is changed
|
||||||
|
|
||||||
|
- name: import root cert for export tests
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\root-cert.pem'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: export cert as pem (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pem
|
||||||
|
register: export_pem_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of export cert as pem (check)
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
register: export_pem_result_check
|
||||||
|
|
||||||
|
- name: assert results of export cert as pem (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pem_check is changed
|
||||||
|
- export_pem_check.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pem_result_check.stat.exists == False
|
||||||
|
|
||||||
|
- name: export cert as pem
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pem
|
||||||
|
register: export_pem
|
||||||
|
|
||||||
|
- name: get result of export cert as pem
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
register: export_pem_result
|
||||||
|
|
||||||
|
- name: assert results of export cert as pem
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pem is changed
|
||||||
|
- export_pem.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pem_result.stat.checksum == '1ebf5467d18230e9f611940a74d12f1d0bc819b7'
|
||||||
|
|
||||||
|
- name: export cert as pem (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pem
|
||||||
|
register: export_pem_again
|
||||||
|
|
||||||
|
- name: assert results of export cert as pem
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not export_pem_again is changed
|
||||||
|
|
||||||
|
- name: export cert as der (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: der
|
||||||
|
register: export_der_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of export cert as der (check)
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
register: export_der_result_check
|
||||||
|
|
||||||
|
- name: assert results of export cert as der (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_der_check is changed
|
||||||
|
- export_der_check.thumbprints == [subj_thumbprint]
|
||||||
|
- export_der_result_check.stat.exists == False
|
||||||
|
|
||||||
|
- name: export cert as der
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: der
|
||||||
|
register: export_der
|
||||||
|
|
||||||
|
- name: get result of export cert as der
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
register: export_der_result
|
||||||
|
|
||||||
|
- name: assert results of export cert as der
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_der is changed
|
||||||
|
- export_der.thumbprints == [subj_thumbprint]
|
||||||
|
- export_der_result.stat.checksum == 'bd7af104cf1872bdb518d95c9534ea941665fd27'
|
||||||
|
|
||||||
|
- name: export cert as der (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: der
|
||||||
|
register: export_der_again
|
||||||
|
|
||||||
|
- name: assert results of export cert as der
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not export_der_again is changed
|
||||||
|
|
||||||
|
- name: export cert as der replacing pem
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: der
|
||||||
|
register: export_der_over_pem
|
||||||
|
|
||||||
|
- name: get result of export cert as der replacing pem
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.pem'
|
||||||
|
register: export_der_over_pem_result
|
||||||
|
|
||||||
|
- name: assert results of export cert as der replacing pem
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_der_over_pem is changed
|
||||||
|
- export_der_over_pem.thumbprints == [subj_thumbprint]
|
||||||
|
- export_der_over_pem_result.stat.checksum == 'bd7af104cf1872bdb518d95c9534ea941665fd27'
|
||||||
|
|
||||||
|
- name: export cert as pem replacing der
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pem
|
||||||
|
register: export_pem_over_der
|
||||||
|
|
||||||
|
- name: get result of export cert as pem replacing der
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert.cer'
|
||||||
|
register: export_pem_over_der_result
|
||||||
|
|
||||||
|
- name: assert results of export cert as pem replacing der
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pem_over_der is changed
|
||||||
|
- export_pem_over_der.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pem_over_der_result.stat.checksum == '1ebf5467d18230e9f611940a74d12f1d0bc819b7'
|
||||||
|
|
||||||
|
- name: export cert with key and password as pfx (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-pass.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
password: '{{key_password}}'
|
||||||
|
register: export_pfx_with_pass_check
|
||||||
|
vars: *become_vars
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of export cert with key and password as pfx (check)
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-pass.pfx'
|
||||||
|
register: export_pfx_with_pass_result_check
|
||||||
|
|
||||||
|
- name: assert results of export cert with key and password as pfx (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pfx_with_pass_check is changed
|
||||||
|
- export_pfx_with_pass_check.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pfx_with_pass_result_check.stat.exists == False
|
||||||
|
|
||||||
|
- name: export cert with key and password as pfx
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-pass.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
password: '{{key_password}}'
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_with_pass
|
||||||
|
|
||||||
|
- name: get result of export cert with key and password as pfx
|
||||||
|
win_shell: |
|
||||||
|
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
|
||||||
|
$cert.Import("{{win_cert_dir}}\exported\cert-pass.pfx", "{{key_password}}", 0)
|
||||||
|
$cert.HasPrivateKey
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_with_pass_result
|
||||||
|
|
||||||
|
- name: assert results of export cert with key and password as pfx
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pfx_with_pass is changed
|
||||||
|
- export_pfx_with_pass.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pfx_with_pass_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: export cert with key and password as pfx (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-pass.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
password: '{{key_password}}'
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_with_pass_again
|
||||||
|
|
||||||
|
- name: assert results of export cert with key and password as pfx (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not export_pfx_with_pass_again is changed
|
||||||
|
|
||||||
|
- name: export cert with key without password as pfx (check)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-without-pass.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_without_pass_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of export cert with key without password as pfx (check)
|
||||||
|
win_stat:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-without-pass.pfx'
|
||||||
|
register: export_pfx_without_pass_result_check
|
||||||
|
|
||||||
|
- name: assert results of export cert with key without password as pfx (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pfx_without_pass_check is changed
|
||||||
|
- export_pfx_without_pass_check.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pfx_without_pass_result_check.stat.exists == False
|
||||||
|
|
||||||
|
- name: export cert with key without password as pfx
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-without-pass.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_without_pass
|
||||||
|
|
||||||
|
- name: get result of export cert with key without password as pfx
|
||||||
|
win_shell: |
|
||||||
|
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
|
||||||
|
$cert.Import("{{win_cert_dir}}\exported\cert-without-pass.pfx", $null, 0)
|
||||||
|
$cert.HasPrivateKey
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_without_pass_result
|
||||||
|
|
||||||
|
- name: assert results of export cert with key without password as pfx
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- export_pfx_without_pass is changed
|
||||||
|
- export_pfx_without_pass.thumbprints == [subj_thumbprint]
|
||||||
|
- export_pfx_without_pass_result.stdout_lines[0] == "True"
|
||||||
|
|
||||||
|
- name: export cert with key without password as pfx (idempotent)
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-without-pass.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
store_location: CurrentUser
|
||||||
|
store_name: TrustedPeople
|
||||||
|
vars: *become_vars
|
||||||
|
register: export_pfx_without_pass_again
|
||||||
|
|
||||||
|
- name: assert results of export cert with key without password as pfx (idempotent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not export_pfx_without_pass_again is changed
|
||||||
|
|
||||||
|
- name: fail to export cert with key as pfx when not marked as exportable
|
||||||
|
win_certificate_store:
|
||||||
|
path: '{{win_cert_dir}}\exported\cert-fail.pfx'
|
||||||
|
thumbprint: '{{subj_thumbprint}}'
|
||||||
|
state: exported
|
||||||
|
file_type: pkcs12
|
||||||
|
vars: *become_vars
|
||||||
|
register: fail_export_non_exportable
|
||||||
|
failed_when: fail_export_non_exportable.msg != 'Cannot export cert with key as PKCS12 when the key is not marked as exportable or not accesible by the current user'
|
Loading…
Reference in New Issue