-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SignedCms with Expired certificate but valid timestamp fails with validation #83478
Comments
Tagging subscribers to this area: @dotnet/area-system-security, @vcsjones Issue DetailsDescriptionUsing SignedCms.CheckSignature(false) fails when the certificate has expired but was countersigned before it was expired. The WinVerifyTrust function on Windows does not report an error with these signatures. Reproduction StepsHere are 2 Authenticode base64 strings of some PowerShell files that have been signed with a now expired certificate. Note these are self signed certs used for testing so they would have been to be trusted to avoid the CA trust failure. The first is one signed with a timestamp using the old Authenticode timestamp functionality:
The second is one signed with a timestamp using the RFC 3161 timestamp functionality:
The code to validate them using System;
using System.Security.Cryptography.Pkcs;
namespace Authenticode;
public class Signature
{
public static void Main(string[] args)
{
byte[] data = Convert.FromBase64String("...");
SignedCms signInfo = new SignedCms();
signInfo.Decode(data);
signInfo.CheckSignature(false);
}
} Expected behaviorIt to not fail with an expired cert error like Actual behaviorOn Windows the error is:
On Linux the error is:
Regression?No response Known WorkaroundsNo response ConfigurationDotnet Version: 7.x I don't believe it is specific to the configuration, although the error messages returned are. Other informationHere is some PowerShell code I am using to verify the trust information with #Requires -Module Ctypes
param ($Path)
ctypes_struct WINTRUST_FILE_INFO {
[int]$CbStruct
[MarshalAs('LPWStr')][string]$FilePath
[IntPtr]$File
[IntPtr]$KnownSubject
}
ctypes_struct WINTRUST_DATA {
[int]$CbStruct
[IntPtr]$PolicyCallbackData
[IntPtr]$SIPClientData
[int]$UIChoice
[int]$RevocationChecks
[int]$UnionChoice
[IntPtr]$Choice
[int]$StateAction
[IntPtr]$StateData
[IntPtr]$URLReference
[int]$ProvFlags
[int]$UIContext
[IntPtr]$SignatureSettings
}
$WINTRUST_ACTION_GENERIC_VERIFY_V2 = [Guid]::new("00AAC56B-CD44-11d0-8CC2-00C04FC295EE")
$WTD_UI_NONE = 2
$WTD_CHOICE_FILE = 1
$WTD_STATEACTION_VERIFY = 1
$fileInfo = [WINTRUST_FILE_INFO]@{
CbStruct = [System.Runtime.InteropServices.Marshal]::SizeOf([type][WINTRUST_FILE_INFO])
FilePath = $Path
}
$fileInfoPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($fileInfo.CbStruct)
try {
[System.Runtime.InteropServices.Marshal]::StructureToPtr($fileInfo, $fileInfoPtr, $false)
$data = [WINTRUST_DATA]@{
CbStruct = [System.Runtime.InteropServices.Marshal]::SizeOf([type][WINTRUST_DATA])
UIChoice = $WTD_UI_NONE
StateAction = $WTD_STATEACTION_VERIFY
UnionChoice = $WTD_CHOICE_FILE
Choice = $fileInfoPtr
}
$wintrust = New-CtypesLib wintrust.dll
$res = $wintrust.WinVerifyTrust(
$null,
[ref]$WINTRUST_ACTION_GENERIC_VERIFY_V2,
[ref]$data
)
if ($res) {
throw "Trust failed - {0} 0x{0:X8}" -f $res
}
}
finally {
[System.Runtime.InteropServices.Marshal]::FreeHGlobal($fileInfoPtr)
} The 2 PowerShell files I've used to verify this behaviour are in the collapsable section below. These files are where I got the PKCS 7 data for the Reproduction Steps section. Windows is correctly validating both of these files without any errors due to the presence of the counter signature signed when the certs were still valid. Please note these files use Click to get .ps1 test filesAuthenticode TimestampWrite-Host test
# SIG # Begin signature block
# MIIehAYJKoZIhvcNAQcCoIIedTCCHnECAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBWYryjZjo1cjdJ
# eX1p42umeyEBm4NaeKGQxt09ACzoa6CCF+IwggTXMIICv6ADAgECAgkA0cnLHrL9
# eEIwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UEAxMKUG93ZXJTaGVsbDAeFw0yMzAz
# MTQyMDM4MzFaFw0yMzAzMTUyMDQzMzFaMBUxEzARBgNVBAMTClBvd2VyU2hlbGww
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwH926aUCIoMbG8rjAavLP
# lTSEJ20S4JoilIKatvJY432v5/gtH+jNMv8qRvrAaceLuo2AusOn68WjW3ZxcZR2
# yAh3llWvaxEfFc/N06Re242LxXGdK8XUq3NPqQkHkPiIFaW4SX6PsQ8R3su9MM66
# WsNvz5/78MYpvbtN7QiXKTfEudpI/QdLYPOHaCQXEr8PzW0g5wx6JMHa/3YewMRK
# YVvsEwBbVGt+5/YMRFZzLcloOYal4W8abUoLxYMT/uoy0MmYz3pmtAiIdLKzOgU1
# +C/1MhrdjGfXF88EHVqHnyyk042pyTmaXAAneAarfyelTmLVTrVO8FVF85iUaDjx
# lSY49V7gjrD8hNcHz/UYK3+RCfXJF35tn+Q3DkfuuooD4GOnMGPUNSY1fqS42q6l
# AAub0eufl4sxRfHw2cqyM2+bBz8gih+gzNf6y0E83D4jbryWr/gkPO8lOqU4mgJc
# yl60/GpkHaLyioln7VLPwT8ay4jXvJqvFw9p1pDBXKhe98enip8PGmmiCESv6HcD
# YEAeNfkO6Pz1RMgDB4yzIcYA13ZEGUTByfoC8JhD2VbsVOHUM/5pviI4eTW39W9e
# lCbKQmasVeavoGaHikGua75h/pL+0uORrJBZxkyxJaG4YQ5BTU+YUvQvJPw6blB6
# bk8Z1WbNN8WW6E1v/8Do8QIDAQABoyowKDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0l
# AQH/BAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggIBAEUQDpyRT3pBX+Ya
# leFXrgBw+QJMEuzwPu+uZI++HR4Crk4h0BIFFwkS0yx6XQlPZT33F3kZ73IXfVsm
# 9FQ99ZqahqyO+aWUz/AAkWM00MD2DTnFWqcRe8hl6BW7tverNXaWDXEAJwJSwY8F
# slBUYeMQMgLwtKVBlu0SnA18GQn+M5KRpsgOUvzTI6LACvRS6y/ehwBN4kR9tilu
# 9t8jqVeKyTN0b2kZ59Ht7C4+J3XnA7Zp9Vr1SlSZ9dLIrQw5HeMasSmDheiFaRBb
# VGmFMcselHxQwCN5kDV9jzDjrmAnIwoDPFSlzG/GRJCQAK6XgXUH8RdVLkj9Tq79
# HXTNCwu+M/pqqPAK6FxQr806KTglqRGWsZF41HJCIttRwWQevqjjEck1MzOYemVw
# I4m5N1I9xvUqfie5Ba+I3Efy4WjhPGLG4b4M+DijnbUKv/iwiCEznztMiKVhcYp+
# EXzHzM5Pr5nUMZsIHv2kAyCl8H7+aLYsJQWdzG7CCGic3nv7bkxXqfDE1AY2xufp
# 8Yy8OCnA2mnt2jHLZA0r/oN/3KkodVhvBSwFfXhjBLtupwp0EKeMAQ4dXH/oQF0o
# 9ExZUI5/ppkVuEW/AobqYCUNEcpn4roZoBia84dt7bfGHnaXgyECn2bvbIB300qY
# QwmOepFYRpTWni94nsD237f6cKkOMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21Di
# CEAYWjANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGln
# aUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtE
# aWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzEx
# MTA5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBU
# cnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/
# 5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xuk
# OBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpz
# MpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa
# vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qT
# XtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRz
# Km6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRc
# Ro9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADk
# RSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMY
# RJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4m
# rLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C
# 1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYD
# VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYD
# VR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkG
# CCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
# Y29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
# aUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6
# Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmww
# EQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+g
# o3QbPbYW1/e/Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0
# /4C5+KH38nLeJLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnL
# nU+nBgMTdydE1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU9
# 6LHc/RzY9HdaXFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ
# 9VVrzyerbHbObyMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9X
# ql4o4rmUMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0B
# AQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVk
# IFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYD
# VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lD
# ZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKR
# N6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZz
# lm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1Oco
# LevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH
# 92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRA
# p8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+g
# GkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU
# 8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/
# FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwj
# jVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQ
# EgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUae
# tdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAw
# HQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LS
# cV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEF
# BQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
# Z2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYy
# aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5j
# cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB
# CwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftw
# ig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalW
# zxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQm
# h2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScb
# qyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLaf
# zYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbD
# Qc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0K
# XzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm
# 8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9
# gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8a
# pIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBsAwggSo
# oAMCAQICEAxNaXJLlPo8Kko9KQeAPVowDQYJKoZIhvcNAQELBQAwYzELMAkGA1UE
# BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2Vy
# dCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0y
# MjA5MjEwMDAwMDBaFw0zMzExMjEyMzU5NTlaMEYxCzAJBgNVBAYTAlVTMREwDwYD
# VQQKEwhEaWdpQ2VydDEkMCIGA1UEAxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIg
# LSAyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz+ylJjrGqfJru43B
# DZrboegUhXQzGias0BxVHh42bbySVQxh9J0Jdz0Vlggva2Sk/QaDFteRkjgcMQKW
# +3KxlzpVrzPsYYrppijbkGNcvYlT4DotjIdCriak5Lt4eLl6FuFWxsC6ZFO7Khbn
# UEi7iGkMiMbxvuAvfTuxylONQIMe58tySSgeTIAehVbnhe3yYbyqOgd99qtu5Wbd
# 4lz1L+2N1E2VhGjjgMtqedHSEJFGKes+JvK0jM1MuWbIu6pQOA3ljJRdGVq/9XtA
# bm8WqJqclUeGhXk+DF5mjBoKJL6cqtKctvdPbnjEKD+jHA9QBje6CNk1prUe2nhY
# HTno+EyREJZ+TeHdwq2lfvgtGx/sK0YYoxn2Off1wU9xLokDEaJLu5i/+k/kezbv
# BkTkVf826uV8MefzwlLE5hZ7Wn6lJXPbwGqZIS1j5Vn1TS+QHye30qsU5Thmh1EI
# a/tTQznQZPpWz+D0CuYUbWR4u5j9lMNzIfMvwi4g14Gs0/EH1OG92V1LbjGUKYvm
# QaRllMBY5eUuKZCmt2Fk+tkgbBhRYLqmgQ8JJVPxvzvpqwcOagc5YhnJ1oV/E9mN
# ec9ixezhe7nMZxMHmsF47caIyLBuMnnHC1mDjcbu9Sx8e47LZInxscS451NeX1XS
# fRkpWQNO+l3qRXMchH7XzuLUOncCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIH
# gDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZ
# MBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2
# mi91jGogj57IbzAdBgNVHQ4EFgQUYore0GH8jzEU7ZcLzT0qlBTfUpwwWgYDVR0f
# BFMwUTBPoE2gS4ZJaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1
# c3RlZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUH
# AQEEgYMwgYAwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBY
# BggrBgEFBQcwAoZMaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
# VHJ1c3RlZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG
# 9w0BAQsFAAOCAgEAVaoqGvNG83hXNzD8deNP1oUj8fz5lTmbJeb3coqYw3fUZPwV
# +zbCSVEseIhjVQlGOQD8adTKmyn7oz/AyQCbEx2wmIncePLNfIXNU52vYuJhZqMU
# KkWHSphCK1D8G7WeCDAJ+uQt1wmJefkJ5ojOfRu4aqKbwVNgCeijuJ3XrR8cuOyY
# QfD2DoD75P/fnRCn6wC6X0qPGjpStOq/CUkVNTZZmg9U0rIbf35eCa12VIp0bcrS
# BWcrduv/mLImlTgZiEQU5QpZomvnIj5EIdI/HMCb7XxIstiSDJFPPGaUr10CU+ue
# 4p7k0x+GAWScAMLpWnR1DT3heYi/HAGXyRkjgNc2Wl+WFrFjDMZGQDvOXTXUWT5D
# mhiuw8nLw/ubE19qtcfg8wXDWd8nYiveQclTuf80EGf2JjKYe/5cQpSBlIKdrAqL
# xksVStOYkEVgM4DgI974A6T2RUflzrgDQkfoQTZxd639ouiXdE4u2h4djFrIHprV
# wvDGIqhPm73YHJpRxC+a9l+nJ5e6li6FV8Bg53hWf2rvwpWaSxECyIKcyRoFfLpx
# tU56mWz06J7UWpjIn7+NuxhcQ/XQKujiYu54BNu90ftbCqhwfvCXhHjjCANdRyxj
# qCU4lwHSPzra5eX25pvcfizM/xdMTQCi2NYBDriL7ubgclWJLCcZYfZ3AYwxggX4
# MIIF9AIBATAiMBUxEzARBgNVBAMTClBvd2VyU2hlbGwCCQDRycsesv14QjANBglg
# hkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3
# DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV
# MC8GCSqGSIb3DQEJBDEiBCAp5V6eZBH6QjWLAZghhEKm8BDpQfO3XcRLMgKTz+Qo
# WTANBgkqhkiG9w0BAQEFAASCAgCHG9QjzwkI7yuZv00SPTUJxSZS23trrb8ss/pz
# QJywAShxpq1SE4qem/pkwFdhRbbv5pSRxHj2SnA0JdONKu3AYD/Y1t7UnpeQmYXQ
# K4RHvnum0JMaMfzEIKangvYsNAf6BbRJe2o0DMrrhKL7UJeJl3dr/aXIRxiVF2q/
# pXeQXVhZu1arm20GMyvYIjCK8Axma1cM2+t5xRVx/ujVnM9/NmV9j1ukhrxYdSwV
# 3osxOgyr8dlWscCc3bl7sSrq6qIEHGPjHsdcqR06ZulZhPdMq7IEkJksag+Tfi+t
# oImii+fwhuYbT7W7eMxINStC4yWhGDg6xZmz+TJDddqC3TuGmaoiBJMh6iLaTWf6
# a7K/Ypazc99YZ1Z2EIV649xqVl4hDxOP/BE2TZogxSloPZHlY5IxiyM0S1413tct
# N5dllUbWMWNGyC6iWe3+14BW+rornbUPo6IA8BENRPQG2J0WAWDeNw6HeH27Qt37
# wnqAHnrlNg1rGOoCDq1Skzr2nOHi3erQA68Jd4aONqjPQ6J/g2ohM+sbcLpoIhUT
# vL7iTyZMI4Lb4cWCaHSr/6F6dZ0NE1fQZ3pAXgK9sFx1bep4Mshu84qPC63HOsRO
# FxR0ypbdUpwl0xw3Y9urfwQMdTg+fECMJ3rRrdYsuNGu2zSaspkLMfDMA6hSMeDo
# +8Af3qGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYT
# AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQg
# VHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAxNaXJL
# lPo8Kko9KQeAPVowDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZI
# hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMzAzMTUyMDM4MzdaMC8GCSqGSIb3DQEJ
# BDEiBCCLhacUFaBSCQ2YRdmF2bd0vIDxDA9iHZCtBnK68oo73TANBgkqhkiG9w0B
# AQEFAASCAgBDe/aboSbY+kOB0318AmEDpuVUPoxnGeg6SY6cQa0ZiL0qOxFTBUmS
# G/Okg3Rg7+PSebnaT272/ukBqjdNL8bTI0zDfJbkUQzWcTDXaJu6qQX/glVRo4GD
# 23eOHFwzB6+bzjbDJaKiTGlHGLJN1D5IBwNfbWOOny08ZnfKuhPIVDQHeZL7O4H/
# FEwgQoYKINvHzc3ocM6MwBPlb6pbc/dxlnOmQHliFGx+hlnaA44rEPyGWKP2ZYbX
# m2htxBVUQFmXOtATwY642sS029JVVQJ7rCb+5Nbn52t2p7CJBOXAJuco6KwNEfjA
# 89ytOEZU7FgsQot6OZglmQ8gKWhTDcPMhz/k8FX5aF6UUtqGrhfw7ddK6y9e89TB
# 2zpS8BqQ6cvUN/P6Lf0VhYsv583Nq2MDYVddKDsICSzfrC4Dy4sjoClB0elaekis
# minOgpdMqmJ3UtE/MzDkvvXXtN0qPBQjymx+SoTnwX7EjaQ5GdTr77Yt1Z4aH2q3
# QAWRcF6YQpijJVkjVRP1XitykjGxSIzdbFn7GsvZ37BgyfmSCW3f9n+nq67Ss4bb
# n9xcgzEk2qhkxoAp3WA2iALdOydavO3Vhxs3u2dko/iqdkQ3z4ubhP60bf1m0U8w
# a39ZYqAx4IpXu4EAlfDTHVJkWU5PU9l/Wohy+0NoHZ10pKI8SzUzOg==
# SIG # End signature block RFC 3161 TimestampWrite-Host test
# SIG # Begin signature block
# MIIfmQYJKoZIhvcNAQcCoIIfijCCH4YCAQMxDTALBglghkgBZQMEAgEwewYKKwYB
# BAGCNwIBBKBtBGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBaNEv+Ne+U+glD
# iFrbl8Ct5Gf+ataCxj80K+LzYzeavaCCBNswggTXMIICv6ADAgECAgkApr9gS57+
# nmAwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UEAxMKUG93ZXJTaGVsbDAeFw0yMzAz
# MTQxOTEyMjBaFw0yMzAzMTUxOTQyMjBaMBUxEzARBgNVBAMTClBvd2VyU2hlbGww
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCfwd4HfoBff9LHby3DWv+u
# TaM9ucOiI5AbVpSsXcjUr7kVQ52ootrpqniox8cAJrGoN4XJvV353eenq64kQheX
# lYvZxs3i8prr/VevA0VLvByMJva2sdkjxeIixFE1jP65W02TOS7cYRMxIBUnS/ix
# OAV1HiiSAZ1/f14UrtsN0P3ueujffNxVBknW6qhgRYVyLzetybBfVVKlUEmGybr/
# uCCzbSyl9EG9stHk7aQUfZL/xzhU8gFmTsh8K4eTFDDMnNzRt3D3OOhNaAQQ+5uW
# CkvdblNwR8kASLTKvHhpe3zzCgwz+3CPExtC/Qz4mT7K77jBuwRy4zl7rEqPWlKk
# Guln9ujO1KtCJFKy3V8jlvld2tg4BWLJag4Z6/8WopO4U/YeNpfqPhfgjWpF9XPQ
# tW4C8UHsNnRbPu6RZhtF+blHDbV7+GM4T02HZBnhD654woUe61cUU1wJ3iZF5QyS
# 0eL2A58muFdWyM4Kcu9uDmBnkIaQXf4XECTsU6h9+4tb+kkszn3Xzs2Nc20YpIAW
# VvzcT3cw0noiDzMlblz4APBiCC5ATPNFHaElpRzWiPD31LXDw8HPkhm5sLcO5Hf0
# pRfZ15zjFZnua/lpz9/YPUxf9hqWlsP0i0TM0XMtb/OPj06F++ZbEPHwTc7pKaYN
# 2ptSUVzBGiFGQrwfDTW6UwIDAQABoyowKDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0l
# AQH/BAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggIBAJ6MYEI/NrvrUBjv
# nYGoYQJksc9m6SOejFt0jZ2xQlpBCfLtChwB8dQWuaUpgVwNKlckodbmkdohh+3S
# 58OgSfapV3bemyzO0cXlO2+tynTsTnr+nsF2WC05Y3zcCrUf38yhNL11iOXxh63m
# wlJvsbmE9jCfziOx9Cw7923bXEIfThyh9OFkquNkXdX5vyYLdl3NIq6l+jeZfY7I
# l3agp0/TjFv0Hz3tba9gK4XSw3ir+UqGKr5LwlcIaA5PAYbyvm8TmhkNzN8KZBvo
# w08/VQ6Jc8LqFOzGkdQTPVk46t3pNnvppnw89JAy519njE2pQsk9vBR7lz5ALx7U
# rjYK+iU2PEgEk8ptOWZGfzghpDHU2CJOdbvhiFx+uvGU/joCFZ+JmsbRmq2qbZpN
# T77K477m7j20RjHFwEYB+STDzlZgFLEzo2kgIIDy4rxe/DIx1nK2nMAyb7nEBxxq
# 7euxKBtHhEsU2aBX0wpNbWMtNOTeGBGr5z4SPZei22wWEyyPXXcU3FS3gIwwetOx
# GFoH8VnlxRaxi6ZelSwPwLfakJtswL4wgWLJjkTvX4qBVjLAlNFuY7CUO8CjwYHe
# Yy0abL1iLPmZGIFcSXxvMnAheK+r9pPOFF9d/mTWOw8IHQdovgaxkurgClt8RMW3
# IrzRuG4R+A7aR3SiKpjKYdFQ7KkcMYIaFDCCGhACAQEwIjAVMRMwEQYDVQQDEwpQ
# b3dlclNoZWxsAgkApr9gS57+nmAwCwYJYIZIAWUDBAIBoHwwEAYKKwYBBAGCNwIB
# DDECMAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIIAulLQTO7GoXVAIp3Kt0pmC
# BTLme/oYiEVvdbIXP5baMAsGCSqGSIb3DQEBAQSCAgAjawJWoj86wLXTBpFDg6ng
# yPOmNNIIhkczeyGWy0stomQHqyj5NdwsfDcRmfHmIJuADr1349dXuEEehfbTSki8
# Cq8m+TdnA1ovTYHzFPqZlkFk81wGwBhVNwcylHyvbJ9FScG7H6unqwI2L92tooTW
# OBI8gHQrZx3tcdc0QVKoRkEhfg+BwRhryiIOy6emorRQMWgJr28k1BIwev1d/N7u
# COPZnAho0w14LWoWua1Ga9RM7ni8v1JxYkVVVtcGCNfphLhriqT9+B8WV4aLmgMt
# l8+4FLkPjJzlUMCv9knzwVxWg3LPrbUWi6nRyti5eulOpAAxYSZ+7dnBGQkqZRSk
# TdQW1HlRCDSUPgVKj2j+yfYUh3FWLtCt8Q29VOtUIXB93PDOqjxlJ/D2TT06PJep
# HDt7PPkT2/2qrZvzJLrw6zp5WjLesAasQVu8AVGSPnE7CwQi8aD4HlOzPV/uBsC4
# WJM200gbUnk3yeOQPYDw3cP4ea3rZ5s9tl4JNPxCrKnkjPrIvsGV6puBdXzRQLUH
# qXk+ASlfLbTbzKFYogEIsO4USi7rHfe9kU78hAG3MGWN9GRYCRrPRCSWgxvFu0NN
# vZLDE2e5B3w5B6s776DG3TvWI6qcVXBotGlm9qX6se5KjBOVDmAhApKTQOY7v8yH
# MWu05GLNplWLcHvvz99UtKGCF0kwghdFBgorBgEEAYI3AwMBMYIXNTCCFzEGCSqG
# SIb3DQEHAqCCFyIwghceAgEDMQ8wDQYJYIZIAWUDBAIBBQAwgYIGCyqGSIb3DQEJ
# EAEEoHMEcTBvAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQgXGFtF8hP
# K5tnyM4Yvcr7ZiZpOFuTFFvT8ck4UFVuwAACEQDqREbe4dpMubzZcmszYtI5GA8y
# MDIzMDMxNTE5MTMwMVoCCHYbQTDn3aVroIITBzCCBY0wggR1oAMCAQICEA6bGI75
# 0C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNV
# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIG
# A1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAw
# MFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGln
# aUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuE
# DcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNw
# wrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs0
# 6wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e
# 5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtV
# gkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85
# tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+S
# kjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1Yxw
# LEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzl
# DlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFr
# b7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATow
# ggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiu
# HA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQE
# AwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
# Z2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2
# hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290
# Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/
# Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNK
# ei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHr
# lnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4
# oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5A
# Y8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNN
# n3O3AamfV6peKOK5lDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJ
# KoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu
# YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQg
# VHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVow
# YzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQD
# EzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGlu
# ZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklR
# VcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54P
# Mx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupR
# PfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvo
# hGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV
# 5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYV
# VSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6i
# c/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/Ci
# PMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5
# K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oi
# qMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuld
# yF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAG
# AQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAW
# gBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAww
# CgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8v
# b2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDow
# OKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRS
# b290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkq
# hkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvH
# UF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0M
# CIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCK
# rOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rA
# J4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZ
# xhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScs
# PT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1M
# rfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXse
# GYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWY
# MbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYp
# hwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPww
# ggbAMIIEqKADAgECAhAMTWlyS5T6PCpKPSkHgD1aMA0GCSqGSIb3DQEBCwUAMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwHhcNMjIwOTIxMDAwMDAwWhcNMzMxMTIxMjM1OTU5WjBGMQswCQYDVQQGEwJV
# UzERMA8GA1UEChMIRGlnaUNlcnQxJDAiBgNVBAMTG0RpZ2lDZXJ0IFRpbWVzdGFt
# cCAyMDIyIC0gMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/spSY6
# xqnya7uNwQ2a26HoFIV0MxomrNAcVR4eNm28klUMYfSdCXc9FZYIL2tkpP0GgxbX
# kZI4HDEClvtysZc6Va8z7GGK6aYo25BjXL2JU+A6LYyHQq4mpOS7eHi5ehbhVsbA
# umRTuyoW51BIu4hpDIjG8b7gL307scpTjUCDHufLckkoHkyAHoVW54Xt8mG8qjoH
# ffarbuVm3eJc9S/tjdRNlYRo44DLannR0hCRRinrPibytIzNTLlmyLuqUDgN5YyU
# XRlav/V7QG5vFqianJVHhoV5PgxeZowaCiS+nKrSnLb3T254xCg/oxwPUAY3ugjZ
# Naa1Htp4WB056PhMkRCWfk3h3cKtpX74LRsf7CtGGKMZ9jn39cFPcS6JAxGiS7uY
# v/pP5Hs27wZE5FX/NurlfDHn88JSxOYWe1p+pSVz28BqmSEtY+VZ9U0vkB8nt9Kr
# FOU4ZodRCGv7U0M50GT6Vs/g9ArmFG1keLuY/ZTDcyHzL8IuINeBrNPxB9Thvdld
# S24xlCmL5kGkZZTAWOXlLimQprdhZPrZIGwYUWC6poEPCSVT8b876asHDmoHOWIZ
# ydaFfxPZjXnPYsXs4Xu5zGcTB5rBeO3GiMiwbjJ5xwtZg43G7vUsfHuOy2SJ8bHE
# uOdTXl9V0n0ZKVkDTvpd6kVzHIR+187i1Dp3AgMBAAGjggGLMIIBhzAOBgNVHQ8B
# Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAg
# BgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZ
# bU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFGKK3tBh/I8xFO2XC809KpQU31Kc
# MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAG
# CCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
# dC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQw
# DQYJKoZIhvcNAQELBQADggIBAFWqKhrzRvN4Vzcw/HXjT9aFI/H8+ZU5myXm93KK
# mMN31GT8Ffs2wklRLHiIY1UJRjkA/GnUypsp+6M/wMkAmxMdsJiJ3HjyzXyFzVOd
# r2LiYWajFCpFh0qYQitQ/Bu1nggwCfrkLdcJiXn5CeaIzn0buGqim8FTYAnoo7id
# 160fHLjsmEHw9g6A++T/350Qp+sAul9Kjxo6UrTqvwlJFTU2WZoPVNKyG39+Xgmt
# dlSKdG3K0gVnK3br/5iyJpU4GYhEFOUKWaJr5yI+RCHSPxzAm+18SLLYkgyRTzxm
# lK9dAlPrnuKe5NMfhgFknADC6Vp0dQ094XmIvxwBl8kZI4DXNlpflhaxYwzGRkA7
# zl011Fk+Q5oYrsPJy8P7mxNfarXH4PMFw1nfJ2Ir3kHJU7n/NBBn9iYymHv+XEKU
# gZSCnawKi8ZLFUrTmJBFYDOA4CPe+AOk9kVH5c64A0JH6EE2cXet/aLol3ROLtoe
# HYxayB6a1cLwxiKoT5u92ByaUcQvmvZfpyeXupYuhVfAYOd4Vn9q78KVmksRAsiC
# nMkaBXy6cbVOepls9Oie1FqYyJ+/jbsYXEP10Cro4mLueATbvdH7WwqocH7wl4R4
# 4wgDXUcsY6glOJcB0j862uXl9uab3H4szP8XTE0AotjWAQ64i+7m4HJViSwnGWH2
# dwGMMYIDdjCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl
# cnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBT
# SEEyNTYgVGltZVN0YW1waW5nIENBAhAMTWlyS5T6PCpKPSkHgD1aMA0GCWCGSAFl
# AwQCAQUAoIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0B
# CQUxDxcNMjMwMzE1MTkxMzAxWjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBTzhyJN
# hjOCkjWplLy9j5bp/hx8czAvBgkqhkiG9w0BCQQxIgQgYsWTfaWXTMtlhLhoLMR8
# GLFVGc0U5R0NszqYyGeph0EwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQgx/ThvjIo
# iSCr4iY6vhrE/E/meBwtZNBMgHVXoCO1tvowDQYJKoZIhvcNAQEBBQAEggIAiDWS
# GTm7kFhbVZOPr5pY76EVwzyDrxRvWRCh+2HwicG81hxq8JS7nRnPo7Jyh0M7XmTc
# yHkLyF0bf5KL93u9MMnwK/K/qKLuJDVkyCIIAd6RCG7JcAATzhmw7aJfLRqBqP/W
# VYlkjFUXkBHwapE75sTfq81AUJbo5r9bzOjP92SnUUe0ImTdNFn7oDFB7InzYzls
# 2t+j9ngz7rzgaLkvmgoELJ0UlXNtKudffy5msUQ2b6rZdubyHr+jSkcpNhWCkQhF
# 6EauruUmr03HDe7200u1MTTMBK9Z/rbK7txoTpfI5JZk/x9Zby0Bi89yxeKEGLoL
# kGr0a1KqE1KcAv6BFOphGvafLnocABLxXWYkJaSO95V6CtGr3PASIOtEWuWujvwy
# LkqED7yGiCZv9fFVA7e23esZxfVijoMtFH586yhhpC8ZU6G6KnGxEINfVwhZE27n
# Ab9lgDq8R8d7HKu7S5WzYEOjIC3opFlN0XRB2h96LStfRkEQFWP6jFf+atV/qhHe
# RJrkK0M+7tvwvO8LNyVOlbk+bLXi3VTiXUHtyAgf4xmT4dO7ISrWb36E6/RAM3/d
# kJfDy4jMY85wJC9zxOywaC8HOVYszroiVNVI5Q+CVpuXNIRfo8lmBkh9I7l/Ieal
# kbGz6Ce3oBt5+fyQjT7xEt3ogiqlytmIv1lD5aU=
# SIG # End signature block
|
As a workaround I've defined a custom extension method that implements public static void CheckSignature(this SignerInfo info, bool verifySignatureOnly, DateTime? verificationTime)
{
info.CheckSignature(true);
if (verifySignatureOnly)
{
return;
}
X509Certificate2 certificate = info.Certificate
?? throw new CryptographicException("Failed to find signing certificate");
X509Chain chain = new();
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
if (verificationTime != null)
{
chain.ChainPolicy.VerificationTime = (DateTime)verificationTime;
}
if (!chain.Build(certificate))
{
X509ChainStatus status = chain.ChainStatus.FirstOrDefault();
throw new CryptographicException(
$"Certificate trust could not be established. The first reported error is: {status.StatusInformation}");
}
const X509KeyUsageFlags SufficientFlags =
X509KeyUsageFlags.DigitalSignature |
X509KeyUsageFlags.NonRepudiation;
foreach (X509Extension ext in certificate.Extensions)
{
if (ext.Oid!.Value != "2.5.29.15") // KeyUsage
{
continue;
}
if (!(ext is X509KeyUsageExtension keyUsage))
{
keyUsage = new X509KeyUsageExtension();
keyUsage.CopyFrom(ext);
}
if ((keyUsage.KeyUsages & SufficientFlags) == 0)
{
throw new CryptographicException("The certificate is not valid for the requested usage.");
}
}
} I then have custom code to extract the counter signature timestamp and pass that in if it was present. On a side note, the SignerInfo.CounterSignerInfos property only seems to be populated when encountering a certificate signed using the Authenticode timestamp OID. If the signature was counter signed using the RFC 3161 method this is absent and I had to manually go through the unsigned attributes to extract this value. I'm not sure if this is intentional or not but something I wanted to point out. |
Thanks for reporting this, @jborean93. For this new behavior, I expect we'd need to offer more control over the validation so that this behavior could be controlled through the call to I'm setting this to the Future milestone. For this to move forward, we'd need an API proposal that shows how control over the aspects of validation could be achieved. |
There are quite a few options here, so I think a new public class SignerInfo
{
+ CheckSignature(SignatureVerificationOptions verificationOptions);
}
+public class SignatureVerificationOptions
+{
+ // If empty, the system trust store is used.
+ public X509Certificate2Collection CustomTrustStore { get; set; } = new();
+ // Corresponds to passing false to SignerInfo.CheckSignature(false)
+ public bool VerifySigningCertificateChain { get; set; } = true;
+ public bool VerifySigningCertificatePurposes { get; set; } = true;
+ // If true, the certificate's timestamps will be verified using the Authenticode/RFC3161 timestamps (if present.)
+ // This means if both are true and both types of timestamps are present, the certificate will be checked twice.
+ // The thrown exception will need to make it clear which timestamp failed verification.
+ public bool VerifyAuthenticodeTimestamp { get; set; } = true;
+ public bool VerifyRfc3161Timestamp { get; set; } = true;
+ // Very similar to VerifySigningCertificateChain and VerifySigningCertificatePurposes, but these apply to the
+ // timestamping certificates. The same properties will apply both to Authenticode and RFC3161.
+ public bool VerifyTimestampingCertificateChain { get; set; } = true;
+ public bool VerifyTimestampingCertificatePurposes { get; set; } = true;
+ // X509ChainPolicy to use when verifying the timestamping certificate. The DisableCertificateDownloads,
+ // RevocationFlag, RevocationMode, TrustMode, UrlRetrievalTimeout and VerificationFlags properties from this
+ // object will be used to verify the timestamping certificate. X509ChainPolicy.CustomTrustStore will be replaced
+ // by the CustomTrustStore property. If null, a default (strict) X509ChainPolicy will be used.
+ public X509ChainPolicy? TimestampCertificateChainPolicy { get; set; } = null;
+} Adding this feature might help PowerShell Core - a managed implementation of Authenticode/RFC3161 timestamping unlocks Get-AuthenticodeSignature on Linux, which opens the way for meaningful cross-platform script signing verification. This is partially tracked by PowerShell/PowerShell#1159 and PowerShell/PowerShell#5770, which were opened in 2016/2018 respectively. It'd be quite a while before I could get around to writing this timestamp verification logic, but if this goes through an API review then the external interface is ready, so someone else can pick this up if they want to do it sooner. Is this enough detail for an API proposal @jeffhandley? |
@edwardneal you might be interested in https://github.com/jborean93/PowerShell-OpenAuthenticode which is what prompted me to open up this issue. I’m using the workaround I mentioned in a comment for now. |
With Azure Trusted Signing in public preview, this will probably be necessary to validate the generated certificates. These certificates are only valid for three days, so we need to use the timestamp from the timestamp token when checking the certificate validity. There might also be some overlap with PowerShell/PowerShell#21550, although I've not got any way to check that directly against ATS. @dotnet/area-system-security, @vcsjones what's the best approach to start the API proposal? I can raise a new issue specifically for that if it's easier to manage. |
Description
Using SignedCms.CheckSignature(false) fails when the certificate has expired but was countersigned before it was expired. The WinVerifyTrust function on Windows does not report an error with these signatures.
Reproduction Steps
Here are 2 Authenticode base64 strings of some PowerShell files that have been signed with a now expired certificate. Note these are self signed certs used for testing so they would have been to be trusted to avoid the CA trust failure.
The first is one signed with a timestamp using the old Authenticode timestamp functionality:
The second is one signed with a timestamp using the RFC 3161 timestamp functionality:
The code to validate them
Expected behavior
It to not fail with an expired cert error like
WinVerifyTrust
doesn't for an expired cert that was counter signed with a valid timestamp. If this can't happen it would be nice to have a way to determine whether the failure was due to an expired timestamp or whether it was something else, like an untrusted root/partial chain/etc. Currently the exception thrown has a platform specific error message which makes it harder to determine the root cause.Actual behavior
On Windows the error is:
On Linux the error is:
Regression?
No response
Known Workarounds
No response
Configuration
Dotnet Version: 7.x
OS: Tested on Windows and Linux
Architecture: x64
I don't believe it is specific to the configuration, although the error messages returned are.
Other information
Here is some PowerShell code I am using to verify the trust information with
WinVerifyTrust
. It's PowerShell code using my module Ctypes.The 2 PowerShell files I've used to verify this behaviour are in the collapsable section below. These files are where I got the PKCS 7 data for the Reproduction Steps section. Windows is correctly validating both of these files without any errors due to the presence of the counter signature signed when the certs were still valid. Please note these files use
\r\n
line endings.Click to get .ps1 test files
Authenticode Timestamp
RFC 3161 Timestamp
The text was updated successfully, but these errors were encountered: