public void TestCertOrdering2() { IList certList = new ArrayList(); MemoryStream bOut = new MemoryStream(); certList.Add(SignCert); certList.Add(OrigCert); IX509Store x509Certs = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(certList)); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); Stream sigOut = gen.Open(bOut, true); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray()); sp.GetSignedContent().Drain(); x509Certs = sp.GetCertificates("Collection"); ArrayList a = new ArrayList(x509Certs.GetMatches(null)); Assert.AreEqual(2, a.Count); Assert.AreEqual(SignCert, a[0]); Assert.AreEqual(OrigCert, a[1]); }
public void TestSha1WithRsa() { MemoryStream bOut = new MemoryStream(); IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert); IX509Store x509Crls = CmsTestUtil.MakeCrlStore(SignCrl, OrigCrl); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); gen.AddCrls(x509Crls); Stream sigOut = gen.Open(bOut); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CheckSigParseable(bOut.ToArray()); CmsSignedDataParser sp = new CmsSignedDataParser( new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray()); sp.GetSignedContent().Drain(); // compute expected content digest byte[] hash = DigestUtilities.CalculateDigest("SHA1", testBytes); VerifySignatures(sp, hash); // // try using existing signer // gen = new CmsSignedDataStreamGenerator(); gen.AddSigners(sp.GetSignerInfos()); gen.AddCertificates(sp.GetCertificates("Collection")); gen.AddCrls(sp.GetCrls("Collection")); bOut.SetLength(0); sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); VerifyEncodedData(bOut); // // look for the CRLs // ArrayList col = new ArrayList(x509Crls.GetMatches(null)); Assert.AreEqual(2, col.Count); Assert.IsTrue(col.Contains(SignCrl)); Assert.IsTrue(col.Contains(OrigCrl)); }
public void TestSha1WithRsaEncapsulatedSubjectKeyID() { MemoryStream bOut = new MemoryStream(); IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, CmsTestUtil.CreateSubjectKeyId(OrigCert.GetPublicKey()).GetKeyIdentifier(), CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); Stream sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray()); sp.GetSignedContent().Drain(); VerifySignatures(sp); byte[] contentDigest = (byte[])gen.GetGeneratedDigests()[CmsSignedGenerator.DigestSha1]; ArrayList signers = new ArrayList(sp.GetSignerInfos().GetSigners()); AttributeTable table = ((SignerInformation)signers[0]).SignedAttributes; Asn1.Cms.Attribute hash = table[CmsAttributes.MessageDigest]; Assert.IsTrue(Arrays.AreEqual(contentDigest, ((Asn1OctetString)hash.AttrValues[0]).GetOctets())); // // try using existing signer // gen = new CmsSignedDataStreamGenerator(); gen.AddSigners(sp.GetSignerInfos()); // gen.AddCertificatesAndCRLs(sp.GetCertificatesAndCrls("Collection", "BC")); gen.AddCertificates(sp.GetCertificates("Collection")); bOut.SetLength(0); sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CmsSignedData sd = new CmsSignedData(new CmsProcessableByteArray(testBytes), bOut.ToArray()); Assert.AreEqual(1, sd.GetSignerInfos().GetSigners().Count); VerifyEncodedData(bOut); }
IList <IDigitalSignature> GetDigitalSignatures(CmsSignedDataParser parser) { var certificates = parser.GetCertificates("Collection"); var signatures = new List <IDigitalSignature> (); var store = parser.GetSignerInfos(); foreach (SignerInformation signerInfo in store.GetSigners()) { var certificate = GetCertificate(certificates, signerInfo.SignerID); var signature = new SecureMimeDigitalSignature(signerInfo); Asn1EncodableVector vector = signerInfo.UnsignedAttributes.GetAll(CmsAttributes.SigningTime); foreach (Org.BouncyCastle.Asn1.Cms.Attribute attr in vector) { Time time = (Time)((DerSet)attr.AttrValues)[0]; signature.CreationDate = time.Date; break; } if (certificate != null) { signature.SignerCertificate = new SecureMimeDigitalCertificate(certificate); } // FIXME: verify the certificate chain with what we have in our local store // var chain = new X509Chain (); // chain.ChainPolicy.UrlRetrievalTimeout = OnlineCertificateRetrievalTimeout; // chain.ChainPolicy.RevocationMode = AllowOnlineCertificateRetrieval ? X509RevocationMode.Online : X509RevocationMode.Offline; // chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; // //if (AllowSelfSignedCertificates) // // chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; // chain.ChainPolicy.VerificationTime = DateTime.Now; // // if (!chain.Build (signerInfo.Certificate)) { // for (int i = 0; i < chain.ChainStatus.Length; i++) { // if (chain.ChainStatus[i].Status.HasFlag (X509ChainStatusFlags.Revoked)) { // signature.Errors |= DigitalSignatureError.CertificateRevoked; // signature.Status = DigitalSignatureStatus.Error; // } // // certificate.ChainStatus |= chain.ChainStatus[i].Status; // } // } signatures.Add(signature); } return(signatures); }
private void CheckSigParseable(byte[] sig) { CmsSignedDataParser sp = new CmsSignedDataParser(sig); sp.Version.ToString(); CmsTypedStream sc = sp.GetSignedContent(); if (sc != null) { sc.Drain(); } sp.GetAttributeCertificates("Collection"); sp.GetCertificates("Collection"); sp.GetCrls("Collection"); sp.GetSignerInfos(); sp.Close(); }
public static Stream ReplaceSigners(Stream original, SignerInformationStore signerInformationStore, Stream outStr) { CmsSignedDataStreamGenerator cmsSignedDataStreamGenerator = new CmsSignedDataStreamGenerator(); CmsSignedDataParser cmsSignedDataParser = new CmsSignedDataParser(original); cmsSignedDataStreamGenerator.AddSigners(signerInformationStore); CmsTypedStream signedContent = cmsSignedDataParser.GetSignedContent(); bool flag = signedContent != null; Stream stream = cmsSignedDataStreamGenerator.Open(outStr, cmsSignedDataParser.SignedContentType.Id, flag); if (flag) { Streams.PipeAll(signedContent.ContentStream, stream); } cmsSignedDataStreamGenerator.AddAttributeCertificates(cmsSignedDataParser.GetAttributeCertificates("Collection")); cmsSignedDataStreamGenerator.AddCertificates(cmsSignedDataParser.GetCertificates("Collection")); cmsSignedDataStreamGenerator.AddCrls(cmsSignedDataParser.GetCrls("Collection")); Platform.Dispose(stream); return(outStr); }
/// <summary> /// Imports certificates (as from a certs-only application/pkcs-mime part) /// from the specified stream. /// </summary> /// <param name="stream">The raw key data.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="stream"/> is <c>null</c>. /// </exception> /// <exception cref="System.NotSupportedException"> /// Importing keys is not supported by this cryptography context. /// </exception> public override void Import(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } var parser = new CmsSignedDataParser(stream); var certs = parser.GetCertificates("Collection"); var store = parser.GetSignerInfos(); foreach (SignerInformation signerInfo in store.GetSigners()) { var matches = certs.GetMatches(signerInfo.SignerID); foreach (X509Certificate certificate in matches) { certificates.Add(certificate); } } }
public certificate Validate(byte[] data, byte[] signature) { using (var dataStream = new MemoryStream(data)) using (var signatureStream = new MemoryStream(signature)) { var cmsTypedStream = new CmsTypedStream(dataStream); var cmsSignedDataParser = new CmsSignedDataParser(cmsTypedStream, signatureStream); var store = cmsSignedDataParser.GetCertificates("Collection"); var signerInfos = cmsSignedDataParser.GetSignerInfos(); var signerInfo = signerInfos.GetSigners().OfType <SignerInformation>().First(); var certificate = store?.GetMatches(signerInfo?.SignerID) .OfType <X509Certificate>().FirstOrDefault(); if (certificate == null) { return(null); } Logger.Debug( CultureInfo.CurrentCulture, "Certificate found in signature {dn}", certificate.SubjectDN.ToString()); var now = DateTime.Now; if (now < certificate.NotBefore || now > certificate.NotAfter) { Logger.Info( CultureInfo.CurrentCulture, "The certificate is not valid right now as it is only valid between {startTime}-{endTime}", certificate.NotBefore, certificate.NotAfter); } return(new certificate { subject = certificate.SubjectDN.ToString(), certificate1 = certificate.GetEncoded() }); } }
/// <summary> /// Imports certificates (as from a certs-only application/pkcs-mime part) /// from the specified stream. /// </summary> /// <remarks> /// Imports certificates (as from a certs-only application/pkcs-mime part) /// from the specified stream. /// </remarks> /// <param name="stream">The raw key data.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="stream"/> is <c>null</c>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public override void Import(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var parser = new CmsSignedDataParser(stream); var certificates = parser.GetCertificates("Collection"); foreach (X509Certificate certificate in certificates.GetMatches(null)) { Import(certificate); } var crls = parser.GetCrls("Collection"); foreach (X509Crl crl in crls.GetMatches(null)) { Import(crl); } }
/// <summary> /// The method used to verify signature. /// </summary> /// <param name="sp"></param> /// <returns></returns> public static bool VerifySignatures(CmsSignedDataParser sp) { List <bool> result = new List <bool>(); IX509Store x509Certs = sp.GetCertificates("Collection"); SignerInformationStore signerInfos = sp.GetSignerInfos(); var signers = signerInfos.GetSigners(); foreach (SignerInformation signer in signers) { ICollection certCollection = x509Certs.GetMatches(signer.SignerID); foreach (Org.BouncyCastle.X509.X509Certificate cert in certCollection) { var isValid = signer.Verify(cert); if (!isValid) { throw new Exception("Certificate verification error, the signer could not be verified."); } result.Add(isValid); } } return(result.TrueForAll(m => m == true)); }
private void VerifySignatures(CmsSignedDataParser sp) { CmsTypedStream sc = sp.GetSignedContent(); if (sc != null) { sc.Drain(); } IX509Store x509Certs = sp.GetCertificates("Collection"); SignerInformationStore signers = sp.GetSignerInfos(); foreach (SignerInformation signer in signers.GetSigners()) { ICollection certCollection = x509Certs.GetMatches(signer.SignerID); IEnumerator certEnum = certCollection.GetEnumerator(); certEnum.MoveNext(); X509Certificate cert = (X509Certificate)certEnum.Current; VerifySigner(signer, cert); } }
private void VerifySignatures( CmsSignedDataParser sp, byte[] contentDigest) { IX509Store certStore = sp.GetCertificates("Collection"); SignerInformationStore signers = sp.GetSignerInfos(); foreach (SignerInformation signer in signers.GetSigners()) { ICollection certCollection = certStore.GetMatches(signer.SignerID); IEnumerator certEnum = certCollection.GetEnumerator(); certEnum.MoveNext(); X509Certificate cert = (X509Certificate)certEnum.Current; Assert.IsTrue(signer.Verify(cert)); if (contentDigest != null) { Assert.IsTrue(Arrays.AreEqual(contentDigest, signer.GetContentDigest())); } } }
public void TestSha1WithRsa() { IList certList = new ArrayList(); IList crlList = new ArrayList(); MemoryStream bOut = new MemoryStream(); certList.Add(OrigCert); certList.Add(SignCert); crlList.Add(SignCrl); crlList.Add(OrigCrl); IX509Store x509Certs = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(certList)); IX509Store x509Crls = X509StoreFactory.Create( "CRL/Collection", new X509CollectionStoreParameters(crlList)); CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1); gen.AddCertificates(x509Certs); gen.AddCrls(x509Crls); Stream sigOut = gen.Open(bOut); byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); CheckSigParseable(bOut.ToArray()); CmsSignedDataParser sp = new CmsSignedDataParser( new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray()); sp.GetSignedContent().Drain(); // // compute expected content digest // IDigest md = DigestUtilities.GetDigest("SHA1"); md.BlockUpdate(testBytes, 0, testBytes.Length); byte[] hash = DigestUtilities.DoFinal(md); VerifySignatures(sp, hash); // // try using existing signer // gen = new CmsSignedDataStreamGenerator(); gen.AddSigners(sp.GetSignerInfos()); gen.AddCertificates(sp.GetCertificates("Collection")); gen.AddCrls(sp.GetCrls("Collection")); bOut.SetLength(0); sigOut = gen.Open(bOut, true); sigOut.Write(testBytes, 0, testBytes.Length); sigOut.Close(); VerifyEncodedData(bOut); // // look for the CRLs // ArrayList col = new ArrayList(x509Crls.GetMatches(null)); Assert.AreEqual(2, col.Count); Assert.IsTrue(col.Contains(SignCrl)); Assert.IsTrue(col.Contains(OrigCrl)); }
protected void Complete(Level?level, Stream embedded, Stream signed, Stream content, X509Certificate2 providedSigner, out TimemarkKey timemarkKey) { #if NETFRAMEWORK trace.TraceEvent(TraceEventType.Information, 0, "Completing the message with of {0} bytes to level {1}", signed.Length, level); #else logger.LogInformation("Completing the message with of {0} bytes to level {1}", signed.Length, level); #endif //Create the objects we need var gen = new CmsSignedDataStreamGenerator(); var parser = new CmsSignedDataParser(signed); timemarkKey = new TimemarkKey(); //preset the digests so we can add the signers afterwards gen.AddDigests(parser.DigestOids); //Copy the content to the output Stream contentOut = gen.Open(embedded, parser.SignedContentType.Id, true); if (content != null) { content.CopyTo(contentOut); } else { parser.GetSignedContent().ContentStream.CopyTo(contentOut); } //Extract the various data from outer layer SignerInformation signerInfo = ExtractSignerInfo(parser); IX509Store embeddedCerts = parser.GetCertificates("Collection"); //Extract the various data from signer info timemarkKey.SignatureValue = signerInfo.GetSignature(); timemarkKey.SigningTime = ExtractSigningTime(signerInfo); timemarkKey.Signer = ExtractSignerCert(embeddedCerts, signerInfo, providedSigner); if (timemarkKey.Signer != null) { timemarkKey.SignerId = DotNetUtilities.FromX509Certificate(timemarkKey.Signer).GetSubjectKeyIdentifier(); } else { timemarkKey.SignerId = signerInfo.SignerID.ExtractSignerId(); } //Extract the various data from unsiged attributes of signer info IDictionary unsignedAttributes = signerInfo.UnsignedAttributes != null?signerInfo.UnsignedAttributes.ToDictionary() : new Hashtable(); TimeStampToken tst = ExtractTimestamp(unsignedAttributes); RevocationValues revocationInfo = ExtractRevocationInfo(unsignedAttributes); //quick check for an expected error and extrapolate some info if (timemarkKey.SignerId == null) { #if NETFRAMEWORK trace.TraceEvent(TraceEventType.Error, 0, "We could not find any signer information"); #else logger.LogError("We could not find any signer information"); #endif throw new InvalidMessageException("The message does not contain any valid signer info"); } if (timemarkKey.SigningTime == default && tst != null) { #if NETFRAMEWORK trace.TraceEvent(TraceEventType.Information, 0, "Implicit signing time is replaced with time-stamp time {1}", tst.TimeStampInfo.GenTime); #else logger.LogInformation("Implicit signing time is replaced with time-stamp time {1}", tst.TimeStampInfo.GenTime); #endif timemarkKey.SigningTime = tst.TimeStampInfo.GenTime; } //Are we missing embedded certs and should we add them? if ((embeddedCerts == null || embeddedCerts.GetMatches(null).Count <= 1) && timemarkKey.Signer != null && level != null) { embeddedCerts = GetEmbeddedCerts(timemarkKey); } if (embeddedCerts != null) { gen.AddCertificates(embeddedCerts); //add the existing or new embedded certs to the output. } //Are we missing timestamp and should we add them (not that time-mark authorities do not require a timestamp provider) if (tst == null && (level & Level.T_Level) == Level.T_Level && timestampProvider != null) { tst = GetTimestamp(timemarkKey); AddTimestamp(unsignedAttributes, tst); } //should be make sure we have the proper revocation info (it is hard to tell if we have everything, just go for it) if ((level & Level.L_Level) == Level.L_Level) { if (embeddedCerts != null && embeddedCerts.GetMatches(null).Count > 0) { //extend the revocation info with info about the embedded certs revocationInfo = GetRevocationValues(timemarkKey, embeddedCerts, revocationInfo); } if (tst != null) { //extend the revocation info with info about the TST revocationInfo = GetRevocationValues(tst, revocationInfo); } //update the unsigned attributes AddRevocationValues(unsignedAttributes, revocationInfo); } //Update the unsigned attributes of the signer info signerInfo = SignerInformation.ReplaceUnsignedAttributes(signerInfo, new BC::Asn1.Cms.AttributeTable(unsignedAttributes)); //Copy the signer gen.AddSigners(new SignerInformationStore(new SignerInformation[] { signerInfo })); contentOut.Close(); }