public static void RemoveCounterSignature_MatchesSubjectKeyIdentifier()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.OneRsaSignerTwoRsaCounterSigners);
            SignerInfo signerInfo    = cms.SignerInfos[0];
            SignerInfo counterSigner = signerInfo.CounterSignerInfos[0];

            Assert.Equal(
                SubjectIdentifierType.SubjectKeyIdentifier,
                counterSigner.SignerIdentifier.Type);

            int countBefore = cms.Certificates.Count;

            Assert.Equal(signerInfo.Certificate, counterSigner.Certificate);

            signerInfo.RemoveCounterSignature(counterSigner);
            Assert.Single(cms.SignerInfos);

            // Removing a CounterSigner doesn't update the current object, it updates
            // the underlying SignedCms object, and a new signer has to be retrieved.
            Assert.Equal(2, signerInfo.CounterSignerInfos.Count);
            Assert.Single(cms.SignerInfos[0].CounterSignerInfos);

            // This certificate is still in use, since we counter-signed ourself,
            // and the remaining countersigner is us.
            Assert.Equal(countBefore, cms.Certificates.Count);

            // Assert.NotThrows
            cms.CheckSignature(true);
            cms.CheckHash();
        }
        public static void RemoveCounterSignature_UsesLiveState()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.OneRsaSignerTwoRsaCounterSigners);
            SignerInfo signerInfo    = cms.SignerInfos[0];
            SignerInfo counterSigner = signerInfo.CounterSignerInfos[0];

            Assert.Equal(
                SubjectIdentifierType.SubjectKeyIdentifier,
                counterSigner.SignerIdentifier.Type);

            int countBefore = cms.Certificates.Count;

            Assert.Equal(signerInfo.Certificate, counterSigner.Certificate);

            signerInfo.RemoveCounterSignature(counterSigner);
            Assert.Single(cms.SignerInfos);

            // Removing a CounterSigner doesn't update the current object, it updates
            // the underlying SignedCms object, and a new signer has to be retrieved.
            Assert.Equal(2, signerInfo.CounterSignerInfos.Count);
            Assert.Single(cms.SignerInfos[0].CounterSignerInfos);
            Assert.Equal(countBefore, cms.Certificates.Count);

            // Even though the CounterSignerInfos collection still contains this, the live
            // document doesn't.
            Assert.Throws <CryptographicException>(
                () => signerInfo.RemoveCounterSignature(counterSigner));

            // Assert.NotThrows
            cms.CheckSignature(true);
            cms.CheckHash();
        }
        public static void RemoveCounterSignature_MatchesIssuerAndSerialNumber()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.OneRsaSignerTwoRsaCounterSigners);
            SignerInfo signerInfo    = cms.SignerInfos[0];
            SignerInfo counterSigner = signerInfo.CounterSignerInfos[1];

            Assert.Equal(
                SubjectIdentifierType.IssuerAndSerialNumber,
                counterSigner.SignerIdentifier.Type);

            int countBefore = cms.Certificates.Count;

            Assert.NotEqual(signerInfo.Certificate, counterSigner.Certificate);

            signerInfo.RemoveCounterSignature(counterSigner);
            Assert.Single(cms.SignerInfos);

            // Removing a CounterSigner doesn't update the current object, it updates
            // the underlying SignedCms object, and a new signer has to be retrieved.
            Assert.Equal(2, signerInfo.CounterSignerInfos.Count);
            Assert.Single(cms.SignerInfos[0].CounterSignerInfos);

            Assert.Equal(countBefore, cms.Certificates.Count);

            // Assert.NotThrows
            cms.CheckSignature(true);
            cms.CheckHash();
        }
        public static void AddFirstCounterSigner_NoSignature_NoPrivateKey()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber);

            SignerInfo firstSigner = cms.SignerInfos[0];

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                Action sign = () =>
                              firstSigner.ComputeCounterSignature(
                    new CmsSigner(
                        SubjectIdentifierType.NoSignature,
                        cert)
                {
                    IncludeOption = X509IncludeOption.None,
                });

                if (PlatformDetection.IsFullFramework)
                {
                    Assert.ThrowsAny <CryptographicException>(sign);
                }
                else
                {
                    sign();
                    cms.CheckHash();
                    Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true));
                    firstSigner.CheckSignature(true);
                }
            }
        }
        public static void DefaultStateBehavior()
        {
            SignedCms cms = new SignedCms();

            Assert.Equal(0, cms.Version);
            Assert.False(cms.Detached, "cms.Detached");

            X509Certificate2Collection certificates = cms.Certificates;
            X509Certificate2Collection certificates2 = cms.Certificates;

            Assert.NotSame(certificates, certificates2);
            Assert.Equal(0, certificates.Count);
            Assert.Equal(0, certificates2.Count);

            ContentInfo content = cms.ContentInfo;
            ContentInfo content2 = cms.ContentInfo;
            Assert.Same(content, content2);

            Assert.Equal("1.2.840.113549.1.7.1", content.ContentType.Value);
            Assert.Equal(Array.Empty<byte>(), content.Content);

            SignerInfoCollection signers = cms.SignerInfos;
            SignerInfoCollection signers2 = cms.SignerInfos;

            Assert.NotSame(signers, signers2);
            Assert.Equal(0, signers.Count);
            Assert.Equal(0, signers2.Count);

            Assert.Throws<InvalidOperationException>(() => cms.CheckSignature(true));
            Assert.Throws<InvalidOperationException>(() => cms.CheckHash());
            Assert.Throws<InvalidOperationException>(() => cms.RemoveSignature(0));
            Assert.Throws<InvalidOperationException>(() => cms.RemoveSignature(-1));
            Assert.Throws<InvalidOperationException>(() => cms.RemoveSignature(10000));
            Assert.Throws<InvalidOperationException>(() => cms.Encode());
        }
        public BankIdNoSignatureVerification(Stream xmlStream)
        {
            var reader = XmlReader.Create(xmlStream, new XmlReaderSettings
            {
                DtdProcessing             = DtdProcessing.Prohibit,
                MaxCharactersFromEntities = 30,
                //XmlResolver = null
            });
            var doc = new XmlDocument {
                PreserveWhitespace = true
            };

            doc.Load(reader);

            var nm = new XmlNamespaceManager(doc.NameTable);

            nm.AddNamespace("sdo", "http://www.npt.no/seid/xmlskjema/SDO_v1.0");
            nm.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
            nm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            nm.AddNamespace("xades", "http://uri.etsi.org/01903/v1.2.2#");

            var node = doc.SelectSingleNode("//sdo:SDOList/sdo:SDO/sdo:SignedObject/sdo:SignersDocument", nm);

            if (node == null)
            {
                throw new Exception("Cannot find SignersDocument node in SDO");
            }

            var documentContentInfo = new ContentInfo(Convert.FromBase64String(node.InnerText));

            var list = doc.SelectNodes("//sdo:SDOList/sdo:SDO/sdo:SDODataPart/sdo:SignatureElement", nm);

            foreach (XmlNode item in list)
            {
                var cms = new SignedCms(documentContentInfo, true);

                var signatureNode = item.SelectSingleNode("//sdo:CMSSignatureElement/sdo:CMSSignature", nm);
                if (signatureNode != null)
                {
                    cms.Decode(Convert.FromBase64String(signatureNode.InnerText));
                }

                var timeStamp = cms.SignerInfos[0]
                                .SignedAttributes.Cast <CryptographicAttributeObject>()
                                .Where(sa => sa.Oid.Value == "1.2.840.113549.1.9.5" &&
                                       (sa.Oid.FriendlyName.Equals("Signing Time") ||
                                        sa.Oid.FriendlyName.Equals("Tidspunkt for signatur")))
                                .Select(sa => ((Pkcs9SigningTime)sa.Values[0]).SigningTime)
                                .Cast <DateTime?>()
                                .FirstOrDefault();

                // TODO: Validate certificate chain when we get the root certificate
                //var signedCertificate = CryptoUtils.GetSignerCertificate(SystemTestBankIdSeRootCertificate, cms.Certificates.Cast<X509Certificate2>().ToList(), timeStamp);

                cms.CheckHash();
                cms.CheckSignature(true);
            }
        }
        public static void CheckHash_AllRemoved()
        {
            SignedCms cms = new SignedCms();
            cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber);
            Assert.Single(cms.SignerInfos);

            cms.RemoveSignature(0);
            Assert.Empty(cms.SignerInfos);

            Assert.Throws<CryptographicException>(() => cms.CheckHash());
        }
        public bool VerifyEnvelopedPKCS7(byte[] p7bData, out byte[] dataToSign)
        {
            SignedCms signedCms = new SignedCms();

            //解密文
            signedCms.Decode(p7bData);
            // 驗證資料完整性
            signedCms.CheckHash();

            dataToSign = signedCms.ContentInfo.Content;

            return(verifySignedCms(p7bData, signedCms));
        }
        public static void AddFirstCounterSigner_NoSignature()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber);

            SignerInfo firstSigner = cms.SignerInfos[0];

            // A certificate shouldn't really be required here, but on .NET Framework
            // it will prompt for the counter-signer's certificate if it's null,
            // even if the signature type is NoSignature.
            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey())
            {
                firstSigner.ComputeCounterSignature(
                    new CmsSigner(
                        SubjectIdentifierType.NoSignature,
                        cert)
                {
                    IncludeOption = X509IncludeOption.None,
                });
            }

            Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true));
            cms.CheckHash();

            byte[] encoded = cms.Encode();
            cms = new SignedCms();
            cms.Decode(encoded);
            Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true));
            cms.CheckHash();

            firstSigner = cms.SignerInfos[0];
            firstSigner.CheckSignature(verifySignatureOnly: true);
            Assert.ThrowsAny <CryptographicException>(() => firstSigner.CheckHash());

            SignerInfo firstCounterSigner = firstSigner.CounterSignerInfos[0];

            Assert.ThrowsAny <CryptographicException>(() => firstCounterSigner.CheckSignature(true));

            if (PlatformDetection.IsFullFramework)
            {
                // NetFX's CheckHash only looks at top-level SignerInfos to find the
                // crypt32 CMS signer ID, so it fails on any check from a countersigner.
                Assert.ThrowsAny <CryptographicException>(() => firstCounterSigner.CheckHash());
            }
            else
            {
                firstCounterSigner.CheckHash();
            }
        }
        private bool verify(byte[] dataToSign, byte[] dataSignature)
        {
            ContentInfo contentInfo = new ContentInfo(dataToSign);

            // Create a new, detached SignedCms message.

            SignedCms signedCms = new SignedCms(contentInfo, true);

            //解密文
            signedCms.Decode(dataSignature);
            // 驗證資料完整性
            signedCms.CheckHash();

            return(verifySignedCms(dataSignature, signedCms));
        }
        public static void NonEmbeddedCertificate()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaCapiTransfer1_NoEmbeddedCert);

            Assert.Equal(3, cms.Version);
            Assert.Equal(Oids.Pkcs7Data, cms.ContentInfo.ContentType.Value);

            Assert.Equal(
                "4D6963726F736F667420436F72706F726174696F6E",
                cms.ContentInfo.Content.ByteArrayToHex());

            Assert.Empty(cms.Certificates);

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);

            SignerInfo signer = signers[0];

            Assert.Equal(3, signer.Version);
            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, signer.SignerIdentifier.Type);
            Assert.Equal("6B4A6B92FDED07EE0119F3674A96D1A70D2A588D", (string)signer.SignerIdentifier.Value);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;

            Assert.Equal(3, signedAttrs.Count);

            Pkcs9ContentType   contentType   = (Pkcs9ContentType)signedAttrs[0].Values[0];
            Pkcs9SigningTime   signingTime   = (Pkcs9SigningTime)signedAttrs[1].Values[0];
            Pkcs9MessageDigest messageDigest = (Pkcs9MessageDigest)signedAttrs[2].Values[0];

            Assert.Equal(Oids.Pkcs7Data, contentType.ContentType.Value);
            Assert.Equal(
                new DateTimeOffset(2017, 11, 2, 15, 34, 4, TimeSpan.Zero),
                signingTime.SigningTime);

            Assert.Equal(DateTimeKind.Utc, signingTime.SigningTime.Kind);

            Assert.Empty(signer.UnsignedAttributes);
            Assert.Empty(signer.CounterSignerInfos);
            Assert.Null(signer.Certificate);

#if NETCOREAPP
            Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "0EDE3870B8A80B45A21BAEC4681D059B46502E1B1AA6B8920CF50D4D837646A5" +
                "5559B4C05849126C655D95FF3C6C1B420E07DC42629F294EE69822FEA56F32D4" +
                "1B824CBB6BF809B7583C27E77B7AC58DFC925B1C60EA4A67AA84D73FC9E9191D" +
                "33B36645F17FD6748A2D8B12C6C384C3C734D27273386211E4518FE2B4ED0147",
                signer.GetSignature().ByteArrayToHex());
#endif

            using (SHA1 sha1 = SHA1.Create())
            {
                Assert.Equal(
                    sha1.ComputeHash(cms.ContentInfo.Content).ByteArrayToHex(),
                    messageDigest.MessageDigest.ByteArrayToHex());
            }

            // Since it's not NoSignature CheckHash will throw.
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // Since there's no matched certificate CheckSignature will throw.
            Assert.Throws <CryptographicException>(() => signer.CheckSignature(true));

            // Since there are no NoSignature signers, SignedCms.CheckHash will succeed
            cms.CheckHash();

            // Since there are no matched certificates SignedCms.CheckSignature will throw.
            Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));

            using (X509Certificate2 wrongCert = Certificates.RSAKeyTransfer1.GetCertificate())
                using (X509Certificate2 rightCert = Certificates.RSAKeyTransferCapi1.GetCertificate())
                {
                    X509Certificate2Collection coll = new X509Certificate2Collection(wrongCert);

                    // Wrong certificate, still throw.
                    Assert.Throws <CryptographicException>(() => signer.CheckSignature(coll, true));
                    Assert.Throws <CryptographicException>(() => cms.CheckSignature(coll, true));

                    coll = new X509Certificate2Collection(rightCert);

                    // Right cert, success
                    signer.CheckSignature(coll, true);
                    Assert.Null(signer.Certificate);
                    cms.CheckSignature(coll, true);
                    Assert.Null(cms.SignerInfos[0].Certificate);

                    coll.Add(wrongCert);

                    // Both right and wrong, success
                    signer.CheckSignature(coll, true);
                    Assert.Null(signer.Certificate);
                    cms.CheckSignature(coll, true);
                    Assert.Null(cms.SignerInfos[0].Certificate);

                    coll = new X509Certificate2Collection(wrongCert);

                    // Just wrong again, no accidental stateful match
                    Assert.Throws <CryptographicException>(() => signer.CheckSignature(coll, true));
                    Assert.Throws <CryptographicException>(() => cms.CheckSignature(coll, true));

                    coll.Add(rightCert);

                    // Wrong then right, success
                    signer.CheckSignature(coll, true);
                    Assert.Null(signer.Certificate);
                    cms.CheckSignature(coll, true);
                    Assert.Null(cms.SignerInfos[0].Certificate);
                }
        }
        public static void CheckNoSignatureDocument()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.NoSignatureSignedWithAttributesAndCounterSignature);

            Assert.Equal(1, cms.Version);
            Assert.Equal(Oids.Pkcs7Data, cms.ContentInfo.ContentType.Value);

            Assert.Equal(
                "4D6963726F736F667420436F72706F726174696F6E",
                cms.ContentInfo.Content.ByteArrayToHex());

            X509Certificate2Collection cmsCerts = cms.Certificates;

            Assert.Single(cmsCerts);

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);

            SignerInfo signer = signers[0];

            Assert.Equal(SubjectIdentifierType.NoSignature, signer.SignerIdentifier.Type);
            Assert.Null(signer.SignerIdentifier.Value);
            Assert.Null(signer.Certificate);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

#if NETCOREAPP
            Assert.Equal("1.3.6.1.5.5.7.6.2", signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "8B70D20D0477A35CD84AB962C10DC52FBA6FAD6B",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Equal(3, signedAttrs.Count);

            Assert.Single(signedAttrs[0].Values);
            Assert.Single(signedAttrs[1].Values);
            Assert.Single(signedAttrs[2].Values);

            Pkcs9ContentType   contentType   = (Pkcs9ContentType)signedAttrs[0].Values[0];
            Pkcs9SigningTime   signingTime   = (Pkcs9SigningTime)signedAttrs[1].Values[0];
            Pkcs9MessageDigest messageDigest = (Pkcs9MessageDigest)signedAttrs[2].Values[0];

            Assert.Equal(Oids.Pkcs7Data, contentType.ContentType.Value);
            Assert.Equal(
                new DateTimeOffset(2017, 11, 1, 17, 17, 17, TimeSpan.Zero),
                signingTime.SigningTime);

            Assert.Equal(DateTimeKind.Utc, signingTime.SigningTime.Kind);

            using (SHA1 sha1 = SHA1.Create())
            {
                Assert.Equal(
                    sha1.ComputeHash(cms.ContentInfo.Content).ByteArrayToHex(),
                    messageDigest.MessageDigest.ByteArrayToHex());
            }

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Single(unsignedAttrs);
            // No need to check the contents, it's a CounterSigner (tested next)

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Single(counterSigners);

            SignerInfo counterSigner = counterSigners[0];
            Assert.Equal(3, counterSigner.Version);
            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, counterSigner.SignerIdentifier.Type);
            Assert.Equal("6B4A6B92FDED07EE0119F3674A96D1A70D2A588D", (string)counterSigner.SignerIdentifier.Value);
            Assert.Equal(Oids.Sha1, counterSigner.DigestAlgorithm.Value);

            CryptographicAttributeObjectCollection csSignedAttrs = counterSigner.SignedAttributes;
            Assert.Equal(2, csSignedAttrs.Count);

            // RFC3369 says that the content-type attribute must not be present for counter-signers, but it is.
            // RFC2630 said that it "is not required".
            Pkcs9ContentType   csContentType   = (Pkcs9ContentType)csSignedAttrs[0].Values[0];
            Pkcs9MessageDigest csMessageDigest = (Pkcs9MessageDigest)csSignedAttrs[1].Values[0];

            Assert.Equal(Oids.Pkcs7Data, csContentType.ContentType.Value);
            Assert.Equal(
                "833378066BDCCBA7047EF6919843D181A57D6479",
                csMessageDigest.MessageDigest.ByteArrayToHex());

#if NETCOREAPP
            Assert.Equal(Oids.Rsa, counterSigner.SignatureAlgorithm.Value);

            Assert.Equal(
                "2155D226DD744166E582D040E60535210195050EA00F2C179897198521DABD0E" +
                "6B27750FD8BA5F9AAF58B4863B6226456F38553A22453CAF0A0F106766C7AB6F" +
                "3D6AFD106753DC50F8A6E4F9E5508426D236C2DBB4BCB8162FA42E995CBA16A3" +
                "40FD7C793569DF1B71368E68253299BC74E38312B40B8F52EAEDE10DF414A522",
                counterSigner.GetSignature().ByteArrayToHex());
#endif

            using (X509Certificate2 capiCert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                Assert.Equal(capiCert, cmsCerts[0]);
                Assert.Equal(capiCert, counterSigner.Certificate);
            }

            // The counter-signer has a (real) signature, and a certificate, so CheckSignature
            // will pass
            counterSigner.CheckSignature(true);

            // The (primary) signer has a hash-only signature with no certificate,
            // so CheckSignature will fail.
            Assert.Throws <CryptographicException>(() => signer.CheckSignature(true));

            // The (primary) signer is a NoSignature type, so CheckHash will succeed
            signer.CheckHash();

            // The document has a NoSignature signer, so CheckHash will do something (and succeed).
            cms.CheckHash();

            // Since the document's primary signer is NoSignature, CheckSignature will fail
            Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));
        }
        public static void ReadRsaPkcs1CounterSigned()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.CounterSignedRsaPkcs1OneSigner);

            Assert.Equal(1, cms.Version);

            ContentInfo contentInfo = cms.ContentInfo;

            Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value);
            Assert.Equal("4D6963726F736F667420436F72706F726174696F6E", contentInfo.Content.ByteArrayToHex());

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);
            SignerInfo signer = signers[0];

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                X509Certificate2Collection certs = cms.Certificates;

                Assert.Single(certs);

                Assert.Equal(cert, certs[0]);
                Assert.Equal(cert, signer.Certificate);
                Assert.NotSame(certs[0], signer.Certificate);
                Assert.NotSame(cert, signer.Certificate);
                Assert.NotSame(cert, certs[0]);
            }

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

#if NETCOREAPP
            Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "5A1717621D450130B3463662160EEC06F7AE77E017DD95F294E97A0BDD433FE6" +
                "B2CCB34FAAC33AEA50BFD7D9E78DC7174836284619F744278AE77B8495091E09" +
                "6EEF682D9CA95F6E81C7DDCEDDA6A12316B453C894B5000701EB09DF57A53B73" +
                "3A4E80DA27FA710870BD88C86E2FDB9DCA14D18BEB2F0C87E9632ABF02BE2FE3",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Empty(signedAttrs);

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Single(unsignedAttrs);

            Assert.Equal(Oids.CounterSigner, unsignedAttrs[0].Oid.Value);

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Single(counterSigners);
            SignerInfo counterSigner = counterSigners[0];

            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, counterSigner.SignerIdentifier.Type);

            // Not universally true, but is in this case.
            Assert.Equal(signer.Certificate, counterSigner.Certificate);
            Assert.NotSame(signer.Certificate, counterSigner.Certificate);

            // Assert.NotThrows
            signer.CheckSignature(true);

            // Assert.NotThrows
            counterSigner.CheckSignature(true);

            // The document should be validly signed, then.
            // Assert.NotThrows
            cms.CheckSignature(true);

            // If CheckSignature succeeds then CheckHash cannot.
            Assert.Throws <CryptographicException>(() => counterSigner.CheckHash());
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // Since there are no NoSignature signers, CheckHash won't throw.
            // Assert.NotThrows
            cms.CheckHash();
        }
        public static void ReadRsaPssDocument(bool fromSpan)
        {
            SignedCms cms = new SignedCms();

            if (fromSpan)
            {
#if !NET472
                cms.Decode(SignedDocuments.RsaPssDocument.AsSpan());
#else
                throw new Xunit.Sdk.XunitException(
                          "This test should not evaluate for .NET Framework, the API is missing.");
#endif
            }
            else
            {
                cms.Decode(SignedDocuments.RsaPssDocument);
            }

            Assert.Equal(3, cms.Version);

            ContentInfo contentInfo = cms.ContentInfo;

            Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value);
            Assert.Equal("54686973206973206120746573740D0A", contentInfo.Content.ByteArrayToHex());

            X509Certificate2Collection certs = cms.Certificates;
            Assert.Single(certs);

            X509Certificate2 topLevelCert = certs[0];
            Assert.Equal("localhost", topLevelCert.GetNameInfo(X509NameType.SimpleName, false));

            Assert.Equal(
                new DateTimeOffset(2016, 3, 2, 2, 37, 54, TimeSpan.Zero),
                new DateTimeOffset(topLevelCert.NotBefore));

            Assert.Equal(
                new DateTimeOffset(2017, 3, 2, 2, 37, 54, TimeSpan.Zero),
                new DateTimeOffset(topLevelCert.NotAfter));

            SignerInfoCollection signers = cms.SignerInfos;
            Assert.Single(signers);

            SignerInfo signer = signers[0];
            Assert.Equal(3, signer.Version);
            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, signer.SignerIdentifier.Type);
            Assert.Equal("1063CAB14FB14C47DC211C0E0285F3EE5946BF2D", signer.SignerIdentifier.Value);
            Assert.Equal("2.16.840.1.101.3.4.2.1", signer.DigestAlgorithm.Value);
#if NETCOREAPP
            Assert.Equal("1.2.840.113549.1.1.10", signer.SignatureAlgorithm.Value);
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Equal(4, signedAttrs.Count);

            Assert.Equal("1.2.840.113549.1.9.3", signedAttrs[0].Oid.Value);
            Assert.Equal("1.2.840.113549.1.9.5", signedAttrs[1].Oid.Value);
            Assert.Equal("1.2.840.113549.1.9.4", signedAttrs[2].Oid.Value);
            Assert.Equal("1.2.840.113549.1.9.15", signedAttrs[3].Oid.Value);

            Assert.Equal(1, signedAttrs[0].Values.Count);
            Assert.Equal(1, signedAttrs[1].Values.Count);
            Assert.Equal(1, signedAttrs[2].Values.Count);
            Assert.Equal(1, signedAttrs[3].Values.Count);

            Pkcs9ContentType contentTypeAttr = (Pkcs9ContentType)signedAttrs[0].Values[0];
            Assert.Equal("1.2.840.113549.1.7.1", contentTypeAttr.ContentType.Value);

            Pkcs9SigningTime signingTimeAttr = (Pkcs9SigningTime)signedAttrs[1].Values[0];
            Assert.Equal(
                new DateTimeOffset(2017, 10, 26, 1, 6, 25, TimeSpan.Zero),
                new DateTimeOffset(signingTimeAttr.SigningTime));

            Pkcs9MessageDigest messageDigestAttr = (Pkcs9MessageDigest)signedAttrs[2].Values[0];
            Assert.Equal(
                "07849DC26FCBB2F3BD5F57BDF214BAE374575F1BD4E6816482324799417CB379",
                messageDigestAttr.MessageDigest.ByteArrayToHex());

            Assert.IsType <Pkcs9AttributeObject>(signedAttrs[3].Values[0]);
#if !NETCOREAPP
            Assert.NotSame(signedAttrs[3].Oid, signedAttrs[3].Values[0].Oid);
#endif
            Assert.Equal(
                "306A300B060960864801650304012A300B0609608648016503040116300B0609" +
                "608648016503040102300A06082A864886F70D0307300E06082A864886F70D03" +
                "0202020080300D06082A864886F70D0302020140300706052B0E030207300D06" +
                "082A864886F70D0302020128",
                signedAttrs[3].Values[0].RawData.ByteArrayToHex());

#if NETCOREAPP
            Assert.Equal(
                "B93E81D141B3C9F159AB0021910635DC72E8E860BE43C28E5D53243D6DC247B7" +
                "D4F18C20195E80DEDCC75B29C43CE5047AD775B65BFC93589BD748B950C68BAD" +
                "DF1A4673130302BBDA8667D5DDE5EA91ECCB13A9B4C04F1C4842FEB1697B7669" +
                "C7692DD3BDAE13B5AA8EE3EB5679F3729D1DC4F2EB9DC89B7E8773F2F8C6108C" +
                "05",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Empty(unsignedAttrs);

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Empty(counterSigners);

            X509Certificate2 signerCertificate = signer.Certificate;
            Assert.Equal(
                "CN=localhost, OU=.NET Framework, O=Microsoft Corp., L=Redmond, S=Washington, C=US",
                signerCertificate.SubjectName.Name);

            // CheckHash always throws for certificate-based signers.
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // At this time we cannot support the PSS parameters for this document.
            Assert.Throws <CryptographicException>(() => signer.CheckSignature(true));

            // Since there are no NoSignature signers the document CheckHash will succeed.
            // Assert.NotThrows
            cms.CheckHash();

            // Since at least one signer fails, the document signature will fail
            Assert.Throws <CryptographicException>(() => cms.CheckSignature(true));
        }
        private static void AddSecondCounterSignature_NoSignature(bool withCertificate, bool addExtraCert)
        {
            X509Certificate2Collection certs;
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber);

            SignerInfo firstSigner = cms.SignerInfos[0];

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.TryGetCertificateWithPrivateKey())
                using (X509Certificate2 cert2 = Certificates.DHKeyAgree1.GetCertificate())
                {
                    firstSigner.ComputeCounterSignature(
                        new CmsSigner(cert)
                    {
                        IncludeOption = X509IncludeOption.None,
                    });

                    CmsSigner counterSigner;

                    if (withCertificate)
                    {
                        counterSigner = new CmsSigner(SubjectIdentifierType.NoSignature, cert);
                    }
                    else
                    {
                        counterSigner = new CmsSigner(SubjectIdentifierType.NoSignature);
                    }

                    if (addExtraCert)
                    {
                        counterSigner.Certificates.Add(cert2);
                    }

                    firstSigner.ComputeCounterSignature(counterSigner);

                    certs = cms.Certificates;

                    if (addExtraCert)
                    {
                        Assert.Equal(2, certs.Count);
                        Assert.NotEqual(cert2.RawData, certs[0].RawData);
                        Assert.Equal(cert2.RawData, certs[1].RawData);
                    }
                    else
                    {
                        Assert.Equal(1, certs.Count);
                        Assert.NotEqual(cert2.RawData, certs[0].RawData);
                    }
                }

            Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true));
            cms.CheckHash();

            byte[] encoded = cms.Encode();
            cms = new SignedCms();
            cms.Decode(encoded);
            Assert.ThrowsAny <CryptographicException>(() => cms.CheckSignature(true));
            cms.CheckHash();

            firstSigner = cms.SignerInfos[0];
            firstSigner.CheckSignature(verifySignatureOnly: true);
            Assert.ThrowsAny <CryptographicException>(() => firstSigner.CheckHash());

            // The NoSignature CounterSigner sorts first.
            SignerInfo firstCounterSigner = firstSigner.CounterSignerInfos[0];

            Assert.Equal(SubjectIdentifierType.NoSignature, firstCounterSigner.SignerIdentifier.Type);
            Assert.ThrowsAny <CryptographicException>(() => firstCounterSigner.CheckSignature(true));

            if (PlatformDetection.IsFullFramework)
            {
                // NetFX's CheckHash only looks at top-level SignerInfos to find the
                // crypt32 CMS signer ID, so it fails on any check from a countersigner.
                Assert.ThrowsAny <CryptographicException>(() => firstCounterSigner.CheckHash());
            }
            else
            {
                firstCounterSigner.CheckHash();
            }

            certs = cms.Certificates;

            if (addExtraCert)
            {
                Assert.Equal(2, certs.Count);
                Assert.Equal("CN=DfHelleKeyAgreement1", certs[1].SubjectName.Name);
            }
            else
            {
                Assert.Equal(1, certs.Count);
            }

            Assert.Equal("CN=RSAKeyTransferCapi1", certs[0].SubjectName.Name);
        }
        public static void ReadRsaPkcs1DoubleCounterSigned()
        {
            SignedCms cms = new SignedCms();

            cms.Decode(SignedDocuments.OneRsaSignerTwoRsaCounterSigners);

            Assert.Equal(1, cms.Version);

            ContentInfo contentInfo = cms.ContentInfo;

            Assert.Equal("1.2.840.113549.1.7.1", contentInfo.ContentType.Value);
            Assert.Equal("4D6963726F736F667420436F72706F726174696F6E", contentInfo.Content.ByteArrayToHex());

            SignerInfoCollection signers = cms.SignerInfos;

            Assert.Single(signers);
            SignerInfo signer = signers[0];

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                X509Certificate2Collection certs = cms.Certificates;

                Assert.Equal(2, certs.Count);

                Assert.Equal(cert, certs[1]);
                Assert.Equal(cert, signer.Certificate);
                Assert.NotSame(certs[1], signer.Certificate);
                Assert.NotSame(cert, signer.Certificate);
                Assert.NotSame(cert, certs[1]);
            }

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, signer.SignerIdentifier.Type);
            Assert.Equal(Oids.Sha1, signer.DigestAlgorithm.Value);

#if NETCOREAPP
            Assert.Equal(Oids.Rsa, signer.SignatureAlgorithm.Value);

            Assert.Equal(
                "5A1717621D450130B3463662160EEC06F7AE77E017DD95F294E97A0BDD433FE6" +
                "B2CCB34FAAC33AEA50BFD7D9E78DC7174836284619F744278AE77B8495091E09" +
                "6EEF682D9CA95F6E81C7DDCEDDA6A12316B453C894B5000701EB09DF57A53B73" +
                "3A4E80DA27FA710870BD88C86E2FDB9DCA14D18BEB2F0C87E9632ABF02BE2FE3",
                signer.GetSignature().ByteArrayToHex());
#endif

            CryptographicAttributeObjectCollection signedAttrs = signer.SignedAttributes;
            Assert.Empty(signedAttrs);

            CryptographicAttributeObjectCollection unsignedAttrs = signer.UnsignedAttributes;
            Assert.Equal(2, unsignedAttrs.Count);

            Assert.Equal(Oids.CounterSigner, unsignedAttrs[0].Oid.Value);

            SignerInfoCollection counterSigners = signer.CounterSignerInfos;
            Assert.Equal(2, counterSigners.Count);
            SignerInfo cs1 = counterSigners[0];
            SignerInfo cs2 = counterSigners[1];

            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, cs1.SignerIdentifier.Type);

            // Not universally true, but is in this case.
            Assert.Equal(signer.Certificate, cs1.Certificate);
            Assert.NotSame(signer.Certificate, cs1.Certificate);

            Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, cs2.SignerIdentifier.Type);
            Assert.NotEqual(signer.Certificate, cs2.Certificate);

            // Assert.NotThrows
            signer.CheckSignature(true);

            // Assert.NotThrows
            cs1.CheckSignature(true);

            // Assert.NotThrows
            cs2.CheckSignature(true);

            // The document should be validly signed, then.
            // Assert.NotThrows
            cms.CheckSignature(true);

#if NETCOREAPP
            Assert.Equal(
                "1AA282DBED4D862D7CEA30F803E790BDB0C97EE852778CEEDDCD94BB9304A155" +
                "2E60A8D36052AC8C2D28755F3B2F473824100AB3A6ABD4C15ABD77E0FFE13D0D" +
                "F253BCD99C718FA673B6CB0CBBC68CE5A4AC671298C0A07C7223522E0E7FFF15" +
                "CEDBAB55AAA99588517674671691065EB083FB729D1E9C04B2BF99A9953DAA5E",
                cs2.GetSignature().ByteArrayToHex());
#endif

            // If CheckSignature succeeds then CheckHash cannot.
            Assert.Throws <CryptographicException>(() => cs1.CheckHash());
            Assert.Throws <CryptographicException>(() => cs2.CheckHash());
            Assert.Throws <CryptographicException>(() => signer.CheckHash());

            // Since there are no NoSignature signers, CheckHash won't throw.
            // Assert.NotThrows
            cms.CheckHash();
        }
Beispiel #17
0
 /// <inheritdoc cref="SignedCms.CheckHash()"/>
 public void CheckHash()
 {
     _signedCms.CheckHash();
 }
Beispiel #18
0
        private void sigcheck()
        {
            uint   MaxMsg = Properties.Settings.Default.MaxMsg;
            uint   MaxSig = Properties.Settings.Default.MaxSig;
            string mfpath = comboFile.Text;
            string sfpath = SignatureFile.Text;

            System.IO.FileStream mfs, sfs;
            uint msglen, siglen;

            byte[] msg;
            byte[] sig = null;

            try
            {
                mfs    = System.IO.File.OpenRead(mfpath);
                msglen = (uint)mfs.Length;
            }
            catch (Exception)
            {
                return;
            }
            if (msglen > MaxMsg)
            {
                result_append(String.Format(Properties.Resources.FileTooLong, mfpath, MaxMsg));
                return;
            }
            msg = new byte[msglen];
            mfs.Read(msg, 0, (int)msglen);
            if (sfpath.Length > 0)
            {
                try
                {
                    sfs    = System.IO.File.OpenRead(sfpath);
                    siglen = (uint)sfs.Length;
                }
                catch (Exception)
                {
                    return;
                }
                if (siglen > MaxSig)
                {
                    result_append(String.Format(Properties.Resources.FileTooLong, sfpath, MaxSig));
                    return;
                }
                sig = new byte[siglen];
                sfs.Read(sig, 0, (int)siglen);
            }
            bool detached = (sig != null);

            try
            {
                ContentInfo cmsg = new ContentInfo(msg);
                SignedCms   cms  = new SignedCms(cmsg, detached);
                if (detached)
                {
                    cms.Decode(sig);
                }
                result_append(Properties.Resources.MessageDecoded);
                cms.CheckHash();
                result_append(Properties.Resources.HashChecked);
                cms.CheckSignature(true);
                result_append(Properties.Resources.SignatureChecked);
                foreach (SignerInfo si in cms.SignerInfos)
                {
                    result_append(
                        Properties.Settings.Default.PrintCertData.ToLower().ToCharArray().Aggregate("\n",
                                                                                                    (result, c) =>
                    {
                        switch (c)
                        {
                        case 'n':
                            result += Properties.Resources.CertSerial;
                            result += si.Certificate.SerialNumber.ToString();
                            break;

                        case 'd':
                            result += Properties.Resources.CertDigestAlgorithm;
                            result += string.Format("{0} ({1})", si.DigestAlgorithm.FriendlyName, si.DigestAlgorithm.Value);
                            break;

                        case 'i':
                            result += Properties.Resources.CertIssuer;
                            result += si.Certificate.Issuer.ToString();
                            break;

                        case 's':
                            result += Properties.Resources.CertSubject;
                            result += si.Certificate.Subject.ToString();
                            break;

                        case 'b':
                            result += Properties.Resources.CertNotBefore;
                            result += si.Certificate.NotBefore.ToString();
                            break;

                        case 'a':
                            result += Properties.Resources.CertNotAfter;
                            result += si.Certificate.NotAfter.ToString();
                            break;

                        case 'f':
                            result += Properties.Resources.CertThumb;
                            result += si.Certificate.Thumbprint.ToLower().ToCharArray().Aggregate("",
                                                                                                  (_result, _c) =>
                                                                                                  _result += ((!string.IsNullOrEmpty(_result) && (_result.Length + 1) % 3 == 0) ? " " : "")
                                                                                                             + _c.ToString()
                                                                                                  );
                            break;

                        default:
                            result += Properties.Resources.CertUnk;
                            result += c.ToString();
                            break;
                        }
                        result += "\n";
                        return(result);
                    }));
                }
                cms.CheckSignature(false);
                result_append(Properties.Resources.SignatureCertChecked);
            }
            catch (Exception e)
            {
                result_append(String.Format("{0:X}: {1}", e.HResult, e.Message));
                return;
            }
            pictureKey.Image = Properties.Resources.Greenkey;
        }
Beispiel #19
0
        private bool verify(byte[] dataToSign, byte[] dataSignature)
        {
            #region 建立驗簽記錄檔
            _log = _ds.pkcs7Envelop.Newpkcs7EnvelopRow();
            _ds.pkcs7Envelop.Addpkcs7EnvelopRow(_log);

            _log.DataToSign    = System.Text.Encoding.Default.GetString(dataToSign);
            _log.DataSignature = Convert.ToBase64String(dataSignature);
            _log.ActionTime    = DateTime.Now;

            #endregion
            bool        result      = false;
            ContentInfo contentInfo = new ContentInfo(dataToSign);

            // Create a new, detached SignedCms message.

            SignedCms signedCms = new SignedCms(contentInfo, true);

            //解密文
            signedCms.Decode(dataSignature);
            // 驗證資料完整性
            signedCms.CheckHash();

            //取得密文中的第一張憑證
            _cert = signedCms.Certificates[0];
            X509Certificate2 cert2 = new X509Certificate2(_cert);

            _log.Issuer    = cert2.Issuer;
            _log.NotAfter  = cert2.NotAfter.ToString();
            _log.NotBefore = cert2.NotBefore.ToString();
            _log.Subject   = cert2.Subject;
            _log.UniqueID  = cert2.SerialNumber;

            IntPtr pCertCtx = IntPtr.Zero;
            pCertCtx = Win32.Win32.CertCreateCertificateContext(MY_ENCODING_TYPE, _cert.GetRawCertData(), _cert.GetRawCertData().Length);

            #region 驗簽

            try
            {
                signedCms.CheckSignature(true);
                #region 檢查憑證是否被信任

                if (isCertTrusted())
                {
                    #region 檢查憑證是否已撤銷
                    if (isCertNotRevoked(pCertCtx, getCertCRLUrl(cert2)))
                    {
                        #region 檢查憑證是否過期
                        if (cert2.NotAfter >= DateTime.Now)
                        {
                            result = true;
                        }
                        else
                        {
                            _log.Message = "憑證已過期!";
                        }

                        #endregion
                    }
                    else
                    {
                        _log.Message = "憑證已撤銷!";
                    }

                    #endregion
                }
                else
                {
                    _log.Message = "憑證是由未被信任的發證單位所發出!";
                }


                #endregion
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                _log.Message = "簽章驗證失敗:" + ex.Message;
            }

            #endregion

            if (pCertCtx != IntPtr.Zero)
            {
                Win32.Win32.CertFreeCertificateContext(pCertCtx);
            }

            if (result)
            {
                Logger.Info(_ds);
            }
            else
            {
                Logger.Warn(_ds);
            }

            return(result);
        }