Public/Import-VcCertificate.ps1
function Import-VcCertificate { <# .SYNOPSIS Import one or more certificates .DESCRIPTION Import one or more certificates and their private keys. Currently PKCS #8 and PKCS #12 (.pfx or .p12) are supported. .PARAMETER Path Path to a certificate file. Provide either this or -Data. .PARAMETER Data Contents of a certificate/key to import. Provide either this or -Path. .PARAMETER Pkcs8 Provided -Data is in PKCS #8 format .PARAMETER Pkcs12 Provided -Data is in PKCS #12 format .PARAMETER PrivateKeyPassword Password the private key was encrypted with .PARAMETER ThrottleLimit Limit the number of threads when running in parallel; the default is 10. Applicable to PS v7+ only. 100 keystores will be imported at a time so it's less important to have a very high throttle limit. .PARAMETER VenafiSession Authentication for the function. The value defaults to the script session object $VenafiSession created by New-VenafiSession. A TLSPC key can also provided. .EXAMPLE Import-VcCertificate -CertificatePath c:\www.VenafiPS.com.pfx Import a certificate/key .EXAMPLE $p12 = Export-VdcCertificate -Path '\ved\policy\my.cert.com' -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' $p12 | Import-VcCertificate -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' -VenafiSession $vaas_key Export from TLSPDC and import into TLSPC. As $VenafiSession can only point to one platform at a time, in this case TLSPDC, the session needs to be overridden for the import. .EXAMPLE $p12 = Find-VdcCertificate -Path '\ved\policy\certs' -Recursive | Export-VdcCertificate -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' $p12 | Import-VcCertificate -Pkcs12 -PrivateKeyPassword 'myPassw0rd!' -VenafiSession $vaas_key Bulk export from TLSPDC and import into TLSPC. As $VenafiSession can only point to one platform at a time, in this case TLSPDC, the session needs to be overridden for the import. .INPUTS Path, Data .LINK https://developer.venafi.com/tlsprotectcloud/reference/certificates_import .NOTES This function requires the use of sodium encryption. .net standard 2.0 or greater is required via PS Core (recommended) or supporting .net runtime. On Windows, the latest Visual C++ redist must be installed. See https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist. #> [CmdletBinding(DefaultParameterSetName = 'ByFile')] [Alias('Import-VaasCertificate')] param ( [Parameter(Mandatory, ParameterSetName = 'ByFile', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidateScript( { if ( -not (Test-Path -Path (Resolve-Path -Path $_) -PathType Leaf) ) { throw "'$_' is not a valid file path" } if ([System.IO.Path]::GetExtension((Resolve-Path -Path $_)) -notin '.pfx', '.p12') { throw "$_ is not a .p12 or .pfx file" } $true })] [Alias('FullName', 'CertificatePath')] [String] $Path, [Parameter(Mandatory, ParameterSetName = 'Pkcs12', ValueFromPipelineByPropertyName)] [Parameter(Mandatory, ParameterSetName = 'Pkcs8', ValueFromPipelineByPropertyName)] [AllowNull()] [AllowEmptyString()] [Alias('CertificateData')] [String] $Data, [Parameter(Mandatory, ParameterSetName = 'Pkcs12')] [switch] $Pkcs12, [Parameter(Mandatory, ParameterSetName = 'Pkcs8')] [switch] $Pkcs8, [Parameter(Mandatory)] [ValidateScript( { if ( $_ -is [string] -or $_ -is [securestring] -or $_ -is [pscredential] ) { $true } else { throw 'Unsupported type. Provide either a String, SecureString, or PSCredential.' } } )] [psobject] $PrivateKeyPassword, [Parameter()] [int32] $ThrottleLimit = 10, [Parameter()] [psobject] $VenafiSession ) begin { Test-VenafiSession -VenafiSession $VenafiSession -Platform 'VC' Initialize-PSSodium $vSat = Get-VcData -Type 'VSatellite' -First if ( -not $vSat ) { throw 'No active VSatellites were found' } $pkPassString = $PrivateKeyPassword | ConvertTo-PlaintextString $allCerts = [System.Collections.Generic.List[hashtable]]::new() } process { if ( $PSBoundParameters.ContainsKey('Path') ) { $thisCertPath = Resolve-Path -Path $Path switch ([System.IO.Path]::GetExtension($thisCertPath)) { { $_ -in '.pfx', '.p12' } { $format = 'Pkcs12' } } if ($PSVersionTable.PSVersion.Major -lt 6) { $cert = Get-Content $thisCertPath -Encoding Byte } else { $cert = Get-Content $thisCertPath -AsByteStream } $allCerts.Add(@{ 'CertData' = [System.Convert]::ToBase64String($cert) 'Format' = $format } ) } else { # check if Data exists since we allow null/empty in case piping from another function and data is not there if ( $Data ) { $addMe = @{ 'Format' = $PSCmdlet.ParameterSetName } switch ($PSCmdlet.ParameterSetName) { 'Pkcs12' { $addMe.'CertData' = $Data -replace "`r|`n|-----BEGIN CERTIFICATE-----|-----END CERTIFICATE-----" } 'Pkcs8' { $splitData = Split-CertificateData -CertificateData $Data $addMe.CertPem = $splitData.CertPem if ( $splitData.KeyPem ) { $addMe.KeyPem = $splitData.KeyPem } } } $allCerts.Add($addMe) } } } end { $importList = [System.Collections.Generic.List[hashtable]]::new() $dekEncryptedPassword = ConvertTo-SodiumEncryptedString -Text $pkPassString -PublicKey $vSat.encryptionKey # rebuild invoke params as the payload can contain multiple keys at once # max 100 keys at a time for ($i = 0; $i -lt $allCerts.Count; $i += 100) { $params = @{ Method = 'post' UriRoot = 'outagedetection/v1' UriLeaf = 'certificates/imports' Body = @{ 'edgeInstanceId' = $vSat.vsatelliteId 'encryptionKeyId' = $vSat.encryptionKeyId } VenafiSession = $VenafiSession } $keystores = foreach ($thisCert in $allCerts[$i..($i + 99)]) { switch ($allCerts[$i].Format) { 'Pkcs12' { @{ 'pkcs12Keystore' = $thisCert.CertData 'dekEncryptedPassword' = $dekEncryptedPassword } } 'Pkcs8' { $thisKeystore = @{ 'certificate' = $thisCert.CertPem 'dekEncryptedPassword' = $dekEncryptedPassword } if ( $thisCert.KeyPem ) { $thisKeystore.passwordEncryptedPrivateKey = $thisCert.KeyPem } $thisKeystore } } } $params.Body.importInformation = @($keystores) $importList.Add($params) } $sb = { $params = $PSItem $requestResponse = Invoke-VenafiRestMethod @params do { Write-Verbose "checking job status for id $($requestResponse.id)" $jobResponse = invoke-VenafiRestMethod -UriRoot 'outagedetection/v1' -UriLeaf "certificates/imports/$($requestResponse.id)" Start-Sleep 2 } until ( $jobResponse.status -in 'COMPLETED', 'FAILED' ) if ( $jobResponse.status -eq 'COMPLETED' ) { $jobResponse.results } else { # importing only 1 keycert that fails does not give us any results to return to the user :( throw 'Import failed' } } $invokeParams = @{ InputObject = $importList ScriptBlock = $sb ThrottleLimit = $ThrottleLimit ProgressTitle = 'Importing certificates' } $invokeResponse = Invoke-VenafiParallel @invokeParams $invokeResponse | Select-Object -Property fingerprint, status, reason } } # SIG # Begin signature block # MIIhigYJKoZIhvcNAQcCoIIhezCCIXcCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCChheQA57xMfWiy # U9io3Mv/jcwky+C7ZFoXHajcgc2ep6CCGokwggd8MIIFZKADAgECAhAEskBM6tH3 # agmQID1jirpbMA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQK # Ew5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBD # b2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjMwOTEzMDAw # MDAwWhcNMjQwOTEyMjM1OTU5WjCBgzELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0 # YWgxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MRUwEwYDVQQKEwxWZW5hZmksIElu # Yy4xHjAcBgNVBAsTFVByb2Zlc3Npb25hbCBTZXJ2aWNlczEVMBMGA1UEAxMMVmVu # YWZpLCBJbmMuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz2ga2w0N # HzoqK1Npwmce0q2VZkosMIa4Mw4eFhDZiSlaWWwXbWKBEQVEEnd/mPlmOMv2jwBE # PaBdTzX4bp5A4gr2Nwpw2Hjr9nsfBuuMNVkCCimXdjqbLhiyU0obIYk+5EMH0Lnw # n1AupTbjtj63kqs7ZDfLRVq6jUtGJVdfDKBrIAjymePXi58G1991J6i8og3vKhhO # 97sWciGXLblirUFNMpZpK32UrHr2QklIqhSo1ucvTT7x8EFW5P33z2eniQCDvssE # UsV7vDdc4zll2io+B1j7vVOicLG+P8Jxhjy13seKsmAXSwfID51tWO3V2SfEZE2x # fuxRN9bLOdXyB9808ifIAyxLmz36Kq7kaX/LQ6eGeVDwbnvdAUoUcCKYGK7FPYQh # J0ZnxtXJRKfQU4rLaZItVtnJbPfXGJX1aXJY10fKZSvnEfYRrcb6pMVFxCyAMoZE # U3XSg9bS0oc9fg+FTjknczyXFjMD97PZW8GcLAXWSukbstyzSHvh0Nh3tyGyXPyy # +yGxMqAw6elop3FcG1sq6Ri9gSNA+oCzD2VfwoKpPJnomLDGrYuCYM/U1WG2hi/z # gnhn/Lu/e8FKTkI8ZRhVB1Yfv4VgrxGSx0WBI+4WB6Bwi6LjVmSuasJZ0Oobl7ik # 59nkseYc885U5bjgWZrUbXhfw34lUrVkfMkCAwEAAaOCAgMwggH/MB8GA1UdIwQY # MBaAFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB0GA1UdDgQWBBSoGeI5UP36z1PFpV0W # 4oYJNTGVKDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRw # Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM # MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI # QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex # LmNybDCBlAYIKwYBBQUHAQEEgYcwgYQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw # LmRpZ2ljZXJ0LmNvbTBcBggrBgEFBQcwAoZQaHR0cDovL2NhY2VydHMuZGlnaWNl # cnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0 # MjAyMUNBMS5jcnQwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAgEADWd6cY3c # UuXXxFhO4O+VPRPxNituYopOy3rgvLio6YncYfbbfZKRmKBYb79Ae6c/Nsz6K3bP # lhs9UuXs6UVlVwRhHpf8w1ko1I9lZLjZM8gbgvXethyIB3bvDDrLXyESUX4iAL/U # DNyuDjsQBOTe+7WvyXPrZhqlJL0kwO6kaMFffm+V+zaTBrSazco7GLlXVtp6+jWY # EHSdzyaeNgY5N4j3nKlsdVo4LhynuyqC9aTyWfxC9KPKpRNq9tGxkTHyjeCB61Y/ # yA6C63GpDmfoZtD0x46nzr1r7AG5c//Td+g9sKA4raai2RxcmLXwoIEG/5W/60cK # TAU44EnUW4ep/rmPBBLpinY3cg+k2b5UjBIUbYebanRVHiZmgCtLKQYLHdH8yu9L # Zc96I6dGmm08C8zsZPTyiYg9JadKPlAdkI3sB1d8263Ufsa6zvHEvSK3QnutLxHf # dOd/7XRwqSWx/oXrk8jggvAo3IAGEX/S+cRBjFYtmKZuhZUPQSh8LbiUfsRLsG/d # omoKJw1JVZubeFORgByyscqIDAIoAptjyZeoKJal+MF1DhkGnBehUNdZe+q4h43c # r573CZl4XZwY5w3y3ekc4Ahls9kE/VvMqkxGfHoTswmaSVM3EJuZ51FCg054zoka # BEgxZ4/59gvjUKfRNuUYC8FfD5Ldj0oI21QwggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqG # SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy # RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg # Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXH # JQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMf # UBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w # 1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRk # tFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYb # qMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUm # cJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP6 # 5x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzK # QtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo # 80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjB # Jgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXche # MBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB # /wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU # 7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDig # NqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZI # hvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd # 4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiC # qBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl # /Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeC # RK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYT # gAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/ # a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37 # xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmL # NriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0 # YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJ # RyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIG # wjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/X+VhFjANBgkqhkiG9w0BAQsFADBjMQsw # CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp # Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB # MB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAxMzIzNTk1OVowSDELMAkGA1UEBhMCVVMx # FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1l # c3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKNTRYcd # g45brD5UsyPgz5/X5dLnXaEOCdwvSKOXejsqnGfcYhVYwamTEafNqrJq3RApih5i # Y2nTWJw1cb86l+uUUI8cIOrHmjsvlmbjaedp/lvD1isgHMGXlLSlUIHyz8sHpjBo # yoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7ReoNYWyd/nFexAaaPPDFLnkPG2ZS48jW # Pl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PBuOZSlbVH13gpOWvgeFmX40QrStWVzu8I # F+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu6QXuqvYk9R28mxyyt1/f8O52fTGZZUdV # nUokL6wrl76f5P17cz4y7lI0+9S769SgLDSb495uZBkHNwGRDxy1Uc2qTGaDiGhi # u7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUGFOpiCBPTaR58ZE2dD9/O0V6MqqtQFcmz # yrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZcClhMAD6FaXXHg2TWdc2PEnZWpST618Rr # IbroHzSYLzrqawGw9/sqhux7UjipmAmhcbJsca8+uG+W1eEQE/5hRwqM/vC2x9XH # 3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U20clfCKRwo+wK8REuZODLIivK8SgTIUlR # fgZm0zu++uuRONhRB8qUt+JQofM604qDy0B7AgMBAAGjggGLMIIBhzAOBgNVHQ8B # Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAg # BgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZ # bU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFKW27xPn783QZKHVVqllMaPe1eNJ # MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAG # CCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy # dC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQw # DQYJKoZIhvcNAQELBQADggIBAIEa1t6gqbWYF7xwjU+KPGic2CX/yyzkzepdIpLs # jCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s1+FgnCvt7T1IjrhrunxdvcJhN2hJd6Pr # kKoS1yeF844ektrCQDifXcigLiV4JZ0qBXqEKZi2V3mP2yZWK7Dzp703DNiYdk9W # uVLCtp04qYHnbUFcjGnRuSvExnvPnPp44pMadqJpddNQ5EQSviANnqlE0PjlSXcI # WiHFtM+YlRpUurm8wWkZus8W8oM3NG6wQSbd3lqXTzON1I13fXVFoaVYJmoDRd7Z # ULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4ZiQPq1JE3701S88lgIcRWR+3aEUuMMsOI # 5ljitts++V+wQtaP4xeR0arAVeOGv6wnLEHQmjNKqDbUuXKWfpd5OEhfysLcPTLf # ddY2Z1qJ+Panx+VPNTwAvb6cKmx5AdzaROY63jg7B145WPR8czFVoIARyxQMfq68 # /qTreWWqaNYiyjvrmoI1VygWy2nyMpqy0tg6uLFGhmu6F/3Ed2wVbK6rr3M66ElG # t9V/zLY4wNjsHPW2obhDLN9OTH0eaHDAdwrUAuBcYLso/zjlUlrWrBciI0707NMX # +1Br/wd3H3GXREHJuEbTbDJ8WC9nR2XlG3O2mflrLAZG70Ee8PBf4NvZrZCARK+A # EEGKMYIGVzCCBlMCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWdu # aW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAEskBM6tH3agmQID1jirpbMA0G # CWCGSAFlAwQCAQUAoIGIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCSqG # SIb3DQEJBTEPFw0yNDA4MDgxNTUwMjhaMBwGCisGAQQBgjcCAQsxDjAMBgorBgEE # AYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAkEq4cfRpuK9E6PFIAC88zVlmhcUuQvuCi # jwxZD+My6zANBgkqhkiG9w0BAQEFAASCAgBh/QxMRuoC3mBry97ic6cXnXl+6/mO # Ppy7moQt52BzVy+sui6elnkt1v5uO5MHX+mC6eKUMpT50tYoQh/ucl5/z4wlV+LC # gsTJM9Y+gqYZw1OkJQvz/rynca9Ej/gupyosgPpJKG+7xuOD/Un9HTVXYQOKbRTS # 3Nby4ur5yBt0og1rTPhTep48jgubCZNWcoayH4OTivjjvxGT1affJLtY9gnsYJbW # AwK0IZas2U/ueemw66MsToBeN7ctqfvLUl2jZgFbwp6t1hBVGboyGsk47xprlFL0 # 9Y5gW17QxdYW91oZTufTndlIq7U/1b5nKviLh4ZLIpYsUkwe/p3BJQKPFodGMemX # AHO5kwBkfQqUNLeryrfO5/NV0Y26FZ+Hi9yf0trDjR524XbO2K42oI7hvLXtnlOn # pz9VNzgg8TnhZZMyCm+s7evQd6iw+xuOD+IRpcHjssY1E04QMapd6SE2lT2+FCzY # jbY+eciJFhNuaSXpMqpfnXkyNjn0PfJeuEGUbQnpIYMvzr7lBqYv3e4c7oXA/OvN # XMBzrjCEHYasFrrVY2DqJmn9+qbmklrGuys9O+GsXJFtKJ2Ytx+rM/4UUIKTs2Er # 46JykZVHr1oRFWwfK4pD0E8xpzNzh0CqB6RMvAJjKKB8Pxr7HKeFwyBPr+t6iVaC # 0Dns62eEwgmYBqGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJ # BgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGln # aUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EC # EAVEr/OUnQg5pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMx # CwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNDA4MDgxNTUwMjlaMC8GCSqG # SIb3DQEJBDEiBCBBrmMVlSfGj0A3D1tQfHEhlBTWXqibzssqdIwfaf20DzANBgkq # hkiG9w0BAQEFAASCAgCUkz3hOw+QXJQiV2OxsPBEanZ66I4KyO6x/t+TL4CenhX/ # weH5129NG4ATfl5uFzxNlGXnRWrq0EqrLMnei96DX5AdAypXZOWR5kykwoZ39jiS # vqzz0zLrRK2H8PB2QE7HO1OhJmhBXDamrU+CZmKPIy2KRdAmySYI1MghKgIIIDR1 # YCagODMnGS885Tpiq68clMD+N3m6YkyeaFTSBJxDX4YRSznw6fnurF9dA1uU10Fv # 6Gkm04OUvrGo4tC39QIOWh9kDbAtHXpNvTeTm2ys96X5PJRDPsxPoTTKAIljqeOS # kV/wpaN7qFfLG+bnVl8iUQ7oTzH3LilFPNmcXUpq/xaAt6z80p5VFp80eVq5ZWT8 # NtkDlJgOPekFlasWB7URlGoaYlws+zPLHp8UyIJfYKe3QSTxCh+0fld18Me+WdTo # dTqEhDlyAN3jEC5blaMjhU+Mn+njD2bA0twGRTviujhdzWyk/5k45AdEQfC3/2fb # 44z1XBugWJkFqQZlKcxa6N8vLDqjCpRR/b5oDW1hIdbp7m91E3F0AmMkY4u+OI2U # xGqr42Qi5EirGGepCl6StsqjqlfGM3/R5dCms8TK2yxfRwim5tAzY/TImrzysAQ5 # Wx4ZtWNn0QozUIaItaEQL01hNYl1oUNz7mzGbgXBang06VPvRcGv4wlg45s1wg== # SIG # End signature block |