Ejemplo n.º 1
0
        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));
        }
        /**
         * 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);

            bool isCounterSignature = (signedContentType == null);

            DerObjectIdentifier contentTypeOid = isCounterSignature
                ? null
                : new DerObjectIdentifier(signedContentType);

            sigGen.AddObject(CalculateVersion(contentTypeOid));

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

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