SecretManagement.Warden.Extension/public/Set-Secret.ps1
function Set-Secret { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "VaultName", Justification = "Function must accept this parameter to be valid.")] param ( [string] $Name, # SecretManagement supports secrets of types: byte[], string, SecureString, PSCredential, and HashTable. [object] $Secret, [string] $VaultName, [hashtable] $AdditionalParameters ) # Enable Verbose Mode inside this script if passed from the wrapper. if($AdditionalParameters.ContainsKey('Verbose') -and ($AdditionalParameters['Verbose'] -eq $true)) {$script:VerbosePreference = 'Continue'} $AdditionalParameters = Merge-Defaults $AdditionalParameters Sync-BitwardenVault $AdditionalParameters.ResyncCacheIfOlderThan $OldSecret = Get-FullSecret -Name $Name -AdditionalParameters $AdditionalParameters $IsNewItem = $false # If OldSecret does not exist, assume this is a new secret and retrieve a secret template. if( !$OldSecret ) { $IsNewItem = $true switch( $Secret.GetType().Name ) { "PSCredential" { $OldSecret = New-Secret -Name $Name -SecretType Login break } { "String","SecureString" -contains $Secret.GetType().Name } { $Field = Read-Host -Prompt "Is this $($Secret.GetType().Name) a UserName, Password, TOTP, URIs, or SecureNote?" if( $Field -iin "UserName","Password","TOTP","URIs" ) { $OldSecret = New-Secret -Name $Name -SecretType Login } elseif( $Field -ieq "SecureNote" ) { $OldSecret = New-Secret -Name $Name -SecretType SecureNote } else { $ex = New-Object System.Management.Automation.Host.PromptingException "$Field is not a valid option!" Write-Error -Exception $ex -Category InvalidArgument -ErrorId "InvalidUserInput" -ErrorAction Stop } break } "HashTable" { if( Test-KeysInHashtable $Secret @("UserName","Password") ) { $OldSecret = New-Secret -Name $Name -SecretType Login } elseif( Test-KeysInHashtable $Secret @("cardholderName","brand","number","expMonth","expYear","code") ) { $OldSecret = New-Secret -Name $Name -SecretType Card } # Identity also includes a username field, but as that more strongly implies a login it is not used to detect an identity. elseif( Test-KeysInHashtable $Secret @("address1","address2","address3","city","company","country","email","firstName","lastName","licenseNumber","middleName","passportNumber","phone","postalCode","ssn","state","title") ) { $OldSecret = New-Secret -Name $Name -SecretType Identity } else { $OldSecret = New-Secret -Name $Name -SecretType SecureNote } break } } } else { # OldSecret.type is retrieved as a number; map it to our enum so it works in the next step. $OldSecret.type = [BitwardenItemType]$OldSecret.type } # Do things differently based on what type of secret we're editing. switch($OldSecret.type) { "Login" { # Do things differently based on what type of information the new secret is. switch($Secret.GetType().Name) { "PSCredential" { if($Secret.UserName -or $IsNewItem) { $OldSecret.login.username = $Secret.UserName } if($Secret.Password -or $IsNewItem) { $OldSecret.login.password = ConvertFrom-SecureString $Secret.Password -AsPlainText } break } "HashTable" { if ( Test-KeysInHashtable $Secret @("userName","password","uris","totp") ) { if($Secret.UserName -or $IsNewItem) { $OldSecret.login.username = if($Secret.UserName -is [SecureString]) { ConvertFrom-SecureString $Secret.UserName -AsPlainText } else { [string]$Secret.UserName } } if($Secret.Password -or $IsNewItem) { $OldSecret.login.password = if($Secret.Password -is [SecureString]) { ConvertFrom-SecureString $Secret.Password -AsPlainText } else { [string]$Secret.Password } } if($Secret.uris) { $OldSecret.login.uris = @([string]$Secret.uris) } elseif($IsNewItem) { $OldSecret.login.uris = @() } if($Secret.totp -or $IsNewItem) { $OldSecret.login.totp = if($Secret.totp -is [SecureString]) { ConvertFrom-SecureString $Secret.totp -AsPlainText } else { [string]$Secret.totp } } } else { $ex = New-Object System.Management.Automation.PSInvalidCastException "Input [HashTable]Secret could not be cast to any part of a Bitwarden Login." Write-Error -Exception $ex -Category InvalidOperation -CategoryReason "Hashtable contains neither UserName nor Password." -ErrorAction Stop } break } { "String","SecureString" -contains $_ } { # Only prompt if the user hasn't answered this question before. if( !$Field ) { $Field = Read-Host -Prompt "Does this $($Secret.GetType().Name) update the UserName, Password, TOTP, or URIs field?" } if( $Field -iin "UserName","Password","TOTP" ) { $OldSecret.login.$Field = if( $Secret -is [SecureString] ) { ConvertFrom-SecureString $Secret -AsPlainText } else { $Secret } } elseif( $Field -ieq "URIs" ) { $OldSecret.login.uris = @( if( $Secret -is [SecureString] ) { ConvertFrom-SecureString $Secret -AsPlainText } else { $Secret } ) } else { $ex = New-Object System.Management.Automation.Host.PromptingException "$Field is not a valid option!" Write-Error -Exception $ex -Category InvalidArgument -ErrorId "InvalidUserInput" -ErrorAction Stop } # If this is a new item, clear out all the default values. if($IsNewItem) { ($OldSecret.login | Get-Member -MemberType NoteProperty).Name | Where-Object { $_ -ine $Field } | ForEach-Object { if($_ -ine "URIs") { $OldSecret.login.$_ = $null } else { $OldSecret.login.$_ = $() } } } break } default { $ex = New-Object System.Management.Automation.PSInvalidCastException "Casting data of $($Secret.GetType().Name) type to a Bitwarden Login is not supported." Write-Error -Exception $ex -Category InvalidType -ErrorId "InvalidCast" -ErrorAction Stop break } } break } "SecureNote" { # Do things differently based on what type of information the new secret is. switch($Secret.GetType().Name) { "String" { $OldSecret.notes = $Secret; break } "SecureString" { $OldSecret.notes = ConvertFrom-SecureString $Secret -AsPlainText; break } "HashTable" { $ObjTemplate = "PowerShellObjectRepresentation: {0}`n{1}" switch($AdditionalParameters.ExportObjectsToSecureNotesAs) { "CliXml" { $tmp = New-TemporaryFile $Secret | Export-Clixml -Depth $AdditionalParameters.MaximumObjectDepth -Path $tmp $OldSecret.notes = $ObjTemplate -f "CliXml", (Get-Content -Path $tmp -Raw) Remove-Item $tmp -Force break } "JSON" { $OldSecret.notes = $ObjTemplate -f "JSON", ($Secret | ConvertTo-Json -Depth $AdditionalParameters.MaximumObjectDepth -Compress) break } default { $ex = New-Object System.NotSupportedException "$($AdditionalParameters.ExportObjectsToSecureNotesAs) is not a supported means of representing a PowerShell Object." Write-Error -Exception $ex -Category NotImplemented -ErrorId "InvalidObjectRepresentation" -RecommendedAction "Change the Vault Parameter: ExportObjectsToSecureNotesAs to a supported value." -ErrorAction Stop break } } break } default { $ex = New-Object System.Management.Automation.PSInvalidCastException "Casting data of $($Secret.GetType().Name) type to a Bitwarden Secure Note is not supported." Write-Error -Exception $ex -Category InvalidType -ErrorId "InvalidCast" -ErrorAction Stop break } } break } "Card" { switch($Secret.GetType().Name) { "HashTable" { $cardFields = "cardholderName","brand","number","expMonth","expYear","code" if ( Test-KeysInHashtable $Secret $cardFields ) { $cardFields | ForEach-Object { if($Secret.$_ -or $IsNewItem) { $OldSecret.card.$_ = if($Secret.$_ -is [SecureString]) { ConvertFrom-SecureString $Secret.$_ -AsPlainText } else { [string]$Secret.$_ } } } } else { $ex = New-Object System.Management.Automation.PSInvalidCastException "Input [HashTable]Secret could not be cast to any part of a Bitwarden Card." Write-Error -Exception $ex -Category InvalidOperation -CategoryReason "Hashtable missing any relevant information." -ErrorAction Stop } break } default { $ex = New-Object System.Management.Automation.PSInvalidCastException "Casting data of $($Secret.GetType().Name) type to a Bitwarden Card is not supported." Write-Error -Exception $ex -Category InvalidType -ErrorId "InvalidCast" -ErrorAction Stop break } } break } "Identity" { switch($Secret.GetType().Name) { "HashTable" { $identFields = "address1","address2","address3","city","company","country","email","firstName","lastName","licenseNumber","middleName","passportNumber","phone","postalCode","ssn","state","title","userName" if ( Test-KeysInHashtable $Secret.Keys $identFields ) { $identFields | ForEach-Object { if($Secret.$_ -or $IsNewItem) { $OldSecret.identity.$_ = if($Secret.$_ -is [SecureString]) { ConvertFrom-SecureString $Secret.$_ -AsPlainText } else { [string]$Secret.$_ } } } } else { $ex = New-Object System.Management.Automation.PSInvalidCastException "Input [HashTable]Secret could not be cast to any part of a Bitwarden Identity." Write-Error -Exception $ex -Category InvalidOperation -CategoryReason "Hashtable missing any relevant information." -ErrorAction Stop } break } default { $ex = New-Object System.Management.Automation.PSInvalidCastException "Casting data of $($Secret.GetType().Name) type to a Bitwarden Identity is not supported." Write-Error -Exception $ex -Category InvalidType -ErrorId "InvalidCast" -ErrorAction Stop break } } break } } if( $IsNewItem ) { [System.Collections.Generic.List[string]]$CmdParams = @("create","item") } else { [System.Collections.Generic.List[string]]$CmdParams = @("edit","item"); $CmdParams.Add($OldSecret.id) } $NewSecret = $OldSecret | ConvertTo-Json -Depth 4 -Compress | ConvertTo-BWEncoding $CmdParams.Add( $NewSecret ) if ( $AdditionalParameters.ContainsKey('organizationid')) { $CmdParams.Add( '--organizationid' ) $CmdParams.Add( $AdditionalParameters['organizationid'] ) } Write-Verbose ($CmdParams -join " ") Invoke-BitwardenCLI @CmdParams } # SIG # Begin signature block # MIInJAYJKoZIhvcNAQcCoIInFTCCJxECAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC9piK5QgLV7ky0 # OaTBZaqHYGSIHVWOBetriNbRGlU/96CCIBAwggVvMIIEV6ADAgECAhBI/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/ # L9Uo2bC5a4CH2RwwggaSMIIE+qADAgECAhEA9BsIJ9y5ugHUWmIFDcoPyDANBgkq # hkiG9w0BAQwFADBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1p # dGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2 # MB4XDTIyMDMyMzAwMDAwMFoXDTI1MDMyMjIzNTk1OVowfjELMAkGA1UEBhMCVVMx # DjAMBgNVBAgMBVRleGFzMSgwJgYDVQQKDB9JbmR1c3RyaWFsIEluZm8gUmVzb3Vy # Y2VzLCBJbmMuMQswCQYDVQQLDAJJVDEoMCYGA1UEAwwfSW5kdXN0cmlhbCBJbmZv # IFJlc291cmNlcywgSW5jLjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AJ7E7i62hCOgQLnF+wZZo8Rfl4dLolApxc+xD6cbXmk767hIZ/c7P+QCmLsZGqaZ # BKT+pBz2HKchvi3I1BqANkPa9arn2MYTRQZ1I57IJmZb/TwgybUxKtiyZxjYjw74 # iRmcReCa52Zyv7TethAR/v5ygApM8HzCgWoqa9/IWGcRSpHKWHHcINmLO/DO/8BX # D93T9fCfRdY4L69H2QbQkNh0lye1QTp/70VDu1o83sdWeGrXJhCZvpZlEeEgUUEG # 2M5zwJr4Ro2ZEVATCAp3BPt/2rjniGh2Zos7yD2+1WmrOgTBYVw/K+Yk265zjhF0 # asr7Ek4frWaccPjiBYWCxDDvLKn7hMfQP8FTD+qzMAsWls2Zn05R1gHrttlZ8gbY # aQXNaOYFhKat6w25emvD9sJPFFJVZCvnp9Pz+fKQhEhqffWeMZBLFdlQoLIvDkhJ # Ws9+jbnowitu0KKlk0dkiQVLYUIQpiPRhPGaJKscyHzAQ87DD3Ox/6S/TGhNJFMM # 3hFuvRnaZ2P12cVvHmD8OqVSwDhQsl01Fg8VioGrd0BxgNP5bWiTz+eMRChf0o3J # Vpj9Ortz6sdTwAJgE8Dd8Im+5sRRWfBHROS3sCR5pgYEJdmNMARcbA7tecdKK20e # P+AkyH4t8Hevx3hMKhS4nZArU/kCE4nGhAv0n4/riHWnAgMBAAGjggGzMIIBrzAf # BgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQUfukDRLuk # n0rpdU1Lx5oydHrJyCowDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYD # VR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAj # BggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkG # A1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1 # YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEF # BQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNp # Z25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28u # Y29tMCgGA1UdEQQhMB+BHWhvc3RtYXN0ZXJAaW5kdXN0cmlhbGluZm8uY29tMA0G # CSqGSIb3DQEBDAUAA4IBgQBXt+ecda0VKyotd+pMQHR1r84lxw40P6/NADb14P48 # p0iQYoFXBNmyq3kGtv4VFYVSDiiu/823nxt7Zm/0JtBN2WcLmt61ZELp23N+MxMA # MSvriQ+PGMSXdix8w3aY3AJACUM0+gmynqTVpwhsZBkhxMlX0OpeFNv6VfoAvLo5 # rNZ5wD0KwlFTEid1WiOQImHHOC7kkQIuj6POkrby9ukDwbDIwRDgwpZEik2K5JtD # /+kKBIK1Zrs6g8nnVPS+vjv494vDZBR6XCrct4HrAJfdU+Ch7/cTlo4DG4MePpEw # MUml/GIQsU8uOqkf932TW6wm1oF6PGh0mysMVZ9ee+CBiL3WwZ6uV2yyZ2+k2+wQ # r4HaM24OPp6r1ubGrAwclydFLBzI6cbxcRzakcPJ6EluQ3FdZyyB2S/S9yWTi//M # IFsFbmywhhr0MrH6bwU4zPzuYOFVTvr6Ek/Cu8ZsEFneZ/7T8KEgoDSmL3XESd6K # YLWkzMgPWqmGZTHmzZbaXzIwggbsMIIE1KADAgECAhAwD2+s3WaYdHypRjaneC25 # MA0GCSqGSIb3DQEBDAUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEpl # cnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJV # U1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9u # IEF1dGhvcml0eTAeFw0xOTA1MDIwMDAwMDBaFw0zODAxMTgyMzU5NTlaMH0xCzAJ # BgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT # B1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDElMCMGA1UEAxMcU2Vj # dGlnbyBSU0EgVGltZSBTdGFtcGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP # ADCCAgoCggIBAMgbAa/ZLH6ImX0BmD8gkL2cgCFUk7nPoD5T77NawHbWGgSlzkeD # tevEzEk0y/NFZbn5p2QWJgn71TJSeS7JY8ITm7aGPwEFkmZvIavVcRB5h/RGKs3E # Wsnb111JTXJWD9zJ41OYOioe/M5YSdO/8zm7uaQjQqzQFcN/nqJc1zjxFrJw06PE # 37PFcqwuCnf8DZRSt/wflXMkPQEovA8NT7ORAY5unSd1VdEXOzQhe5cBlK9/gM/R # EQpXhMl/VuC9RpyCvpSdv7QgsGB+uE31DT/b0OqFjIpWcdEtlEzIjDzTFKKcvSb/ # 01Mgx2Bpm1gKVPQF5/0xrPnIhRfHuCkZpCkvRuPd25Ffnz82Pg4wZytGtzWvlr7a # TGDMqLufDRTUGMQwmHSCIc9iVrUhcxIe/arKCFiHd6QV6xlV/9A5VC0m7kUaOm/N # 14Tw1/AoxU9kgwLU++Le8bwCKPRt2ieKBtKWh97oaw7wW33pdmmTIBxKlyx3GSuT # lZicl57rjsF4VsZEJd8GEpoGLZ8DXv2DolNnyrH6jaFkyYiSWcuoRsDJ8qb/fVfb # Enb6ikEk1Bv8cqUUotStQxykSYtBORQDHin6G6UirqXDTYLQjdprt9v3GEBXc/Bx # o/tKfUU2wfeNgvq5yQ1TgH36tjlYMu9vGFCJ10+dM70atZ2h3pVBeqeDAgMBAAGj # ggFaMIIBVjAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4E # FgQUGqH4YRkgD8NBd0UojtE1XwYSBFUwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB # /wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRV # HSAAMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V # U0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcB # AQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VS # VHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3Au # dXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAbVSBpTNdFuG1U4GRdd8D # ejILLSWEEbKw2yp9KgX1vDsn9FqguUlZkClsYcu1UNviffmfAO9Aw63T4uRW+VhB # z/FC5RB9/7B0H4/GXAn5M17qoBwmWFzztBEP1dXD4rzVWHi/SHbhRGdtj7BDEA+N # 5Pk4Yr8TAcWFo0zFzLJTMJWk1vSWVgi4zVx/AZa+clJqO0I3fBZ4OZOTlJux3LJt # QW1nzclvkD1/RXLBGyPWwlWEZuSzxWYG9vPWS16toytCiiGS/qhvWiVwYoFzY16g # u9jc10rTPa+DBjgSHSSHLeT8AtY+dwS8BDa153fLnC6NIxi5o8JHHfBd1qFzVwVo # mqfJN2Udvuq82EKDQwWli6YJ/9GhlKZOqj0J9QVst9JkWtgqIsJLnfE5XkzeSD2b # NJaaCV+O/fexUpHOP4n2HKG1qXUfcb9bQ11lPVCBbqvw0NP8srMftpmWJvQ8eYtc # ZMzN7iea5aDADHKHwW5NWtMe6vBE5jJvHOsXTpTDeGUgOw9Bqh/poUGd/rG4oGUq # NODeqPk85sEwu8CgYyz8XBYAqNDEf+oRnR4GxqZtMl20OAkrSQeq/eww2vGnL8+3 # /frQo4TZJ577AWZ3uVYQ4SBuxq6x+ba6yDVdM3aO8XwgDCp3rrWiAoa6Ke60WgCx # jKvj+QrJVF3UuWp0nr1Irpgwggb1MIIE3aADAgECAhA5TCXhfKBtJ6hl4jvZHSLU # MA0GCSqGSIb3DQEBDAUAMH0xCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVy # IE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28g # TGltaXRlZDElMCMGA1UEAxMcU2VjdGlnbyBSU0EgVGltZSBTdGFtcGluZyBDQTAe # Fw0yMzA1MDMwMDAwMDBaFw0zNDA4MDIyMzU5NTlaMGoxCzAJBgNVBAYTAkdCMRMw # EQYDVQQIEwpNYW5jaGVzdGVyMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAq # BgNVBAMMI1NlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgU2lnbmVyICM0MIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApJMoUkvPJ4d2pCkcmTjA5w7U0Rzs # aMsBZOSKzXewcWWCvJ/8i7u7lZj7JRGOWogJZhEUWLK6Ilvm9jLxXS3AeqIO4OBW # ZO2h5YEgciBkQWzHwwj6831d7yGawn7XLMO6EZge/NMgCEKzX79/iFgyqzCz2Ix6 # lkoZE1ys/Oer6RwWLrCwOJVKz4VQq2cDJaG7OOkPb6lampEoEzW5H/M94STIa7GZ # 6A3vu03lPYxUA5HQ/C3PVTM4egkcB9Ei4GOGp7790oNzEhSbmkwJRr00vOFLUHty # 4Fv9GbsfPGoZe267LUQqvjxMzKyKBJPGV4agczYrgZf6G5t+iIfYUnmJ/m53N9e7 # UJ/6GCVPE/JefKmxIFopq6NCh3fg9EwCSN1YpVOmo6DtGZZlFSnF7TMwJeaWg4Ga # 9mBmkFgHgM1Cdaz7tJHQxd0BQGq2qBDu9o16t551r9OlSxihDJ9XsF4lR5F0zXUS # 0Zxv5F4Nm+x1Ju7+0/WSL1KF6NpEUSqizADKh2ZDoxsA76K1lp1irScL8htKycOU # QjeIIISoh67DuiNye/hU7/hrJ7CF9adDhdgrOXTbWncC0aT69c2cPcwfrlHQe2zY # HS0RQlNxdMLlNaotUhLZJc/w09CRQxLXMn2YbON3Qcj/HyRU726txj5Ve/Fchzpk # 8WBLBU/vuS/sCRMCAwEAAaOCAYIwggF+MB8GA1UdIwQYMBaAFBqh+GEZIA/DQXdF # KI7RNV8GEgRVMB0GA1UdDgQWBBQDDzHIkSqTvWPz0V1NpDQP0pUBGDAOBgNVHQ8B # Af8EBAMCBsAwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDBK # BgNVHSAEQzBBMDUGDCsGAQQBsjEBAgEDCDAlMCMGCCsGAQUFBwIBFhdodHRwczov # L3NlY3RpZ28uY29tL0NQUzAIBgZngQwBBAIwRAYDVR0fBD0wOzA5oDegNYYzaHR0 # cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBVGltZVN0YW1waW5nQ0EuY3Js # MHQGCCsGAQUFBwEBBGgwZjA/BggrBgEFBQcwAoYzaHR0cDovL2NydC5zZWN0aWdv # LmNvbS9TZWN0aWdvUlNBVGltZVN0YW1waW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdo # dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEATJtlWPrg # ec/vFcMybd4zket3WOLrvctKPHXefpRtwyLHBJXfZWlhEwz2DJ71iSBewYfHAyTK # x6XwJt/4+DFlDeDrbVFXpoyEUghGHCrC3vLaikXzvvf2LsR+7fjtaL96VkjpYeWa # OXe8vrqRZIh1/12FFjQn0inL/+0t2v++kwzsbaINzMPxbr0hkRojAFKtl9RieCqE # eajXPawhj3DDJHk6l/ENo6NbU9irALpY+zWAT18ocWwZXsKDcpCu4MbY8pn76rSS # ZXwHfDVEHa1YGGti+95sxAqpbNMhRnDcL411TCPCQdB6ljvDS93NkiZ0dlw3oJok # nk5fTtOPD+UTT1lEZUtDZM9I+GdnuU2/zA2xOjDQoT1IrXpl5Ozf4AHwsypKOazB # pPmpfTXQMkCgsRkqGCGyyH0FcRpLJzaq4Jgcg3Xnx35LhEPNQ/uQl3YqEqxAwXBb # mQpA+oBtlGF7yG65yGdnJFxQjQEg3gf3AdT4LhHNnYPl+MolHEQ9J+WwhkcqCxuE # dn17aE+Nt/cTtO2gLe5zD9kQup2ZLHzXdR+PEMSU5n4k5ZVKiIwn1oVmHfmuZHaR # 6Ej+yFUK7SnDH944psAU+zI9+KmDYjbIw74Ahxyr+kpCHIkD3PVcfHDZXXhO7p9e # IOYJanwrCKNI9RX8BE/fzSEceuX1jhrUuUAxggZqMIIGZgIBATBpMFQxCzAJBgNV # BAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3Rp # Z28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYCEQD0Gwgn3Lm6AdRaYgUNyg/I # MA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJ # KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB # gjcCARUwLwYJKoZIhvcNAQkEMSIEIOK9xMFSSWGuCRIElIXCsrVo1HFdSMkeoxhv # YKVtHnuYMA0GCSqGSIb3DQEBAQUABIICACucguVNZIDKwqmcZrBQuqvpzEbkt+JW # MomwLMadVljwMixzd6uSU2+gje2K9rp/e/TWtYGQubuq+OD+dm6BW1idbVJbgjYv # Asi30Pr6jBaya6AUQv5L0ZVWjLIrIwQAMZorrSd4fMauV87uhu2bir0BOaNO5zei # +lcb1zaBuFWO3L/MiOpO48wyEKxUYAxtx1UmIUjB7z9cNrS34IYJVp8qHPX+lYD/ # oulPRhfZdoCvrdx+MVpOPJIVIM7caiavsxtL2vAHCHkgs4UJ9ONXUyeP9maH4jpu # bqQPVTst49PhrpFzhcjjisGVq3Pv7SwcYlSeaIPLnZ5+bo46EnftMicrzdOFOn6C # D9yv72EgTW1E75jaMu9UXWtAOVsSRfYPrdQVdFvpVHHy/OPJnSAMgjTDbqxjEL5/ # fHiV+Dp+rZVkg6dtuMzAZ661BxWxwDZ1pu7hmxwDR2/9+4feyutb22hJ25i5VbDV # epD4EFvbI78Y0l00kbcERhI48bV6XsC7iSqO/3DBCzIO3TKuyqb3ku3SDuwWtjY2 # lY5mfIN8JTasdvaQQ/eeMMiz3XcUzjOatUnrGytArdNpFf+rOBp0Zu+IEW6QdFSp # jiWrvPBCHoaPiLR2pIPWWjSWzsvicKczbErC8tWfomaChjRv5L9kK+SsghZmnOIB # RBocyWrSKGhRoYIDSzCCA0cGCSqGSIb3DQEJBjGCAzgwggM0AgEBMIGRMH0xCzAJ # BgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcT # B1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDElMCMGA1UEAxMcU2Vj # dGlnbyBSU0EgVGltZSBTdGFtcGluZyBDQQIQOUwl4XygbSeoZeI72R0i1DANBglg # hkgBZQMEAgIFAKB5MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcN # AQkFMQ8XDTI0MDcxNzIxMDQ0M1owPwYJKoZIhvcNAQkEMTIEMDo7MKyKX5Hjiyzw # vzLPJMY4lqLJASZtHWkb8kE9+OQcmlS3miMW9hKS+gFoTdYCAjANBgkqhkiG9w0B # AQEFAASCAgA7RNl+HSHAXBzJSxm7jv6abuFieED0lOM+P0iOx/xDaBANjyZ7v4A/ # jlfDcwVDyY3FEiOoCZ0BATuHjaLQLuH5KzJUBL6zIBYvFbSdLzsa4WlzO1pitF9O # TfETcaOTqlSwtzkznYUXD8HX66GeAX/PuW30ASc10e19tENf8VyJ88huj6/KiY7r # Cc9vhQtD4+Htp+7xXwqpxvtBf7k2l0F7zOQ2HkQrW2Wxn5TdYVunLcZH659QYbNr # LmDPD3l8WiOpCo44qVIzh7EP5BTmUhK/JlpCgdjB3tdVvNCJztoNLdkFgLwTXTw3 # iRMBr4RGG8S2FcLSRgUvPn6qrijOqJ/bZbsZJggeRdIBJ+al1ydNwDLX+H38tD1O # HQvIc0D7tgGb8x7r04DkrZ2GhIydqP/xQFVczm7AqfLFbFMI56m+wPZdQ4t7j2TH # mmil/1folskX+HzjhqEhfmMra1gYZ7ob8piWmd0UiyWSDDQpc/gA/atAYShAxrk8 # PZ+57FavyFK0c6orMW37oT1/k4RQ39wh54Z6QPG11/HVZapIFXqwq5XIgjtjKmDu # JSDLoPAnsRPVg+ZncTSCt++TEdo8bMsF1yJ11Sr+j7Ac0v8CAVuNBJr5RRuQoph6 # CnoPPHB47LQyuX+vfnA3eDKVx2F/X5wMmaBrHAjK8DGv5I7frUQpag== # SIG # End signature block |