示例#1
0
 internal virtual DerSet CreateDerSet(
     DefiniteLengthInputStream dIn)
 {
     return(DerSet.FromVector(BuildDerEncodableVector(dIn), false));
 }
        /**
        * 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);
        }
		/**
		* Return a signer information object with the passed in unsigned
		* attributes replacing the ones that are current associated with
		* the object passed in.
		*
		* @param signerInformation the signerInfo to be used as the basis.
		* @param unsignedAttributes the unsigned attributes to add.
		* @return a copy of the original SignerInformationObject with the changed attributes.
		*/
		public static SignerInformation ReplaceUnsignedAttributes(
			SignerInformation		signerInformation,
			Asn1.Cms.AttributeTable	unsignedAttributes)
		{
			SignerInfo sInfo = signerInformation.info;
			Asn1Set unsignedAttr = null;

			if (unsignedAttributes != null)
			{
				unsignedAttr = new DerSet(unsignedAttributes.ToAsn1EncodableVector());
			}

			return new SignerInformation(
				new SignerInfo(
					sInfo.SignerID,
					sInfo.DigestAlgorithm,
					sInfo.AuthenticatedAttributes,
					sInfo.DigestEncryptionAlgorithm,
					sInfo.EncryptedDigest,
					unsignedAttr),
				signerInformation.contentType,
				signerInformation.content,
				null);
		}
示例#4
0
		/**
		* Replace the signerinformation store associated with this
		* CmsSignedData object 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.
		*
		* @param signedData the signed data object to be used as a base.
		* @param signerInformationStore the new signer information store to use.
		* @return a new signed data object.
		*/
		public static CmsSignedData ReplaceSigners(
			CmsSignedData           signedData,
			SignerInformationStore  signerInformationStore)
		{
			//
			// copy
			//
			CmsSignedData cms = new CmsSignedData(signedData);

			//
			// replace the store
			//
			cms.signerInfoStore = signerInformationStore;

			//
			// replace the signers in the SignedData object
			//
			Asn1EncodableVector digestAlgs = new Asn1EncodableVector();
			Asn1EncodableVector vec = new Asn1EncodableVector();

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

			Asn1Set digests = new DerSet(digestAlgs);
			Asn1Set signers = new DerSet(vec);
			Asn1Sequence sD = (Asn1Sequence)signedData.signedData.ToAsn1Object();

			//
			// signers are the last item in the sequence.
			//
			vec = new Asn1EncodableVector(
				sD[0], // version
				digests);

			for (int i = 2; i != sD.Count - 1; i++)
			{
				vec.Add(sD[i]);
			}

			vec.Add(signers);

			cms.signedData = SignedData.GetInstance(new BerSequence(vec));

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

			return cms;
		}