Accepting request 255752 from home:jsegitz:branches:devel:openSUSE:Factory

- Fixed buffer overflow and OOB access in shim trusted code path
  (bnc#889332, CVE-2014-3675, CVE-2014-3676, CVE-2014-3677)
  * added bug-889332_shim-mok-oob.patch, bug-889332_shim-overflow.patch
- Added new certificate by Microsoft

OBS-URL: https://build.opensuse.org/request/show/255752
OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=88
This commit is contained in:
Stephan Kulow 2014-10-13 13:58:14 +00:00 committed by Git OBS Bridge
parent 2176e5a32f
commit 0876ada789
5 changed files with 312 additions and 68 deletions

View File

@ -0,0 +1,69 @@
Index: shim-0.7.318.81ee561d/MokManager.c
===================================================================
--- shim-0.7.318.81ee561d.orig/MokManager.c
+++ shim-0.7.318.81ee561d/MokManager.c
@@ -163,8 +163,18 @@ static UINT32 count_keys(void *Data, UIN
EFI_SIGNATURE_LIST *CertList = Data;
UINTN dbsize = DataSize;
UINT32 MokNum = 0;
+ void *end = Data + DataSize;
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+
+ /* Use ptr arithmetics to ensure bounded access. Do not allow 0
+ * SignatureListSize that will cause endless loop.
+ */
+ if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
+ console_notify(L"Invalid MOK detected! Ignoring MOK List.");
+ return 0;
+ }
+
if (CertList->SignatureListSize == 0 ||
CertList->SignatureListSize <= CertList->SignatureSize) {
console_errorbox(L"Corrupted signature list");
@@ -192,6 +202,7 @@ static MokListNode *build_mok_list(UINT3
EFI_GUID CertType = X509_GUID;
UINTN dbsize = DataSize;
UINTN count = 0;
+ void *end = Data + DataSize;
list = AllocatePool(sizeof(MokListNode) * num);
@@ -201,12 +212,24 @@ static MokListNode *build_mok_list(UINT3
}
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
+ /* CertList out of bounds? */
+ if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) {
+ FreePool(list);
+ return NULL;
+ }
+
/* Omit the signature check here since we already did it
in count_keys() */
Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) +
sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ /* Cert out of bounds? */
+ if ((void *)(Cert + 1) > end || CertList->SignatureSize <= sizeof(EFI_GUID)) {
+ FreePool(list);
+ return NULL;
+ }
+
list[count].Type = CertList->SignatureType;
if (CompareGuid (&CertList->SignatureType, &CertType) == 0) {
list[count].MokSize = CertList->SignatureSize -
@@ -218,6 +241,12 @@ static MokListNode *build_mok_list(UINT3
list[count].Mok = (void *)Cert;
}
+ /* MOK out of bounds? */
+ if (list[count].MokSize > end - (void *)list[count].Mok) {
+ FreePool(list);
+ return NULL;
+ }
+
count++;
dbsize -= CertList->SignatureListSize;
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +

View File

@ -0,0 +1,161 @@
diff --git a/netboot.c b/netboot.c
index 5ef53f7..f01a9bc 100644
--- a/netboot.c
+++ b/netboot.c
@@ -116,29 +116,34 @@ BOOLEAN findNetboot(EFI_HANDLE device)
static CHAR8 *get_v6_bootfile_url(EFI_PXE_BASE_CODE_DHCPV6_PACKET *pkt)
{
- void *optr;
- EFI_DHCP6_PACKET_OPTION *option;
- CHAR8 *url;
- UINT32 urllen;
+ void *optr = NULL, *end = NULL;
+ EFI_DHCP6_PACKET_OPTION *option = NULL;
+ CHAR8 *url = NULL;
+ UINT32 urllen = 0;
optr = pkt->DhcpOptions;
+ end = optr + sizeof(pkt->DhcpOptions);
- for(;;) {
+ for (;;) {
option = (EFI_DHCP6_PACKET_OPTION *)optr;
if (ntohs(option->OpCode) == 0)
- return NULL;
+ break;
if (ntohs(option->OpCode) == 59) {
/* This is the bootfile url option */
urllen = ntohs(option->Length);
- url = AllocateZeroPool(urllen+1);
+ if ((void *)(option->Data + urllen) > end)
+ break;
+ url = AllocateZeroPool(urllen + 1);
if (!url)
- return NULL;
+ break;
memcpy(url, option->Data, urllen);
return url;
}
optr += 4 + ntohs(option->Length);
+ if (optr + sizeof(EFI_DHCP6_PACKET_OPTION) > end)
+ break;
}
return NULL;
@@ -164,45 +169,60 @@ static CHAR16 str2ns(CHAR8 *str)
static CHAR8 *str2ip6(CHAR8 *str)
{
- UINT8 i, j, p;
- size_t len;
- CHAR8 *a, *b, t;
- static UINT16 ip[8];
+ UINT8 i = 0, j = 0, p = 0;
+ size_t len = 0, dotcount = 0;
+ enum { MAX_IP6_DOTS = 7 };
+ CHAR8 *a = NULL, *b = NULL, t = 0;
+ static UINT16 ip[8];
- for(i=0; i < 8; i++) {
- ip[i] = 0;
- }
- len = strlen(str);
- a = b = str;
- for(i=p=0; i < len; i++, b++) {
- if (*b != ':')
- continue;
- *b = '\0';
- ip[p++] = str2ns(a);
- *b = ':';
- a = b + 1;
- if ( *(b+1) == ':' )
- break;
- }
- a = b = (str + len);
- for(j=len, p=7; j > i; j--, a--) {
- if (*a != ':')
- continue;
- t = *b;
- *b = '\0';
- ip[p--] = str2ns(a+1);
- *b = t;
- b = a;
- }
- return (CHAR8 *)ip;
+ memset(ip, 0, sizeof(ip));
+
+ /* Count amount of ':' to prevent overflows.
+ * max. count = 7. Returns an invalid ip6 that
+ * can be checked against
+ */
+ for (a = str; *a != 0; ++a) {
+ if (*a == ':')
+ ++dotcount;
+ }
+ if (dotcount > MAX_IP6_DOTS)
+ return (CHAR8 *)ip;
+
+ len = strlen(str);
+ a = b = str;
+ for (i = p = 0; i < len; i++, b++) {
+ if (*b != ':')
+ continue;
+ *b = '\0';
+ ip[p++] = str2ns(a);
+ *b = ':';
+ a = b + 1;
+ if (b[1] == ':' )
+ break;
+ }
+ a = b = (str + len);
+ for (j = len, p = 7; j > i; j--, a--) {
+ if (*a != ':')
+ continue;
+ t = *b;
+ *b = '\0';
+ ip[p--] = str2ns(a+1);
+ *b = t;
+ b = a;
+ }
+ return (CHAR8 *)ip;
}
static BOOLEAN extract_tftp_info(CHAR8 *url)
{
CHAR8 *start, *end;
CHAR8 ip6str[40];
+ CHAR8 ip6inv[16];
CHAR8 *template = (CHAR8 *)translate_slashes(DEFAULT_LOADER_CHAR);
+ // to check against str2ip6() errors
+ memset(ip6inv, 0, sizeof(ip6inv));
+
if (strncmp((UINT8 *)url, (UINT8 *)"tftp://", 7)) {
Print(L"URLS MUST START WITH tftp://\n");
return FALSE;
@@ -217,7 +237,7 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
end = start;
while ((*end != '\0') && (*end != ']')) {
end++;
- if (end - start > 39) {
+ if (end - start >= (int)sizeof(ip6str)) {
Print(L"TFTP URL includes malformed IPv6 address\n");
return FALSE;
}
@@ -226,10 +246,12 @@ static BOOLEAN extract_tftp_info(CHAR8 *url)
Print(L"TFTP SERVER MUST BE ENCLOSED IN [..]\n");
return FALSE;
}
- memset(ip6str, 0, 40);
+ memset(ip6str, 0, sizeof(ip6str));
memcpy(ip6str, start, end - start);
end++;
memcpy(&tftp_addr.v6, str2ip6(ip6str), 16);
+ if (memcmp(&tftp_addr.v6, ip6inv, sizeof(ip6inv)) == 0)
+ return FALSE;
full_path = AllocateZeroPool(strlen(end)+strlen(template)+1);
if (!full_path)
return FALSE;

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Mon Oct 13 13:09:14 UTC 2014 - jsegitz@novell.com
- Fixed buffer overflow and OOB access in shim trusted code path
(bnc#889332, CVE-2014-3675, CVE-2014-3676, CVE-2014-3677)
* added bug-889332_shim-mok-oob.patch, bug-889332_shim-overflow.patch
- Added new certificate by Microsoft
-------------------------------------------------------------------
Wed Sep 3 12:32:25 UTC 2014 - lnussel@suse.de

View File

@ -56,6 +56,10 @@ Patch4: shim-mokmanager-support-sha-family.patch
Patch5: shim-signed-unsigned-compares.patch
# PATCH-FIX-UPSTREAM shim-update-openssl-0.9.8zb.patch glin@suse.com -- Update openssl to 0.9.8zb
Patch6: shim-update-openssl-0.9.8zb.patch
# PATCH-FIX-UPSTREAM bug-889332_shim-overflow.patch krahmer@suse.com -- patch for overflow issue.
Patch7: bug-889332_shim-overflow.patch
# PATCH-FIX-UPSTREAM bug-889332_shim-mok-oob.patch krahmer@suse.com -- patch for MOK OOB access.
Patch8: bug-889332_shim-mok-oob.patch
# PATCH-FIX-OPENSUSE shim-opensuse-cert-prompt.patch glin@suse.com -- Show the prompt to ask whether the user trusts openSUSE certificate or not
Patch100: shim-opensuse-cert-prompt.patch
BuildRequires: gnu-efi >= 3.0t
@ -87,6 +91,8 @@ Authors:
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch100 -p1
%build

View File

@ -1,11 +1,11 @@
hash: bdd01126e9d85710d3fe75af1cc1702a29f081b4f6fdf6a2b2135c0297a9cec5
hash: be435df7cd28aa2a7c8db4fc8173475b77e5abf392f76b7c76fa3f698cb71a9a
# 2069-04-10 06:07:54
timestamp: babababa
checksum: ff45
checksum: ee96
-----BEGIN AUTHENTICODE SIGNATURE-----
MIIh3AYJKoZIhvcNAQcCoIIhzTCCIckCAQExDzANBglghkgBZQMEAgEFADBcBgor
MIIh2QYJKoZIhvcNAQcCoIIhyjCCIcYCAQExDzANBglghkgBZQMEAgEFADBcBgor
BgEEAYI3AgEEoE4wTDAXBgorBgEEAYI3AgEPMAkDAQCgBKICgAAwMTANBglghkgB
ZQMEAgEFAAQgvdARJunYVxDT/nWvHMFwKinwgbT2/faishNcApepzsWgggs8MIIF
ZQMEAgEFAAQgvkNd980oqip8jbT8gXNHW3flq/OS92t8dvo/aYy3Gpqgggs8MIIF
JDCCBAygAwIBAgITMwAAAApmQvP0n7c3lgABAAAACjANBgkqhkiG9w0BAQsFADCB
gTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMi
@ -65,31 +65,31 @@ HYw9Rw5EpuSwmzQ1sfq2U6gsgeykBXHInbi66BtEZuRHVA6OVn+znxaYsobQaD6Q
I7UvXo9QhY3GjYJfQaH0Lg3gmdJsdeS2abUhhvoH0fbiTdHarSx3Ux4lMjfHbFJy
lYaw8TVhahn1sjuBUFamMi3+oon5QoYnGFWhgspam/gwmFQUpkeWJS/IJuRBlBpc
Aj/lluOFWzw+P7tHFnJV4iUisdl75wMGKqP3HpBGwwAN1hmJ4w41J2IDcRWm79An
oKBZN2D4OJS44Hhw+LpMhoeU9uCuAkXuZcK2o35pFnUHkpv1prxZg1gxghYTMIIW
DwIBATCBmTCBgTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
oKBZN2D4OJS44Hhw+LpMhoeU9uCuAkXuZcK2o35pFnUHkpv1prxZg1gxghYQMIIW
DAIBATCBmTCBgTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEr
MCkGA1UEAxMiTWljcm9zb2Z0IENvcnBvcmF0aW9uIFVFRkkgQ0EgMjAxMQITMwAA
AApmQvP0n7c3lgABAAAACjANBglghkgBZQMEAgEFAKCCAREwGQYJKoZIhvcNAQkD
MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJ
KoZIhvcNAQkEMSIEIKOfDrPjsHj5IpbLDH/emIN2ujjTNjWxi+JiBMeM1lejMIGk
KoZIhvcNAQkEMSIEIH8k1QzoaOGI7RKFvmbvflQd2+npQctwEZe5x8YjIvvQMIGk
BgorBgEEAYI3AgEMMYGVMIGSoF6AXABoAHQAdABwADoALwAvAHcAdwB3AC4AbQBp
AGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAHcAaABkAGMALwBoAGMAbAAvAGQAZQBm
AGEAdQBsAHQALgBtAHMAcAB4oTCALmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS93
aGRjL2hjbC9kZWZhdWx0Lm1zcHgwDQYJKoZIhvcNAQEBBQAEggEAThlP7UGIWeaL
wSgeXtn8Whnj2NuB/+fBohdlEmuU4oOJsKt07jxVrzXWHO0/znARfCMhsqGnwQq6
IU45DSbqHiBsPS2bucCmygVJZjS+lYUY0o1OSiAOgkcOb3byqbOhFx+yU4jyi1I6
vZsetJf0VIB/50CUDWw/jgC29MS5uLKPbljn6Gav6BmWkbzR7g7e44QInagtQsEm
kxI4FaHRkaKnkTtrJZ2htMCGJUEm83iyEaFB1jfwE+eSVilltwZeUiM8cm5jSIeZ
CWyF2+bOgaOyIk47XVZWI0683wwf43yftlRMsuySQuD7Vk4sKsRM87Nl1SszQSqI
murrQX0OHqGCEzUwghMxBgorBgEEAYI3AwMBMYITITCCEx0GCSqGSIb3DQEHAqCC
Ew4wghMKAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggE1BgsqhkiG9w0BCRABBKCCASQE
ggEgMIIBHAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCBhVxDrnAE1
Odf8YYCrsCpxqlspu1YwtY7Xj0HNqt+MlgIGU8faFW37GBMyMDE0MDgwMjAwMjcx
My4yMzVaMAcCAQGAAgH0oIGxpIGuMIGrMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
aGRjL2hjbC9kZWZhdWx0Lm1zcHgwDQYJKoZIhvcNAQEBBQAEggEAHJkR2IJxl5GE
ftK0A1yP8Iy4hL30Fc1gsWa37MpcCBtVW2LgzVQ3ZiPfiliQ3/PUWUrWYgY0+KFF
pi+nfLDIFRf2BBQCl6TLiBSlzCMmdy4d8v53dkWuxsKbwabRSNHhmFe2rjDkbgOf
65dCa3F1JDEAIsPN7I0OOWrwWPX4mOF2lOfWk198m2Hcc1DOoenDXJAy2B8iCHtQ
B607QuKZpWPLuhkjiJcceGhyX6LqEUIm5RIhhINjtoVzvjv3xKENunU8MMbV8Bp5
uQDIf6C7bMPqMRMPshzURESwcXK1klfWZ5a+bSojMbd+5a37x49Fy1qpFyJ7PZ+q
DaKGK5QUXKGCEzIwghMuBgorBgEEAYI3AwMBMYITHjCCExoGCSqGSIb3DQEHAqCC
EwswghMHAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggE1BgsqhkiG9w0BCRABBKCCASQE
ggEgMIIBHAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCDX3+3JKDpB
nqCqpXqYaaP8IB6oYhVoGH1aOrhn2NGHBwIGVBrtfM7aGBMyMDE0MDkyNDE1NTkx
NS41ODVaMAcCAQGAAgH0oIGxpIGuMIGrMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
V0ExEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
dGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjMx
QzUtMzBCQS03QzkxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2
aWNloIIOwDCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAw
dGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOkJC
RUMtMzBDQS0yREJFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2
aWNloIIOvTCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAw
gYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMT
KU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEw
@ -123,65 +123,65 @@ fYPw4TtxCd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir995yfmFrb3ep
gcunCaw5u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMu
Ein1wC9UJyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmK
LxvHIa9Zta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu
7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJEjCCBNIwggO6oAMCAQICEzMAAABP
rehUlVAolGcAAAAAAE8wDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzAR
7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJEjCCBNIwggO6oAMCAQICEzMAAABQ
ZzO71/vhFxoAAAAAAFAwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzAR
BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh
bXAgUENBIDIwMTAwHhcNMTQwNTIzMTcyMDA4WhcNMTUwODIzMTcyMDA4WjCBqzEL
bXAgUENBIDIwMTAwHhcNMTQwNTIzMTcyMDA5WhcNMTUwODIzMTcyMDA5WjCBqzEL
MAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIxJzAlBgNV
BAsTHm5DaXBoZXIgRFNFIEVTTjozMUM1LTMwQkEtN0M5MTElMCMGA1UEAxMcTWlj
BAsTHm5DaXBoZXIgRFNFIEVTTjpCQkVDLTMwQ0EtMkRCRTElMCMGA1UEAxMcTWlj
cm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKFVkneQwi1RLhVhgJoMVZY6JIU3jigasjbuZClciQzP0d0z9Ev8
mxS2T2+fdfVkWZWKQXeYmD5mejixNPhFpoQR0zWhpfNQe4XA7x4l8a48+P483uz3
7sMyBlYtYaQEnfBPmCqG/Wbr9cdH9QVx94F4NKVZFnSa/eEq3hDRLfqqiDmkRTN4
t+w8d3Yx41CVzx6TBgh6bE2km58m5YS/+54xLirgm44nHlmQCut58IGTZ6CArg/1
g1cqGrFbMUZC/mhSgCA4uFNSRctPc56zSTBbsM5vP6PqOW6J8VWJICxREyBqg2gV
Qp7JhZmczo+DtG+W3QyjPO8Thwx+mo3iFnkCAwEAAaOCARswggEXMB0GA1UdDgQW
BBQrpekQU9AS8xkbQCwKTRfMxEXJLjAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYb
ADCCAQoCggEBAJEhjxO+q6WM252ntWKyoMJcVUKjwcITIIpviOgAlGana6vpyGUq
64TfinxqrYIewPts3MQx4HQ05m4Q8s/7D/Htz2Uk5XU3klY9+7exCA1WB++u7dA9
8YKX0Sf+gTiw+Guw6H0kokwX4ADL7I+ejfiGGYOQx382pJcSwEqwOz2orleDr30N
+/abfhb1gmvzNnQthTd6eCf8G2Gs6oA78lS3bajvwPv+DDX9e927oDO4wYF2aZJi
lOkQArMD7vAbwH7ib6gasZoktwb8fRjDMjzAon9eq1SFlrON/8OH99kFC1BUiOgT
HUzftAFvVChVRGoQxc+hnfIJuNumVMo86RsCAwEAAaOCARswggEXMB0GA1UdDgQW
BBQIBFn2oC+3IbRoBgG252aBsP1B2zAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYb
xTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5j
b20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmww
WgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29m
dC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNV
HRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IB
AQBhbgv5FjD4pzjfVhGhfk23Gom8Ip4kfRTobqi7up1JHBTWidiUVKwoszU9TPi+
PTuCNBDJgWuMIXNGcpXRTLTENDW9Maln6yp7zFUEtYGulWSFT9EGMLfjBTLoBl4M
GxU8IDviiM6GuCy7vV0QbsNfeBZpo761j42sHJccu7LPTk8VD24W1diIEaCjePJW
FRBKidTcAQRHki0xDK4xYbN9GFncfhXaMlQn4TN/mRx6YBTELjiP1RH3rdW9I/NX
0kXfCGth/BbVctp6rGRkK8NQaHkq9rXqt+C75sVwASx/JxMkXS1q+Rnwbilso9Rq
LsiE9SszQjNKzc+rebhHpUELoYIDcTCCAlkCAQEwgduhgbGkga4wgasxCzAJBgNV
AQBeUPsfXveaA2srFUYG1UfpVOfxW9WXF3qeftvU6FdW2TfH+i3FV8jryywreT59
IBfCqy8Qe93c+Rb4nSwbQwt/nvft9HcBnC/YvXpcpTA587RxM22ypCDICnKNBk1p
z4BTGOO+pNJkrDcfhNARDlYDJTFO6IKUHOgNVzPbrNH0HDCA1KUzvPYza2XEohaA
MCmfR1hA12cSm6BsKMnRr3D6lGuJEeqTFM/0hJ1xARDZ5nQwwc9nggHHutnQIA8E
vowp2uKbfgiEcFNYaPlHNW7ntNrNtG9RRZS57n7+3Mblh/6wij8g0blll3hCC5Gt
k7lyZtb20wDYJ9USachQ+iSRoYIDbjCCAlYCAQEwgduhgbGkga4wgasxCzAJBgNV
BAYTAlVTMQswCQYDVQQIEwJXQTEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
TWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BSMScwJQYDVQQLEx5u
Q2lwaGVyIERTRSBFU046MzFDNS0zMEJBLTdDOTExJTAjBgNVBAMTHE1pY3Jvc29m
dCBUaW1lLVN0YW1wIFNlcnZpY2WiJQoBATAJBgUrDgMCGgUAAxUAKLyR2kF+5obQ
k1yVhHi3u5xWWaqggcIwgb+kgbwwgbkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
Q2lwaGVyIERTRSBFU046QkJFQy0zMENBLTJEQkUxJTAjBgNVBAMTHE1pY3Jvc29m
dCBUaW1lLVN0YW1wIFNlcnZpY2WiJQoBATAJBgUrDgMCGgUAAxUAMibb8Tfny12c
vCOQ33PvTJE7C8WggcIwgb+kgbwwgbkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
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
msnGanls8Y3/8+BkXs5NkigVrGNqiy424xWVhFRdRKADwd+CMYIC9TCCAvECAQEw
gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAABQZzO71/vhFxoA
AAAAAFAwDQYJYIZIAWUDBAIBBQCgggEyMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B
CRABBDAvBgkqhkiG9w0BCQQxIgQgipcVbZMN5q/tvhNA5uFl75KiSkhlJO+gE53r
G0I83aAwgeIGCyqGSIb3DQEJEAIMMYHSMIHPMIHMMIGxBBQyJtvxN+fLXZy8I5Df
c+9MkTsLxTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMz
AAAAUGczu9f74RcaAAAAAABQMBYEFIrVwV/mRE/CM8XDaIYkRLS4deD7MA0GCSqG
SIb3DQEBCwUABIIBADb96TT37ulMALmrrCuKtnpd4ReAFGcpLa2KCNrFv/SfjmDc
5lGMLSR1qjSH/WR3IF9mnwXJEeuDoAKj/TBAWPLYudzvjoRtmEckXiCsqHqTfgWW
ucFrW/kgALfXY6ExM1W+YYZDkRytHm6y9Iym9vlb62q5D55B0Nd1HVxzkXdF4Ivr
VUeUdBiicV2IRg0GlGjJZWbSsw42A6TACQdlNJW0ysHsE0cVfxk8SUfUUrydS//1
MYe6xv2B8dOODqmxWTjHoetvthNqZPK5NZUGv7VG3E6qnhfr4F1wvrmy5b4ASTYw
QOqkkUGXMCcnWDlmSzaw7FlmfdqsFHbRKVVGwlsAAAA=
-----END AUTHENTICODE SIGNATURE-----