コード例 #1
0
        /**
         * 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
            //
            var sGen = new BerSequenceGenerator(outStream);

            sGen.AddObject(CmsObjectIdentifiers.SignedData);

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

            bool isCounterSignature = (signedContentType == null);

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

            sigGen.AddObject(CalculateVersion(contentTypeOid));

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

            var 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));
        }
コード例 #2
0
            protected override void Dispose(bool disposing)
            {
                try
                {
                    if (!disposing)
                    {
                        return;
                    }

                    _out.Dispose();

                    // TODO Parent context(s) should really be be closed explicitly

                    _eiGen.Close();

                    _outer._digests.Clear(); // clear the current preserved digest state

                    if (_outer._certs.Count > 0)
                    {
                        Asn1Set certs = CmsUtilities.CreateBerSetFromList(_outer._certs);

                        WriteToGenerator(_sigGen, new BerTaggedObject(false, 0, certs));
                    }

                    if (_outer._crls.Count > 0)
                    {
                        Asn1Set crls = CmsUtilities.CreateBerSetFromList(_outer._crls);

                        WriteToGenerator(_sigGen, new BerTaggedObject(false, 1, crls));
                    }

                    //
                    // Calculate the digest hashes
                    //
                    foreach (DictionaryEntry de in _outer._messageDigests)
                    {
                        _outer._messageHashes.Add(de.Key, DigestUtilities.DoFinal((IDigest)de.Value));
                    }

                    // TODO If the digest OIDs for precalculated signers weren't mixed in with
                    // the others, we could fill in outer._digests here, instead of SignerInfoGenerator.Generate

                    //
                    // collect all the SignerInfo objects
                    //
                    var signerInfos = new Asn1EncodableVector();

                    //
                    // add the generated SignerInfo objects
                    //
                    {
                        foreach (DigestAndSignerInfoGeneratorHolder holder in _outer._signerInfs)
                        {
                            AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm;

                            var calculatedDigest = (byte[])_outer._messageHashes[Helper.GetDigestAlgName(holder.DigestOID)];
                            _outer._digests[holder.DigestOID] = calculatedDigest.Clone();

                            signerInfos.Add(holder.SignerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest));
                        }
                    }

                    //
                    // add the precalculated SignerInfo objects.
                    //
                    {
                        foreach (SignerInformation signer in _outer._signers)
                        {
                            // TODO Verify the content type and calculated digest match the precalculated SignerInfo
                            //						if (!signer.ContentType.Equals(_contentOID))
                            //						{
                            //							// TODO The precalculated content type did not match - error?
                            //						}
                            //
                            //						byte[] calculatedDigest = (byte[])outer._digests[signer.DigestAlgOid];
                            //						if (calculatedDigest == null)
                            //						{
                            //							// TODO We can't confirm this digest because we didn't calculate it - error?
                            //						}
                            //						else
                            //						{
                            //							if (!Arrays.AreEqual(signer.GetContentDigest(), calculatedDigest))
                            //							{
                            //								// TODO The precalculated digest did not match - error?
                            //							}
                            //						}

                            signerInfos.Add(signer.ToSignerInfo());
                        }
                    }

                    WriteToGenerator(_sigGen, new DerSet(signerInfos));

                    _sigGen.Close();
                    _sGen.Close();
                }
                finally
                {
                    base.Dispose(disposing);
                }
            }
コード例 #3
0
 /**
  * base constructor - content with detached signature.
  *
  * @param signedContent the content that was signed.
  * @param sigData the signature object.
  */
 public CmsSignedData(
     CmsProcessable signedContent,
     Stream sigData)
     : this(signedContent, CmsUtilities.ReadContentInfo(sigData))
 {
 }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
 /**
  * Content with detached signature, digests precomputed
  *
  * @param hashes a map of precomputed digests for content indexed by name of hash.
  * @param sigBlock the signature object.
  */
 public CmsSignedData(
     IDictionary hashes,
     byte[]          sigBlock)
     : this(hashes, CmsUtilities.ReadContentInfo(sigBlock))
 {
 }
コード例 #6
0
 public CmsSignedData(
     CmsProcessable signedContent,
     byte[]                  sigBlock)
     : this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false)))
 {
 }
コード例 #7
0
 public CmsSignedData(
     byte[] sigBlock)
     : this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false)))
 {
 }
コード例 #8
0
        /**
         * Replace the certificate and CRL information associated with this
         * CmsSignedData object with the new one passed in.
         *
         * @param signedData the signed data object to be used as a base.
         * @param x509Certs the new certificates to be used.
         * @param x509Crls the new CRLs to be used.
         * @return a new signed data object.
         * @exception CmsException if there is an error processing the stores
         */
        public static CmsSignedData ReplaceCertificatesAndCrls(
            CmsSignedData signedData,
            IX509Store x509Certs,
            IX509Store x509Crls,
            IX509Store x509AttrCerts)
        {
            if (x509AttrCerts != null)
            {
                throw Platform.CreateNotImplementedException("Currently can't replace attribute certificates");
            }

            //
            // copy
            //
            CmsSignedData cms = new CmsSignedData(signedData);

            //
            // replace the certs and crls in the SignedData object
            //
            Asn1Set certs = null;

            try
            {
                Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList(
                    CmsUtilities.GetCertificatesFromStore(x509Certs));

                if (asn1Set.Count != 0)
                {
                    certs = asn1Set;
                }
            }
            catch (X509StoreException e)
            {
                throw new CmsException("error getting certificates from store", e);
            }

            Asn1Set crls = null;

            try
            {
                Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList(
                    CmsUtilities.GetCrlsFromStore(x509Crls));

                if (asn1Set.Count != 0)
                {
                    crls = asn1Set;
                }
            }
            catch (X509StoreException e)
            {
                throw new CmsException("error getting CRLs from store", e);
            }

            //
            // replace the CMS structure.
            //
            SignedData old = signedData.signedData;

            cms.signedData = new SignedData(
                old.DigestAlgorithms,
                old.EncapContentInfo,
                certs,
                crls,
                old.SignerInfos);

            //
            // replace the contentInfo with the new one
            //
            cms.contentInfo = new ContentInfo(cms.contentInfo.ContentType, cms.signedData);

            return(cms);
        }
コード例 #9
0
 /**
  * base constructor - with encapsulated content
  */
 public CmsSignedData(
     Stream sigData)
     : this(CmsUtilities.ReadContentInfo(sigData))
 {
 }