Client/Convert-PfxToPem.ps1
|
function Convert-PfxToPem { <# .ExternalHelp PSPKI.Help.xml #> [CmdletBinding(DefaultParameterSetName = '__pfxfile')] param( [Parameter(Mandatory = $true, ParameterSetName = '__pfxfile', Position = 0)] [IO.FileInfo]$InputFile, [Parameter(Mandatory = $true, ParameterSetName = '__cert', Position = 0)] [Security.Cryptography.X509Certificates.X509Certificate2]$Certificate, [Parameter(Mandatory = $true, ParameterSetName = '__pfxfile', Position = 1)] [Security.SecureString]$Password, [Parameter(Mandatory = $true, Position = 2)] [IO.FileInfo]$OutputFile, [Parameter(Position = 3)] [ValidateSet("Pkcs1","Pkcs8")] [string]$OutputType = "Pkcs8", [switch]$IncludeChain ) $signature = @" [DllImport("crypt32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CryptAcquireCertificatePrivateKey( IntPtr pCert, uint dwFlags, IntPtr pvReserved, ref IntPtr phCryptProv, ref uint pdwKeySpec, ref bool pfCallerFreeProv ); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CryptGetUserKey( IntPtr hProv, uint dwKeySpec, ref IntPtr phUserKey ); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CryptExportKey( IntPtr hKey, IntPtr hExpKey, uint dwBlobType, uint dwFlags, byte[] pbData, ref uint pdwDataLen ); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CryptDestroyKey( IntPtr hKey ); [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool PFXIsPFXBlob( CRYPTOAPI_BLOB pPFX ); [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool PFXVerifyPassword( CRYPTOAPI_BLOB pPFX, [MarshalAs(UnmanagedType.LPWStr)] string szPassword, int dwFlags ); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct CRYPTOAPI_BLOB { public int cbData; public IntPtr pbData; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PUBKEYBLOBHEADERS { public byte bType; public byte bVersion; public short reserved; public uint aiKeyAlg; public uint magic; public uint bitlen; public uint pubexp; } "@ Add-Type -MemberDefinition $signature -Namespace PKI -Name PfxTools #region helper functions function Encode-Integer ([Byte[]]$RawData) { # since CryptoAPI is little-endian by nature, we have to change byte ordering # to big-endian. [array]::Reverse($RawData) # if high byte contains more than 7 bits, an extra zero byte is added if ($RawData[0] -ge 128) {$RawData = ,0 + $RawData} [SysadminsLV.Asn1Parser.Asn1Utils]::Encode($RawData, 2) } #endregion #region parameterset processing switch ($PsCmdlet.ParameterSetName) { "__pfxfile" { $bytes = [IO.File]::ReadAllBytes($InputFile) $ptr = [Runtime.InteropServices.Marshal]::AllocHGlobal($bytes.Length) [Runtime.InteropServices.Marshal]::Copy($bytes,0,$ptr,$bytes.Length) $pfx = New-Object PKI.PfxTools+CRYPTOAPI_BLOB -Property @{ cbData = $bytes.Length; pbData = $ptr } # just check whether input file is valid PKCS#12/PFX file. if ([PKI.PfxTools]::PFXIsPFXBlob($pfx)) { $certs = New-Object Security.Cryptography.X509Certificates.X509Certificate2Collection try { $certs.Import( $bytes, [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)), "Exportable" ) $Certificate = ($certs | Where-Object {$_.HasPrivateKey})[0] } catch { throw $_ return } finally { [Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) Remove-Variable bytes, ptr, pfx -Force } } else { [Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) Remove-Variable bytes, ptr, pfx -Force Write-Error -Category InvalidData -Message "Input file is not valid PKCS#12/PFX file." -ErrorAction Stop } } "__cert" { if (!$Certificate.HasPrivateKey) { Write-Error -Category InvalidOperation -Message "Specified certificate object does not contain associated private key." -ErrorAction Stop } } } #endregion #region constants $CRYPT_ACQUIRE_SILENT_FLAG = 0x40 $PRIVATEKEYBLOB = 0x7 $CRYPT_OAEP = 0x40 #endregion #region private key export routine $phCryptProv = [IntPtr]::Zero $pdwKeySpec = 0 $pfCallerFreeProv = $false # attempt to acquire private key container if (![PKI.PfxTools]::CryptAcquireCertificatePrivateKey($Certificate.Handle,$CRYPT_ACQUIRE_SILENT_FLAG,0,[ref]$phCryptProv,[ref]$pdwKeySpec,[ref]$pfCallerFreeProv)) { throw New-Object ComponentModel.Win32Exception ([Runtime.InteropServices.Marshal]::GetLastWin32Error()) return } $phUserKey = [IntPtr]::Zero # attempt to acquire private key handle if (![PKI.PfxTools]::CryptGetUserKey($phCryptProv,$pdwKeySpec,[ref]$phUserKey)) { throw New-Object ComponentModel.Win32Exception ([Runtime.InteropServices.Marshal]::GetLastWin32Error()) return } $pdwDataLen = 0 # attempt to export private key. This method fails if certificate has non-exportable private key. if (![PKI.PfxTools]::CryptExportKey($phUserKey,0,$PRIVATEKEYBLOB,$CRYPT_OAEP,$null,[ref]$pdwDataLen)) { throw New-Object ComponentModel.Win32Exception ([Runtime.InteropServices.Marshal]::GetLastWin32Error()) return } $pbytes = New-Object byte[] -ArgumentList $pdwDataLen [void][PKI.PfxTools]::CryptExportKey($phUserKey,0,$PRIVATEKEYBLOB,$CRYPT_OAEP,$pbytes,[ref]$pdwDataLen) # release private key handle [void][PKI.PfxTools]::CryptDestroyKey($phUserKey) #endregion #region private key blob splitter # extracting private key blob header. $headerblob = $pbytes[0..19] # extracting actual private key data exluding header. $keyblob = $pbytes[20..($pbytes.Length - 1)] Remove-Variable pbytes -Force # public key structure header has fixed length: 20 bytes: http://msdn.microsoft.com/en-us/library/aa387689(VS.85).aspx # copy header information to unmanaged memory and copy it to structure. $ptr = [Runtime.InteropServices.Marshal]::AllocHGlobal(20) [Runtime.InteropServices.Marshal]::Copy($headerblob,0,$ptr,20) $header = [Runtime.InteropServices.Marshal]::PtrToStructure($ptr,[Type][PKI.PfxTools+PUBKEYBLOBHEADERS]) [Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) # extract public exponent from blob header and convert it to a byte array $pubExponentHex = "{0:x2}" -f $header.pubexp if ($pubExponentHex.Length % 2) {$pubExponentHex = "0" + $pubExponentHex} $publicExponent = $pubExponentHex -split "([a-f0-9]{2})" | Where-Object {$_} | ForEach-Object {[Convert]::ToByte($_,16)} # this object is created to reduce code size. This object has properties, where each property represents # a part (component) of the private key and property value contains private key component length. # 8 means that the length of the component is KeyLength / 8. Resulting length is measured in bytes. # for details see private key structure description: http://msdn.microsoft.com/en-us/library/aa387689(VS.85).aspx $obj = New-Object psobject -Property @{ modulus = 8; privateExponent = 8; prime1 = 16; prime2 = 16; exponent1 = 16; exponent2 = 16; coefficient = 16; } $offset = 0 # I pass variable names (each name represents the component of the private key) to foreach loop # in the order as they follow in the private key structure and parse private key for # appropriate offsets and write component information to variable. "modulus","prime1","prime2","exponent1","exponent2","coefficient","privateExponent" | ForEach-Object { Set-Variable -Name $_ -Value ($keyblob[$offset..($offset + $header.bitlen / $obj.$_ - 1)]) $offset = $offset + $header.bitlen / $obj.$_ } # PKCS#1/PKCS#8 uses slightly different component order, therefore I reorder private key # components and pass them to a simplified ASN encoder. $asnblob = Encode-Integer 0 $asnblob += "modulus","publicExponent","privateExponent","prime1","prime2","exponent1","exponent2","coefficient" | ForEach-Object { Encode-Integer (Get-Variable -Name $_).Value } # remove unused variables Remove-Variable modulus,publicExponent,privateExponent,prime1,prime2,exponent1,exponent2,coefficient -Force # encode resulting set of INTEGERs to a SEQUENCE $asnblob = [SysadminsLV.Asn1Parser.Asn1Utils]::Encode($asnblob, 48) # $out variable just holds output file. The file will contain private key and public certificate # each will be enclosed with header and footer. $out = New-Object Text.StringBuilder if ($OutputType -eq "Pkcs8") { $asnblob = [SysadminsLV.Asn1Parser.Asn1Utils]::Encode($asnblob, 4) $algid = [Security.Cryptography.CryptoConfig]::EncodeOID("1.2.840.113549.1.1.1") + 5,0 $algid = [SysadminsLV.Asn1Parser.Asn1Utils]::Encode($algid, 48) $asnblob = 2,1,0 + $algid + $asnblob $asnblob = [SysadminsLV.Asn1Parser.Asn1Utils]::Encode($asnblob, 48) $base64 = [SysadminsLV.Asn1Parser.AsnFormatter]::BinaryToString($asnblob,"Base64").Trim() [void]$out.AppendFormat("{0}{1}", "-----BEGIN PRIVATE KEY-----", [Environment]::NewLine) [void]$out.AppendFormat("{0}{1}", $base64, [Environment]::NewLine) [void]$out.AppendFormat("{0}{1}", "-----END PRIVATE KEY-----", [Environment]::NewLine) } else { # PKCS#1 requires RSA identifier in the header. # PKCS#1 is an inner structure of PKCS#8 message, therefore no additional encodings are required. $base64 = [SysadminsLV.Asn1Parser.AsnFormatter]::BinaryToString($asnblob,"Base64").Trim() [void]$out.AppendFormat("{0}{1}", "-----BEGIN RSA PRIVATE KEY-----", [Environment]::NewLine) [void]$out.AppendFormat("{0}{1}", $base64, [Environment]::NewLine) [void]$out.AppendFormat("{0}{1}", "-----END RSA PRIVATE KEY-----", [Environment]::NewLine) } $base64 = [SysadminsLV.Asn1Parser.AsnFormatter]::BinaryToString($Certificate.RawData,"Base64Header") $out.Append($base64) if ($IncludeChain) { $chain = New-Object Security.Cryptography.X509Certificates.X509Chain $chain.ChainPolicy.RevocationMode = "NoCheck" if ($certs) { $chain.ChainPolicy.ExtraStore.AddRange($certs) } [void]$chain.Build($Certificate) for ($n = 1; $n -lt $chain.ChainElements.Count; $n++) { $base64 = [SysadminsLV.Asn1Parser.AsnFormatter]::BinaryToString($chain.ChainElements[$n].Certificate.RawData,"Base64Header") $out.Append($base64) } } [IO.File]::WriteAllLines($OutputFile,$out.ToString()) #endregion } # SIG # Begin signature block # MIIvDQYJKoZIhvcNAQcCoIIu/jCCLvoCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCBpoWLr0VJkW4r # 7IM4+XwmAUPpYyOx/JJsDfPzej3vgKCCE5kwggWQMIIDeKADAgECAhAFmxtXno4h # MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z # ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z # G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ # anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s # Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL # 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb # BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 # JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c # AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx # YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 # viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL # T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud # EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf # Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk # aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS # PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK # 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB # cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp # 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg # dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri # RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 # 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 # nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 # i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H # EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggdNMIIFNaADAgECAhAObby6tbZ0sFYtkajicQ8aMA0GCSqGSIb3DQEBDAUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjYwMjA2MDAwMDAwWhcNMjkwMjI3MjM1OTU5WjBVMQsw # CQYDVQQGEwJMVjEOMAwGA1UEBwwFUsSrZ2ExGjAYBgNVBAoMEUlLICJTeXNhZG1p # bnMgTFYiMRowGAYDVQQDDBFJSyAiU3lzYWRtaW5zIExWIjCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBAKwGGasrfMfwdc37W1d3/vgvVZ5Wgfmk8Rd4sb3e # f1vZ4D2kA0sLNU1AwbwfLjnnRT0brMbrI2y/MSt10oqOFSnR7nw9AkhW/1PVZS9l # rxRYX/g/RjO+lG5TnxRTsaWUiw7clvhRipxBgWJuxky8MuUD/eTyMLu1rn6He7p/ # cp4kg6nu6ZsaPxsEY9EBTAdXzlyYS/U3NJMk8GjrLdVAlZpoONXnoB9yChIly409 # yh2xWczWIUv9ku2SFrZbB6l3YhY2inDAPKpAKyCd0xeQPKSeRoC+JXAnA1dSSRJ9 # 557LFFBfnR4XFh4E1OHuKRfTk18UjfwQqdF4cdmH5I4rR5Pqhy2shwBP8XrT26em # OhpfUAWVfJWIWcoQPq9JV/3dr8tPZgCW97dZpmu0/q3TlHS/sPASNO279diN2o/f # H0fsNPBzFSe85BCtUk3muyEhVHU3R//Lg1MSFB0BRFeAafhlsm/VvhIQ8tQvb7it # a7UB7gacdB795+XhpY0MLc0fFsrSTENxXeH5N7sIlNa3zao4l3IiNmR6lwvm6IMf # L8aRBPWg6PicLK2sXa10PDQLxee533dHuuvvpaVdpyvcEpaCHlaSKxeFhwur339D # yuaWQ37rospo/pS8oaG05edihaF7O4LRiqeVDx1RL9Yd4uPH02J284seLMKTZ7wa # Tle1AgMBAAGjggIDMIIB/zAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfRO # QjAdBgNVHQ4EFgQU8Tdc7JEZ0WMWKjWL7tfz8hanUtgwPgYDVR0gBDcwNTAzBgZn # gQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BT # MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGt # MIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz # dGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZN # aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNp # Z25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGE # MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUH # MAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH # NENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAw # DQYJKoZIhvcNAQEMBQADggIBAIRcHe3iWZ4t2G3pttGtw01+okbWPPachOEYxiGL # 2Gp7DBP3Pvfw1qEHnwULtPs0hBG/Rd8+TtKkTpyZO0E2EfIYfe/EVmXjr+6jrOnU # beRiVDMahp7ym37FhrRPzzDEihFmyzz/Ec8YmE4oeEH+0ZTKT+7F7VThVmVGWQ6x # YIGqSL3k6/Af1P1gdK+1MdQtB/E1mg+7aDqiOxCRRsfwXwLjB+LSi0GflBQZeeHf # pvogtHPWM6yMEZVZkY6sxF9jo9ewhVc9DJB86KQSxJ14vkM0OAu7Q83L8N+exia2 # XuC3C+7nuVdHB7+HHu3z/Cz1aftWuHLnVRYrhJZCZ+46YvjRFQxf+GIjqyopBfDh # DX6Oq4GlOSrJPnSnyRgNu4Mr4nOWJ2LuTzFmgJu+GmeHSLH+U2uudNdagjkjRnWQ # TOZ4hdnqG0WlhMazHMf0RGx8s3DRIX9kjttDQ3RbYUJRqMq9KVf5K+CdNYKRyqET # 4tn+ixidYWazVTgsaQi1ZxmdxmS784F5CQxLlg87xWIUlWyIA2fWWnqePxGaLZrB # pDr0KkKT6gF3z2+Bs9q3o1sOAvjP7SvaBLJHuBmC5oeKnbZa+iuVEJFQShEdfl28 # Khk3jA3RU0cOK+CJMup5FXo4mdydO2ItLKZ62vC4f2m3IinXfyh7MfUyZQ0heZMi # Who4MYIayjCCGsYCAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWdu # aW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAObby6tbZ0sFYtkajicQ8aMA0G # CWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZI # hvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcC # ARUwLwYJKoZIhvcNAQkEMSIEICWdp2o4SfRu8hvXVmpF33Za9by1sqd3y97tZY57 # OR1IMA0GCSqGSIb3DQEBAQUABIICAKkXlwEvVTU+Ojhg8O08KdwzFK0iusZlILKE # ATAMTZtlKVVpUr/+XYLJqiCQhA7dVtll4SZCPbva1L1YSgyX5greo0QhzT+7ALZP # 7HdxmxsaRxYWMoWiZNg/b5zgb/5JEzBcxocI3OVUS2I/GsYF6nARzkrjK69P40KI # u2x/Zg+afCS5WuA42WIMzFfyr0p3JiW1MljkUvc4dT+iyU3jet2vUQDWbS1rMW/h # zEFLk0pnjY04Kjxo1peQFQpYYR4+HpXxhUqAUBc2tZDxOOPqLTdIS7PWIcEjJxS+ # TGnaFNxl+pDy7CYDRkX8UYyQCIBwcHROyyGwW+52nh0FRpxN1fLRcKMQjIN1qcim # mwShve/yrGzflGUyIpe1BQBOWcO2LYwp3GeJaFuC1CvYXozDcCFeX1fPbJAxujZB # eBtpvQdRHcVQa27+YhOsyO2a9COktrRJxPNY5CxRXY8D3TNom/J1zqX/iuHUsru0 # BdhTDnQSyC7JTarnzlvkCOFt5iZ9xvBsvLjovnsUt+pPbL7KPD3e/p1qako8gy7Z # tBEsNQvPxx7tMGBnXDqftAW+0pulsegaE2DWTADVDbb5E17qg8a0hqStpRCa95Cc # uo/KT4Y7sktm8CofL7y0XqbThfY7da7eYgIMhJzbsABfXSNw6t9nTPd2bl8UBWCv # TNiKXXIOoYIXlzCCF5MGCisGAQQBgjcDAwExgheDMIIXfwYJKoZIhvcNAQcCoIIX # cDCCF2wCAQMxDzANBglghkgBZQMEAgIFADCBhwYLKoZIhvcNAQkQAQSgeAR2MHQC # AQEGCWCGSAGG/WwHATBBMA0GCWCGSAFlAwQCAgUABDDc9tXhGdFCV7zPma9owSjS # xX8z1/wdSElZFsF/6hQqUXKjyRvaCwYweU3hc1I3sBoCEFEdntJ5hUbhMUNm7M58 # OSQYDzIwMjYwNjA4MjExNTU5WqCCEzowggbtMIIE1aADAgECAhAMIENJ+dD3WfuY # LeQIG4h7MA0GCSqGSIb3DQEBDAUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5E # aWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1l # U3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwHhcNMjUwNjA0MDAwMDAw # WhcNMzYwOTAzMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFNIQTM4NCBSU0E0MDk2IFRpbWVz # dGFtcCBSZXNwb25kZXIgMjAyNSAxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEA2zlS+4t0t+XJDVHY+vNJxpv794sM3O4UQycmKRXmYLs+YRfztyl8QJ7n # /UqxNTKWmjdFDWGv43+a2oiJ41yxOe0sLoFx8F1az2JRTZc7dhAxbne+byd5bf2S # EZlCruGxxWSqbpUY6dAGRCCyBOaiFaoXhkn+L15efcomDSrTnA5Vgd9pvMO+7bM+ # tSW4JzAiIbO2mIPyCEdKYscmPl+YBuenSP7NJw9icL1tWpn61uM6WyUNv4RcyBAz # +NvJbNf5kTM7F46cvBwp0lZYisZR985y5sYj4e4yUBbPBxyrT5aNMZ++5tis8GDm # HCpqyVLQ4eLHwpim5iwR49TREfETtlEFORWTkJ2hOO1zzVAWs6jtdep12VtFZoQO # hIwdUfPHSsAw39xFVevFEFf2u+DVr1sOV7JACY+xcG8hWIeqPGVUwkiyBRUTgA7H # eAxJb0iQl4GDBC6ZBA4wGN/ahMxF4fuJsOs1zwkPBSnXmHkm18HwHgIPKk287dMI # chZyjm7zGcCYZ4bisoUYWL9oTga9JCfFMTc9yl26XDB0zl9rdSwviOmaYSlaRanF # 84oxAYnqgBy6Z89ykPgWnb7SRi31NyP359Whok+36fkyxTPjSrCWvMK7pzbRg8tf # IRlUnxl7G5bIrkPqMbD9zJoB79MHFgLr5ljU7rrcLwy+cEfpzFMCAwEAAaOCAZUw # ggGRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFFWeuednyJEQSbQ2Uo15tyTFPy34 # MB8GA1UdIwQYMBaAFO9vU0rp5AZ8esrikFb2L9RJ7MtOMA4GA1UdDwEB/wQEAwIH # gDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDCBlQYIKwYBBQUHAQEEgYgwgYUwJAYI # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBdBggrBgEFBQcwAoZR # aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGlt # ZVN0YW1waW5nUlNBNDA5NlNIQTI1NjIwMjVDQTEuY3J0MF8GA1UdHwRYMFYwVKBS # oFCGTmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRp # bWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNybDAgBgNVHSAEGTAXMAgG # BmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQEMBQADggIBABt+CySH2Alq # xUHnUWnZJI7rpdAqo0PcikyV48Ltk5QWFgxpHP9WtjR3lskEAOk3TszmuNyMid7V # uxHlQJl4KcdTr5cQ2YLy+l560peBgM7kA4HCJqGqdQdzjXyrlg3YCdfnjs9w/7BO # 8xUmlAaq/D+PTZZO+Mnxa3/IoyYsF+L9gWX4VJxZLljVs5JKmpSonnysMYv7Caqk # QpBDmJWU2F68mLLZXfU0wXbDy9QQTskgcHviyQDeB1l6jl/WwOQiSNTNafYQUR2Z # sJ5rPJu1NPzO1htKwdiUjWenHwq5BRK1BR7+D+TwG97UHX4V0W+JvFZp8z3d3G5s # A7Pt9qO5/6AWZ+0yf8nN58D+HAAShHmny25t6W7qF6VSRZCIpGr8hbAjfbBhO4MY # 8G2U9zwVKp6SljuKknxd2buihO33dioCGsB6trX++xQKf4QlYSggFvD9ZWSG4ysJ # PYOx+hbsBTEONFtr99x6OgJnnyVkDoudIn+gmV+Bq+a2G++BLU5AXOVclExpuoUQ # XUZF5p3sUrd21QjF9Ra0x4RD02gS4XwgzN+tvuY+tjhPICwXmH3ERL+fPIoxZT0X # gwVP+17UqUbi5Zpe4YdadG5WjCTBvtmlM4JVovGYRvyAyfmYJJx0/0T+qK05wRJp # g4q81vOKuCQPaE9H99JCVvfCDBm4KjrEMIIGtDCCBJygAwIBAgIQDcesVwX/IZku # QEMiDDpJhjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM # RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQD # ExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjUwNTA3MDAwMDAwWhcNMzgw # MTE0MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu # Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJT # QTQwOTYgU0hBMjU2IDIwMjUgQ0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAtHgx0wqYQXK+PEbAHKx126NGaHS0URedTa2NDZS1mZaDLFTtQ2oRjzUX # MmxCqvkbsDpz4aH+qbxeLho8I6jY3xL1IusLopuW2qftJYJaDNs1+JH7Z+QdSKWM # 06qchUP+AbdJgMQB3h2DZ0Mal5kYp77jYMVQXSZH++0trj6Ao+xh/AS7sQRuQL37 # QXbDhAktVJMQbzIBHYJBYgzWIjk8eDrYhXDEpKk7RdoX0M980EpLtlrNyHw0Xm+n # t5pnYJU3Gmq6bNMI1I7Gb5IBZK4ivbVCiZv7PNBYqHEpNVWC2ZQ8BbfnFRQVESYO # szFI2Wv82wnJRfN20VRS3hpLgIR4hjzL0hpoYGk81coWJ+KdPvMvaB0WkE/2qHxJ # 0ucS638ZxqU14lDnki7CcoKCz6eum5A19WZQHkqUJfdkDjHkccpL6uoG8pbF0LJA # QQZxst7VvwDDjAmSFTUms+wV/FbWBqi7fTJnjq3hj0XbQcd8hjj/q8d6ylgxCZSK # i17yVp2NL+cnT6Toy+rN+nM8M7LnLqCrO2JP3oW//1sfuZDKiDEb1AQ8es9Xr/u6 # bDTnYCTKIsDq1BtmXUqEG1NqzJKS4kOmxkYp2WyODi7vQTCBZtVFJfVZ3j7OgWmn # hFr4yUozZtqgPrHRVHhGNKlYzyjlroPxul+bgIspzOwbtmsgY1MCAwEAAaOCAV0w # ggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFO9vU0rp5AZ8esrikFb2 # L9RJ7MtOMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB # /wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYI # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1 # aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RH # NC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29t # L0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIw # CwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQAXzvsWgBz+Bz0RdnEwvb4L # yLU0pn/N0IfFiBowf0/Dm1wGc/Do7oVMY2mhXZXjDNJQa8j00DNqhCT3t+s8G0iP # 5kvN2n7Jd2E4/iEIUBO41P5F448rSYJ59Ib61eoalhnd6ywFLerycvZTAz40y8S4 # F3/a+Z1jEMK/DMm/axFSgoR8n6c3nuZB9BfBwAQYK9FHaoq2e26MHvVY9gCDA/JY # sq7pGdogP8HRtrYfctSLANEBfHU16r3J05qX3kId+ZOczgj5kjatVB+NdADVZKON # /gnZruMvNYY2o1f4MXRJDMdTSlOLh0HCn2cQLwQCqjFbqrXuvTPSegOOzr4EWj7P # tspIHBldNE2K9i697cvaiIo2p61Ed2p8xMJb82Yosn0z4y25xUbI7GIN/TpVfHIq # Q6Ku/qjTY6hc3hsXMrS+U0yy+GWqAXam4ToWd2UQ1KYT70kZjE4YtL8Pbzg0c1ug # MZyZZd/BdHLiRu7hAWE6bTEm4XYRkA6Tl4KSFLFk43esaUeqGkH/wyW4N7Oigizw # JWeukcyIPbAvjSabnf7+Pu0VrFgoiovRDiyx3zEdmcif/sYQsfch28bZeUz2rtY/ # 9TCA6TD8dC3JE3rYkrhLULy7Dc90G6e8BlqmyIjlgp2+VqsS9/wQD7yFylIz0scm # bKvFoW2jNrbM1pD2T7m3XDCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFow # DQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNl # cnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIz # NTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG # A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3Rl # ZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2je # u+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bG # l20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBE # EC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/N # rDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A # 2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8 # IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfB # aYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaa # RBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZi # fvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXe # eqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g # /KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB # /wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQY # MBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEF # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3Js # My5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1Ud # IAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22 # Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih # 9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYD # E3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c # 2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88n # q2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5 # lDGCA4wwggOIAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0 # LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGlu # ZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENBMQIQDCBDSfnQ91n7mC3kCBuIezANBglg # hkgBZQMEAgIFAKCB4TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZI # hvcNAQkFMQ8XDTI2MDYwODIxMTU1OVowKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU # crz9oBB/STSwBxxhD+bXllAAmHcwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgMvPj # sb2i17JtTx0bjN29j4uEdqF4ntYSzTyqep7/NcIwPwYJKoZIhvcNAQkEMTIEMMeC # 6e98u9GvDSQm5DwPRMH1mLNSR/NpLXjeh3izUZ3WYhFjaNfjykjSeG470TzjZzAN # BgkqhkiG9w0BAQEFAASCAgBl0Y5k6B2AI12E/2LV6sGo7/ITY8jA0kxVBDo/h930 # xjf4p2Fr6mGMWH1MrjlQsal68xPQ7DZYPWsrsh1Qaedy5ZTjBu4WcqN4E4qfvBJP # CGmSndjptcjHR4MczAu31rN57Mbt+6aqYGCsoDS/aA2FcrqhANU6nZAyWWM2FeBP # /TBNYXAoQseCi7pyPhex7SbVhhhK66OnG3haIwYWYMZDn1rVQkOaMd/IXdz+hQWC # 51c8VctRllJKkf3B0DEzSOpRV307ad42VNwdvXHYoJXv5sanjkujrSR2YL78d5yF # 1w+3tOST9X/W9w9VAG8lYUlUTDe9+fJxooqyCTKldd0UNVI9LOaCaqqJzg2ius13 # f468BaI0Oba6QZ5gThtx2snFaaF7D7QEn99c3sK5diPPxnZTiM/hCJTN68SOzdGW # jLjrYMBAf+LK0xKOpkTLhu0Y9RqdMWxQe+xkW5yn4cZB3BavZslQM1mtlWLQQ86k # x5xLIxTr/WKmZpP0II+fBDXIh1hWQMX105IQLjSZxkVSyj/nWplNxvu/+jSmltgk # BG3z4pjanNP32hrMLX9suY0Dn14icQ1FAlj6JT2/1EzCk3ecjSNFTbx7xIj4oMQM # SfSFYe0WsccJSgtDPXDcukUT3QXhZo/PgHA8RJMVu+Yh8+LkZMRVpqWVVHPBMga7 # ig== # SIG # End signature block |