Functions/New-CertificateRequest.ps1
<#
.SYNOPSIS Creates a new Certificate Signing Request (CSR) based on the given Parameters. The CSR can directly be signed by a given Signing Certificate. Can also be used to create self-signed Certificates. .PARAMETER MachineContext By default, the Key for Certificate Request gets created in the current User's Context. By specifying this Parameter, it will be created as a Machine Key. You must execute the Command with Elevation (Run as Administrator) then. .PARAMETER Subject Specifies the Subject DN for the Certificate. May be left empty if you specify a DnsName, Upn or IP instead. .PARAMETER Eku Specifies or or more Enhanced Key Usage to be included in the Certificate Request. They get identified by their Friendly Name. Especially useful when creating a Certificate with the Cmdlet. .PARAMETER Dns Specifies one or more DNS Names to be written into the Subject Alternative Name (SAN) Extension of the Certificate Request. May be left Empty if you specify a Subject, Upn, Email or IP instead. .PARAMETER Upn Specifies one or more User Principal Names to be written into the Subject Alternative Name (SAN) Extension of the Certificate Request. May be left Empty if you specify a Subject, DnsName, Email or IP instead. .PARAMETER Email Specifies one or more E-Mail addresses (RFC 822) to be written into the Subject Alternative Name (SAN) Extension of the Certificate Request. May be left Empty if you specify a Subject, DnsName, Upn or IP instead. .PARAMETER IP Specifies or more IP Addresses to be written into the Subject Alternative Name (SAN) Extension of the Certificate Request. May be left Empty if you specify a Subject, DnsName, Email or Upn instead. .PARAMETER Smime Specifies the S/MIME Capabilities the requestor supports. .PARAMETER Aki Specifies the Authority Key Identifier Attribute to be included in the Request. If supported by the CA, it will sign the Certificate Request with the specified Key instead of the default one. This is especially useful for creating OCSP Certificate Requests. .PARAMETER Cdp Specifies one or more URLs to be included in the CRL Distribution Points Extension. Especially useful when creating a Certificate with the Cmdlet. .PARAMETER Aia Specifies one or more URLs to be included in the Authority Information Access Extension. Especially useful when creating a Certificate with the Cmdlet. .PARAMETER KeyUsage Specified the Key Usage of the Certificate. This usually gets overwritten by the CA, therefore this is intended for creating a Certificate. Default is DigitalSignature for Leaf Certificates and keyCertSign plus keyCrlSign for CA Certificates. .PARAMETER Ksp Specifies the Cryptographic Service Provider (CSP) or Key Storage Provider (KSP) to be used for the Private Key of the Certificate. You can specify any CSP or KSP that is installed on the System. Defaults to the Microsoft Software Key Storage Provider. .PARAMETER SigningCert Specifies the Signing Certificate used to sign the Certificate Request and thus creating a certificate. .PARAMETER KeyAlgorithm Specifies the Algorithm to be used when creating the Key Pair. Defaults to "RSA". .PARAMETER KeyLength Specifies the Key Length for the Key pair of the Certificate. Gets applied only when KeyAlgorithm is "RSA". Defaults to 3072 Bits. .PARAMETER PrivateKeyExportable Specifies if the Private Key of the Certificate shall be marked as exportable. Defaults to the Key being not marked as exportable. .PARAMETER SignatureHashAlgorithm Specifies the Hash Algorithm that is being used to sign the Certificate Request or the Certificate. Defaults to SHA-256. .PARAMETER CA Instructs the CmdLet to include the bits relevant to a CA Certificate. .PARAMETER ValidityPeriod Specifies the Validity Period when creating a Certificate. Defaults to "Years". .PARAMETER ValidityPeriodUnits Specifies the Validity Period Unit when creating a Certificate. Defaults to 1. .PARAMETER ClockSkew Specifies the Clock Skew to use when creating a Certificate. Defaults to 10 (Minutes). .PARAMETER SerialNumber Specifies the Serial Number to use when creating a Certificate. Will use a random Serial Number if not specified. .PARAMETER SubjectEncoding Specifies the Subject Encoding to be used. Defaults to PrintableString. .PARAMETER PathLength Specifies the Path Length Constraint to be used when creating a CA Certificate. Defaults to none. .PARAMETER SelfSign Instructs the Cmdlet to Self-Sign the request, thus creating a Certificate. .OUTPUTS System.String or System.Security.Cryptography.X509Certificates.X509Certificate. Either the BASE64-encoded Certificate Signing Request, or the Certificate as an Object. #> Function New-CertificateRequest { [cmdletbinding()] param ( [Alias("Machine")] [Parameter(Mandatory=$False)] [Switch] $MachineContext = $False, [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] [String] $Subject, [Alias("EnhancedKeyUsage")] [Parameter(Mandatory=$False)] [ValidateSet( "EnrollmentAgent", "ClientAuthentication", "CodeSigning", "LifeTimeSigning", "DocumentSigning", "DocumentEncryption", "EncryptingFileSystem", "FileRecovery", "IPSecEndSystem", "IPSecIKEIntermediate", "IPSecTunnelEndpoint", "IPSecUser", "KeyRecovery", "KDCAuthentication", "SecureEmail", "ServerAuthentication", "SmartCardLogon", "TimeStamping", "OCSPSigning", "RemoteDesktopAuthentication", "PrivateKeyArchival" )] [String[]] $Eku, [Alias("DnsName")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] [ValidateScript({ $_ | ForEach-Object -Process { [System.Uri]::CheckHostName($_) -eq [System.UriHostnameType]::Dns } })] [String[]] $Dns, [Alias("UserPrincipalName")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] [mailaddress[]] $Upn, [Alias("RFC822Name")] [Alias("E-Mail")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] [mailaddress[]] $Email, [Alias("IPAddress")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] [System.Net.IPAddress[]] $IP, [Alias("SmimeCapabilities")] [Parameter(Mandatory=$False)] [ValidateSet( "des", "des3", "rc2", "rc4", "des3wrap", "rc2wrap", "aes128", "aes192", "aes256", "aes128wrap", "aes192wrap", "aes256wrap", "md5", "sha1", "sha256", "sha384", "sha512" )] [String[]] $Smime, [Alias("SecurityIdentifier")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] [ValidatePattern("^S-1-5-21-[0-9]*-[0-9]*-[0-9]*-[0-9]*$")] [String] $Sid, [Alias("AuthorityKeyIdentifier")] [Parameter(Mandatory=$False)] [ValidatePattern("^[0-9a-fA-F]{40}$")] [String] $Aki, [Alias("CrlDistributionPoint")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] # anyone has a http and ldap regex? [String[]] $Cdp, [Alias("AuthorityInformationAccess")] [Parameter(Mandatory=$False)] [ValidateNotNullOrEmpty()] # anyone has a http and ldap regex? [String[]] $Aia, [Parameter(Mandatory=$False)] [ValidateSet( "CrlSign", "DataEncipherment", "DecipherOnly", "DigitalSignature", "EncipherOnly", "KeyAgreement", "KeyCertSign", "KeyEncipherment", "None", "NonRepudiation" )] [String[]] $KeyUsage = "DigitalSignature", [Alias("KeyStorageProvider")] [Parameter(Mandatory=$False)] [ValidateScript({ $Ksp = $_ [bool](Get-KeyStorageProvider | Where-Object { $_.Name -eq $Ksp })} )] [String] $Ksp = "Microsoft Software Key Storage Provider", [Parameter(Mandatory=$False)] [ValidateScript({($_.HasPrivateKey) -and ($null -ne $_.PSParentPath)})] [System.Security.Cryptography.X509Certificates.X509Certificate2] $SigningCert, [Parameter(Mandatory=$False)] [ValidateSet( "RSA", "ECDSA_P256", "ECDSA_P384", "ECDSA_P521", "ECDH_P256", "ECDH_P384", "ECDH_P521" )] [String] $KeyAlgorithm = "RSA", [Alias("KeySize")] [Parameter(Mandatory=$False)] [ValidateSet(512,1024,2048,3072,4096,8192)] [Int] $KeyLength = 3072, [Alias("Exportable")] [Parameter(Mandatory=$False)] [Switch] $PrivateKeyExportable = $False, [Alias("Hash")] [Parameter(Mandatory=$False)] [ValidateSet("SHA1","SHA256","SHA384","SHA512")] [String] $SignatureHashAlgorithm = "SHA256", [Parameter(Mandatory=$False)] [Switch] $CA = $False, [Parameter(Mandatory=$False)] [ValidateSet("Minutes","Hours","Days","Weeks","Months","Years")] [String] $ValidityPeriod = "Years", [Parameter(Mandatory=$False)] [ValidateRange(1,1000)] [Int] $ValidityPeriodUnits = 1, [Parameter(Mandatory=$False)] [ValidateRange(0,1440)] # One Day should be more than enough [Int] $ClockSkew = 10, <# https://tools.ietf.org/html/rfc5280#section-4.1.2.2 Certificate users MUST be able to handle serialNumber values up to 20 octets. Conforming CAs MUST NOT use serialNumber values longer than 20 octets. #> [Parameter(Mandatory=$False)] [ValidatePattern("^[0-9a-fA-F]{1,40}$")] [String] $SerialNumber, [Parameter(Mandatory=$False)] [ValidateSet("PrintableString","utf8")] [String] $SubjectEncoding = "PrintableString", [Parameter(Mandatory=$False)] [ValidateRange(-1,16)] # Should be sufficient...? RFC? [Int] $PathLength = -1, # -1 means none [Parameter(Mandatory=$False)] [Switch] $SelfSign ) begin {} process { # Ensuring the Code will be executed on a supported Operating System If ([int32](Get-WmiObject Win32_OperatingSystem).BuildNumber -lt $BUILD_NUMBER_WINDOWS_7) { Write-Error -Message "This must be executed on Windows 7/Windows Server 2008 R2 or newer!" return } # Ensuring we work with Elevation when messing with the Computer Certificate Store If ($MachineContext.IsPresent) { If (-not ( [Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Error -Message "This must be run with Elevation (Run as Administrator) when using the Machine Context!" return } } If ((-not $Dns) -and (-not $Upn) -and (-not $Email) -and (-not $IP) -and (-not $Subject)) { Write-Error -Message "You must provide an Identity, either in Form ob a Subject or Subject Alternative Name!" return } # We first create the Private Key # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509privatekey # Setting the Provider Attribute on the CertRequest Object afterwards seems not to work with Key Storage Providers...why? $PrivateKey = New-Object -ComObject 'X509Enrollment.CX509PrivateKey' $PrivateKey.ProviderName = $Ksp $PrivateKey.MachineContext = [int]($MachineContext.IsPresent) $PrivateKey.ExportPolicy = [int]($PrivateKeyExportable.IsPresent) # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/ne-certenroll-x509keyspec If ($False -eq (Get-KeyStorageProvider | Where-Object { $_.Name -eq $Ksp }).LegacyCsp) { # The intended use is not identified. This value is set if the provider that supports the key is a # Cryptography API: Next Generation (CNG) key storage provider (KSP). $PrivateKey.KeySpec = $X509KeySpec.XCN_AT_NONE } Else { # A Legacy CSP is being used # The key can be used for signing. $PrivateKey.KeySpec = $X509KeySpec.XCN_AT_SIGNATURE If (-not $CA.IsPresent) { $KeyUsage | ForEach-Object -Process { If ($_ -in ("KeyEncipherment","KeyAgreement","DataEncipherment","EncipherOnly")) { # The key can be used to encrypt (including key exchange) or sign depending on the algorithm. # For RSA algorithms, if this value is set, the key can be used for both signing and encryption. # For other algorithms, signing may not be supported. Further, only encryption for key exchange may be supported. $PrivateKey.KeySpec = $X509KeySpec.XCN_AT_KEYEXCHANGE } } } } If ($KeyAlgorithm -ne "RSA") { $Algorithm = New-Object -ComObject 'X509Enrollment.CObjectId' # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nf-certenroll-iobjectid-initializefromalgorithmname $Algorithm.InitializeFromAlgorithmName( $ObjectIdGroupId.XCN_CRYPT_PUBKEY_ALG_OID_GROUP_ID, $ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, $AlgorithmFlags.AlgorithmFlagsNone, $KeyAlgorithm ) # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nf-certenroll-ix509privatekey-put_algorithm $PrivateKey.Algorithm = $Algorithm [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($Algorithm)) } # Key Length is only relevant when Key Type is "RSA" If ($KeyAlgorithm -eq "RSA") { $PrivateKey.Length = $KeyLength } Try { $PrivateKey.Create() } Catch { [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($PrivateKey)) Write-Error -Message $PSItem.Exception.Message return } # Begin Assembling the Certificate Signing Request # https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/certificate-request-functions If (($SelfSign.IsPresent) -or ($SigningCert)) { # Enables you to create a certificate directly without applying to a certification authority (CA). $CertificateRequestPkcs10 = New-Object -ComObject 'X509Enrollment.CX509CertificateRequestCertificate' } Else { # Represents a PKCS #10 certificate request. A PKCS #10 request can be sent directly to a CA, or it can be wrapped by a PKCS #7 or CMC request. $CertificateRequestPkcs10 = New-Object -ComObject 'X509Enrollment.CX509CertificateRequestPkcs10' } $CertificateRequestPkcs10.InitializeFromPrivateKey( [int]($MachineContext.IsPresent)+1, $PrivateKey, [String]::Empty ) # Determine if we shall encode Subject and Issuer in PrintableString # (Default for AD CS, non-default for CX509CertificateRequestCertificate) or UTF-8 # This is required for matching with the CRL if you mess with a CA Key If ($SubjectEncoding -eq "PrintableString") { $SubjectEncodingFlag = $X500NameFlags.XCN_CERT_NAME_STR_DISABLE_UTF8_DIR_STR_FLAG } ElseIf ($SubjectEncoding -eq "utf8") { $SubjectEncodingFlag = $X500NameFlags.XCN_CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG } # Set Certificate Subject Name # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379394(v=vs.85).aspx Try { $SubjectDnObject = New-Object -ComObject "X509Enrollment.CX500DistinguishedName" $SubjectDnObject.Encode( $Subject, $SubjectEncodingFlag ) $CertificateRequestPkcs10.Subject = $SubjectDnObject } Catch { [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($CertificateRequestPkcs10)) [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($SubjectDnObject)) [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($PrivateKey)) Write-Error -Message "Invalid Subject Distinguished Name supplied!" return } If ($SelfSign.IsPresent) { <# https://tools.ietf.org/html/rfc5280#section-6.1 A certificate is self-issued if the same DN appears in the subject and issuer fields #> $CertificateRequestPkcs10.Issuer = $SubjectDnObject } If ($SigningCert) { # https://msdn.microsoft.com/en-us/library/windows/desktop/aa376832(v=vs.85).aspx $SignerCertificate = New-Object -ComObject 'X509Enrollment.CSignerCertificate' $SignerCertificate.Initialize( [int]($SigningCert.PSParentPath -match "Machine"), $X509PrivateKeyVerify.VerifyNone, # We did this already during Parameter Validation $EncodingType.XCN_CRYPT_STRING_BASE64, [Convert]::ToBase64String($SigningCert.RawData) ) $CertificateRequestPkcs10.SignerCertificate = $SignerCertificate # If we have a Signing Certificate, we copy its Subject to the Target Certificates Issuer $IssuerDnObject = New-Object -ComObject 'X509Enrollment.CX500DistinguishedName' # We must have the DN encoded as printableString instead of UTF-8, otherwise CRL verification will fail # During certificate chain validation (from the end entity to a trusted root) the KeyId is used to create # the certificate chain and it works independently of the subject and issuer codification (PrintableString or UTF8) # During revocation status validation, a binary comparison is made between the certificate issuer and the CRL issuer, # so both fields must use the same codification in order to match (PrintableString or UTF8) # https://social.technet.microsoft.com/Forums/windowsserver/en-US/0459983f-4f19-48ee-b099-dfd484483176/active-directory-certificate-services-cannot-verify-certificate-chain-bad-cert-issuer-base-crl?forum=winserversecurity # https://msdn.microsoft.com/en-us/library/windows/desktop/bb540814(v=vs.85).aspx # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379394(v=vs.85).aspx $IssuerDnObject.Encode( $SigningCert.Subject, $SubjectEncodingFlag ) $CertificateRequestPkcs10.Issuer = $IssuerDnObject } # These apply to all cases where a Certificate will be generated instead of a Signing Request If (($SelfSign.IsPresent) -or ($SigningCert)) { # Set Certificate Validity Period # Validity Periods are always written into the Cert as Universal Time $Now = (Get-Date).ToUniversalTime() Switch ($ValidityPeriod) { "Minutes" { $NotAfter = $Now.AddMinutes($ValidityPeriodUnits) } "Hours" { $NotAfter = $Now.AddHours($ValidityPeriodUnits) } "Days" { $NotAfter = $Now.AddDays($ValidityPeriodUnits) } "Weeks" { $NotAfter = $Now.AddWeeks($ValidityPeriodUnits) } "Months" { $NotAfter = $Now.AddMonths($ValidityPeriodUnits) } "Years" { $NotAfter = $Now.AddYears($ValidityPeriodUnits) } } # Backup $ClockSkew in Minutes (Default: 10) to avoid timing issues $CertificateRequestPkcs10.NotBefore = $Now.AddMinutes($ClockSkew * -1) $CertificateRequestPkcs10.NotAfter = $NotAfter.AddMinutes($ClockSkew) # Set Serial Number of the Certificate if specified as Argument, otherwise use a random SN If ($SerialNumber) { # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nf-certenroll-ix509certificaterequestpkcs10-initializedecode $CertificateRequestPkcs10.SerialNumber.InvokeSet( $(Convert-StringToCertificateSerialNumber -SerialNumber $SerialNumber), $EncodingType.XCN_CRYPT_STRING_BASE64 ) } } # Set the Key Usage Extension If ($CA.IsPresent) { # CA Certifcate Key Usages # Add these to the Parameters (if not $CA or look if different default Values can be applied) # https://security.stackexchange.com/questions/49229/root-certificate-key-usage-non-self-signed-end-entity # https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keyusageflags(v=vs.110).aspx # Since a CA is supposed to issue certificate and CRL, it should have, on a general basis, the keyCertSign and cRLSign flags. # These two flags are sufficient. [Security.Cryptography.X509Certificates.X509KeyUsageFlags]$KeyUsageFlags = "KeyCertSign, CrlSign" } Else { # Leaf Certificate Key Usages [Security.Cryptography.X509Certificates.X509KeyUsageFlags]$KeyUsageFlags = $KeyUsage } # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509extensionkeyusage $KeyUsageExtension = New-Object -ComObject X509Enrollment.CX509ExtensionKeyUsage $KeyUsageExtension.InitializeEncode([Int]$KeyUsageFlags) $KeyUsageExtension.Critical = $True # Add the Key Usage Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($KeyUsageExtension) # If we build a CA certificate, set Basic Constraints Extension If ($CA.IsPresent) { # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509extensionbasicconstraints $BasicConstraintsExtension = New-Object -ComObject X509Enrollment.CX509ExtensionBasicConstraints $BasicConstraintsExtension.InitializeEncode( $True, # it is a CA $PathLength ) # Only mark as critical if it is a CA certificate $BasicConstraintsExtension.Critical = $True # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($BasicConstraintsExtension) } # Set the Enhanced Key Usages Extension if specified as Argument If ($Eku) { # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509extensionenhancedkeyusage $EnhancedKeyUsageExtension = New-Object -ComObject X509Enrollment.CX509ExtensionEnhancedKeyUsage $EnhancedKeyUsageOids = New-Object -ComObject X509Enrollment.CObjectIds.1 $Eku | Sort-Object | Get-Unique | ForEach-Object -Process { $EnhancedKeyUsageOid = New-Object -ComObject X509Enrollment.CObjectId $EnhancedKeyUsageOid.InitializeFromValue($EkuNameToOidTable[$_]) $EnhancedKeyUsageOids.Add($EnhancedKeyUsageOid) } $EnhancedKeyUsageExtension.InitializeEncode($EnhancedKeyUsageOids) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($EnhancedKeyUsageExtension) } # Set the Subject Alternative Names Extension if specified as Argument If ($Upn -or $Email -or $Dns -or $IP) { # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509extensionalternativenames $SubjectAlternativeNamesExtension = New-Object -ComObject X509Enrollment.CX509ExtensionAlternativeNames $Sans = New-Object -ComObject X509Enrollment.CAlternativeNames # https://msdn.microsoft.com/en-us/library/aa374981(VS.85).aspx Foreach ($Entry in $Upn) { $AlternativeNameObject = New-Object -ComObject X509Enrollment.CAlternativeName $AlternativeNameObject.InitializeFromString( $AlternativeNameType.XCN_CERT_ALT_NAME_USER_PRINCIPLE_NAME, $Entry ) $Sans.Add($AlternativeNameObject) [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($AlternativeNameObject)) } Foreach ($Entry in $Email) { $AlternativeNameObject = New-Object -ComObject X509Enrollment.CAlternativeName $AlternativeNameObject.InitializeFromString( $AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, $Entry ) $Sans.Add($AlternativeNameObject) [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($AlternativeNameObject)) } Foreach ($Entry in $Dns) { $AlternativeNameObject = New-Object -ComObject X509Enrollment.CAlternativeName $AlternativeNameObject.InitializeFromString( $AlternativeNameType.XCN_CERT_ALT_NAME_DNS_NAME, $Entry ) $Sans.Add($AlternativeNameObject) [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($AlternativeNameObject)) } Foreach ($Entry in $IP) { $AlternativeNameObject = New-Object -ComObject X509Enrollment.CAlternativeName $AlternativeNameObject.InitializeFromRawData( $AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, $EncodingType.XCN_CRYPT_STRING_BASE64, [Convert]::ToBase64String($Entry.GetAddressBytes()) ) $Sans.Add($AlternativeNameObject) [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($AlternativeNameObject)) } $SubjectAlternativeNamesExtension.Critical = $True $SubjectAlternativeNamesExtension.InitializeEncode($Sans) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($SubjectAlternativeNamesExtension) } # Set the S/MIME Capabilities Extension if specified as Argument If ($Smime) { # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509extensionsmimecapabilities $SmimeExtension = New-Object -ComObject X509Enrollment.CX509ExtensionSmimeCapabilities # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ismimecapabilities $SmimeCapabilitiesObject = New-Object -ComObject X509Enrollment.CSmimeCapabilities $Smime | ForEach-Object -Process { # The Bit length is only relevant for RC2 and RC4. We use the same defaults as Microsoft does. If ($_ -in ("rc2","rc2wrap","rc4")) { $BitCount = 128 } Else { $BitCount = 0 } $OidObject = New-Object -ComObject X509Enrollment.CObjectId $OidObject.InitializeFromValue($SmimeCapabilityToOidTable[$_]) # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nf-certenroll-ismimecapability-initialize $SmimeCapabilityObject = New-Object -ComObject X509Enrollment.CSmimeCapability $SmimeCapabilityObject.Initialize( $OidObject, $BitCount ) $SmimeCapabilitiesObject.Add($SmimeCapabilityObject) } $SmimeExtension.InitializeEncode($SmimeCapabilitiesObject) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($SmimeExtension) } # Set the Authority Key Identifier Extension if specified as Argument If ($Aki) { # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509extensionauthoritykeyidentifier $AkiExtension = New-Object -ComObject X509Enrollment.CX509ExtensionAuthorityKeyIdentifier # https://docs.microsoft.com/en-us/windows/desktop/api/certenroll/nf-certenroll-ix509extensionauthoritykeyidentifier-initializeencode $AkiExtension.InitializeEncode( $EncodingType.XCN_CRYPT_STRING_BASE64, $(Convert-DERToBASE64 -String $Aki) ) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($AkiExtension) } # Set the szOID_NTDS_CA_SECURITY_EXT if specified as argument If ($Sid) { $SidExtension = New-Object -ComObject X509Enrollment.CX509Extension $SidExtensionOid = New-Object -ComObject X509Enrollment.CObjectId $SidExtensionOid.InitializeFromValue($Oid.szOID_NTDS_CA_SECURITY_EXT) $SidExtension.Critical = $False # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378511(v=vs.85).aspx $SidExtension.Initialize( $SidExtensionOid, $EncodingType.XCN_CRYPT_STRING_BASE64, $(New-SidExtension -Sid $Sid) ) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($SidExtension) } # Set the CRL Distribution Points Extension if specified as Argument If ($Cdp) { # No Interface for this OID, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa378077(v=vs.85).aspx # Therefore, we will build the data by hand (Function New-CdpExtension) $CdpExtension = New-Object -ComObject X509Enrollment.CX509Extension $CdpExtensionOid = New-Object -ComObject X509Enrollment.CObjectId $CdpExtensionOid.InitializeFromValue($Oid.XCN_OID_CRL_DIST_POINTS) $CdpExtension.Critical = $False # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378511(v=vs.85).aspx $CdpExtension.Initialize( $CdpExtensionOid, $EncodingType.XCN_CRYPT_STRING_BASE64, $(New-CdpExtension -Url $Cdp) ) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($CdpExtension) } # Set the Authority Information Access Extension if specified as Argument If ($Aia) { # No Interface for this OID, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa378077(v=vs.85).aspx # Therefore, we will build the data by hand (Function New-AiaExtension) $AiaExtension = New-Object -ComObject X509Enrollment.CX509Extension $AiaExtensionOid = New-Object -ComObject X509Enrollment.CObjectId $AiaExtensionOid.InitializeFromValue($Oid.XCN_OID_AUTHORITY_INFO_ACCESS) $AiaExtension.Critical = $False # https://msdn.microsoft.com/en-us/library/windows/desktop/aa378511(v=vs.85).aspx $AiaExtension.Initialize( $AiaExtensionOid, $EncodingType.XCN_CRYPT_STRING_BASE64, $(New-AiaExtension -Url $Aia) ) # Adding the Extension to the Certificate $CertificateRequestPkcs10.X509Extensions.Add($AiaExtension) } # Specifying the Hashing Algorithm to use for the Request / the Certificate # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-iobjectid $HashAlgorithmObject = New-Object -ComObject X509Enrollment.CObjectId $HashAlgorithmObject.InitializeFromAlgorithmName( $ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID, $ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, $AlgorithmFlags.AlgorithmFlagNone, $SignatureHashAlgorithm ) $CertificateRequestPkcs10.HashAlgorithm = $HashAlgorithmObject # Encoding the Certificate Signing Request Try { $CertificateRequestPkcs10.Encode() } Catch { Write-Error -Message $PSItem.Exception.Message return } # Building the Certificate Request # https://docs.microsoft.com/en-us/windows/win32/api/certenroll/nn-certenroll-ix509enrollment $EnrollmentObject = New-Object -ComObject 'X509Enrollment.CX509Enrollment' $EnrollmentObject.InitializeFromRequest($CertificateRequestPkcs10) $CertificateRequest = $EnrollmentObject.CreateRequest($EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER) # Either presenting the CSR, or signing ist as a Certificate If (($SelfSign.IsPresent) -or ($SigningCert)) { # Signing the Certificate $EnrollmentObject.InstallResponse( $InstallResponseRestrictionFlags.AllowUntrustedCertificate, $CertificateRequest, $EncodingType.XCN_CRYPT_STRING_BASE64REQUESTHEADER, [String]::Empty # No Password ) # We load the Certificate into an X509Certificate2 Object so that we can call Certificate Properties $CertificateObject = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertificateObject.Import([Convert]::FromBase64String($EnrollmentObject.Certificate())) # Return the resulting Certificate If ($MachineContext.IsPresent) { Get-ChildItem -Path "Cert:\LocalMachine\My\$($CertificateObject.Thumbprint)" } Else { Get-ChildItem -Path "Cert:\CurrentUser\My\$($CertificateObject.Thumbprint)" } } Else { # Return the Certificate Signing Request $CertificateRequest } # Cleaning up the COM Objects, avoiding any User Errors to be reported $CertificateRequestPkcs10, $SubjectDnObject, $PrivateKey, $SignerCertificate, $IssuerDnObject, $BasicConstraintsExtension, $EnhancedKeyUsageExtension, $EnhancedKeyUsageOids, $EnhancedKeyUsageOid, $SubjectAlternativeNamesExtension, $Sans, $AlternativeNameObject, $AkiExtension, $CdpExtension, $CdpExtensionOid, $AiaExtension, $AiaExtensionOid, $HashAlgorithmObject, $EnrollmentObject | ForEach-Object -Process { Try { [void]([System.Runtime.Interopservices.Marshal]::ReleaseComObject($_)) } Catch { # we don't want to return anything here } } } end {} } # SIG # Begin signature block # MIIk6gYJKoZIhvcNAQcCoIIk2zCCJNcCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBAylO26b/MoNrl # 0zre8RpGD0+WE8rsokraj8iasqkf5KCCHqwwggVAMIIEKKADAgECAhEAjyqX/F4u # bPBaKM2QGtlbKTANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJHQjEbMBkGA1UE # CBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQK # Ew9TZWN0aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUgU2ln # bmluZyBDQTAeFw0yMDExMjAwMDAwMDBaFw0yMzExMjAyMzU5NTlaMIGHMQswCQYD # VQQGEwJERTEOMAwGA1UEEQwFOTE2MDIxHTAbBgNVBAcMFETDvHJyd2FuZ2VuIEhh # bHNiYWNoMRUwEwYDVQQJDAxXZWloZXJ3ZWcgMTUxGDAWBgNVBAoMD1V3ZSBHcmFk # ZW5lZ2dlcjEYMBYGA1UEAwwPVXdlIEdyYWRlbmVnZ2VyMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA53wYl/2oLVZBtzGBVrhekovOH+jLXaqR8bcrXUEt # GzZS5mhld6V58oliKsdanM2WGRtGga/ew1QKAqlEO3LPWQd/6O+T6ewH1IJy0xxy # Zv3zsEDySr+2iAZaOqUdxAV8ROuW/fPGJCR3nrRO2vH047z+aAi9S5sZbiO21634 # BRXw94cl4JArB62gSfehtyCqO5oBLjWdz9/41pfrCQPyIoalfL4Ksdt+WEAJqy9T # JyEF/8GWbGxko/yx/p1k03QjtNT2SM7kDw2JYCnsn2hPPS18q4ca6sZqqUAxBQl0 # P1E0POzP4I3XD8uNuSF8lrCegjxdHuDycgE4fZ1/5giY9QIDAQABo4IBrzCCAasw # HwYDVR0jBBgwFoAUDuE6qFM6MdWKvsG7rWcaA4WtNA4wHQYDVR0OBBYEFCmcAsJF # JdY/qAsyvvsYLFw96N2aMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBKBgNVHSAEQzBB # MDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28u # Y29tL0NQUzAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5z # ZWN0aWdvLmNvbS9TZWN0aWdvUlNBQ29kZVNpZ25pbmdDQS5jcmwwcwYIKwYBBQUH # AQEEZzBlMD4GCCsGAQUFBzAChjJodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3Rp # Z29SU0FDb2RlU2lnbmluZ0NBLmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Au # c2VjdGlnby5jb20wHQYDVR0RBBYwFIESdXdlQGdyYWRlbmVnZ2VyLmV1MA0GCSqG # SIb3DQEBCwUAA4IBAQCEQ6MLH2xJoylM/1EVGcnHx1yfR4N0KTpMZmUHeDKHbhVa # 75UQJRd3/Wy9knpqk8NGnPaS8XNOUgR8A5EoO5djvZfp4JLtUVOM28TI0U+avrtP # olQHtCRrpb12kCqG5/E5DQNFL9qTK0/cngkXQFiJncjF+AAfWOL+5e4zIPWMVJaw # PKFIyT47S6BjD5NopviPxcJY3uQ3y5WFqpeYMWL1cpMpC26tvEQbecJLGW51m3l8 # MiaPtxieiuEje8YplJdBOOBDVO+NTJvhiOhOhM2Nnp/PcdqYAuiLpAcv2ekcHp6Q # svBWxRbwb23mjni1DipueBqn98FCTQkNDQLb6KRuMIIFgTCCBGmgAwIBAgIQOXJE # Ovkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7MQswCQYDVQQGEwJHQjEbMBkG # A1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYD # VQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRl # IFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4MTIzMTIzNTk1OVowgYgxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkg # Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVV # U0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sIs9CsVw127c0n00ytUINh4qog # TQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnGvDoZtF+mvX2do2NCtnbyqTsr # kfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQIjy8/hPwhxR79uQfjtTkUcYR # Z0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfbIWax1Jt4A8BQOujM8Ny8nkz+ # rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0tyA9yn8iNK5+O2hmAUTnAU5G # U5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97Exwzf4TKuzJM7UXiVZ4vuPVb+ # DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNVicQNwZNUMBkTrNN9N6frXTps # NVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5D9kCnusSTJV882sFqV4Wg8y4 # Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJWBp/kjbmUZIO8yZ9HE0XvMns # QybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ5lhCLkMaTLTwJUdZ+gQek9Qm # RkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzGKAgEJTm4Diup8kyXHAc/DVL1 # 7e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSgEQojPpbxB+zirynvgqV/0DCk # tDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgGG # MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEMGA1UdHwQ8MDow # OKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0FBQUNlcnRpZmljYXRlU2Vy # dmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUAA4IBAQAYh1HcdCE9nIrgJ7cz # 0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+rvSNb3I8QzvAP+u431yqqcau # 8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+/czSAaF9ffgZGclCKxO/WIu6 # pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gACiIDEOUMsfnNkjcZ7Tvx5Dq2 # +UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1FzZOFli9d31kWTz9RvdVFGD/t # So7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyAvGp4z7h/jnZymQyd/teRCBah # o1+VMIIF9TCCA92gAwIBAgIQHaJIMG+bJhjQguCWfTPTajANBgkqhkiG9w0BAQwF # ADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcT # C0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAs # BgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcN # MTgxMTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjB8MQswCQYDVQQGEwJHQjEbMBkG # A1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUg # U2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIYijTKF # ehifSfCWL2MIHi3cfJ8Uz+MmtiVmKUCGVEZ0MWLFEO2yhyemmcuVMMBW9aR1xqkO # UGKlUZEQauBLYq798PgYrKf/7i4zIPoMGYmobHutAMNhodxpZW0fbieW15dRhqb0 # J+V8aouVHltg1X7XFpKcAC9o95ftanK+ODtj3o+/bkxBXRIgCFnoOc2P0tbPBrRX # BbZOoT5Xax+YvMRi1hsLjcdmG0qfnYHEckC14l/vC0X/o84Xpi1VsLewvFRqnbyN # VlPG8Lp5UEks9wO5/i9lNfIi6iwHr0bZ+UYc3Ix8cSjz/qfGFN1VkW6KEQ3fBiSV # fQ+noXw62oY1YdMCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFFN5v1qqK0rPVIDh # 2JvAnfKyA2bLMB0GA1UdDgQWBBQO4TqoUzox1Yq+wbutZxoDha00DjAOBgNVHQ8B # Af8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEFBQcD # AwYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGG # P2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0 # aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0 # dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNy # dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG # 9w0BAQwFAAOCAgEATWNQ7Uc0SmGk295qKoyb8QAAHh1iezrXMsL2s+Bjs/thAIia # G20QBwRPvrjqiXgi6w9G7PNGXkBGiRL0C3danCpBOvzW9Ovn9xWVM8Ohgyi33i/k # lPeFM4MtSkBIv5rCT0qxjyT0s4E307dksKYjalloUkJf/wTr4XRleQj1qZPea3FA # mZa6ePG5yOLDCBaxq2NayBWAbXReSnV+pbjDbLXP30p5h1zHQE1jNfYw08+1Cg4L # BH+gS667o6XQhACTPlNdNKUANWlsvp8gJRANGftQkGG+OY96jk32nw4e/gdREmaD # JhlIlc5KycF/8zoFm/lv34h/wCOe0h5DekUxwZxNqfBZslkZ6GqNKQQCd3xLS81w # vjqyVVp4Pry7bwMQJXcVNIr5NsxDkuS6T/FikyglVyn7URnHoSVAaoRXxrKdsbwc # Ctp8Z359LukoTBh+xHsxQXGaSynsCz1XUNLK3f2eBVHlRHjdAd6xdZgNVCT98E7j # 4viDvXK6yz067vBeF5Jobchh+abxKgoLpbn0nu6YMgWFnuv5gynTxix9vTp3Los3 # QqBqgu07SqqUEKThDfgXxbZaeTMYkuO1dfih6Y4KJR7kHvGfWocj/5+kUZ77OYAR # zdu1xKeogG/lU9Tg46LC0lsa+jImLWpXcBw8pFguo/NbSwfcMlnzh6cabVgwggbs # MIIE1KADAgECAhAwD2+s3WaYdHypRjaneC25MA0GCSqGSIb3DQEBDAUAMIGIMQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5 # IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEuMCwGA1UEAxMl # VVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xOTA1MDIw # MDAwMDBaFw0zODAxMTgyMzU5NTlaMH0xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJH # cmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1Nl # Y3RpZ28gTGltaXRlZDElMCMGA1UEAxMcU2VjdGlnbyBSU0EgVGltZSBTdGFtcGlu # ZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMgbAa/ZLH6ImX0B # mD8gkL2cgCFUk7nPoD5T77NawHbWGgSlzkeDtevEzEk0y/NFZbn5p2QWJgn71TJS # eS7JY8ITm7aGPwEFkmZvIavVcRB5h/RGKs3EWsnb111JTXJWD9zJ41OYOioe/M5Y # SdO/8zm7uaQjQqzQFcN/nqJc1zjxFrJw06PE37PFcqwuCnf8DZRSt/wflXMkPQEo # vA8NT7ORAY5unSd1VdEXOzQhe5cBlK9/gM/REQpXhMl/VuC9RpyCvpSdv7QgsGB+ # uE31DT/b0OqFjIpWcdEtlEzIjDzTFKKcvSb/01Mgx2Bpm1gKVPQF5/0xrPnIhRfH # uCkZpCkvRuPd25Ffnz82Pg4wZytGtzWvlr7aTGDMqLufDRTUGMQwmHSCIc9iVrUh # cxIe/arKCFiHd6QV6xlV/9A5VC0m7kUaOm/N14Tw1/AoxU9kgwLU++Le8bwCKPRt # 2ieKBtKWh97oaw7wW33pdmmTIBxKlyx3GSuTlZicl57rjsF4VsZEJd8GEpoGLZ8D # Xv2DolNnyrH6jaFkyYiSWcuoRsDJ8qb/fVfbEnb6ikEk1Bv8cqUUotStQxykSYtB # ORQDHin6G6UirqXDTYLQjdprt9v3GEBXc/Bxo/tKfUU2wfeNgvq5yQ1TgH36tjlY # Mu9vGFCJ10+dM70atZ2h3pVBeqeDAgMBAAGjggFaMIIBVjAfBgNVHSMEGDAWgBRT # eb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUGqH4YRkgD8NBd0UojtE1XwYS # BFUwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwEwYDVR0lBAww # CgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGG # P2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0 # aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0 # dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNy # dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG # 9w0BAQwFAAOCAgEAbVSBpTNdFuG1U4GRdd8DejILLSWEEbKw2yp9KgX1vDsn9Fqg # uUlZkClsYcu1UNviffmfAO9Aw63T4uRW+VhBz/FC5RB9/7B0H4/GXAn5M17qoBwm # WFzztBEP1dXD4rzVWHi/SHbhRGdtj7BDEA+N5Pk4Yr8TAcWFo0zFzLJTMJWk1vSW # Vgi4zVx/AZa+clJqO0I3fBZ4OZOTlJux3LJtQW1nzclvkD1/RXLBGyPWwlWEZuSz # xWYG9vPWS16toytCiiGS/qhvWiVwYoFzY16gu9jc10rTPa+DBjgSHSSHLeT8AtY+ # dwS8BDa153fLnC6NIxi5o8JHHfBd1qFzVwVomqfJN2Udvuq82EKDQwWli6YJ/9Gh # lKZOqj0J9QVst9JkWtgqIsJLnfE5XkzeSD2bNJaaCV+O/fexUpHOP4n2HKG1qXUf # cb9bQ11lPVCBbqvw0NP8srMftpmWJvQ8eYtcZMzN7iea5aDADHKHwW5NWtMe6vBE # 5jJvHOsXTpTDeGUgOw9Bqh/poUGd/rG4oGUqNODeqPk85sEwu8CgYyz8XBYAqNDE # f+oRnR4GxqZtMl20OAkrSQeq/eww2vGnL8+3/frQo4TZJ577AWZ3uVYQ4SBuxq6x # +ba6yDVdM3aO8XwgDCp3rrWiAoa6Ke60WgCxjKvj+QrJVF3UuWp0nr1Irpgwggb2 # MIIE3qADAgECAhEAkDl/mtJKOhPyvZFfCDipQzANBgkqhkiG9w0BAQwFADB9MQsw # CQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQH # EwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNVBAMTHFNl # Y3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0EwHhcNMjIwNTExMDAwMDAwWhcNMzMw # ODEwMjM1OTU5WjBqMQswCQYDVQQGEwJHQjETMBEGA1UECBMKTWFuY2hlc3RlcjEY # MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSwwKgYDVQQDDCNTZWN0aWdvIFJTQSBU # aW1lIFN0YW1waW5nIFNpZ25lciAjMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC # AgoCggIBAJCycT954dS5ihfMw5fCkJRy7Vo6bwFDf3NaKJ8kfKA1QAb6lK8KoYO2 # E+RLFQZeaoogNHF7uyWtP1sKpB8vbH0uYVHQjFk3PqZd8R5dgLbYH2DjzRJqiB/G # /hjLk0NWesfOA9YAZChWIrFLGdLwlslEHzldnLCW7VpJjX5y5ENrf8mgP2xKrdUA # T70KuIPFvZgsB3YBcEXew/BCaer/JswDRB8WKOFqdLacRfq2Os6U0R+9jGWq/fzD # POgNnDhm1fx9HptZjJFaQldVUBYNS3Ry7qAqMfwmAjT5ZBtZ/eM61Oi4QSl0AT8N # 4BN3KxE8+z3N0Ofhl1tV9yoDbdXNYtrOnB786nB95n1LaM5aKWHToFwls6UnaKNY # /fUta8pfZMdrKAzarHhB3pLvD8Xsq98tbxpUUWwzs41ZYOff6Bcio3lBYs/8e/OS # 2q7gPE8PWsxu3x+8Iq+3OBCaNKcL//4dXqTz7hY4Kz+sdpRBnWQd+oD9AOH++DrU # w167aU1ymeXxMi1R+mGtTeomjm38qUiYPvJGDWmxt270BdtBBcYYwFDk+K3+rGNh # R5G8RrVGU2zF9OGGJ5OEOWx14B0MelmLLsv0ZCxCR/RUWIU35cdpp9Ili5a/xq3g # vbE39x/fQnuq6xzp6z1a3fjSkNVJmjodgxpXfxwBws4cfcz7lhXFAgMBAAGjggGC # MIIBfjAfBgNVHSMEGDAWgBQaofhhGSAPw0F3RSiO0TVfBhIEVTAdBgNVHQ4EFgQU # JS5oPGuaKyQUqR+i3yY6zxSm8eAwDgYDVR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQC # MAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwSgYDVR0gBEMwQTA1BgwrBgEEAbIx # AQIBAwgwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYG # Z4EMAQQCMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwuc2VjdGlnby5jb20v # U2VjdGlnb1JTQVRpbWVTdGFtcGluZ0NBLmNybDB0BggrBgEFBQcBAQRoMGYwPwYI # KwYBBQUHMAKGM2h0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1JTQVRpbWVT # dGFtcGluZ0NBLmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5j # b20wDQYJKoZIhvcNAQEMBQADggIBAHPa7Whyy8K5QKExu7QDoy0UeyTntFsVfajp # /a3Rkg18PTagadnzmjDarGnWdFckP34PPNn1w3klbCbojWiTzvF3iTl/qAQF2jTD # FOqfCFSr/8R+lmwr05TrtGzgRU0ssvc7O1q1wfvXiXVtmHJy9vcHKPPTstDrGb4V # LHjvzUWgAOT4BHa7V8WQvndUkHSeC09NxKoTj5evATUry5sReOny+YkEPE7jghJi # 67REDHVBwg80uIidyCLxE2rbGC9ueK3EBbTohAiTB/l9g/5omDTkd+WxzoyUbNsD # bSgFR36bLvBk+9ukAzEQfBr7PBmA0QtwuVVfR745ZM632iNUMuNGsjLY0imGyRVd # gJWvAvu00S6dOHw14A8c7RtHSJwialWC2fK6CGUD5fEp80iKCQFMpnnyorYamZTr # lyjhvn0boXztVoCm9CIzkOSEU/wq+sCnl6jqtY16zuTgS6Ezqwt2oNVpFreOZr9f # +h/EqH+noUgUkQ2C/L1Nme3J5mw2/ndDmbhpLXxhL+2jsEn+W75pJJH/k/xXaZJL # 2QU/bYZy06LQwGTSOkLBGgP70O2aIbg/r6ayUVTVTMXKHxKNV8Y57Vz/7J8mdq1k # ZmfoqjDg0q23fbFqQSduA4qjdOCKCYJuv+P2t7yeCykYaIGhnD9uFllLFAkJmuau # v2AV3Yb1MYIFlDCCBZACAQEwgZEwfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy # ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2Vj # dGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcg # Q0ECEQCPKpf8Xi5s8FoozZAa2VspMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQB # gjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICX6gqW2 # rtqdv4Z+qlNdaimNqyaQWL5g/CWeRaXSzgJuMA0GCSqGSIb3DQEBAQUABIIBABvd # zLySU9sW9EXmGgVcJr1Fj/PasCHo/GtMV4sIQYQXLQXP62n34jesHridjnrbSL/o # V4Xc5hYIfyaNaJOtDF08kkZDXNVmU3NBLM3ESdk9StNp92Jhc8I6cZzJpZBSmcdS # WFakWBmQHWR7xCkdZQPiNBpfxV+tMyb6Po9oN+uIQ198tXtgTuTfQhs7jtaHYdRf # EgGDJ6f/oTmIcNhou8Ug5Jn7y0uIswOp1MEqV16h20ZLNx8yd3LlIFbDpaRPUSqs # g4d4qn8/MB8GATcYgHHrN86K3C2ms7uEtrG338A5eSpxHGP4oUXgrXGhm1ydxANy # BDjpkdbQEEWn529rhcihggNMMIIDSAYJKoZIhvcNAQkGMYIDOTCCAzUCAQEwgZIw # fTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G # A1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSUwIwYDVQQD # ExxTZWN0aWdvIFJTQSBUaW1lIFN0YW1waW5nIENBAhEAkDl/mtJKOhPyvZFfCDip # QzANBglghkgBZQMEAgIFAKB5MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ # KoZIhvcNAQkFMQ8XDTIyMTIxMzE5MDIxNFowPwYJKoZIhvcNAQkEMTIEMFC672+D # 113u7D5y3xEYScL3QoNIpyAt7xa/fJfOMDQGGn4Bdo7GNaRlRxEDq+09QjANBgkq # hkiG9w0BAQEFAASCAgAcGxJRehsc4BHZkltI+s7/coQpi0ev/ALWvMGOBq/W0fwW # Cptfp++KksU1e7t7pKWF+K6+ZoCsXdI74oIMuJk0wk4Mg54i2NJ4w58X92wyqvSD # 9iB9wtO1b80Pku8o0U3E3DsOLhX2NXqm2PTJiZGiDwxr5lmRLae0kPgK8BgKDNxK # E9qF4mbcNxdhjtuLqAl0q0/j77H0Ygt1RvQAA3qLONjqzcKLfTiq0VpPo9ID3+xZ # rZalB9rsb53Y6LuZWU5mUP/PvDepUSxOG80sD3vI4t8wMkMnyrHW1HEzwxphwWnv # cppezMNhCTRnt1YerOqEYiNxeshAzWmOsbN4CAU/EHCQdRhZV6xPnrqJgCwudYRL # I4tcNLIZ6buWSGw3arlqVZ5shooSFrgLFPBiEniUcABubG9nXm1PObSMDI93yXCR # R8UHLCBekm0SxXBQOzuYrH4YvNSMEZYzTRbLTtnt1rPIxD8nbZm1VKxUzUb5uSmn # kw2sO6BK0OVdXKSxsxbhYTqQXJnjYYFuQW1globDbh7rcRci0d+WUMDRH9MTtGFW # N4iDtTyGdSI/+gKnxIVK1nYI4slHt+KXy3NQVqBtUaVHgU6kKvBsYEqjbiumdLP7 # eZCN2B9O6IOnzYm5VWaEwOBQPDzxTmL2rX46x2zZs5F+vJRVzpjmXcWU2CyKqQ== # SIG # End signature block |