Inheritance: Org.BouncyCastle.Cms.CmsSignedGenerator
			internal SignerInfoGeneratorImpl(
				CmsSignedDataStreamGenerator	outer,
				AsymmetricKeyParameter			key,
				SignerIdentifier				signerIdentifier,
				string							digestOID,
				string							encOID,
				CmsAttributeTableGenerator		sAttr,
				CmsAttributeTableGenerator		unsAttr)
			{
				this.outer = outer;

				_signerIdentifier = signerIdentifier;
				_digestOID = digestOID;
				_encOID = encOID;
				_sAttr = sAttr;
				_unsAttr = unsAttr;
				_encName = Helper.GetEncryptionAlgName(_encOID);

				string digestName = Helper.GetDigestAlgName(_digestOID);
				string signatureName = digestName + "with" + _encName;

				if (_sAttr != null)
				{
            		_sig = Helper.GetSignatureInstance(signatureName);
				}
				else
				{
					// Note: Need to use raw signatures here since we have already calculated the digest
					if (_encName.Equals("RSA"))
					{
						_sig = Helper.GetSignatureInstance("RSA");
					}
					else if (_encName.Equals("DSA"))
					{
						_sig = Helper.GetSignatureInstance("NONEwithDSA");
					}
					// TODO Add support for raw PSS
//					else if (_encName.equals("RSAandMGF1"))
//					{
//						_sig = CMSSignedHelper.INSTANCE.getSignatureInstance("NONEWITHRSAPSS", _sigProvider);
//						try
//						{
//							// Init the params this way to avoid having a 'raw' version of each PSS algorithm
//							Signature sig2 = CMSSignedHelper.INSTANCE.getSignatureInstance(signatureName, _sigProvider);
//							PSSParameterSpec spec = (PSSParameterSpec)sig2.getParameters().getParameterSpec(PSSParameterSpec.class);
//							_sig.setParameter(spec);
//						}
//						catch (Exception e)
//						{
//							throw new SignatureException("algorithm: " + _encName + " could not be configured.");
//						}
//					}
					else
					{
						throw new SignatureException("algorithm: " + _encName + " not supported in base signatures.");
					}
				}

				_sig.Init(true, new ParametersWithRandom(key, outer.rand));
			}
        /**
         * Replace the certificate and CRL information associated with this
         * CMSSignedData object with the new one passed in.
         * <p>
         * The output stream is returned unclosed.
         * </p>
         * @param original the signed data stream to be used as a base.
         * @param certsAndCrls the new certificates and CRLs to be used.
         * @param out the stream to Write the new signed data object to.
         * @return out.
         * @exception CmsException if there is an error processing the CertStore
         */
        public static Stream ReplaceCertificatesAndCrls(
            Stream original,
            IX509Store x509Certs,
            IX509Store x509Crls,
            IX509Store x509AttrCerts,
            Stream outStr)
        {
            // NB: SecureRandom would be ignored since using existing signatures only
            CmsSignedDataStreamGenerator gen    = new CmsSignedDataStreamGenerator();
            CmsSignedDataParser          parser = new CmsSignedDataParser(original);

            gen.AddDigests(parser.DigestOids);

            CmsTypedStream signedContent = parser.GetSignedContent();
            bool           encapsulate   = (signedContent != null);
            Stream         contentOut    = gen.Open(outStr, parser.SignedContentType.Id, encapsulate);

            if (encapsulate)
            {
                Streams.PipeAll(signedContent.ContentStream, contentOut);
            }

//			gen.AddAttributeCertificates(parser.GetAttributeCertificates("Collection"));
//			gen.AddCertificates(parser.GetCertificates("Collection"));
//			gen.AddCrls(parser.GetCrls("Collection"));
            if (x509AttrCerts != null)
            {
                gen.AddAttributeCertificates(x509AttrCerts);
            }
            if (x509Certs != null)
            {
                gen.AddCertificates(x509Certs);
            }
            if (x509Crls != null)
            {
                gen.AddCrls(x509Crls);
            }

            gen.AddSigners(parser.GetSignerInfos());

            contentOut.Close();

            return(outStr);
        }
        public Stream Open(Stream outStream, string signedContentType, bool encapsulate, Stream dataOutputStream)
        {
            if (outStream == null)
            {
                throw new ArgumentNullException("outStream");
            }
            if (!outStream.CanWrite)
            {
                throw new ArgumentException("Expected writeable stream", "outStream");
            }
            if (dataOutputStream != null && !dataOutputStream.CanWrite)
            {
                throw new ArgumentException("Expected writeable stream", "dataOutputStream");
            }
            this._messageDigestsLocked = true;
            BerSequenceGenerator berSequenceGenerator = new BerSequenceGenerator(outStream);

            berSequenceGenerator.AddObject(CmsObjectIdentifiers.SignedData);
            BerSequenceGenerator berSequenceGenerator2 = new BerSequenceGenerator(berSequenceGenerator.GetRawOutputStream(), 0, true);
            DerObjectIdentifier  derObjectIdentifier   = (signedContentType == null) ? null : new DerObjectIdentifier(signedContentType);

            berSequenceGenerator2.AddObject(this.CalculateVersion(derObjectIdentifier));
            Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new Asn1Encodable[0]);

            foreach (string identifier in this._messageDigestOids)
            {
                asn1EncodableVector.Add(new Asn1Encodable[]
                {
                    new AlgorithmIdentifier(new DerObjectIdentifier(identifier), DerNull.Instance)
                });
            }
            byte[] encoded = new DerSet(asn1EncodableVector).GetEncoded();
            berSequenceGenerator2.GetRawOutputStream().Write(encoded, 0, encoded.Length);
            BerSequenceGenerator berSequenceGenerator3 = new BerSequenceGenerator(berSequenceGenerator2.GetRawOutputStream());

            berSequenceGenerator3.AddObject(derObjectIdentifier);
            Stream s = encapsulate ? CmsUtilities.CreateBerOctetOutputStream(berSequenceGenerator3.GetRawOutputStream(), 0, true, this._bufferSize) : null;
            Stream safeTeeOutputStream = CmsSignedDataStreamGenerator.GetSafeTeeOutputStream(dataOutputStream, s);
            Stream outStream2          = CmsSignedDataStreamGenerator.AttachDigestsToOutputStream(this._messageDigests.Values, safeTeeOutputStream);

            return(new CmsSignedDataStreamGenerator.CmsSignedDataOutputStream(this, outStream2, signedContentType, berSequenceGenerator, berSequenceGenerator2, berSequenceGenerator3));
        }
            internal SignerInf(
                CmsSignedDataStreamGenerator outer,
                AsymmetricKeyParameter key,
                byte[]                                                  subjectKeyID,
                string digestOID,
                string encOID,
                CmsAttributeTableGenerator sAttr,
                CmsAttributeTableGenerator unsAttr,
                ISigner signature)
            {
                this.outer = outer;

                _key          = key;
                _subjectKeyID = subjectKeyID;
                _digestOID    = digestOID;
                _encOID       = encOID;
                _sAttr        = sAttr;
                _unsAttr      = unsAttr;
                _signature    = signature;
            }
            internal SignerInf(
				CmsSignedDataStreamGenerator	outer,
				AsymmetricKeyParameter			key,
				X509Certificate					cert,
				string							digestOID,
				string							encOID,
				CmsAttributeTableGenerator		sAttr,
				CmsAttributeTableGenerator		unsAttr,
				ISigner							signature)
			{
				this.outer = outer;

				_key = key;
				_cert = cert;
				_digestOID = digestOID;
				_encOID = encOID;
				_sAttr = sAttr;
				_unsAttr = unsAttr;
				_signature = signature;
			}
            internal SignerInf(
                CmsSignedDataStreamGenerator outer,
                AsymmetricKeyParameter key,
                X509Certificate cert,
                string digestOID,
                string encOID,
                CmsAttributeTableGenerator sAttr,
                CmsAttributeTableGenerator unsAttr,
                ISigner signature)
            {
                this.outer = outer;

                _key       = key;
                _cert      = cert;
                _digestOID = digestOID;
                _encOID    = encOID;
                _sAttr     = sAttr;
                _unsAttr   = unsAttr;
                _signature = signature;
            }
Exemple #7
0
        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         val           = cmsSignedDataStreamGenerator.Open(outStr, cmsSignedDataParser.SignedContentType.Id, flag);

            if (flag)
            {
                Streams.PipeAll(signedContent.ContentStream, val);
            }
            cmsSignedDataStreamGenerator.AddAttributeCertificates(cmsSignedDataParser.GetAttributeCertificates("Collection"));
            cmsSignedDataStreamGenerator.AddCertificates(cmsSignedDataParser.GetCertificates("Collection"));
            cmsSignedDataStreamGenerator.AddCrls(cmsSignedDataParser.GetCrls("Collection"));
            Platform.Dispose(val);
            return(outStr);
        }
		public void TestSha1WithRsaEncapsulatedBuffered()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

			//
			// find unbuffered length
			//
			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
			gen.AddCertificates(x509Certs);

			Stream sigOut = gen.Open(bOut, true);

			for (int i = 0; i != 2000; i++)
			{
				sigOut.WriteByte((byte)(i & 0xff));
			}

			sigOut.Close();

			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);

			int unbufferedLength = bOut.ToArray().Length;

			//
			// find buffered length - buffer size less than default
			//
			bOut.SetLength(0);

			gen = new CmsSignedDataStreamGenerator();
			gen.SetBufferSize(300);
            gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
			gen.AddCertificates(x509Certs);

            sigOut = gen.Open(bOut, true);

			for (int i = 0; i != 2000; i++)
			{
				sigOut.WriteByte((byte)(i & 0xff));
			}

			sigOut.Close();

			VerifyEncodedData(bOut);

			Assert.IsTrue(unbufferedLength < bOut.ToArray().Length);
		}
		public void TestSha1WithRsaEncapsulatedBufferedStream()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

            //
			// find unbuffered length
			//
			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
			gen.AddCertificates(x509Certs);

			Stream sigOut = gen.Open(bOut, true);
			for (int i = 0; i != 2000; i++)
			{
				sigOut.WriteByte((byte)(i & 0xff));
			}
			sigOut.Close();

			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());

            sp.GetSignedContent().Drain();

            VerifySignatures(sp);

			int unbufferedLength = bOut.ToArray().Length;

			//
			// find buffered length with buffered stream - should be equal
			//
			bOut.SetLength(0);

			gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
			gen.AddCertificates(x509Certs);

			sigOut = gen.Open(bOut, true);

			byte[] data = new byte[2000];
			for (int i = 0; i != 2000; i++)
			{
				data[i] = (byte)(i & 0xff);
			}

            Streams.PipeAll(new MemoryStream(data, false), sigOut);
			sigOut.Close();

            VerifyEncodedData(bOut);

			Assert.AreEqual(unbufferedLength, bOut.ToArray().Length);
		}
		public void TestSha1AndMD5WithRsa()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			gen.AddDigests(CmsSignedDataStreamGenerator.DigestSha1,
				CmsSignedDataStreamGenerator.DigestMD5);

            byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);

            Stream sigOut = gen.Open(bOut);
			sigOut.Write(testBytes, 0, testBytes.Length);

			gen.AddCertificates(x509Certs);
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestMD5);

			sigOut.Close();

			CheckSigParseable(bOut.ToArray());

			CmsSignedDataParser sp = new CmsSignedDataParser(
				new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);
		}
        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);

            CmsCompressedDataStreamGenerator cGen = new CmsCompressedDataStreamGenerator();

            Stream cOut = cGen.Open(sigOut, CmsCompressedDataStreamGenerator.ZLib);

            byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
            cOut.Write(testBytes, 0, testBytes.Length);

            cOut.Close();

            sigOut.Close();

            CheckSigParseable(bOut.ToArray());

            // generate compressed stream
            MemoryStream cDataOut = new MemoryStream();

            cOut = cGen.Open(cDataOut, CmsCompressedDataStreamGenerator.ZLib);

            cOut.Write(testBytes, 0, testBytes.Length);

            cOut.Close();

            CmsSignedDataParser sp = new CmsSignedDataParser(
                new CmsTypedStream(new MemoryStream(cDataOut.ToArray(), false)), bOut.ToArray());

            sp.GetSignedContent().Drain();

            //
            // compute expected content digest
            //
            IDigest md = DigestUtilities.GetDigest("SHA1");
            byte[] cDataOutBytes = cDataOut.ToArray();
            md.BlockUpdate(cDataOutBytes, 0, cDataOutBytes.Length);
            byte[] hash = DigestUtilities.DoFinal(md);

            VerifySignatures(sp, hash);
        }
        Stream Sign(CmsSigner signer, Stream content, bool encapsulate)
        {
            var cms = new CmsSignedDataStreamGenerator ();

            cms.AddSigner (signer.PrivateKey, signer.Certificate, GetDigestOid (signer.DigestAlgorithm),
                signer.SignedAttributes, signer.UnsignedAttributes);

            var memory = new MemoryStream ();

            using (var stream = cms.Open (memory, encapsulate)) {
                content.CopyTo (stream, 4096);
            }

            memory.Position = 0;

            return memory;
        }
        public void TestCertsOnly()
        {
            IList certList = new ArrayList();
            certList.Add(OrigCert);
            certList.Add(SignCert);

            IX509Store x509Certs = X509StoreFactory.Create(
                "Certificate/Collection",
                new X509CollectionStoreParameters(certList));

            MemoryStream bOut = new MemoryStream();

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
            gen.AddCertificates(x509Certs);
            gen.Open(bOut).Close();

            CheckSigParseable(bOut.ToArray());
        }
		public void TestWithAttributeCertificate()
		{
            IX509Store x509Certs = CmsTestUtil.MakeCertStore(SignCert);

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataGenerator.DigestSha1);
			gen.AddCertificates(x509Certs);

            IX509AttributeCertificate attrCert = CmsTestUtil.GetAttributeCertificate();

            IX509Store store = CmsTestUtil.MakeAttrCertStore(attrCert);

            gen.AddAttributeCertificates(store);

            MemoryStream bOut = new MemoryStream();

            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();

			Assert.AreEqual(4, sp.Version);

			store = sp.GetAttributeCertificates("Collection");

			ArrayList coll = new ArrayList(store.GetMatches(null));

			Assert.AreEqual(1, coll.Count);

			Assert.IsTrue(coll.Contains(attrCert));
		}
		public void TestEncapsulatedCertStoreReplacement()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigDsaCert);

			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();

			//
			// create new certstore with the right certificates
			//
            x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

            //
			// replace certs
			//
			MemoryStream original = new MemoryStream(bOut.ToArray(), false);
			MemoryStream newOut = new MemoryStream();

			CmsSignedDataParser.ReplaceCertificatesAndCrls(original, x509Certs, null, null, newOut);

			CmsSignedDataParser sp = new CmsSignedDataParser(newOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);
		}
		public void TestSignerStoreReplacement()
		{
			IList certList = new ArrayList();
			MemoryStream bOut = new MemoryStream();
			byte[] data = Encoding.ASCII.GetBytes(TestMessage);

			certList.Add(OrigCert);
			certList.Add(SignCert);

			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, false);

			sigOut.Write(data, 0, data.Length);

			sigOut.Close();

			CheckSigParseable(bOut.ToArray());

			//
			// create new Signer
			//
			MemoryStream original = new MemoryStream(bOut.ToArray(), false);

			bOut.SetLength(0);

			gen = new CmsSignedDataStreamGenerator();

			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha224);

			gen.AddCertificates(x509Certs);

			sigOut = gen.Open(bOut);

			sigOut.Write(data, 0, data.Length);

			sigOut.Close();

			CheckSigParseable(bOut.ToArray());

			CmsSignedData sd = new CmsSignedData(bOut.ToArray());

			//
			// replace signer
			//
			MemoryStream newOut = new MemoryStream();

			CmsSignedDataParser.ReplaceSigners(original, sd.GetSignerInfos(), newOut);

			sd = new CmsSignedData(new CmsProcessableByteArray(data), newOut.ToArray());

			IEnumerator signerEnum = sd.GetSignerInfos().GetSigners().GetEnumerator();
			signerEnum.MoveNext();
			SignerInformation signer = (SignerInformation) signerEnum.Current;

			Assert.AreEqual(signer.DigestAlgOid, CmsSignedDataStreamGenerator.DigestSha224);

			CmsSignedDataParser sp = new CmsSignedDataParser(new CmsTypedStream(
				new MemoryStream(data, false)), newOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);
		}
		public void TestSha1AndMD5WithRsa()
		{
			IList certList = new ArrayList();
			MemoryStream bOut = new MemoryStream();

			certList.Add(OrigCert);
			certList.Add(SignCert);

			IX509Store x509Certs = X509StoreFactory.Create(
				"Certificate/Collection",
				new X509CollectionStoreParameters(certList));

			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();

			gen.AddDigests(CmsSignedDataStreamGenerator.DigestSha1,
				CmsSignedDataStreamGenerator.DigestMD5);

			Stream sigOut = gen.Open(bOut);

			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
			sigOut.Write(testBytes, 0, testBytes.Length);

			gen.AddCertificates(x509Certs);

			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha1);
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestMD5);

			sigOut.Close();

			CheckSigParseable(bOut.ToArray());

			CmsSignedDataParser sp = new CmsSignedDataParser(
				new CmsTypedStream(new MemoryStream(testBytes, false)), bOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);
		}
		public void TestSha1WithRsaNonData()
		{
			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, "1.2.3.4", true);

			byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);
			sigOut.Write(testBytes, 0, testBytes.Length);

			sigOut.Close();

			CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());

			CmsTypedStream stream = sp.GetSignedContent();

			Assert.AreEqual("1.2.3.4", stream.ContentType);

			stream.Drain();

			//
			// compute expected content digest
			//
			IDigest md = DigestUtilities.GetDigest("SHA1");
			md.BlockUpdate(testBytes, 0, testBytes.Length);
			byte[] hash = DigestUtilities.DoFinal(md);

			VerifySignatures(sp, hash);
		}
		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));
		}
	    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);
	    }
        public void TestCertsOnly()
        {
            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

            MemoryStream bOut = new MemoryStream();

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
            gen.AddCertificates(x509Certs);
            gen.Open(bOut).Close();

            CheckSigParseable(bOut.ToArray());
        }
		public void TestAttributeGenerators()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

			CmsAttributeTableGenerator signedGen = new SignedGenAttributeTableGenerator();
			CmsAttributeTableGenerator unsignedGen = new UnsignedGenAttributeTableGenerator();

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
            gen.AddSigner(OrigKP.Private, OrigCert,
				CmsSignedDataStreamGenerator.DigestSha1, signedGen, unsignedGen);
			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);

			//
			// check attributes
			//
			SignerInformationStore signers = sp.GetSignerInfos();

			foreach (SignerInformation signer in signers.GetSigners())
			{
				CheckAttribute(signer.GetContentDigest(), signer.SignedAttributes[dummyOid1]);
				CheckAttribute(signer.GetSignature(), signer.UnsignedAttributes[dummyOid2]);
			}
		}
Exemple #23
0
        protected void Sign(Stream signed, Stream unsigned, X509Certificate2 selectedCert)
        {
            BC::X509.X509Certificate bcSelectedCert = DotNetUtilities.FromX509Certificate(selectedCert);
            trace.TraceEvent(TraceEventType.Information, 0, "Signing the message in name of {0}", selectedCert.Subject);

            //Signing time
            DateTime signingTime = DateTime.UtcNow;

            CmsSignedDataStreamGenerator signedGenerator = new CmsSignedDataStreamGenerator();

            //For compatibility we don't add it to the CMS (most implementations, including BC, don't support OCSP here)
            //IX509Store crlStore = X509StoreFactory.Create("CRL/COLLECTION", new X509CollectionStoreParameters(crl's));
            //signedGenerator.AddCrls(crlStore);

            //add signed attributes to the signature (own signing time)
            IDictionary signedAttrDictionary = new Hashtable();
            BC::Asn1.Cms.Attribute signTimeattr = new BC::Asn1.Cms.Attribute(CmsAttributes.SigningTime,
                    new DerSet(new BC::Asn1.Cms.Time(signingTime)));
            signedAttrDictionary.Add(signTimeattr.AttrType, signTimeattr);
            BC::Asn1.Cms.AttributeTable signedAttrTable = new BC.Asn1.Cms.AttributeTable(signedAttrDictionary);

            //Add the signatures
            SignatureAlgorithm signAlgo;
            if (((RSACryptoServiceProvider)selectedCert.PrivateKey).CspKeyContainerInfo.Exportable) {
                signAlgo =  EteeActiveConfig.Seal.NativeSignatureAlgorithm;
                signedGenerator.AddSigner(DotNetUtilities.GetKeyPair(selectedCert.PrivateKey).Private,
                    bcSelectedCert, signAlgo.EncryptionAlgorithm.Value, signAlgo.DigestAlgorithm.Value,
                    signedAttrTable, null);
            } else {
                signAlgo = EteeActiveConfig.Seal.WindowsSignatureAlgorithm;
                signedGenerator.AddSigner(new ProxyRsaKeyParameters((RSACryptoServiceProvider)selectedCert.PrivateKey),
                    bcSelectedCert, signAlgo.EncryptionAlgorithm.Value, signAlgo.DigestAlgorithm.Value,
                    signedAttrTable, null);
            }
            trace.TraceEvent(TraceEventType.Verbose, 0, "Added Signer [EncAlgo={0} ({1}), DigestAlgo={2} ({3})",
                signAlgo.EncryptionAlgorithm.FriendlyName,
                signAlgo.EncryptionAlgorithm.Value,
                signAlgo.DigestAlgorithm.FriendlyName,
                signAlgo.DigestAlgorithm.Value);

            Stream signingStream = signedGenerator.Open(signed, true);
            trace.TraceEvent(TraceEventType.Verbose, 0, "Create embedded signed message (still empty)");
            try
            {
                unsigned.CopyTo(signingStream);
                trace.TraceEvent(TraceEventType.Verbose, 0, "Message copied and digest calculated");
            }
            finally
            {
                signingStream.Close();
                trace.TraceEvent(TraceEventType.Verbose, 0, "Signature block added");
            }
        }
		public void TestEncapsulatedSignerStoreReplacement()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(OrigCert, SignCert);

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, 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();

			//
			// create new Signer
			//
			MemoryStream  original = new MemoryStream(bOut.ToArray(), false);

			bOut.SetLength(0);

			gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, CmsSignedDataStreamGenerator.DigestSha224);
			gen.AddCertificates(x509Certs);

            sigOut = gen.Open(bOut, true);
			sigOut.Write(testBytes, 0, testBytes.Length);
			sigOut.Close();

            CmsSignedData sd = new CmsSignedData(bOut.ToArray());

            //
			// replace signer
			//
			MemoryStream newOut = new MemoryStream();

			CmsSignedDataParser.ReplaceSigners(original, sd.GetSignerInfos(), newOut);

			sd = new CmsSignedData(newOut.ToArray());

			IEnumerator signerEnum = sd.GetSignerInfos().GetSigners().GetEnumerator();
			signerEnum.MoveNext();
			SignerInformation signer = (SignerInformation) signerEnum.Current;

			Assert.AreEqual(signer.DigestAlgOid, CmsSignedDataStreamGenerator.DigestSha224);

			CmsSignedDataParser sp = new CmsSignedDataParser(newOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);
		}
		public void TestCertStoreReplacement()
		{
			IList certList = new ArrayList();
			MemoryStream bOut = new MemoryStream();
			byte[] data = Encoding.ASCII.GetBytes(TestMessage);

			certList.Add(OrigDsaCert);

			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);

			sigOut.Write(data, 0, data.Length);

			sigOut.Close();

			CheckSigParseable(bOut.ToArray());

			//
			// create new certstore with the right certificates
			//
			certList = new ArrayList();
			certList.Add(OrigCert);
			certList.Add(SignCert);

			x509Certs = X509StoreFactory.Create(
				"Certificate/Collection",
				new X509CollectionStoreParameters(certList));

			//
			// replace certs
			//
			MemoryStream original = new MemoryStream(bOut.ToArray(), false);
			MemoryStream newOut = new MemoryStream();

			CmsSignedDataParser.ReplaceCertificatesAndCrls(original, x509Certs, null, null, newOut);

			CmsSignedDataParser sp = new CmsSignedDataParser(new CmsTypedStream(new MemoryStream(data, false)), newOut.ToArray());

			sp.GetSignedContent().Drain();

			VerifySignatures(sp);
		}
		public void TestCertOrdering2()
		{
			MemoryStream bOut = new MemoryStream();

            IX509Store x509Certs = CmsTestUtil.MakeCertStore(SignCert, OrigCert);

            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			gen.AddSigner(OrigKP.Private, OrigCert, 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();
			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]);
		}
			internal SignerInf(
				CmsSignedDataStreamGenerator	outer,
				AsymmetricKeyParameter			key,
				byte[]							subjectKeyID,
				string							digestOID,
				string							encOID,
				CmsAttributeTableGenerator		sAttr,
				CmsAttributeTableGenerator		unsAttr,
				ISigner							signature)
	        {
				this.outer = outer;

	            _key = key;
	            _subjectKeyID = subjectKeyID;
	            _digestOID = digestOID;
	            _encOID = encOID;
	            _sAttr = sAttr;
	            _unsAttr = unsAttr;
	            _signature = signature;
	        }
		public void TestEarlyInvalidKeyException()
		{
			try
			{
				CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
				gen.AddSigner(OrigKP.Private, OrigCert,
					"DSA", // DOESN'T MATCH KEY ALG
					CmsSignedDataStreamGenerator.DigestSha1);

				Assert.Fail("Expected InvalidKeyException in AddSigner");
			}
			catch (InvalidKeyException)
			{
				// Ignore
			}
		}
Exemple #29
0
        protected void Complete(Level level, Stream embedded, Stream signed, X509Certificate2 providedSigner, out TimemarkKey timemarkKey)
        {
            trace.TraceEvent(TraceEventType.Information, 0, "Completing the message with of {0} bytes to level {1}", signed.Length, level);

            //Prepare generator, parser and time-mark Key
            CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
            CmsSignedDataParser parser = new CmsSignedDataParser(signed);
            timemarkKey = new TimemarkKey();

            //preset the digests so we can add the signers afterwards
            gen.AddDigests(parser.DigestOids);

            //Copy the content
            CmsTypedStream signedContent = parser.GetSignedContent();
            Stream contentOut = gen.Open(embedded, parser.SignedContentType.Id, true);
            signedContent.ContentStream.CopyTo(contentOut);

            //Extract the signer info
            SignerInformationStore signerInfoStore = parser.GetSignerInfos();
            IEnumerator signerInfos = signerInfoStore.GetSigners().GetEnumerator();
            if (!signerInfos.MoveNext())
            {
                trace.TraceEvent(TraceEventType.Error, 0, "The message to complete does not contain a signature");
                throw new InvalidMessageException("The message does not contain a signature");
            }
            SignerInformation signerInfo = (SignerInformation)signerInfos.Current;
            if (signerInfos.MoveNext())
            {
                trace.TraceEvent(TraceEventType.Error, 0, "The message to complete does not contain more then one signature");
                throw new InvalidMessageException("The message does contain multiple signatures, which isn't supported");
            }

            //Extract the signing key
            timemarkKey.SignatureValue = signerInfo.GetSignature();

            //Extract the unsigned attributes & signing time
            bool hasSigningTime;
            IDictionary unsignedAttributes = signerInfo.UnsignedAttributes != null ? signerInfo.UnsignedAttributes.ToDictionary() : new Hashtable();
            BC::Asn1.Cms.Attribute singingTimeAttr = signerInfo.SignedAttributes != null ? signerInfo.SignedAttributes[CmsAttributes.SigningTime] : null;
            if (singingTimeAttr == null)
            {
                trace.TraceEvent(TraceEventType.Warning, 0, "The message to complete does not contain a signing time");
                hasSigningTime = false;
                timemarkKey.SigningTime = DateTime.UtcNow;
            }
            else
            {
                hasSigningTime = false;
                timemarkKey.SigningTime = new BC::Asn1.Cms.Time(((DerSet)singingTimeAttr.AttrValues)[0].ToAsn1Object()).Date;
            }

            //Extract the signer, if available
            IX509Store embeddedCerts = parser.GetCertificates("Collection");
            if (embeddedCerts != null && embeddedCerts.GetMatches(null).Count > 0)
            {
                //Embedded certs found, we use that
                IEnumerator signerCerts = embeddedCerts.GetMatches(signerInfo.SignerID).GetEnumerator();
                if (!signerCerts.MoveNext()) {
                    trace.TraceEvent(TraceEventType.Error, 0, "The message does contains certificates, but the signing certificate is missing");
                    throw new InvalidMessageException("The message does not contain the signer certificate");
                }
                timemarkKey.Signer = new X509Certificate2(((BC::X509.X509Certificate)signerCerts.Current).GetEncoded());
                trace.TraceEvent(TraceEventType.Verbose, 0, "The message contains certificates, of which {0} is the signer", timemarkKey.Signer.Subject);

                //Add the certs to the new message
                gen.AddCertificates(embeddedCerts);
            }
            else
            {
                //No embedded certs, lets construct it.
                if (providedSigner == null)
                {
                    trace.TraceEvent(TraceEventType.Error, 0, "The provided message does not contain any embedded certificates");
                    throw new InvalidMessageException("The message does not contain any embedded certificates");
                }
                timemarkKey.Signer = providedSigner;
                trace.TraceEvent(TraceEventType.Verbose, 0, "The message does not contains certificates, adding the chain of {0}", timemarkKey.Signer.Subject);

                //Construct the chain of certificates
                Chain chain = timemarkKey.Signer.BuildBasicChain(timemarkKey.SigningTime, extraStore);
                if (chain.ChainStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0)
                {
                    trace.TraceEvent(TraceEventType.Error, 0, "The certification chain of {0} failed with errors", chain.ChainElements[0].Certificate.Subject);
                    throw new InvalidMessageException(string.Format("The certificate chain of the signer {0} fails basic validation", timemarkKey.Signer.Subject));
                }

                List<BC::X509.X509Certificate> senderChainCollection = new List<BC::X509.X509Certificate>();
                foreach (ChainElement ce in chain.ChainElements)
                {
                    trace.TraceEvent(TraceEventType.Verbose, 0, "Adding the certificate {0} to the message", ce.Certificate.Subject);
                    senderChainCollection.Add(DotNetUtilities.FromX509Certificate(ce.Certificate));
                }
                embeddedCerts = X509StoreFactory.Create("CERTIFICATE/COLLECTION", new X509CollectionStoreParameters(senderChainCollection));

                //Add the certificates to the new message
                gen.AddCertificates(embeddedCerts);

            }

            //Getting any existing time stamps
            TimeStampToken tst = null;
            BC::Asn1.Cms.Attribute timestampAttr = (BC::Asn1.Cms.Attribute)unsignedAttributes[PkcsObjectIdentifiers.IdAASignatureTimeStampToken];
            if (timestampAttr == null || ((DerSet)timestampAttr.AttrValues).Count == 0)
            {
                //there is no TST
                if ((level & Level.T_Level) == Level.T_Level && timestampProvider != null)
                {
                    //There should be a TST
                    if (DateTime.UtcNow > (timemarkKey.SigningTime + EteeActiveConfig.ClockSkewness + Settings.Default.TimestampGracePeriod))
                    {
                        trace.TraceEvent(TraceEventType.Error, 0, "The message was created on {0}, which is beyond the allows period of {2} to time-stamp", timemarkKey.SigningTime, Settings.Default.TimestampGracePeriod);
                        throw new InvalidMessageException("The message it to old to add a time-stamp");
                    }

                    SHA256 sha = SHA256.Create();
                    byte[] signatureHash = sha.ComputeHash(timemarkKey.SignatureValue);
                    trace.TraceEvent(TraceEventType.Verbose, 0, "SHA-256 hashed the signature value from {0} to {1}", Convert.ToBase64String(timemarkKey.SignatureValue),  Convert.ToBase64String(signatureHash));

                    byte[] rawTst = timestampProvider.GetTimestampFromDocumentHash(signatureHash, "http://www.w3.org/2001/04/xmlenc#sha256");
                    tst = rawTst.ToTimeStampToken();

                    if (!tst.IsMatch(new MemoryStream(timemarkKey.SignatureValue)))
                    {
                        trace.TraceEvent(TraceEventType.Error, 0, "The time-stamp does not correspond to the signature value {0}", Convert.ToBase64String(timemarkKey.SignatureValue));
                        throw new InvalidOperationException("The time-stamp authority did not return a matching time-stamp");
                    }

                    //Don't verify the time-stamp, it is done later

                    //embed TST
                    BC::Asn1.Cms.Attribute signatureTstAttr = new BC::Asn1.Cms.Attribute(PkcsObjectIdentifiers.IdAASignatureTimeStampToken, new DerSet(Asn1Object.FromByteArray(rawTst)));
                    unsignedAttributes[signatureTstAttr.AttrType] = signatureTstAttr;
                    trace.TraceEvent(TraceEventType.Verbose, 0, "Added the time-stamp: {0}", Convert.ToBase64String(rawTst));

                    //The certs are part of the TST, so no need to add them to the CMS
                }
            }
            else
            {
                //There is one, extract it we need it later
                DerSet rawTsts = (DerSet)timestampAttr.AttrValues;
                if (rawTsts.Count > 1)
                {
                    trace.TraceEvent(TraceEventType.Error, 0, "There are {0} signature timestamps present", rawTsts.Count);
                    throw new NotSupportedException("The library does not support more then one time-stamp");
                }

                tst = rawTsts[0].GetEncoded().ToTimeStampToken();
                if (!hasSigningTime)
                {
                    trace.TraceEvent(TraceEventType.Information, 0, "Implicit signing time {0} is replaced with time-stamp time {1}", timemarkKey.SigningTime, tst.TimeStampInfo.GenTime);
                    timemarkKey.SigningTime = tst.TimeStampInfo.GenTime;
                }
                if (tst.TimeStampInfo.GenTime > (timemarkKey.SigningTime + EteeActiveConfig.ClockSkewness + Settings.Default.TimestampGracePeriod))
                {
                    trace.TraceEvent(TraceEventType.Error, 0, "The message was time-stamped on {0}, which is beyond the allows period of {2} from the signing time {1}", tst.TimeStampInfo.GenTime, timemarkKey.SigningTime, Settings.Default.TimestampGracePeriod);
                    throw new InvalidMessageException("The message wasn't timestamped on time");
                }
            }

            if ((level & Level.L_Level) == Level.L_Level)
            {
                //Add revocation info
                IList<CertificateList> crls = null;
                IList<BasicOcspResponse> ocsps = null;
                BC::Asn1.Cms.Attribute revocationAttr = (BC::Asn1.Cms.Attribute)unsignedAttributes[PkcsObjectIdentifiers.IdAAEtsRevocationValues];
                if (revocationAttr != null)
                {
                    DerSet revocationInfoSet = (DerSet) revocationAttr.AttrValues;
                    if (revocationInfoSet == null || revocationInfoSet.Count == 0)
                    {
                        RevocationValues revocationInfo = RevocationValues.GetInstance(revocationInfoSet[0]);
                        crls = new List<CertificateList>(revocationInfo.GetCrlVals());
                        trace.TraceEvent(TraceEventType.Verbose, 0, "Found {1} CRL's in the message", crls.Count);
                        ocsps = new List<BasicOcspResponse>(revocationInfo.GetOcspVals());
                        trace.TraceEvent(TraceEventType.Verbose, 0, "Found {1} OCSP's in the message", ocsps.Count);
                    }
                }
                if (crls == null) crls = new List<CertificateList>();
                if (ocsps == null) ocsps = new List<BasicOcspResponse>();

                //Add the message certificate chain revocation info + check if successful
                var extraStore = new X509Certificate2Collection();
                foreach (Org.BouncyCastle.X509.X509Certificate cert in embeddedCerts.GetMatches(null))
                {
                    extraStore.Add(new X509Certificate2(cert.GetEncoded()));
                }
                Chain chain = timemarkKey.Signer.BuildChain(timemarkKey.SigningTime, extraStore, ref crls, ref ocsps);
                if (chain.ChainStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0)
                {
                    trace.TraceEvent(TraceEventType.Error, 0, "The certificate chain of the signer {0} failed with {1} issues: {2}, {3}", timemarkKey.Signer.Subject,
                        chain.ChainStatus.Count, chain.ChainStatus[0].Status, chain.ChainStatus[0].StatusInformation);
                    throw new InvalidMessageException(string.Format("The certificate chain of the signer {0} fails revocation validation", timemarkKey.Signer.Subject));
                }

                //Add the time-stamp certificate chain revocation info + check if successful
                if (tst != null)
                {
                    Timestamp ts = tst.Validate(ref crls, ref ocsps);
                    if (ts.TimestampStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0)
                    {
                        trace.TraceEvent(TraceEventType.Error, 0, "The certificate chain of the time-stamp signer {0} failed with {1} issues: {2}, {3}", ts.CertificateChain.ChainElements[0].Certificate.Subject,
                        ts.TimestampStatus.Count, ts.TimestampStatus[0].Status, ts.TimestampStatus[0].StatusInformation);
                        throw new InvalidMessageException("The embedded time-stamp fails validation");
                    }
                }

                //Embed revocation info
                RevocationValues revocationValues = new RevocationValues(crls, ocsps, null);
                revocationAttr = new BC::Asn1.Cms.Attribute(PkcsObjectIdentifiers.IdAAEtsRevocationValues, new DerSet(revocationValues.ToAsn1Object()));
                unsignedAttributes[revocationAttr.AttrType] = revocationAttr;
                trace.TraceEvent(TraceEventType.Verbose, 0, "Added {0} OCSP's and {1} CRL's to the message", ocsps.Count, crls.Count);
            }

            //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();
        }
			public CmsSignedDataOutputStream(
				CmsSignedDataStreamGenerator	outer,
				Stream							outStream,
                string							contentOID,
                BerSequenceGenerator			sGen,
                BerSequenceGenerator			sigGen,
                BerSequenceGenerator			eiGen)
            {
				this.outer = outer;

				_out = outStream;
                _contentOID = new DerObjectIdentifier(contentOID);
                _sGen = sGen;
                _sigGen = sigGen;
                _eiGen = eiGen;
            }
		public void TestEarlyNoSuchAlgorithmException()
		{
			try
			{
				CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
				gen.AddSigner(OrigKP.Private, OrigCert,
					CmsSignedDataStreamGenerator.DigestSha1, // BAD OID!
					CmsSignedDataStreamGenerator.DigestSha1);

				Assert.Fail("Expected NoSuchAlgorithmException in AddSigner");
			}
			catch (SecurityUtilityException)
			{
				// Ignore
			}
		}
        /// <summary>
        /// Exports the certificates for the specified mailboxes.
        /// </summary>
        /// <returns>A new <see cref="MimeKit.Cryptography.ApplicationPkcs7Mime"/> instance containing
        /// the exported keys.</returns>
        /// <param name="mailboxes">The mailboxes.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="mailboxes"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// No mailboxes were specified.
        /// </exception>
        /// <exception cref="CertificateNotFoundException">
        /// A certificate for one or more of the <paramref name="mailboxes"/> could not be found.
        /// </exception>
        /// <exception cref="Org.BouncyCastle.Cms.CmsException">
        /// An error occurred in the cryptographic message syntax subsystem.
        /// </exception>
        public override MimePart Export(IEnumerable<MailboxAddress> mailboxes)
        {
            if (mailboxes == null)
                throw new ArgumentNullException ("mailboxes");

            var certificates = new X509CertificateStore ();
            int count = 0;

            foreach (var mailbox in mailboxes) {
                var recipient = GetCmsRecipient (mailbox);
                certificates.Add (recipient.Certificate);
                count++;
            }

            if (count == 0)
                throw new ArgumentException ("No mailboxes specified.", "mailboxes");

            var cms = new CmsSignedDataStreamGenerator ();
            var memory = new MemoryStream ();

            cms.AddCertificates (certificates);
            cms.Open (memory).Close ();
            memory.Position = 0;

            return new ApplicationPkcs7Mime (SecureMimeType.CertsOnly, memory);
        }
		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));
		}
		/**
		 * Replace the certificate and CRL information associated with this
		 * CMSSignedData object with the new one passed in.
		 * <p>
		 * The output stream is returned unclosed.
		 * </p>
		 * @param original the signed data stream to be used as a base.
		 * @param certsAndCrls the new certificates and CRLs to be used.
		 * @param out the stream to Write the new signed data object to.
		 * @return out.
		 * @exception CmsException if there is an error processing the CertStore
		 */
		public static Stream ReplaceCertificatesAndCrls(
			Stream			original,
			IX509Store		x509Certs,
			IX509Store		x509Crls,
			IX509Store		x509AttrCerts,
			Stream			outStr)
		{
			// NB: SecureRandom would be ignored since using existing signatures only
			CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator();
			CmsSignedDataParser parser = new CmsSignedDataParser(original);

			gen.AddDigests(parser.DigestOids);

			CmsTypedStream signedContent = parser.GetSignedContent();
			bool encapsulate = (signedContent != null);
			Stream contentOut = gen.Open(outStr, parser.SignedContentType.Id, encapsulate);
			if (encapsulate)
			{
				Streams.PipeAll(signedContent.ContentStream, contentOut);
			}

//			gen.AddAttributeCertificates(parser.GetAttributeCertificates("Collection"));
//			gen.AddCertificates(parser.GetCertificates("Collection"));
//			gen.AddCrls(parser.GetCrls("Collection"));
			if (x509AttrCerts != null)
				gen.AddAttributeCertificates(x509AttrCerts);
			if (x509Certs != null)
				gen.AddCertificates(x509Certs);
			if (x509Crls != null)
				gen.AddCrls(x509Crls);

			gen.AddSigners(parser.GetSignerInfos());

			contentOut.Close();

			return outStr;
		}
		public void TestSha1WithRsaNonData()
		{
			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);

            byte[] testBytes = Encoding.ASCII.GetBytes(TestMessage);

            Stream sigOut = gen.Open(bOut, "1.2.3.4", true);
			sigOut.Write(testBytes, 0, testBytes.Length);
			sigOut.Close();

            CmsSignedDataParser sp = new CmsSignedDataParser(bOut.ToArray());

            CmsTypedStream stream = sp.GetSignedContent();

			Assert.AreEqual("1.2.3.4", stream.ContentType);

			stream.Drain();

            // compute expected content digest
            byte[] hash = DigestUtilities.CalculateDigest("SHA1", testBytes);

            VerifySignatures(sp, hash);
		}