Public/SEPPmailAPI-UserCrypto.ps1

<#
.SYNOPSIS
    Get S/MIME and PGP key information of a local user.
.DESCRIPTION
    Calls GET /crypto/user/{email} or GET /crypto/user/{email}/{serial_or_keyid}
    depending on whether -key is provided.
#>

function Get-SMAUserKey {
    [CmdletBinding()]
    param (
        [Parameter(ParameterSetName = 'email', Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
        [Parameter(ParameterSetName = 'keyId', Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
        [string]$eMail,

        [Parameter(ParameterSetName = 'keyId', Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('serial', 'keyId')]
        [string]$key,

        [Parameter(Mandatory = $false)]
        [bool]$list = $false,

        [Parameter(Mandatory = $false)]
        [int]$limit = 0,

        [Parameter(Mandatory = $false)]
        [ValidateSet('pgp', 'smime', 'both')]
        [string]$technology = 'both',

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [secureString]$password,

        [Parameter(Mandatory = $false)]
        [string]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [string]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential]$SMACred = $Script:activeCfg.SMACred,

        [Parameter(Mandatory = $false)]
        [switch]$SMASkipCertCheck = $Script:activeCfg.SMAskipCertCheck
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage) }
    }
    process {
        if ($PSBoundParameters.ContainsKey('key')) {
            $uriPath = '{0}/{1}/{2}/{3}' -f 'crypto', 'user', $eMail.ToLower(), $key
        } else {
            $uriPath = '{0}/{1}/{2}' -f 'crypto', 'user', $eMail.ToLower()
        }

        $queryParam = @{
            list       = $list
            limit      = $limit
            technology = $technology
        }
        if ($PSBoundParameters.ContainsKey('password')) {
            $queryParam.password = (ConvertFrom-SecureString -secureString $password -AsPlainText)
        }

        $smaParams = @{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
        $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParam @smaParams

        $invokeParam = @{
            Uri           = $uri
            Method        = 'GET'
            Cred          = $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }
        $result = Invoke-SMARestMethod @invokeParam
        if ($result) { return $result }
    }
}

<#
.SYNOPSIS
    Add private and public user S/MIME and/or PGP key.
.DESCRIPTION
    Calls POST /crypto/user/{email}.
.PARAMETER action
    API action: import or generate.
.PARAMETER technology
    API technology: both, smime, or pgp.
.PARAMETER importData
    Import payload object according to API schema.
.PARAMETER generateData
    Generate payload object according to API schema.
.PARAMETER public
    If true, imports only public key material.
.NOTES
    The API may return HTTP 409 (Conflict) if the submitted key material
    conflicts with existing entries.
#>

function Add-SMAUserKey {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
        [string]$eMail,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateSet('import', 'generate')]
        [string]$action,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateSet('both', 'smime', 'pgp')]
        [string]$technology = 'both',

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [object]$importData,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [object]$generateData,

        [Parameter(Mandatory = $false)]
        [bool]$public = $false,

        [Parameter(Mandatory = $false)]
        [string]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [string]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential]$SMACred = $Script:activeCfg.SMACred,

        [Parameter(Mandatory = $false)]
        [switch]$SMASkipCertCheck = $Script:activeCfg.SMAskipCertCheck
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage) }
    }
    process {
        $uriPath = '{0}/{1}/{2}' -f 'crypto', 'user', $eMail.ToLower()
        $queryParam = @{ public = $public }
        $smaParams = @{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
        $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParam @smaParams

        $bodyHt = @{
            action     = $action
            technology = $technology
        }
        if ($PSBoundParameters.ContainsKey('importData')) { $bodyHt.importData = $importData }
        if ($PSBoundParameters.ContainsKey('generateData')) { $bodyHt.generateData = $generateData }
        $body = $bodyHt | ConvertTo-Json -Depth 100

        $invokeParam = @{
            Uri           = $uri
            Method        = 'POST'
            Body          = $body
            Cred          = $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }

        if ($PSCmdlet.ShouldProcess($eMail, 'Add user key')) {
            $result = Invoke-SMARestMethod @invokeParam
            if ($result) { return $result }
        }
    }
}

<#
.SYNOPSIS
    Modify metadata of a user key.
.DESCRIPTION
    Calls PUT /crypto/user/{email}/{serial_or_keyid}.
#>

function Set-SMAUserKey {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
        [string]$eMail,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('serial', 'keyId')]
        [string]$key,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [string[]]$mailAddresses,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [bool]$allowEncryption,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [bool]$allowDecryption,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [bool]$allowSigning,

        [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [string]$comment,

        [Parameter(Mandatory = $false)]
        [string]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [string]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential]$SMACred = $Script:activeCfg.SMACred,

        [Parameter(Mandatory = $false)]
        [switch]$SMASkipCertCheck = $Script:activeCfg.SMAskipCertCheck
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage) }
    }
    process {
        $uriPath = '{0}/{1}/{2}/{3}' -f 'crypto', 'user', $eMail.ToLower(), $key
        $smaParams = @{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
        $uri = New-SMAQueryString -uriPath $uriPath @smaParams

        $bodyHt = @{}
        $apiParams = @('mailAddresses', 'allowEncryption', 'allowDecryption', 'allowSigning', 'comment')
        foreach ($param in $apiParams) {
            if ($PSBoundParameters.ContainsKey($param)) {
                $bodyHt[$param] = $PSBoundParameters[$param]
            }
        }
        $body = $bodyHt | ConvertTo-Json -Depth 100

        $invokeParam = @{
            Uri           = $uri
            Method        = 'PUT'
            Body          = $body
            Cred          = $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }

        if ($PSCmdlet.ShouldProcess($eMail, "Modify user key $key")) {
            $result = Invoke-SMARestMethod @invokeParam
            if ($result) { return $result }
        }
    }
}

<#
.SYNOPSIS
    Remove one S/MIME or PGP key of a local user.
.DESCRIPTION
    Calls DELETE /crypto/user/{email}/{serial_or_keyid}.
#>

function Remove-SMAUserKey {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)]
        [string]$eMail,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('serial', 'keyid')]
        [string]$key,

        [Parameter(Mandatory = $false)]
        [bool]$revoke = $true,

        [Parameter(Mandatory = $false)]
        [bool]$delete = $false,

        [Parameter(Mandatory = $false)]
        [string]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [string]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential]$SMACred = $Script:activeCfg.SMACred,

        [Parameter(Mandatory = $false)]
        [switch]$SMASkipCertCheck = $Script:activeCfg.SMAskipCertCheck
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage) }
    }
    process {
        $uriPath = '{0}/{1}/{2}/{3}' -f 'crypto', 'user', $eMail.ToLower(), $key
        $queryParam = @{}
        if ($PSBoundParameters.ContainsKey('delete')) { $queryParam.delete = $delete }
        if ($PSBoundParameters.ContainsKey('revoke')) { $queryParam.revoke = $revoke }

        $smaParams = @{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
        $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParam @smaParams

        $invokeParam = @{
            Uri           = $uri
            Method        = 'DELETE'
            Cred          = $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }

        if ($PSCmdlet.ShouldProcess($eMail, "Remove user key $key")) {
            $result = Invoke-SMARestMethod @invokeParam
            if ($result) { return $result }
        }
    }
}

# SIG # Begin signature block
# MIIVyAYJKoZIhvcNAQcCoIIVuTCCFbUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDQDI6yMmmzuIwt
# tuun+GFGZeZVamuCl2rJ3B9r4qbGCaCCEgQwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
# L9Uo2bC5a4CH2RwwggZvMIIE16ADAgECAhBIqMP3CCLHOHtOKuaWNyeFMA0GCSqG
# SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw
# HhcNMjYwNDE1MDAwMDAwWhcNMjcwNzE0MjM1OTU5WjBmMQswCQYDVQQGEwJERTEP
# MA0GA1UECAwGQmF5ZXJuMSIwIAYDVQQKDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBH
# bWJIMSIwIAYDVQQDDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBHbWJIMIICIjANBgkq
# hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvAFzE8MbJpvQt+IdIh1M+bKYsJBFDk4b
# 9ySe25IrCi00B9o5XmQtIw42MqyIKbUq1tDARtp9KTQedEP9W+rflAF2l+0Z046J
# kiqumU9/enbqWLDyln1aS/p7HOgwZFMhnsR9zH0MfFckiklUmkzJO+vmzYAK7ZmD
# xajNLJs0gkGRU2/BecAx/TSvLXMaKONsKZCyMKQCnwo1mCY/tFl5EgUz7YQFrPOR
# BQGfQke/hkdBfQDqNRsi/J6+KhJWc6LvgQihdRg/INQbQsTxlow18NWvyFsjjueH
# 7kG6HR4YKfbv07xgrsIh8xvq9ZJ1SBhLXmkg4SdoQGASjqR6o3keAX+bDRFf+hml
# WWJp/FqVHR5QomF3vbK2/bbz4jAclYSPx/sPasNJ0YnKFkgmowZ7Ysa0KA0/egBg
# tI4gJ+8V7zrqIVEG3rMQh9KCdMnJqP2aM9o4gUzQvE1M4x606liX9EWwdLLS+fe7
# 9o+Fzo5oH4wBE/En6hQQkzseHHu+TXCDd6zUUZ/PlTK0gTaDIRXt6UzPNqJ4RiRC
# W2pNFcPt078qqVTuwKUXoE4ufxGgXKFrZlCYST/9eG1TnW2oq19nz8A333GCsL3g
# poNIKvfmDyGMMNzvx2aeqn2v6e75z8kH19iGSNZ51xT+WgS9F1aIvjz08/T7XAv7
# iDPF1/gPIp8CAwEAAaOCAakwggGlMB8GA1UdIwQYMBaAFA8qyyCHKLjsb0iuK1Sm
# KaoXpM0MMB0GA1UdDgQWBBS30/Tq+alF3j2BY5up8n5zpAU23DAOBgNVHQ8BAf8E
# BAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNVHSAE
# QzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp
# Z28uY29tL0NQUzAIBgZngQwBBAEwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2Ny
# bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcmww
# eQYIKwYBBQUHAQEEbTBrMEQGCCsGAQUFBzAChjhodHRwOi8vY3J0LnNlY3RpZ28u
# Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNydDAjBggrBgEFBQcw
# AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wHgYDVR0RBBcwFYETc3VwcG9ydEBz
# ZXBwbWFpbC5jaDANBgkqhkiG9w0BAQwFAAOCAYEAi7fmb5UYoemWG3CC4K2UZWVr
# R6GOfi8gbJKgjPbKO4zrCrU/x6cOdyp6scKZfUEGFDf8KH6pP4pAQv1Hsbi49gU2
# kxoUWLlCiipn05qJY663DHx9hlStej/ZdEatou0wyCDiG5xD7kmG+1t6iLyyCBgE
# B88tJpzTjI61qXmBTS/FGEOAsB4SDEW1ngA7bc5FOv4IUKA43hp8M+N3GeYFzDqw
# JELYEfVVYheBW3o7q4VrCdfFEuaQihOtvfDfYpP6ANgekNn8HdsMT8rx9D1I50Rl
# i/qQFo2BOuPyb2SIQPzJvCs5wgi5qgp1nHiN6igumu2Cz7BmGjOazGUgCSUY5Qwy
# E8+F+R2tVM+2O15rfX01+e56ZfojBEiEjMwfPHs3fa3V3gokWWNwUMkton/v0R/n
# l2zjmOr2okohOINZEDh9frg21zUCN5ZD8Y4zQWuiJLCvvvBZs0JR4c9xl2k2wtw/
# QLPhGU69zM3smGpRoLE8M6zvUvSU7jXjvefazUniMYIDGjCCAxYCAQEwaDBUMQsw
# CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJT
# ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhBIqMP3CCLHOHtOKuaW
# NyeFMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAw
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIE1ZCynABJXjImrjkufO+uMZ1i+C1oV7
# 4aNopABXFC6WMA0GCSqGSIb3DQEBAQUABIICAILCkVEB9K1lsTdDPIxKcckOAz45
# TYs0PdtszTYsgy805hgkS9nG7ianzHS1rz1csvXPA37NfXbOv6IEAgwyKh5Gj4zB
# s+CtS/rbvVsx8tQLjSuzMOuroKwAWNx9wjye/8ApclewlgHMCdctUXzDADuYBKWH
# WSO5KW5nBatPQqckDpiGOnEdrrjmR49/v6h8QJhLzfKCmQ1H8FjAlcFxWCs438jb
# 3WR4/FklHybOiVOKP8JUfQbF9MfKfy3MRYsTRcWwmnq0WWoan5x4QqmdMdkNe3lP
# gssyz/9Uxm3T1Fra5h5VJe7hmn0CJfv3VHWp3e+zMV6YkgevKY0MRcb0GN/I/VgX
# tKeTwfAjHO/FzeO4hh1StBaxOS1RRO5W3xLG2ZllTy4d+XIrFMoXHaq5xK78Sqkk
# nf2LBBHYdzDBQ5AB0cMCLK5H6sqN/ZM7rnxrYAvMgmKpnPCqqN2h1c0tBi2zhvIk
# 63t4nrwfgdi0XqE9a0nWAoVVTumCH2D5GDA8zAuJhNC8TmtQYkaslSDlJm6kzVvr
# u7A3WxQldVvbbEgSPBNoRNmGDEqyev7mFiFFm9JWtPguSUzx9vsyopOEQsWad13K
# EsTYcvQVKtX58WjrGcyVc+1lsayd1Bq2iZ501XxqSTYBUuImmrycNypaeYgEmIDu
# AyUsAPcDYb0C9c/d
# SIG # End signature block