Ignore non-X509 certificates in SignedCms
authorKevin Jones <kevin@vcsjones.com>
Fri, 28 Jan 2022 16:24:27 +0000 (11:24 -0500)
committerGitHub <noreply@github.com>
Fri, 28 Jan 2022 16:24:27 +0000 (08:24 -0800)
This allows for AttributeCertificateV1/AttributeCertificateV2/OtherCertificate
entries in the SignedCms without causing a decode error.  That data is not presented
to callers via the SignedCms object, but the behavior is consistent with SignedCms on
.NET Framework and its underlying WinCryptMsg counterpart.

Co-authored-by: Jeremy Barton <jbarton@microsoft.com>
src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj
src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/CertificateChoiceAsn.xml
src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/CertificateChoiceAsn.xml.cs
src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OtherCertificateFormat.xml [new file with mode: 0644]
src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OtherCertificateFormat.xml.cs [new file with mode: 0644]
src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignedCms.cs
src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs
src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs

index 9ccb53c..c0c2da2 100644 (file)
@@ -490,6 +490,10 @@ System.Security.Cryptography.Pkcs.EnvelopedCms</PackageDescription>
     <Compile Include="System\Security\Cryptography\Pkcs\Asn1\MessageImprint.xml.cs">
       <DependentUpon>System\Security\Cryptography\Pkcs\Asn1\MessageImprint.xml</DependentUpon>
     </Compile>
+    <AsnXml Include="System\Security\Cryptography\Pkcs\Asn1\OtherCertificateFormat.xml" />
+    <Compile Include="System\Security\Cryptography\Pkcs\Asn1\OtherCertificateFormat.xml.cs">
+      <DependentUpon>System\Security\Cryptography\Pkcs\Asn1\OtherCertificateFormat.xml</DependentUpon>
+    </Compile>
     <Compile Include="System\Security\Cryptography\Pkcs\Asn1\PkiFailureInfo.cs" />
     <Compile Include="System\Security\Cryptography\Pkcs\Asn1\PkiStatus.cs" />
     <AsnXml Include="System\Security\Cryptography\Pkcs\Asn1\PkiStatusInfo.xml" />
index d9b497a..9bc76b3 100644 (file)
         other[3] IMPLICIT OtherCertificateFormat
     }
 
-    OtherCertificateFormat ::= SEQUENCE {
-        otherCertFormat OBJECT IDENTIFIER,
-        otherCert ANY DEFINED BY otherCertFormat
-    }
-
-    Except we only support public key certificates, so just trim the choice here.
   -->
   <asn:AnyValue name="Certificate" universalTagNumber="16" />
+  <asn:AnyValue name="ExtendedCertificate" implicitTag="0" />
+  <asn:AnyValue name="AttributeCertificateV1" implicitTag="1" />
+  <asn:AnyValue name="AttributeCertificateV2" implicitTag="2" />
+  <asn:AsnType name="OtherCertificateFormat" typeName="System.Security.Cryptography.Pkcs.Asn1.OtherCertificateFormat" implicitTag="3" />
 </asn:Choice>
index c9107fa..0b602a0 100644 (file)
@@ -12,6 +12,10 @@ namespace System.Security.Cryptography.Pkcs.Asn1
     internal partial struct CertificateChoiceAsn
     {
         internal ReadOnlyMemory<byte>? Certificate;
+        internal ReadOnlyMemory<byte>? ExtendedCertificate;
+        internal ReadOnlyMemory<byte>? AttributeCertificateV1;
+        internal ReadOnlyMemory<byte>? AttributeCertificateV2;
+        internal System.Security.Cryptography.Pkcs.Asn1.OtherCertificateFormat? OtherCertificateFormat;
 
 #if DEBUG
         static CertificateChoiceAsn()
@@ -28,6 +32,10 @@ namespace System.Security.Cryptography.Pkcs.Asn1
             };
 
             ensureUniqueTag(new Asn1Tag((UniversalTagNumber)16), "Certificate");
+            ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "ExtendedCertificate");
+            ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 1), "AttributeCertificateV1");
+            ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 2), "AttributeCertificateV2");
+            ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 3), "OtherCertificateFormat");
         }
 #endif
 
@@ -60,6 +68,90 @@ namespace System.Security.Cryptography.Pkcs.Asn1
                 wroteValue = true;
             }
 
+            if (ExtendedCertificate.HasValue)
+            {
+                if (wroteValue)
+                    throw new CryptographicException();
+
+                // Validator for tag constraint for ExtendedCertificate
+                {
+                    if (!Asn1Tag.TryDecode(ExtendedCertificate.Value.Span, out Asn1Tag validateTag, out _) ||
+                        !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
+                    {
+                        throw new CryptographicException();
+                    }
+                }
+
+                try
+                {
+                    writer.WriteEncodedValue(ExtendedCertificate.Value.Span);
+                }
+                catch (ArgumentException e)
+                {
+                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+                }
+                wroteValue = true;
+            }
+
+            if (AttributeCertificateV1.HasValue)
+            {
+                if (wroteValue)
+                    throw new CryptographicException();
+
+                // Validator for tag constraint for AttributeCertificateV1
+                {
+                    if (!Asn1Tag.TryDecode(AttributeCertificateV1.Value.Span, out Asn1Tag validateTag, out _) ||
+                        !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
+                    {
+                        throw new CryptographicException();
+                    }
+                }
+
+                try
+                {
+                    writer.WriteEncodedValue(AttributeCertificateV1.Value.Span);
+                }
+                catch (ArgumentException e)
+                {
+                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+                }
+                wroteValue = true;
+            }
+
+            if (AttributeCertificateV2.HasValue)
+            {
+                if (wroteValue)
+                    throw new CryptographicException();
+
+                // Validator for tag constraint for AttributeCertificateV2
+                {
+                    if (!Asn1Tag.TryDecode(AttributeCertificateV2.Value.Span, out Asn1Tag validateTag, out _) ||
+                        !validateTag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
+                    {
+                        throw new CryptographicException();
+                    }
+                }
+
+                try
+                {
+                    writer.WriteEncodedValue(AttributeCertificateV2.Value.Span);
+                }
+                catch (ArgumentException e)
+                {
+                    throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+                }
+                wroteValue = true;
+            }
+
+            if (OtherCertificateFormat.HasValue)
+            {
+                if (wroteValue)
+                    throw new CryptographicException();
+
+                OtherCertificateFormat.Value.Encode(writer, new Asn1Tag(TagClass.ContextSpecific, 3));
+                wroteValue = true;
+            }
+
             if (!wroteValue)
             {
                 throw new CryptographicException();
@@ -107,6 +199,28 @@ namespace System.Security.Cryptography.Pkcs.Asn1
                 tmpSpan = reader.ReadEncodedValue();
                 decoded.Certificate = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
             }
+            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0)))
+            {
+                tmpSpan = reader.ReadEncodedValue();
+                decoded.ExtendedCertificate = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
+            }
+            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1)))
+            {
+                tmpSpan = reader.ReadEncodedValue();
+                decoded.AttributeCertificateV1 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
+            }
+            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2)))
+            {
+                tmpSpan = reader.ReadEncodedValue();
+                decoded.AttributeCertificateV2 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
+            }
+            else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3)))
+            {
+                System.Security.Cryptography.Pkcs.Asn1.OtherCertificateFormat tmpOtherCertificateFormat;
+                System.Security.Cryptography.Pkcs.Asn1.OtherCertificateFormat.Decode(ref reader, new Asn1Tag(TagClass.ContextSpecific, 3), rebind, out tmpOtherCertificateFormat);
+                decoded.OtherCertificateFormat = tmpOtherCertificateFormat;
+
+            }
             else
             {
                 throw new CryptographicException();
diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OtherCertificateFormat.xml b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OtherCertificateFormat.xml
new file mode 100644 (file)
index 0000000..704a42f
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<asn:Sequence
+  xmlns:asn="http://schemas.dot.net/asnxml/201808/"
+  name="OtherCertificateFormat"
+  namespace="System.Security.Cryptography.Pkcs.Asn1">
+
+  <!--
+    https://tools.ietf.org/html/rfc5652#section-10.2.2
+
+    OtherCertificateFormat ::= SEQUENCE {
+        otherCertFormat OBJECT IDENTIFIER,
+        otherCert ANY DEFINED BY otherCertFormat
+    }
+  -->
+  <asn:ObjectIdentifier name="OtherCertFormat" backingType="string" />
+  <asn:AnyValue name="OtherCert" />
+</asn:Sequence>
diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OtherCertificateFormat.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OtherCertificateFormat.xml.cs
new file mode 100644 (file)
index 0000000..aeb1813
--- /dev/null
@@ -0,0 +1,98 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#pragma warning disable SA1028 // ignore whitespace warnings for generated code
+using System;
+using System.Formats.Asn1;
+using System.Runtime.InteropServices;
+
+namespace System.Security.Cryptography.Pkcs.Asn1
+{
+    [StructLayout(LayoutKind.Sequential)]
+    internal partial struct OtherCertificateFormat
+    {
+        internal string OtherCertFormat;
+        internal ReadOnlyMemory<byte> OtherCert;
+
+        internal void Encode(AsnWriter writer)
+        {
+            Encode(writer, Asn1Tag.Sequence);
+        }
+
+        internal void Encode(AsnWriter writer, Asn1Tag tag)
+        {
+            writer.PushSequence(tag);
+
+            try
+            {
+                writer.WriteObjectIdentifier(OtherCertFormat);
+            }
+            catch (ArgumentException e)
+            {
+                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+            }
+            try
+            {
+                writer.WriteEncodedValue(OtherCert.Span);
+            }
+            catch (ArgumentException e)
+            {
+                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+            }
+            writer.PopSequence(tag);
+        }
+
+        internal static OtherCertificateFormat Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+        {
+            return Decode(Asn1Tag.Sequence, encoded, ruleSet);
+        }
+
+        internal static OtherCertificateFormat Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet)
+        {
+            try
+            {
+                AsnValueReader reader = new AsnValueReader(encoded.Span, ruleSet);
+
+                DecodeCore(ref reader, expectedTag, encoded, out OtherCertificateFormat decoded);
+                reader.ThrowIfNotEmpty();
+                return decoded;
+            }
+            catch (AsnContentException e)
+            {
+                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+            }
+        }
+
+        internal static void Decode(ref AsnValueReader reader, ReadOnlyMemory<byte> rebind, out OtherCertificateFormat decoded)
+        {
+            Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded);
+        }
+
+        internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out OtherCertificateFormat decoded)
+        {
+            try
+            {
+                DecodeCore(ref reader, expectedTag, rebind, out decoded);
+            }
+            catch (AsnContentException e)
+            {
+                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
+            }
+        }
+
+        private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out OtherCertificateFormat decoded)
+        {
+            decoded = default;
+            AsnValueReader sequenceReader = reader.ReadSequence(expectedTag);
+            ReadOnlySpan<byte> rebindSpan = rebind.Span;
+            int offset;
+            ReadOnlySpan<byte> tmpSpan;
+
+            decoded.OtherCertFormat = sequenceReader.ReadObjectIdentifier();
+            tmpSpan = sequenceReader.ReadEncodedValue();
+            decoded.OtherCert = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
+
+            sequenceReader.ThrowIfNotEmpty();
+        }
+    }
+}
index 188ca00..bc38187 100644 (file)
@@ -89,8 +89,16 @@ namespace System.Security.Cryptography.Pkcs
 
                 foreach (CertificateChoiceAsn choice in certChoices)
                 {
-                    Debug.Assert(choice.Certificate.HasValue);
-                    coll.Add(new X509Certificate2(choice.Certificate.Value.ToArray()));
+                    if (choice.Certificate.HasValue)
+                    {
+                        coll.Add(new X509Certificate2(choice.Certificate.Value
+#if NET5_0_OR_GREATER
+                            .Span
+#else
+                            .ToArray()
+#endif
+                            ));
+                    }
                 }
 
                 return coll;
index c53e966..c89cfa5 100644 (file)
@@ -1602,6 +1602,15 @@ namespace System.Security.Cryptography.Pkcs.Tests
             signers[0].CheckHash();
         }
 
+        [Fact]
+        public static void Decode_CanDecodeWithAttributeCertificate()
+        {
+            SignedCms cms = new SignedCms();
+            cms.Decode(SignedDocuments.TstWithAttributeCertificate);
+            Assert.Equal(2, cms.Certificates.Count);
+            cms.CheckSignature(verifySignatureOnly: true);
+        }
+
         private static void CheckNoSignature(byte[] encoded, bool badOid=false)
         {
             SignedCms cms = new SignedCms();
index 55d42f6..cce3114 100644 (file)
@@ -1472,5 +1472,159 @@ namespace System.Security.Cryptography.Pkcs.Tests
             "2B78166BDB1612848B535ADC3F0E7BE52991A17F48AFDCCC1698A236BA338930" +
             "50EBAAC4460DAA35185C16670F597E0E6E0CB0AA83F51AAEF452F3367DD9350A" +
             "8A49A5A8F79DF8E921303AB5D6646A482F0F59D9980310E1AE3EE8D77CB857").HexToByteArray();
+
+        internal static readonly byte[] TstWithAttributeCertificate = (
+            "308212E306092A864886F70D010702A08212D4308212D0020103310F300D0609" +
+            "608648016503040201050030820159060B2A864886F70D0109100104A0820148" +
+            "0482014430820140020101060A2B0601040184590A03013031300D0609608648" +
+            "01650304020105000420C61245B435391DCDD1EFF021681FA2A46E69410A9E23" +
+            "09F1B1736BB7C2BB504402066148B8B838B11813323032313130303730343230" +
+            "30372E3037345A3004800201F4A081D8A481D53081D2310B3009060355040613" +
+            "025553311330110603550408130A57617368696E67746F6E3110300E06035504" +
+            "0713075265646D6F6E64311E301C060355040A13154D6963726F736F66742043" +
+            "6F72706F726174696F6E312D302B060355040B13244D6963726F736F66742049" +
+            "72656C616E64204F7065726174696F6E73204C696D6974656431263024060355" +
+            "040B131D5468616C6573205453532045534E3A303834322D344245362D433239" +
+            "41312530230603550403131C4D6963726F736F66742054696D652D5374616D70" +
+            "2053657276696365A0820E4A308204F9308203E1A00302010202133300000139" +
+            "CCE8E8438BF034E1000000000139300D06092A864886F70D01010B0500307C31" +
+            "0B3009060355040613025553311330110603550408130A57617368696E67746F" +
+            "6E3110300E060355040713075265646D6F6E64311E301C060355040A13154D69" +
+            "63726F736F667420436F72706F726174696F6E312630240603550403131D4D69" +
+            "63726F736F66742054696D652D5374616D70205043412032303130301E170D32" +
+            "30313031353137323832315A170D3232303131323137323832315A3081D2310B" +
+            "3009060355040613025553311330110603550408130A57617368696E67746F6E" +
+            "3110300E060355040713075265646D6F6E64311E301C060355040A13154D6963" +
+            "726F736F667420436F72706F726174696F6E312D302B060355040B13244D6963" +
+            "726F736F6674204972656C616E64204F7065726174696F6E73204C696D697465" +
+            "6431263024060355040B131D5468616C6573205453532045534E3A303834322D" +
+            "344245362D43323941312530230603550403131C4D6963726F736F6674205469" +
+            "6D652D5374616D70205365727669636530820122300D06092A864886F70D0101" +
+            "0105000382010F003082010A0282010100DA13F98CE3259325A18EB32A06FCA2" +
+            "78F85A1F98374F7F50C1DBBA1EA02759C2E5CFDFD92A80BF405CF8E606F469DD" +
+            "7822FA856859B627AA3EBE185B7F8A1024E1C34DC8D95C12904DB413FF0E8B09" +
+            "6BDD0979C5425D9AF2711DE3612613BAF145598ABA66C7A04295F90C1874673B" +
+            "D2AE4EF0CD9892A27F4AD72B16116D9A117172F559FA08386B3CEF13CEFEB282" +
+            "33615EB3A8CD8A58EFD34B2F597A88B95F84286D5E802AEC091F4F32499DA540" +
+            "15F39DDF2BC03CF2EBE058A895E29BE6FE57EEC4DFBE356FA710F5F98E340A47" +
+            "2E1906AA8D3BFC1D783641AAA8EF7BF210235ED5684292A32AEEB2C57CECB294" +
+            "278F4AE57EC57F1F2496FE5FA2CF1ECA4F0203010001A382011B30820117301D" +
+            "0603551D0E04160414999E9B867254C299DA928AB19F46F6502D060CE9301F06" +
+            "03551D23041830168014D5633A5C8A3190F3437B7C461BC533685A856D553056" +
+            "0603551D1F044F304D304BA049A0478645687474703A2F2F63726C2E6D696372" +
+            "6F736F66742E636F6D2F706B692F63726C2F70726F64756374732F4D69635469" +
+            "6D5374615043415F323031302D30372D30312E63726C305A06082B0601050507" +
+            "0101044E304C304A06082B06010505073002863E687474703A2F2F7777772E6D" +
+            "6963726F736F66742E636F6D2F706B692F63657274732F4D696354696D537461" +
+            "5043415F323031302D30372D30312E637274300C0603551D130101FF04023000" +
+            "30130603551D25040C300A06082B06010505070308300D06092A864886F70D01" +
+            "010B05000382010100585C286AF3FF371A85CDC15AED438288BF100DB126FBBA" +
+            "F6118893A16D20F1D758C8AE566B514077FCA7243D6AC9CFD9C71F473FDD32A9" +
+            "7293FABCF8835C08B1049694A09BDD71B821586C584084B26DA28CDFDFC687E6" +
+            "B63667158DF5BB831249C97E21A22BA43EF2490235699B5A3D83C51C0417C21F" +
+            "0708C5EC43E160381D8A52B3E3CEAEC21828B28AF51AE0D68A56231A830DAB79" +
+            "6BC0322463FF37294A49868AE5A6205D908344B159027F3C842E67BD0B7B5A99" +
+            "9B4C497C6B519C17E96ADFDDD498100AB2DFA3C9649AE2C13C21BF38C87AA0FC" +
+            "78ACD4521DEE7C4DBF1231006DA6C1842A36FAD528CA74FA4C026D8DD8AF6B88" +
+            "3B3FBDFF550AD270C73082067130820459A003020102020A6109812A00000000" +
+            "0002300D06092A864886F70D01010B0500308188310B30090603550406130255" +
+            "53311330110603550408130A57617368696E67746F6E3110300E060355040713" +
+            "075265646D6F6E64311E301C060355040A13154D6963726F736F667420436F72" +
+            "706F726174696F6E31323030060355040313294D6963726F736F667420526F6F" +
+            "7420436572746966696361746520417574686F726974792032303130301E170D" +
+            "3130303730313231333635355A170D3235303730313231343635355A307C310B" +
+            "3009060355040613025553311330110603550408130A57617368696E67746F6E" +
+            "3110300E060355040713075265646D6F6E64311E301C060355040A13154D6963" +
+            "726F736F667420436F72706F726174696F6E312630240603550403131D4D6963" +
+            "726F736F66742054696D652D5374616D7020504341203230313030820122300D" +
+            "06092A864886F70D01010105000382010F003082010A0282010100A91D0DBC77" +
+            "118A3A20ECFC1397F5FA7F69946B745410D5A50A008285FBED7C684B2C5FC5C3" +
+            "E561C276B73E662B5BF015532704311F411B1A951DCE09138E7C613059B13044" +
+            "0FF160888454430CD74DB83808B342DD93ACD67330572682A3450DD0EAF54781" +
+            "CDBF246032586046F258478632841E746167915F8154B1CF934C92C1C4A65DD1" +
+            "61136E28C61AF98680BBDF61FC46C1271D246712721A218AAF4B64895062B15D" +
+            "FD771F3DF05775ACBD8A424D4051D10F9C063E677FF566C00396447EEFD04BFD" +
+            "6EE59ACAB1A8F27A2A0A31F0DA4E0691B6880835E8781CB0E999CD3CE72F44BA" +
+            "A7F4DC64BDA401C120099378CDFCBCC0C9445D5E169C01054F224D0203010001" +
+            "A38201E6308201E2301006092B06010401823715010403020100301D0603551D" +
+            "0E04160414D5633A5C8A3190F3437B7C461BC533685A856D55301906092B0601" +
+            "040182371402040C1E0A00530075006200430041300B0603551D0F0404030201" +
+            "86300F0603551D130101FF040530030101FF301F0603551D23041830168014D5" +
+            "F656CB8FE8A25C6268D13D94905BD7CE9A18C430560603551D1F044F304D304B" +
+            "A049A0478645687474703A2F2F63726C2E6D6963726F736F66742E636F6D2F70" +
+            "6B692F63726C2F70726F64756374732F4D6963526F6F4365724175745F323031" +
+            "302D30362D32332E63726C305A06082B06010505070101044E304C304A06082B" +
+            "06010505073002863E687474703A2F2F7777772E6D6963726F736F66742E636F" +
+            "6D2F706B692F63657274732F4D6963526F6F4365724175745F323031302D3036" +
+            "2D32332E6372743081A00603551D200101FF04819530819230818F06092B0601" +
+            "040182372E03308181303D06082B060105050702011631687474703A2F2F7777" +
+            "772E6D6963726F736F66742E636F6D2F504B492F646F63732F4350532F646566" +
+            "61756C742E68746D304006082B0601050507020230341E32201D004C00650067" +
+            "0061006C005F0050006F006C006900630079005F00530074006100740065006D" +
+            "0065006E0074002E201D300D06092A864886F70D01010B0500038202010007E6" +
+            "88510DE2C6E0983F8171033D9DA3A1216FB3EBA6CCF531BECF05E2A9FEFA576D" +
+            "1930B3C2C566C96ADFF5E7F078BDC7A89E25E3F9BCED6B5457082B51824412FB" +
+            "B9538CCCF460128A76CC4040419BDC5C17FF5CF95E17359824564B74EF4210C8" +
+            "AFBF7FC67FF2377D5A3F1CF299794A915200AF380F17F52F798165D9A9B56BE4" +
+            "C7CEF6CA7A006F4B304424223CCFED03A5968F5929BCB6FD04E1709F324A27FD" +
+            "55AF2FFEB6E58E33BB625F9ADB5740E9F1CE9966908CFF6A627FDDC54A0B9126" +
+            "E239EC194A71639D7B216DC39CA3A23CFA7F7D966A9078A66DD2E19CF91DFC38" +
+            "D894F4C6A50A9686A4BD9E1AAE044283B8B5809B223820B525E564ECF7F4BF7E" +
+            "6359250F7A2E395776A271AA068A0F8916BA61A711CB9AD80E479A80C5D0CDA7" +
+            "D0EF7D83F0E13B7109DF5D7498220861DAB0501E6FBDF1E100DFE73107A4933A" +
+            "F7654778E8F8A848ABF7DE727E616B6F77A981CBA709AC39BBECC6CBD882B472" +
+            "CD1DF4B885011E80FB1B892A5439B25BDAC80D55997A87733B08E6982DEA8DE0" +
+            "332E1229F5C02F542721F7C8AC4EDA28B8B1A9DB96B2A742A2C9CF19414DE086" +
+            "F92A9AA3116630D3BB74324BDF637BF5998A2F1BC721AF59B5AEDC443C975071" +
+            "D7A1D2C555E369DE57C1D1DE30C0FDCCE64DFB0DBF5D4FE99D1E19382FBCCF58" +
+            "052EEF0DA05035DAEF09271CD5B37E351E08BADA36DBD35F8FDE74884912A182" +
+            "02D43082023D02010130820100A181D8A481D53081D2310B3009060355040613" +
+            "025553311330110603550408130A57617368696E67746F6E3110300E06035504" +
+            "0713075265646D6F6E64311E301C060355040A13154D6963726F736F66742043" +
+            "6F72706F726174696F6E312D302B060355040B13244D6963726F736F66742049" +
+            "72656C616E64204F7065726174696F6E73204C696D6974656431263024060355" +
+            "040B131D5468616C6573205453532045534E3A303834322D344245362D433239" +
+            "41312530230603550403131C4D6963726F736F66742054696D652D5374616D70" +
+            "2053657276696365A2230A0101300706052B0E03021A0315000D4D94FE1BDE96" +
+            "848D743F1DEE4A04C6B3658C07A08183308180A47E307C310B30090603550406" +
+            "13025553311330110603550408130A57617368696E67746F6E3110300E060355" +
+            "040713075265646D6F6E64311E301C060355040A13154D6963726F736F667420" +
+            "436F72706F726174696F6E312630240603550403131D4D6963726F736F667420" +
+            "54696D652D5374616D70205043412032303130300D06092A864886F70D010105" +
+            "0500020500E5084E973022180F32303231313030373030333433315A180F3230" +
+            "3231313030383030333433315A3074303A060A2B0601040184590A0401312C30" +
+            "2A300A020500E5084E97020100300702010002021DE630070201000202113630" +
+            "0A020500E509A0170201003036060A2B0601040184590A040231283026300C06" +
+            "0A2B0601040184590A0302A00A3008020100020307A120A10A30080201000203" +
+            "0186A0300D06092A864886F70D0101050500038181002AE0DF2A01AAE13A86C0" +
+            "2DD8ECA787327C8F04A7C13D47256E65C60676B8372EE46362CD35391B6B898E" +
+            "DC1884082AAA7CF9B1CF40BE2C30146D0080ACB225C50B7C1FE94694732EDEEB" +
+            "9EDE73DB7D8C0762CBDFABD3ACCC82DD3858AA16C3ED185A40A39E9676772099" +
+            "346E3362621286651B06D9AD26D574F967F6C7EC335A3182030D308203090201" +
+            "01308193307C310B3009060355040613025553311330110603550408130A5761" +
+            "7368696E67746F6E3110300E060355040713075265646D6F6E64311E301C0603" +
+            "55040A13154D6963726F736F667420436F72706F726174696F6E312630240603" +
+            "550403131D4D6963726F736F66742054696D652D5374616D7020504341203230" +
+            "313002133300000139CCE8E8438BF034E1000000000139300D06096086480165" +
+            "030402010500A082014A301A06092A864886F70D010903310D060B2A864886F7" +
+            "0D0109100104302F06092A864886F70D01090431220420EA37C01965AB5A8B08" +
+            "C2A59F8EF2008C2B60F78E7F0385E2DD18A07C63433EF43081FA060B2A864886" +
+            "F70D010910022F3181EA3081E73081E43081BD04203CA18EE438A3D7247B3142" +
+            "B1E28105AE7C6A5527F39A7A9F26A6D4A0070FFC9F308198308180A47E307C31" +
+            "0B3009060355040613025553311330110603550408130A57617368696E67746F" +
+            "6E3110300E060355040713075265646D6F6E64311E301C060355040A13154D69" +
+            "63726F736F667420436F72706F726174696F6E312630240603550403131D4D69" +
+            "63726F736F66742054696D652D5374616D702050434120323031300213330000" +
+            "0139CCE8E8438BF034E1000000000139302204204A6E54AC16FAF6985726E0CB" +
+            "5480381C41888386AB1D1BECC241E6BCFCBDD45B300D06092A864886F70D0101" +
+            "0B0500048201006957F018A5C13CC539EB266EC2725998F4AC0ED50CE1CAA696" +
+            "CAE377977F45FB8030136A4038B49F7E5A6ADCF72FA3901C26B52815621F52A2" +
+            "EB2ACFC423087ECD954F34C341342E31BDF30443CAC4F1297AB0181467B90604" +
+            "DDCF11F9F8930290614E8AA9D868E56971E4F83427819F8A1A11ED87AD1D5469" +
+            "7AFFE60A8D7B7877CBB1D09F46397769B9D0F8EB605DBFE8F05C47A3F8BC1F65" +
+            "F9F63553F187194B35E971FEFFB00C9127BDFD0F7FCF2424BE2A108AC5C532EA" +
+            "6AB46C76047604BA7DF071EE0137B73F4D9DF616095C8F1CA9EB925B6D4C6ABC" +
+            "FFEB73A81903169C6B487B316AFC951F696831A4B29B9ABCEA7EBCD243A553D2" +
+            "F8B44FDA1B0AC0").HexToByteArray();
     }
 }