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)"); }
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); }
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)"); }
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); }
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)"); }
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); }
//[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; } } }
//[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; } } }
/// <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); }
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()); }
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); }
/// <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()); }
/// <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)); }
public void Constructor_DateTime_1601() { DateTime dt = new DateTime(1601, 01, 01, 00, 00, 00); Pkcs9SigningTime st = new Pkcs9SigningTime(dt); }
public void Constructor_DateTime_1600() { DateTime dt = new DateTime(1600, 12, 31, 11, 59, 59); Pkcs9SigningTime st = new Pkcs9SigningTime(dt); }
public void Constructor_DateTime_MinValue() { Pkcs9SigningTime st = new Pkcs9SigningTime(DateTime.MinValue); }
public void Constructor_Bytes_Null() { Pkcs9SigningTime st = new Pkcs9SigningTime(null); }
/// <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())); }
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); }
/// <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); }
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); }