public Stream Open(
			Stream	outStream,
			string	contentOID,
			string	compressionOID)
		{
			BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

			sGen.AddObject(CmsObjectIdentifiers.CompressedData);

			//
			// Compressed Data
			//
			BerSequenceGenerator cGen = new BerSequenceGenerator(
				sGen.GetRawOutputStream(), 0, true);

			// CMSVersion
			cGen.AddObject(new DerInteger(0));

			// CompressionAlgorithmIdentifier
			cGen.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier(ZLib)));

			//
			// Encapsulated ContentInfo
			//
			BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream());

			eiGen.AddObject(new DerObjectIdentifier(contentOID));

			Stream octetStream = CmsUtilities.CreateBerOctetOutputStream(
				eiGen.GetRawOutputStream(), 0, true, _bufferSize);

			return new CmsCompressedOutputStream(
				new ZOutputStream(octetStream, JZlib.Z_DEFAULT_COMPRESSION), sGen, cGen, eiGen);
		}
        public Stream Open(
			Stream	outStream,
			string	contentOID,
			string	compressionOID)
        {
            BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

            sGen.AddObject(CmsObjectIdentifiers.CompressedData);

            //
            // Compressed Data
            //
            BerSequenceGenerator cGen = new BerSequenceGenerator(
                sGen.GetRawOutputStream(), 0, true);

            // CMSVersion
            cGen.AddObject(new DerInteger(0));

            // CompressionAlgorithmIdentifier
            cGen.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier(ZLib)));

            //
            // Encapsulated ContentInfo
            //
            BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream());

            eiGen.AddObject(new DerObjectIdentifier(contentOID));

            BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                eiGen.GetRawOutputStream(), 0, true);

            return new CmsCompressedOutputStream(
                new ZDeflaterOutputStream(octGen.GetOctetOutputStream()), sGen, cGen, eiGen);
        }
			public CmsAuthenticatedDataOutputStream(
				Stream					macStream,
				IMac					mac,
				BerSequenceGenerator	cGen,
				BerSequenceGenerator	authGen,
				BerSequenceGenerator	eiGen)
			{
				this.macStream = macStream;
				this.mac = mac;
				this.cGen = cGen;
				this.authGen = authGen;
				this.eiGen = eiGen;
			}
		protected Stream Open(
			Stream        			outStr,
			AlgorithmIdentifier		macAlgId,
			ICipherParameters		cipherParameters,
			Asn1EncodableVector		recipientInfos)
		{
			try
			{
				//
				// ContentInfo
				//
				BerSequenceGenerator cGen = new BerSequenceGenerator(outStr);

				cGen.AddObject(CmsObjectIdentifiers.AuthenticatedData);

				//
				// Authenticated Data
				//
				BerSequenceGenerator authGen = new BerSequenceGenerator(
					cGen.GetRawOutputStream(), 0, true);

				authGen.AddObject(new DerInteger(AuthenticatedData.CalculateVersion(null)));

				Stream authRaw = authGen.GetRawOutputStream();
				Asn1Generator recipGen = _berEncodeRecipientSet
					?	(Asn1Generator) new BerSetGenerator(authRaw)
					:	new DerSetGenerator(authRaw);

				foreach (Asn1Encodable ae in recipientInfos)
				{
					recipGen.AddObject(ae);
				}

				recipGen.Close();

				authGen.AddObject(macAlgId);

				BerSequenceGenerator eiGen = new BerSequenceGenerator(authRaw);
				eiGen.AddObject(CmsObjectIdentifiers.Data);

				Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream(
					eiGen.GetRawOutputStream(), 0, false, _bufferSize);

				IMac mac = MacUtilities.GetMac(macAlgId.ObjectID);
				// TODO Confirm no ParametersWithRandom needed
	            mac.Init(cipherParameters);
				Stream mOut = new TeeOutputStream(octetOutputStream, new MacOutputStream(mac));

				return new CmsAuthenticatedDataOutputStream(mOut, mac, cGen, authGen, eiGen);
			}
			catch (SecurityUtilityException e)
			{
				throw new CmsException("couldn't create cipher.", e);
			}
			catch (InvalidKeyException e)
			{
				throw new CmsException("key invalid in message.", e);
			}
			catch (IOException e)
			{
				throw new CmsException("exception decoding algorithm parameters.", e);
			}
		}
 internal CmsCompressedOutputStream(
     ZDeflaterOutputStream outStream,
     BerSequenceGenerator sGen,
     BerSequenceGenerator cGen,
     BerSequenceGenerator eiGen)
 {
     _out = outStream;
     _sGen = sGen;
     _cGen = cGen;
     _eiGen = eiGen;
 }
			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;
            }
		/**
		* generate a signed object that for a CMS Signed Data
		* object using the given provider - if encapsulate is true a copy
		* of the message will be included in the signature. The content type
		* is set according to the OID represented by the string signedContentType.
		* @param out stream the CMS object is to be written to.
		* @param signedContentType OID for data to be signed.
		* @param encapsulate true if data should be encapsulated.
		* @param dataOutputStream output stream to copy the data being signed to.
		*/
		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");

			_messageDigestsLocked = true;
			
			//
            // ContentInfo
            //
            BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

			sGen.AddObject(CmsObjectIdentifiers.SignedData);

			//
            // Signed Data
            //
            BerSequenceGenerator sigGen = new BerSequenceGenerator(
				sGen.GetRawOutputStream(), 0, true);

			sigGen.AddObject(CalculateVersion(signedContentType));

			Asn1EncodableVector digestAlgs = new Asn1EncodableVector();

			foreach (string digestOid in _messageDigestOids)
            {
				digestAlgs.Add(
            		new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance));
            }

            {
				byte[] tmp = new DerSet(digestAlgs).GetEncoded();
				sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length);
			}

			BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());

			eiGen.AddObject(new DerObjectIdentifier(signedContentType));

			Stream digStream;
			if (encapsulate)
            {
                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
					eiGen.GetRawOutputStream(), 0, true);

				digStream = octGen.GetOctetOutputStream(_bufferSize);

				if (dataOutputStream != null)
				{
					digStream = new TeeOutputStream(dataOutputStream, digStream);
				}
            }
            else
            {
				if (dataOutputStream != null)
				{
					digStream = dataOutputStream;
				}
				else
				{
					digStream = new NullOutputStream();
				}
			}

			foreach (IDigest d in _messageDigests.Values)
			{
                digStream = new DigestStream(digStream, null, d);
            }

			return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen);
        }
        /**
        * generate a signed object that for a CMS Signed Data
        * object using the given provider - if encapsulate is true a copy
        * of the message will be included in the signature. The content type
        * is set according to the OID represented by the string signedContentType.
        * @param out stream the CMS object is to be written to.
        * @param signedContentType OID for data to be signed.
        * @param encapsulate true if data should be encapsulated.
        * @param dataOutputStream output stream to copy the data being signed to.
        */
        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");

            _messageDigestsLocked = true;

            //
            // ContentInfo
            //
            BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

            //
            // Signed Data
            //
            BerSequenceGenerator sigGen = new BerSequenceGenerator(
                sGen.GetRawOutputStream(), 0, true);

            sigGen.AddObject(CalculateVersion(signedContentType));

            Asn1EncodableVector digestAlgs = new Asn1EncodableVector();

            foreach (string digestOid in _messageDigestOids)
            {
                digestAlgs.Add(
                    new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance));
            }

            {
                byte[] tmp = new DerSet(digestAlgs).GetEncoded();
                sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length);
            }

            BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());
            eiGen.AddObject(new DerObjectIdentifier(signedContentType));

            // If encapsulating, add the data as an octet string in the sequence
            Stream encapStream = encapsulate
                ?	CmsUtilities.CreateBerOctetOutputStream(eiGen.GetRawOutputStream(), 0, true, _bufferSize)
                :	null;

            // Also send the data to 'dataOutputStream' if necessary
            Stream teeStream = GetSafeTeeOutputStream(dataOutputStream, encapStream);

            // Let all the digests see the data as it is written
            Stream digStream = AttachDigestsToOutputStream(_messageDigests.Values, teeStream);

            return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen);
        }
			public CmsEnvelopedDataOutputStream(
				CmsEnvelopedGenerator	outer,
				CipherStream			outStream,
				BerSequenceGenerator	cGen,
				BerSequenceGenerator	envGen,
				BerSequenceGenerator	eiGen)
			{
				_outer = outer;
				_out = outStream;
				_cGen = cGen;
				_envGen = envGen;
				_eiGen = eiGen;
			}
		private Stream Open(
			Stream				outStream,
			AlgorithmIdentifier	encAlgID,
			ICipherParameters	cipherParameters,
			Asn1EncodableVector	recipientInfos)
		{
			try
			{
				//
				// ContentInfo
				//
				BerSequenceGenerator cGen = new BerSequenceGenerator(outStream);

				cGen.AddObject(CmsObjectIdentifiers.EnvelopedData);

				//
				// Encrypted Data
				//
				BerSequenceGenerator envGen = new BerSequenceGenerator(
					cGen.GetRawOutputStream(), 0, true);

				envGen.AddObject(this.Version);

				Stream envRaw = envGen.GetRawOutputStream();
				Asn1Generator recipGen = _berEncodeRecipientSet
					?	(Asn1Generator) new BerSetGenerator(envRaw)
					:	new DerSetGenerator(envRaw);

				foreach (Asn1Encodable ae in recipientInfos)
				{
					recipGen.AddObject(ae);
				}

				recipGen.Close();

				BerSequenceGenerator eiGen = new BerSequenceGenerator(envRaw);
				eiGen.AddObject(CmsObjectIdentifiers.Data);
				eiGen.AddObject(encAlgID);

				Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream(
					eiGen.GetRawOutputStream(), 0, false, _bufferSize);

				IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.ObjectID);
				cipher.Init(true, new ParametersWithRandom(cipherParameters, rand));
				CipherStream cOut = new CipherStream(octetOutputStream, null, cipher);

				return new CmsEnvelopedDataOutputStream(this, cOut, cGen, envGen, eiGen);
			}
			catch (SecurityUtilityException e)
			{
				throw new CmsException("couldn't create cipher.", e);
			}
			catch (InvalidKeyException e)
			{
				throw new CmsException("key invalid in message.", e);
			}
			catch (IOException e)
			{
				throw new CmsException("exception decoding algorithm parameters.", e);
			}
		}
        /**
        * generate a signed object that for a CMS Signed Data
        * object - if encapsulate is true a copy
        * of the message will be included in the signature. The content type
        * is set according to the OID represented by the string signedContentType.
        */
        public Stream Open(
            Stream	outStream,
            string	signedContentType,
            bool	encapsulate)
        {
            //
            // ContentInfo
            //
            BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

            //
            // Signed Data
            //
            BerSequenceGenerator sigGen = new BerSequenceGenerator(
                sGen.GetRawOutputStream(), 0, true);

            sigGen.AddObject(CalculateVersion(signedContentType));

            Asn1EncodableVector digestAlgs = new Asn1EncodableVector();

            //
            // add the precalculated SignerInfo digest algorithms.
            //
            foreach (SignerInformation signer in _signers)
            {
                digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID));
            }

            //
            // add the new digests
            //
            foreach (SignerInf signer in _signerInfs)
            {
                digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID));
            }

            {
                byte[] tmp = new DerSet(digestAlgs).GetEncoded();
                sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length);
            }

            BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());

            eiGen.AddObject(new DerObjectIdentifier(signedContentType));

            Stream digStream;
            if (encapsulate)
            {
                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                    eiGen.GetRawOutputStream(), 0, true);

                if (_bufferSize != 0)
                {
                    digStream = octGen.GetOctetOutputStream(new byte[_bufferSize]);
                }
                else
                {
                    digStream = octGen.GetOctetOutputStream();
                }
            }
            else
            {
                digStream = new NullOutputStream();
            }

            foreach (IDigest d in _messageDigests)
            {
                digStream = new DigestStream(digStream, null, d);
            }

            return new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen);
        }
        protected Stream Open(
            Stream					outStream,
            string					encryptionOid,
            KeyParameter			encKey,
			Asn1Encodable			asn1Params,
			Asn1EncodableVector		recipientInfos)
        {
            Asn1Object asn1Object;
            ICipherParameters cipherParameters;

            if (asn1Params != null)
            {
                asn1Object = asn1Params.ToAsn1Object();
                cipherParameters = ParameterUtilities.GetCipherParameters(
                    encryptionOid, encKey, asn1Object);
            }
            else
            {
                asn1Object = DerNull.Instance;
                cipherParameters = encKey;
            }

            try
            {
                AlgorithmIdentifier encAlgId = new AlgorithmIdentifier(
                    new DerObjectIdentifier(encryptionOid),
                    asn1Object);

                //
                // ContentInfo
                //
                BerSequenceGenerator cGen = new BerSequenceGenerator(outStream);

                cGen.AddObject(CmsObjectIdentifiers.EnvelopedData);

                //
                // Encrypted Data
                //
                BerSequenceGenerator envGen = new BerSequenceGenerator(
                    cGen.GetRawOutputStream(), 0, true);

                envGen.AddObject(this.Version);

                DerSet derSet = _berEncodeRecipientSet
                    ?	new BerSet(recipientInfos)
                    :	new DerSet(recipientInfos);

                byte[] derSetEncoding = derSet.GetEncoded();

                envGen.GetRawOutputStream().Write(derSetEncoding, 0, derSetEncoding.Length);

                IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid);

                cipher.Init(true, cipherParameters);

                BerSequenceGenerator eiGen = new BerSequenceGenerator(
                    envGen.GetRawOutputStream());

                eiGen.AddObject(PkcsObjectIdentifiers.Data);

                byte[] tmp = encAlgId.GetEncoded();
                eiGen.GetRawOutputStream().Write(tmp, 0, tmp.Length);

                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                    eiGen.GetRawOutputStream(), 0, false);

                Stream octetOutputStream = _bufferSize != 0
                    ?	octGen.GetOctetOutputStream(new byte[_bufferSize])
                    :	octGen.GetOctetOutputStream();

                CipherStream cOut = new CipherStream(octetOutputStream, null, cipher);

                return new CmsEnvelopedDataOutputStream(cOut, cGen, envGen, eiGen);
            }
            catch (SecurityUtilityException e)
            {
                throw new CmsException("couldn't create cipher.", e);
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key invalid in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("exception decoding algorithm parameters.", e);
            }
        }
示例#13
0
        /**
         * Replace the signerinformation store associated with the passed
         * in message contained in the stream original with the new one passed in.
         * You would probably only want to do this if you wanted to change the unsigned
         * attributes associated with a signer, or perhaps delete one.
         * <p>
         * The output stream is returned unclosed.
         * </p>
         * @param original the signed data stream to be used as a base.
         * @param signerInformationStore the new signer information store to use.
         * @param out the stream to Write the new signed data object to.
         * @return out.
         */
        public static Stream ReplaceSigners(
			Stream					original,
			SignerInformationStore	signerInformationStore,
			Stream					outStr)
        {
            Asn1StreamParser inStr = new Asn1StreamParser(original, CmsUtilities.MaximumMemory);
            ContentInfoParser contentInfo = new ContentInfoParser((Asn1SequenceParser)inStr.ReadObject());
            SignedDataParser signedData = SignedDataParser.GetInstance(contentInfo.GetContent(Asn1Tags.Sequence));

            BerSequenceGenerator sGen = new BerSequenceGenerator(outStr);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

            BerSequenceGenerator sigGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true);

            // version number
            sigGen.AddObject(signedData.Version);

            // digests
            signedData.GetDigestAlgorithms().ToAsn1Object();  // skip old ones

            Asn1EncodableVector digestAlgs = new Asn1EncodableVector();

            foreach (SignerInformation signer in signerInformationStore.GetSigners())
            {
                digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID));
            }

            WriteToGenerator(sigGen, new DerSet(digestAlgs));

            // encap content info
            ContentInfoParser encapContentInfo = signedData.GetEncapContentInfo();

            BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());

            eiGen.AddObject(encapContentInfo.ContentType);

            Asn1OctetStringParser octs = (Asn1OctetStringParser)encapContentInfo.GetContent(Asn1Tags.OctetString);

            if (octs != null)
            {
                BerOctetStringGenerator octGen = new BerOctetStringGenerator(
                    eiGen.GetRawOutputStream(), 0, true);
                byte[] inBuffer = new byte[4096];
                byte[] outBuffer = new byte[4096];
                Stream inOctets = octs.GetOctetStream();
                Stream outOctets = octGen.GetOctetOutputStream(outBuffer);

                int len;
                while ((len = inOctets.Read(inBuffer, 0, inBuffer.Length)) > 0)
                {
                    outOctets.Write(inBuffer, 0, len);
                }

                outOctets.Close();
            }

            eiGen.Close();

            WriteSetToGeneratorTagged(sigGen, signedData.GetCertificates(), 0);
            WriteSetToGeneratorTagged(sigGen, signedData.GetCrls(), 1);

            Asn1EncodableVector signerInfos = new Asn1EncodableVector();
            foreach (SignerInformation signer in signerInformationStore.GetSigners())
            {
                signerInfos.Add(signer.ToSignerInfo());
            }

            WriteToGenerator(sigGen, new DerSet(signerInfos));

            sigGen.Close();

            sGen.Close();

            return outStr;
        }
示例#14
0
        /**
         * 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)
        {
            if (x509AttrCerts != null)
                throw new NotImplementedException("Currently can't replace attribute certificates");

            Asn1StreamParser inStr = new Asn1StreamParser(original, CmsUtilities.MaximumMemory);
            ContentInfoParser contentInfo = new ContentInfoParser((Asn1SequenceParser)inStr.ReadObject());
            SignedDataParser signedData = SignedDataParser.GetInstance(contentInfo.GetContent(Asn1Tags.Sequence));

            BerSequenceGenerator sGen = new BerSequenceGenerator(outStr);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

            BerSequenceGenerator sigGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true);

            // version number
            sigGen.AddObject(signedData.Version);

            // digests
            WriteToGenerator(sigGen, signedData.GetDigestAlgorithms().ToAsn1Object());

            // encap content info
            ContentInfoParser encapContentInfo = signedData.GetEncapContentInfo();

            BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream());

            eiGen.AddObject(encapContentInfo.ContentType);

            Asn1OctetStringParser octs = (Asn1OctetStringParser)encapContentInfo.GetContent(Asn1Tags.OctetString);

            if (octs != null)
            {
                BerOctetStringGenerator octGen = new BerOctetStringGenerator(eiGen.GetRawOutputStream(), 0, true);
                byte[] inBuffer = new byte[4096];
                byte[] outBuffer = new byte[4096];
                Stream inOctets = octs.GetOctetStream();
                Stream outOctets = octGen.GetOctetOutputStream(outBuffer);

                int len;
                while ((len = inOctets.Read(inBuffer, 0, inBuffer.Length)) > 0)
                {
                    outOctets.Write(inBuffer, 0, len);
                }

                outOctets.Close();
            }

            eiGen.Close();

            //
            // skip existing certs and CRLs
            //
            GetAsn1Set(signedData.GetCertificates());
            GetAsn1Set(signedData.GetCrls());

            //
            // replace the certs and crls in the SignedData object
            //
            Asn1Set certs;
            try
            {
                certs = CmsUtilities.CreateDerSetFromList(
                    CmsUtilities.GetCertificatesFromStore(x509Certs));
            }
            catch (X509StoreException e)
            {
                throw new CmsException("error getting certs from certStore", e);
            }

            if (certs.Count > 0)
            {
                WriteToGenerator(sigGen, new DerTaggedObject(false, 0, certs));
            }

            Asn1Set crls;
            try
            {
                crls = CmsUtilities.CreateDerSetFromList(
                    CmsUtilities.GetCrlsFromStore(x509Crls));
            }
            catch (X509StoreException e)
            {
                throw new CmsException("error getting crls from certStore", e);
            }

            if (crls.Count > 0)
            {
                WriteToGenerator(sigGen, new DerTaggedObject(false, 1, crls));
            }

            WriteToGenerator(sigGen, signedData.GetSignerInfos().ToAsn1Object());

            sigGen.Close();

            sGen.Close();

            return outStr;
        }