Exemplo n.º 1
0
        public void Constructor_DateTime_After1950()
        {
            DateTime dt = new DateTime(1950, 01, 01, 00, 00, 00);
            // UTCTIME (0x17), i.e. 2 digits years, limited to 1950-2050
            Pkcs9SigningTime st = new Pkcs9SigningTime(dt);

            Assert.AreEqual(signingTimeName, st.Oid.FriendlyName, "Oid.FriendlyName");
            Assert.AreEqual(signingTimeOid, st.Oid.Value, "Oid.Value");
            Assert.AreEqual(15, st.RawData.Length, "RawData.Length");
            Assert.AreEqual("17-0D-35-30-30-31-30-31-30-30-30-30-30-30-5A", BitConverter.ToString(st.RawData));
            Assert.AreEqual(dt, st.SigningTime, "st.SigningTime");
            Assert.AreEqual("17 0d 35 30 30 31 30 31 30 30 30 30 30 30 5a", st.Format(true), "Format(true)");
            Assert.AreEqual("17 0d 35 30 30 31 30 31 30 30 30 30 30 30 5a", st.Format(false), "Format(false)");
        }
Exemplo n.º 2
0
        public static void SigningTimeFromCookedData_Unspecified()
        {
            DateTime         dateTime = new DateTime(2015, 4, 1);
            Pkcs9SigningTime p        = new Pkcs9SigningTime(dateTime);
            string           oid      = p.Oid.Value;

            Assert.Equal(s_OidSigningTime, oid);

            Pkcs9SigningTime p2         = new Pkcs9SigningTime(p.RawData);
            DateTime         cookedData = p2.SigningTime;

            Assert.Equal(dateTime, cookedData);
            Assert.Equal(DateTimeKind.Utc, cookedData.Kind);
        }
Exemplo n.º 3
0
        public void Constructor_DateTime_Before2050()
        {
            DateTime dt = new DateTime(2049, 12, 31, 11, 59, 59);
            // up to 2050 encoding should stay with UTCTIME (0x17), i.e. 2 digits years
            Pkcs9SigningTime st = new Pkcs9SigningTime(dt);

            Assert.AreEqual(signingTimeName, st.Oid.FriendlyName, "Oid.FriendlyName");
            Assert.AreEqual(signingTimeOid, st.Oid.Value, "Oid.Value");
            Assert.AreEqual(15, st.RawData.Length, "RawData.Length");
            Assert.AreEqual("17-0D-34-39-31-32-33-31-31-31-35-39-35-39-5A", BitConverter.ToString(st.RawData));
            Assert.AreEqual(dt, st.SigningTime, "st.SigningTime");
            Assert.AreEqual("17 0d 34 39 31 32 33 31 31 31 35 39 35 39 5a", st.Format(true), "Format(true)");
            Assert.AreEqual("17 0d 34 39 31 32 33 31 31 31 35 39 35 39 5a", st.Format(false), "Format(false)");
        }
Exemplo n.º 4
0
        CmsSigner CreateSigner(X509Certificate2 cert)
        {
            CmsSigner signer = new CmsSigner(cert)
            {
                IncludeOption   = m_certChainInclude,
                DigestAlgorithm = ToDigestAlgorithmOid(m_digestAlgorithm)
            };

            Pkcs9SigningTime signingTime = new Pkcs9SigningTime();

            signer.SignedAttributes.Add(signingTime);

            return(signer);
        }
Exemplo n.º 5
0
        public void Constructor_Bytes()
        {
            byte[] date = new byte [15] {
                0x17, 0x0D, 0x30, 0x34, 0x30, 0x36, 0x33, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5A
            };
            Pkcs9SigningTime st = new Pkcs9SigningTime(date);

            Assert.AreEqual(signingTimeName, st.Oid.FriendlyName, "Oid.FriendlyName");
            Assert.AreEqual(signingTimeOid, st.Oid.Value, "Oid.Value");
            Assert.AreEqual(15, st.RawData.Length, "RawData.Length");
            Assert.AreEqual("17-0D-30-34-30-36-33-30-30-34-30-30-30-30-5A", BitConverter.ToString(st.RawData), "RawData");
            Assert.AreEqual(mono10release, st.SigningTime, "st.SigningTime");
            Assert.AreEqual("17 0d 30 34 30 36 33 30 30 34 30 30 30 30 5a", st.Format(true), "Format(true)");
            Assert.AreEqual("17 0d 30 34 30 36 33 30 30 34 30 30 30 30 5a", st.Format(false), "Format(false)");
        }
Exemplo n.º 6
0
        public static void SigningTimeFromRawData()
        {
            DateTime dateTime = new DateTime(2015, 4, 1);

            byte[]           rawData = "170d3135303430313030303030305a".HexToByteArray();
            Pkcs9SigningTime p       = new Pkcs9SigningTime(rawData);

            Assert.Equal(rawData, p.RawData);
            DateTime cookedData = p.SigningTime;

            Assert.Equal(dateTime, cookedData);
            string oid = p.Oid.Value;

            Assert.Equal(s_OidSigningTime, oid);
        }
Exemplo n.º 7
0
 //[ExpectedException (typeof (ArgumentOutOfRangeException))]
 public void Constructor_DateTime_MinValue()
 {
     try {
         Pkcs9SigningTime st = new Pkcs9SigningTime(DateTime.MinValue);
     }
     catch (Exception ex) {
         if (ex is ArgumentOutOfRangeException || ex is CryptographicException)
         {
             Assert.Pass();
         }
         else
         {
             throw;
         }
     }
 }
Exemplo n.º 8
0
 //[ExpectedException (typeof (ArgumentOutOfRangeException))]
 public void Constructor_DateTime_1600()
 {
     try {
         DateTime         dt = new DateTime(1600, 12, 31, 11, 59, 59);
         Pkcs9SigningTime st = new Pkcs9SigningTime(dt);
     }
     catch (Exception ex) {
         if (ex is ArgumentOutOfRangeException || ex is CryptographicException)
         {
             Assert.Pass();
         }
         else
         {
             throw;
         }
     }
 }
Exemplo n.º 9
0
        /// <summary>
        /// Generates a SignedCMS object for some content.
        /// </summary>
        /// <param name="content"></param>
        /// <param name="cert">Certificate for cms signer</param>
        /// <returns>SignedCms object</returns>
        public static SignedCms GenerateSignedCms(X509Certificate2 cert, byte[] content)
        {
            var contentInfo = new ContentInfo(content);
            var cmsSigner   = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, cert);
            var signingTime = new Pkcs9SigningTime();

            cmsSigner.SignedAttributes.Add(
                new CryptographicAttributeObject(
                    signingTime.Oid,
                    new AsnEncodedDataCollection(signingTime)));

            var cms = new SignedCms(contentInfo);

            cms.ComputeSignature(cmsSigner);

            return(cms);
        }
Exemplo n.º 10
0
        public byte[] GetSignature(byte[] content)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            var certificate = _certificateProvider.GetCertificate();

            if (!certificate.HasPrivateKey)
            {
                throw new InvalidOperationException($"Certificate does not have a private key - Subject:{certificate.Subject} Thumbprint:{certificate.Thumbprint}.");
            }

            var certificateChain = _certificateChainProvider.GetCertificates();

            var contentInfo = new ContentInfo(content);
            var signedCms   = new SignedCms(contentInfo, true);

            signedCms.Certificates.AddRange(certificateChain);

            var signer      = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
            var signingTime = new Pkcs9SigningTime(_dateTimeProvider.Now());

            signer.SignedAttributes.Add(new CryptographicAttributeObject(signingTime.Oid, new AsnEncodedDataCollection(signingTime)));

            try
            {
                signedCms.ComputeSignature(signer);
            }
            catch (Exception e)
            {
                //NB. Cannot catch the internal exception type (cross-platform design of .NET Core)
                if (e.GetType().Name == "WindowsCryptographicException" && e.Message == "Keyset does not exist" && !WindowsIdentityQueries.CurrentUserIsAdministrator())
                {
                    throw new InvalidOperationException("Failed to sign with certificate when current user does not have UAC elevated permissions.", e);
                }

                throw;
            }

            return(signedCms.Encode());
        }
Exemplo n.º 11
0
        public static void InputDateTimeAsX509TimeBetween1950And2049_Utc()
        {
            var exception = Record.Exception(() => {
                DateTime dt         = new DateTime(1950, 1, 1, 00, 00, 00, DateTimeKind.Utc);
                Pkcs9SigningTime st = new Pkcs9SigningTime(dt);
                dt = new DateTime(2049, 12, 31, 23, 59, 59, DateTimeKind.Utc);
                st = new Pkcs9SigningTime(dt);

                dt = new DateTime(1950, 1, 2);
                st = new Pkcs9SigningTime(dt);
                dt = new DateTime(2049, 12, 30);
                st = new Pkcs9SigningTime(dt);

                dt = new DateTime(1950, 1, 2, 00, 00, 00, DateTimeKind.Local);
                st = new Pkcs9SigningTime(dt);
                dt = new DateTime(2049, 12, 30, 23, 59, 59, DateTimeKind.Local);
                st = new Pkcs9SigningTime(dt);
            });

            Assert.Null(exception);
        }
Exemplo n.º 12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="signingCertificate"></param>
        /// <param name="encryptionCertificate"></param>
        /// <returns></returns>
        internal static byte[] GetSignature(Byte[] message, X509Certificate2 signingCertificate, X509Certificate2 encryptionCertificate)
        {
            SignedCms signedCms = new SignedCms(new ContentInfo(message), true);

            CmsSigner cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signingCertificate);

            cmsSigner.IncludeOption = X509IncludeOption.WholeChain;

            if (encryptionCertificate != null)
            {
                cmsSigner.Certificates.Add(encryptionCertificate);
            }

            Pkcs9SigningTime signingTime = new Pkcs9SigningTime();

            cmsSigner.SignedAttributes.Add(signingTime);

            signedCms.ComputeSignature(cmsSigner, false);

            return(signedCms.Encode());
        }
Exemplo n.º 13
0
        /// <summary>
        /// 연대 서명과 관련된 정보를 반환합니다.
        /// </summary>
        /// <param name="filePath">연대 서명이 포함된 파일의 경로입니다.</param>
        /// <param name="counterCertificate">연대 서명의 인증서입니다.</param>
        /// <param name="signingTime">UTC+0 기준에서의 서명 시간입니다.</param>
        public static bool GetCounterSignerInfo(string filePath, ref X509Certificate2 counterCertificate, ref Pkcs9SigningTime signingTime)
        {
            try
            {
                int    encodingType;
                int    contentType;
                int    formatType;
                IntPtr certStore = IntPtr.Zero;
                IntPtr cryptMsg  = IntPtr.Zero;
                IntPtr context   = IntPtr.Zero;

                if (!CryptQueryObject(
                        CERT_QUERY_OBJECT_FILE,
                        Marshal.StringToHGlobalUni(filePath),
                        CERT_QUERY_CONTENT_FLAG_ALL,
                        CERT_QUERY_FORMAT_FLAG_ALL,
                        0,
                        out encodingType,
                        out contentType,
                        out formatType,
                        ref certStore,
                        ref cryptMsg,
                        ref context))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                /* contentType = 10; CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
                 * encodingType = 65537; PKCS_7_ASN_ENCODING | X509_ASN_ENCODING (65536 + 1)
                 */

                //Console.WriteLine("Querying file '{0}':", filePath);
                //Console.WriteLine("  Encoding Type: {0}", encodingType);
                //Console.WriteLine("  Content Type: {0}", contentType);
                //Console.WriteLine("  Format Type: {0}", formatType);
                //Console.WriteLine("  Cert Store: {0}", certStore.ToInt32());
                //Console.WriteLine("  Crypt Msg: {0}", cryptMsg.ToInt32());
                //Console.WriteLine("  Context: {0}", context.ToInt32());


                // Get size of the encoded message.
                int cbData = 0;
                if (!CryptMsgGetParam(
                        cryptMsg,
                        CMSG_ENCODED_MESSAGE,//Crypt32.CMSG_SIGNER_INFO_PARAM,
                        0,
                        IntPtr.Zero,
                        ref cbData))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var vData = new byte[cbData];

                // Get the encoded message.
                if (!CryptMsgGetParam(
                        cryptMsg,
                        CMSG_ENCODED_MESSAGE,//Crypt32.CMSG_SIGNER_INFO_PARAM,
                        0,
                        vData,
                        ref cbData))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var signedCms = new SignedCms();
                signedCms.Decode(vData);

                foreach (var signerInfo in signedCms.SignerInfos)
                {
                    foreach (var unsignedAttribute in signerInfo.UnsignedAttributes)
                    {
                        if (unsignedAttribute.Oid.Value != szOID_RSA_counterSign)
                        {
                            continue;
                        }

                        // 하나 이상의 연대 서명이 존재하는 파일이 만약 있다면 Collection을 반환하도록 다시 짜야함
                        foreach (var counterSignInfo in signerInfo.CounterSignerInfos)
                        {
                            // 연대 서명 정보 얻는 부분
                            counterCertificate = counterSignInfo.Certificate;   // 연대 서명의 인증서

                            foreach (var signedAttribute in counterSignInfo.SignedAttributes)
                            {
                                if (signedAttribute.Oid.Value == szOID_RSA_signingTime)
                                {
                                    // 연대 서명의 서명시간
                                    signingTime = (Pkcs9SigningTime)signedAttribute.Values[0];
                                    //Console.Out.WriteLine("Signing Time UTC: " + signingTime.SigningTime);
                                }
                            }
                        }
                    }
                }
            }
            catch (Win32Exception ex)
            {
                // 해당 파일에 연대 서명 정보가 없는 경우
                if (ex.HResult == -2147467259) // ex.HResult == 0x80004005
                {
                    return(false);
                }
                throw;  // 겪어본 적 없는 예외
            }

            return(true);
        }
        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 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));
        }
Exemplo n.º 17
0
 public void Constructor_DateTime_1601()
 {
     DateTime         dt = new DateTime(1601, 01, 01, 00, 00, 00);
     Pkcs9SigningTime st = new Pkcs9SigningTime(dt);
 }
Exemplo n.º 18
0
 public void Constructor_DateTime_1600()
 {
     DateTime         dt = new DateTime(1600, 12, 31, 11, 59, 59);
     Pkcs9SigningTime st = new Pkcs9SigningTime(dt);
 }
Exemplo n.º 19
0
 public void Constructor_DateTime_MinValue()
 {
     Pkcs9SigningTime st = new Pkcs9SigningTime(DateTime.MinValue);
 }
Exemplo n.º 20
0
 public void Constructor_Bytes_Null()
 {
     Pkcs9SigningTime st = new Pkcs9SigningTime(null);
 }
Exemplo n.º 21
0
        /// <summary>
        /// Create a byte array containing a signed S/MIME message.
        /// </summary>
        /// <param name="buffer">A byte array to streamline bit shuffling.</param>
        /// <param name="contentBytes">The contents of the envelope to be encrypted.</param>
        /// <param name="message">An OpaqueMail.MailMessage that contains the message to send.</param>
        /// <param name="alreadyEncrypted">Whether a portion of the message has previously been signed, as when triple wrapping.</param>
        /// <param name="boundaryName">Text delimiting S/MIME message parts related to signatures.</param>
        public byte[] SmimeSign(byte[] buffer, byte[] contentBytes, MailMessage message, bool alreadyEncrypted, out string boundaryName)
        {
            if (message.SmimeSigningCertificate == null)
            {
                // If the implementation requires S/MIME signing (the default), throw an error if there's no certificate.
                if ((message.SmimeSettingsMode & SmimeSettingsMode.RequireExactSettings) > 0)
                {
                    throw new SmtpException("Trying to send a signed message, but no signing certificate has been assigned.");
                }
                else
                {
                    boundaryName = null;
                    return(contentBytes);
                }
            }

            // First, create a buffer for tracking the unsigned portion of this message.
            StringBuilder unsignedMessageBuilder = new StringBuilder(Constants.SMALLSBSIZE);

            // If triple wrapping, the previous layer was an encrypted envelope and needs to be Base64 encoded.
            if (alreadyEncrypted)
            {
                unsignedMessageBuilder.Append("Content-Type: application/pkcs7-mime; smime-type=enveloped-data;\r\n\tname=\"smime.p7m\"\r\n");
                unsignedMessageBuilder.Append("Content-Transfer-Encoding: base64\r\n");
                unsignedMessageBuilder.Append("Content-Description: \"S/MIME Cryptographic envelopedCms\"\r\n");
                unsignedMessageBuilder.Append("Content-Disposition: attachment; filename=\"smime.p7m\"\r\n\r\n");

                unsignedMessageBuilder.Append(Functions.ToBase64String(contentBytes));
            }
            else
            {
                unsignedMessageBuilder.Append(Encoding.UTF8.GetString(contentBytes));
            }

            // Prepare the signing parameters.
            ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(unsignedMessageBuilder.ToString()));
            SignedCms   signedCms   = new SignedCms(contentInfo, true);

            CmsSigner signer = new CmsSigner(message.SubjectIdentifierType, message.SmimeSigningCertificate);

            signer.IncludeOption = X509IncludeOption.WholeChain;

            // Sign the current time.
            if ((message.SmimeSigningOptionFlags & SmimeSigningOptionFlags.SignTime) > 0)
            {
                Pkcs9SigningTime signingTime = new Pkcs9SigningTime();
                signer.SignedAttributes.Add(signingTime);
            }

            // Encode the signed message.
            signedCms.ComputeSignature(signer);
            byte[] signedBytes = signedCms.Encode();

            // Embed the signed and original version of the message using MIME.
            StringBuilder messageBuilder = new StringBuilder(Constants.SMALLSBSIZE);

            // Build the MIME message by embedding the unsigned and signed portions.
            boundaryName = alreadyEncrypted ? SmimeTripleSignedCmsBoundaryName : SmimeSignedCmsBoundaryName;
            messageBuilder.Append("This is a multi-part S/MIME signed message.\r\n\r\n");
            messageBuilder.Append("--" + boundaryName + "\r\n");
            messageBuilder.Append(unsignedMessageBuilder.ToString());
            messageBuilder.Append("\r\n--" + boundaryName + "\r\n");
            messageBuilder.Append("Content-Type: application/x-pkcs7-signature; smime-type=signed-data; name=\"smime.p7s\"\r\n");
            messageBuilder.Append("Content-Transfer-Encoding: base64\r\n");
            messageBuilder.Append("Content-Description: \"S/MIME Cryptographic signedCms\"\r\n");
            messageBuilder.Append("Content-Disposition: attachment; filename=\"smime.p7s\"\r\n\r\n");
            messageBuilder.Append(Functions.ToBase64String(signedBytes, 0, signedBytes.Length));
            messageBuilder.Append("\r\n--" + boundaryName + "--\r\n");

            return(Encoding.UTF8.GetBytes(messageBuilder.ToString()));
        }
Exemplo n.º 22
0
 public void Constructor_DateTime_Before1950()
 {
     DateTime dt = new DateTime(1949, 12, 31, 11, 59, 59);
     // UTCTIME (0x17), i.e. 2 digits years, limited to 1950-2050
     Pkcs9SigningTime st = new Pkcs9SigningTime(dt);
 }
Exemplo n.º 23
0
        /// <summary>
        /// Проверка файла с подписью на валидность подписи
        /// </summary>
        /// <returns>Сообщения (или ошибки) о проверки подписи</returns>
        public ValidationResult Verify()
        {
            var result = new ValidationResult();

            if (this.Signature == null)
            {
                result.AddError("Отсутствует файл с подписью!");
                return(result);
            }

            //Создаем пакет с подписью для проверки самой подписи
            SignedCms cms = null;

            if (this.Detached)
            {//отсоединенная подпись
                //создаем контейнер с оригинальными данными, подпись которых будет проверяться
                ContentInfo content = new ContentInfo(this.Original);

                //формируем пакет с оригинальными данными и параметрами подписи
                cms = new SignedCms(content, true);
            }
            else
            {// присоединенная подпись
                //формируем пустой пакет с данными
                //так как в случае присоединенной подписи
                //данные содержатся в самом подписанном файле
                cms = new SignedCms();
            }


            try
            {
                //декодируем файл, содержащий подпись
                //если вылетает ошибка - значит подпись не верна!!!
                cms.Decode(this.Signature);

                //возможно, информация о подписаниях отсутствует
                if (cms.SignerInfos.Count <= 0)
                {
                    result.AddError("Нет информации о подписях (возможно файл не подписан)");
                    return(result);
                }

                result.AddInfo("Электронная Подпись Вернa.");
                result.AddNewLine();
                result.Add("Файл подписан следующим(и) сертификатом(и):");

                foreach (SignerInfo si in cms.SignerInfos)
                {
                    var certificate = new Certificate(si.Certificate);
                    if (_certificate == null)
                    {
                        _certificate = certificate;
                    }

                    result.AddNewLine();
                    result.Add(certificate.SerialNumber + " [" + certificate.Thumbprint + "]");
                    result.Add(certificate.SubjectCommonName);

                    //дергаем время подписания документа текущей подписью
                    for (int i = 0; i < si.SignedAttributes.Count; i++)
                    {
                        if (si.SignedAttributes[i].Oid.Value == "1.2.840.113549.1.9.5") // Oid время подписания
                        {
                            Pkcs9SigningTime pkcs9_time = new Pkcs9SigningTime(si.SignedAttributes[i].Values[0].RawData);
                            result.Add("Дата и Время подписания:  " + pkcs9_time.SigningTime.ToString());
                            break;
                        }
                    }
                }
            }
            catch
            {
                result.AddError("Подпись НЕ верна!");
            }

            return(result);
        }
Exemplo n.º 24
0
 public void Constructor_DateTime_After2050()
 {
     DateTime dt = new DateTime(2050, 01, 01, 00, 00, 00);
     // in 2050 encoding should switch to GENERALIZEDTIME (0x18), i.e. 4 digits years
     Pkcs9SigningTime st = new Pkcs9SigningTime(dt);
 }