/// <exception cref="System.IO.IOException"></exception> public virtual Document ExtendSignatures(Document document, Document originalData , SignatureParameters parameters) { try { CmsSignedData signedData = new CmsSignedData(document.OpenStream()); SignerInformationStore signerStore = signedData.GetSignerInfos(); AList<SignerInformation> siArray = new AList<SignerInformation>(); foreach (SignerInformation si in signerStore.GetSigners()) { try { //jbonilla - Hack para evitar errores cuando una firma ya ha sido extendida. //Se asume que sólo se extiende las firmas desde BES. //TODO jbonilla - Se debería validar hasta qué punto se extendió (BES, T, C, X, XL). if(si.UnsignedAttributes.Count == 0) { siArray.AddItem(ExtendCMSSignature(signedData, si, parameters, originalData)); } else { LOG.Error("Already extended?"); siArray.AddItem(si); } } catch (IOException) { LOG.Error("Exception when extending signature"); siArray.AddItem(si); } } SignerInformationStore newSignerStore = new SignerInformationStore(siArray); CmsSignedData extended = CmsSignedData.ReplaceSigners(signedData, newSignerStore); return new InMemoryDocument(extended.GetEncoded()); } catch (CmsException) { throw new IOException("Cannot parse CMS data"); } }
/// <exception cref="System.IO.IOException"></exception> public virtual Document ExtendSignature(object signatureId, Document document, Document originalData, SignatureParameters parameters) { SignerID toExtendId = (SignerID)signatureId; try { CmsSignedData signedData = new CmsSignedData(document.OpenStream()); SignerInformationStore signerStore = signedData.GetSignerInfos(); AList<SignerInformation> siArray = new AList<SignerInformation>(); //Iterator<object> infos = signerStore.GetSigners().Iterator(); IEnumerator infos = signerStore.GetSigners().GetEnumerator(); while (infos.MoveNext()) { SignerInformation si = (SignerInformation)infos.Current; if (si.SignerID.Equals(toExtendId)) { try { siArray.AddItem(ExtendCMSSignature(signedData, si, parameters, originalData)); } catch (IOException) { LOG.Error("Exception when extending signature"); siArray.AddItem(si); } } } SignerInformationStore newSignerStore = new SignerInformationStore(siArray); CmsSignedData extended = CmsSignedData.ReplaceSigners(signedData, newSignerStore); return new InMemoryDocument(extended.GetEncoded()); } catch (CmsException) { throw new IOException("Cannot parse CMS data"); } }
/// <param name="signedData"></param> /// <returns></returns> public virtual CmsSignedData ExtendCMSSignedData(CmsSignedData signedData, Document originalData, SignatureParameters parameters) { SignerInformationStore signerStore = signedData.GetSignerInfos(); AList<SignerInformation> siArray = new AList<SignerInformation>(); //Iterator<SignerInformation> infos = signerStore.GetSigners().Iterator(); IEnumerator infos = signerStore.GetSigners().GetEnumerator(); while (infos.MoveNext()) { SignerInformation si = (SignerInformation)infos.Current; try { siArray.AddItem(ExtendCMSSignature(signedData, si, parameters, originalData)); } catch (IOException) { LOG.Error("Exception when extending signature"); siArray.AddItem(si); } } SignerInformationStore newSignerStore = new SignerInformationStore(siArray); return CmsSignedData.ReplaceSigners(signedData, newSignerStore); }
/** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore GetSignerInfos() { if (signerInfoStore == null) { IList signerInfos = Platform.CreateArrayList(); Asn1Set s = signedData.SignerInfos; foreach (object obj in s) { SignerInfo info = SignerInfo.GetInstance(obj); DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType; if (hashes == null) { signerInfos.Add(new SignerInformation(info, contentType, signedContent, null)); } else { byte[] hash = (byte[])hashes[info.DigestAlgorithm.ObjectID.Id]; signerInfos.Add(new SignerInformation(info, contentType, null, new BaseDigestCalculator(hash))); } } signerInfoStore = new SignerInformationStore(signerInfos); } return(signerInfoStore); }
/// <summary> /// Return the collection of signers that are associated with the signatures for the message. /// </summary> /// <returns>A (possibly empty) collection of signers.</returns> public SignerInformationStore GetSignerInfos() { if (signerInfoStore == null) { IList <SignerInformation> signerInfos = new List <SignerInformation>(); Asn1Set s = signedData.SignerInfos; foreach (object obj in s) { SignerInfo info = SignerInfo.GetInstance(obj); DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType; if (hashes == null) { signerInfos.Add(new SignerInformation(info, contentType, signedContent, null)); } else { byte[] hash = (byte[])hashes[info.DigestAlgorithm.Algorithm]; signerInfos.Add(new SignerInformation(info, contentType, null, hash)); } } signerInfoStore = new SignerInformationStore(signerInfos); } return(signerInfoStore); }
/** * 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) { // NB: SecureRandom would be ignored since using existing signatures only CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); CmsSignedDataParser parser = new CmsSignedDataParser(original); // gen.AddDigests(parser.DigestOids); gen.AddSigners(signerInformationStore); 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")); // gen.AddSigners(parser.GetSignerInfos()); contentOut.Close(); return(outStr); }
public SignerInformationStore GetSignerInfos() { if (this._signerInfoStore == null) { this.PopulateCertCrlSets(); IList list = Platform.CreateArrayList(); IDictionary dictionary = Platform.CreateHashtable(); foreach (object current in this._digests.Keys) { dictionary[current] = DigestUtilities.DoFinal((IDigest)this._digests[current]); } try { Asn1SetParser signerInfos = this._signedData.GetSignerInfos(); IAsn1Convertible asn1Convertible; while ((asn1Convertible = signerInfos.ReadObject()) != null) { SignerInfo instance = SignerInfo.GetInstance(asn1Convertible.ToAsn1Object()); string digestAlgName = CmsSignedDataParser.Helper.GetDigestAlgName(instance.DigestAlgorithm.ObjectID.Id); byte[] digest = (byte[])dictionary[digestAlgName]; list.Add(new SignerInformation(instance, this._signedContentType, null, new BaseDigestCalculator(digest))); } } catch (IOException ex) { throw new CmsException("io exception: " + ex.Message, ex); } this._signerInfoStore = new SignerInformationStore(list); } return(this._signerInfoStore); }
private CmsSignedData(CmsSignedData c) { signedData = c.signedData; contentInfo = c.contentInfo; signedContent = c.signedContent; signerInfoStore = c.signerInfoStore; }
private CmsSignedData(CmsSignedData c) { this.signedData = c.signedData; this.contentInfo = c.contentInfo; this.signedContent = c.signedContent; this.signerInfoStore = c.signerInfoStore; }
/** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void AddSigners( SignerInformationStore signerStore) { foreach (object o in signerStore.GetSigners()) { _signers.Add(o); } }
/** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void AddSigners( SignerInformationStore signerStore) { foreach (SignerInformation o in signerStore.GetAll()) { _signers.Add(o); } }
private CmsSignedData( CmsSignedData c) { this.signedData = c.signedData; this.contentInfo = c.contentInfo; this.signedContent = c.signedContent; this.signerInfoStore = c.signerInfoStore; }
public void AddSigners(SignerInformationStore signerStore) { foreach (SignerInformation signerInformation in signerStore.GetSigners()) { this._signers.Add(signerInformation); this.AddSignerCallback(signerInformation); } }
/** * Add a store of precalculated signers to the generator. * * @param signerStore store of signers */ public void AddSigners( SignerInformationStore signerStore) { foreach (SignerInformation o in signerStore.GetSigners()) { _signers.Add(o); AddSignerCallback(o); } }
/** * 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); }
public SignerInformationStore GetSignerInfos() { //IL_00e9: Expected O, but got Unknown if (_signerInfoStore == null) { PopulateCertCrlSets(); global::System.Collections.IList list = Platform.CreateArrayList(); IDictionary val = Platform.CreateHashtable(); { global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)_digests.get_Keys()).GetEnumerator(); try { while (enumerator.MoveNext()) { object current = enumerator.get_Current(); val.set_Item(current, (object)DigestUtilities.DoFinal((IDigest)_digests.get_Item(current))); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } } try { Asn1SetParser signerInfos = _signedData.GetSignerInfos(); IAsn1Convertible asn1Convertible; while ((asn1Convertible = signerInfos.ReadObject()) != null) { SignerInfo instance = SignerInfo.GetInstance(asn1Convertible.ToAsn1Object()); string digestAlgName = Helper.GetDigestAlgName(instance.DigestAlgorithm.Algorithm.Id); byte[] digest = (byte[])val.get_Item((object)digestAlgName); list.Add((object)new SignerInformation(instance, _signedContentType, null, new BaseDigestCalculator(digest))); } } catch (IOException val2) { IOException val3 = val2; throw new CmsException("io exception: " + ((global::System.Exception)(object) val3).get_Message(), (global::System.Exception)(object) val3); } _signerInfoStore = new SignerInformationStore((global::System.Collections.ICollection)list); } return(_signerInfoStore); }
/** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore GetSignerInfos() { if (signerInfoStore == null) { IList signerInfos = new ArrayList(); Asn1Set s = signedData.SignerInfos; foreach (object obj in s) { signerInfos.Add(new SignerInformation(SignerInfo.GetInstance(obj), signedData.EncapContentInfo.ContentType, signedContent, null)); } signerInfoStore = new SignerInformationStore(signerInfos); } return(signerInfoStore); }
/** * return the collection of signers that are associated with the * signatures for the message. * @throws CmsException */ public SignerInformationStore GetSignerInfos() { if (_signerInfoStore == null) { IList signerInfos = new ArrayList(); IDictionary hashes = new Hashtable(); foreach (object digestKey in _digests.Keys) { hashes[digestKey] = DigestUtilities.DoFinal( (IDigest)_digests[digestKey]); } try { Asn1SetParser s = _signedData.GetSignerInfos(); IAsn1Convertible o; while ((o = s.ReadObject()) != null) { SignerInfo info = SignerInfo.GetInstance(o.ToAsn1Object()); string digestName = Helper.GetDigestAlgName( info.DigestAlgorithm.ObjectID.Id); byte[] hash = (byte[])hashes[digestName]; signerInfos.Add( new SignerInformation( info, new DerObjectIdentifier(_signedContent.ContentType), null, hash)); } } catch (IOException e) { throw new CmsException("io exception: " + e.Message, e); } _signerInfoStore = new SignerInformationStore(signerInfos); } return(_signerInfoStore); }
public static CmsSignedData ReplaceSigners(CmsSignedData signedData, SignerInformationStore signerInformationStore) { CmsSignedData cmsSignedData = new CmsSignedData(signedData); cmsSignedData.signerInfoStore = signerInformationStore; Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new Asn1Encodable[0]); Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(new Asn1Encodable[0]); foreach (SignerInformation signerInformation in signerInformationStore.GetSigners()) { asn1EncodableVector.Add(new Asn1Encodable[] { CmsSignedData.Helper.FixAlgID(signerInformation.DigestAlgorithmID) }); asn1EncodableVector2.Add(new Asn1Encodable[] { signerInformation.ToSignerInfo() }); } Asn1Set asn1Set = new DerSet(asn1EncodableVector); Asn1Set asn1Set2 = new DerSet(asn1EncodableVector2); Asn1Sequence asn1Sequence = (Asn1Sequence)signedData.signedData.ToAsn1Object(); asn1EncodableVector2 = new Asn1EncodableVector(new Asn1Encodable[] { asn1Sequence[0], asn1Set }); for (int num = 2; num != asn1Sequence.Count - 1; num++) { asn1EncodableVector2.Add(new Asn1Encodable[] { asn1Sequence[num] }); } asn1EncodableVector2.Add(new Asn1Encodable[] { asn1Set2 }); cmsSignedData.signedData = SignedData.GetInstance(new BerSequence(asn1EncodableVector2)); cmsSignedData.contentInfo = new ContentInfo(cmsSignedData.contentInfo.ContentType, cmsSignedData.signedData); return(cmsSignedData); }
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); }
/** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation AddCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 SignerInfo sInfo = signerInformation.info; Asn1.Cms.AttributeTable unsignedAttr = signerInformation.UnsignedAttributes; Asn1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.ToAsn1EncodableVector(); } else { v = new Asn1EncodableVector(); } Asn1EncodableVector sigs = new Asn1EncodableVector(); foreach (SignerInformation sigInf in counterSigners.GetSigners()) { sigs.Add(sigInf.ToSignerInfo()); } v.Add(new Asn1.Cms.Attribute(CmsAttributes.CounterSignature, new DerSet(sigs))); return(new SignerInformation( new SignerInfo( sInfo.SignerID, sInfo.DigestAlgorithm, sInfo.AuthenticatedAttributes, sInfo.DigestEncryptionAlgorithm, sInfo.EncryptedDigest, new DerSet(v)), signerInformation.contentType, signerInformation.content, null)); }
public void AddSigners(SignerInformationStore signerStore) { global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)signerStore.GetSigners()).GetEnumerator(); try { while (enumerator.MoveNext()) { SignerInformation signerInformation = (SignerInformation)enumerator.get_Current(); _signers.Add((object)signerInformation); AddSignerCallback(signerInformation); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } }
public static CmsSignedData ReplaceSigners(CmsSignedData signedData, SignerInformationStore signerInformationStore) { CmsSignedData cmsSignedData = new CmsSignedData(signedData); cmsSignedData.signerInfoStore = signerInformationStore; Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(); Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(); global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)signerInformationStore.GetSigners()).GetEnumerator(); try { while (enumerator.MoveNext()) { SignerInformation signerInformation = (SignerInformation)enumerator.get_Current(); asn1EncodableVector.Add(Helper.FixAlgID(signerInformation.DigestAlgorithmID)); asn1EncodableVector2.Add(signerInformation.ToSignerInfo()); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } Asn1Set asn1Set = new DerSet(asn1EncodableVector); Asn1Set asn1Set2 = new DerSet(asn1EncodableVector2); Asn1Sequence asn1Sequence = (Asn1Sequence)signedData.signedData.ToAsn1Object(); asn1EncodableVector2 = new Asn1EncodableVector(asn1Sequence[0], asn1Set); for (int i = 2; i != asn1Sequence.Count - 1; i++) { asn1EncodableVector2.Add(asn1Sequence[i]); } asn1EncodableVector2.Add(asn1Set2); cmsSignedData.signedData = SignedData.GetInstance(new BerSequence(asn1EncodableVector2)); cmsSignedData.contentInfo = new ContentInfo(cmsSignedData.contentInfo.ContentType, cmsSignedData.signedData); return(cmsSignedData); }
public SignerInformationStore GetSignerInfos() { if (signerInfoStore == null) { global::System.Collections.IList list = Platform.CreateArrayList(); Asn1Set signerInfos = signedData.SignerInfos; { global::System.Collections.IEnumerator enumerator = signerInfos.GetEnumerator(); try { while (enumerator.MoveNext()) { object current = enumerator.get_Current(); SignerInfo instance = SignerInfo.GetInstance(current); DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType; if (hashes == null) { list.Add((object)new SignerInformation(instance, contentType, signedContent, null)); continue; } byte[] digest = (byte[])hashes.get_Item((object)instance.DigestAlgorithm.Algorithm.Id); list.Add((object)new SignerInformation(instance, contentType, null, new BaseDigestCalculator(digest))); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } } signerInfoStore = new SignerInformationStore((global::System.Collections.ICollection)list); } return(signerInfoStore); }
public SignerInformationStore GetSignerInfos() { if (this.signerInfoStore == null) { IList list = Platform.CreateArrayList(); Asn1Set signerInfos = this.signedData.SignerInfos; foreach (object current in signerInfos) { SignerInfo instance = SignerInfo.GetInstance(current); DerObjectIdentifier contentType = this.signedData.EncapContentInfo.ContentType; if (this.hashes == null) { list.Add(new SignerInformation(instance, contentType, this.signedContent, null)); } else { byte[] digest = (byte[])this.hashes[instance.DigestAlgorithm.ObjectID.Id]; list.Add(new SignerInformation(instance, contentType, null, new BaseDigestCalculator(digest))); } } this.signerInfoStore = new SignerInformationStore(list); } return(this.signerInfoStore); }
/** * 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) { // NB: SecureRandom would be ignored since using existing signatures only CmsSignedDataStreamGenerator gen = new CmsSignedDataStreamGenerator(); CmsSignedDataParser parser = new CmsSignedDataParser(original); // gen.AddDigests(parser.DigestOids); gen.AddSigners(signerInformationStore); 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")); // gen.AddSigners(parser.GetSignerInfos()); contentOut.Close(); return outStr; }
/** * return the collection of signers that are associated with the * signatures for the message. * @throws CmsException */ public SignerInformationStore GetSignerInfos() { if (_signerInfoStore == null) { PopulateCertCrlSets(); IList signerInfos = Platform.CreateArrayList(); IDictionary hashes = Platform.CreateHashtable(); foreach (object digestKey in _digests.Keys) { hashes[digestKey] = DigestUtilities.DoFinal( (IDigest)_digests[digestKey]); } try { Asn1SetParser s = _signedData.GetSignerInfos(); IAsn1Convertible o; while ((o = s.ReadObject()) != null) { SignerInfo info = SignerInfo.GetInstance(o.ToAsn1Object()); string digestName = Helper.GetDigestAlgName( info.DigestAlgorithm.ObjectID.Id); byte[] hash = (byte[]) hashes[digestName]; signerInfos.Add(new SignerInformation(info, _signedContentType, null, new BaseDigestCalculator(hash))); } } catch (IOException e) { throw new CmsException("io exception: " + e.Message, e); } _signerInfoStore = new SignerInformationStore(signerInfos); } return _signerInfoStore; }
/** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore GetSignerInfos() { if (signerInfoStore == null) { IList signerInfos = new ArrayList(); Asn1Set s = signedData.SignerInfos; foreach (object obj in s) { signerInfos.Add(new SignerInformation(SignerInfo.GetInstance(obj), signedData.EncapContentInfo.ContentType, signedContent, null)); } signerInfoStore = new SignerInformationStore(signerInfos); } return signerInfoStore; }
/** * 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(); { Asn1SetParser set = signedData.GetCertificates(); if (set != null) { Asn1Object setObj = set.ToAsn1Object(); Asn1TaggedObject taggedObj = (set is BerSetParser) ? new BerTaggedObject(false, 0, setObj) : new DerTaggedObject(false, 0, setObj); WriteToGenerator(sigGen, taggedObj); } } { Asn1SetParser set = signedData.GetCrls(); if (set != null) { Asn1Object setObj = set.ToAsn1Object(); Asn1TaggedObject taggedObj = (set is BerSetParser) ? new BerTaggedObject(false, 1, setObj) : new DerTaggedObject(false, 1, setObj); WriteToGenerator(sigGen, taggedObj); } } 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); }
private SignatureSecurityInformation Verify(SignerInformationStore signerInfos, IX509Store certs, SignatureSecurityInformation outer) { trace.TraceEvent(TraceEventType.Information, 0, "Verifying the {0} signature information", outer != null ? "outer" : "inner"); SignatureSecurityInformation result = new SignatureSecurityInformation(); //Check if signed (only allow single signatures) SignerInformation signerInfo = null; IEnumerator iterator = signerInfos.GetSigners().GetEnumerator(); if (!iterator.MoveNext()) { result.securityViolations.Add(SecurityViolation.NotSigned); trace.TraceEvent(TraceEventType.Warning, 0, "Although it is a correct CMS file it isn't signed"); return result; } signerInfo = (SignerInformation)iterator.Current; trace.TraceEvent(TraceEventType.Verbose, 0, "Found signature, with signer ID = issuer {0} and serial number {1}", signerInfo.SignerID.Issuer, signerInfo.SignerID.SerialNumber); if (iterator.MoveNext()) { trace.TraceEvent(TraceEventType.Error, 0, "Found more then one signature, this isn't supported (yet)"); throw new InvalidMessageException("An eHealth compliant message can have only one signer"); } //check if signer used correct digest algorithm int i = 0; bool found = false; StringBuilder algos = new StringBuilder(); while (!found && i < EteeActiveConfig.Unseal.SignatureAlgorithms.Count) { Oid algoDigest = EteeActiveConfig.Unseal.SignatureAlgorithms[i].DigestAlgorithm; Oid algoEnc = EteeActiveConfig.Unseal.SignatureAlgorithms[i++].EncryptionAlgorithm; algos.Append(algoDigest.Value + " (" + algoDigest.FriendlyName + ") + " + algoEnc.Value + " (" + algoEnc.FriendlyName + "), "); found = (algoDigest.Value == signerInfo.DigestAlgOid) && (algoEnc.Value == signerInfo.EncryptionAlgOid); } if (!found) { result.securityViolations.Add(SecurityViolation.NotAllowedSignatureDigestAlgorithm); trace.TraceEvent(TraceEventType.Warning, 0, "The signature digest + encryption algorithm {0} + {1} isn't allowed, only {2} are", signerInfo.DigestAlgOid, signerInfo.EncryptionAlgOid, algos); } trace.TraceEvent(TraceEventType.Verbose, 0, "Verified the signature digest and encryption algorithm"); //Find the singing certificate and relevant info Org.BouncyCastle.X509.X509Certificate signerCert = null; if (certs.GetMatches(null).Count > 0) { //We got certificates, so lets find the signer IEnumerator signerCerts = certs.GetMatches(signerInfo.SignerID).GetEnumerator(); if (!signerCerts.MoveNext()) { //found no certificate result.securityViolations.Add(SecurityViolation.NotFoundSigner); trace.TraceEvent(TraceEventType.Warning, 0, "Could not find the signer certificate"); return result; } //Getting the first certificate signerCert = (Org.BouncyCastle.X509.X509Certificate)signerCerts.Current; trace.TraceEvent(TraceEventType.Verbose, 0, "Found the signer certificate: {0}", signerCert.SubjectDN.ToString()); //Check if the outer certificate matches the inner certificate if (outer != null) { Org.BouncyCastle.X509.X509Certificate authCert = DotNetUtilities.FromX509Certificate(outer.Subject.Certificate); trace.TraceEvent(TraceEventType.Verbose, 0, "Comparing The signer certificate {0} ({1}) with the authentication certificate {2} ({3})", signerCert.SubjectDN, signerCert.IssuerDN, authCert.SubjectDN, authCert.IssuerDN); //_safe_ check if the serial numbers of the subject name are equal and they have the same issuer if (!authCert.SubjectDN.GetOidList().Contains(X509Name.SerialNumber) || !signerCert.SubjectDN.GetOidList().Contains(X509Name.SerialNumber) || authCert.SubjectDN.GetValueList(X509Name.SerialNumber).Count != 1 || signerCert.SubjectDN.GetValueList(X509Name.SerialNumber).Count != 1 || !authCert.SubjectDN.GetValueList(X509Name.SerialNumber)[0].Equals(signerCert.SubjectDN.GetValueList(X509Name.SerialNumber)[0]) || !authCert.IssuerDN.Equals(signerCert.IssuerDN)) { result.securityViolations.Add(SecurityViolation.SubjectDoesNotMachEnvelopingSubject); trace.TraceEvent(TraceEventType.Warning, 0, "The signer certificate {0} ({1}) does not match the authentication certificate {2} ({3})", signerCert.SubjectDN, signerCert.IssuerDN, authCert.SubjectDN, authCert.IssuerDN); } } if (signerCerts.MoveNext()) { //found several certificates... trace.TraceEvent(TraceEventType.Error, 0, "Several certificates correspond to the signer"); throw new NotSupportedException("More then one certificate found that corresponds to the sender information in the message, this isn't supported by the library"); } } else { if (outer == null) { trace.TraceEvent(TraceEventType.Error, 0, "The outer signature does not contain any certificates"); throw new InvalidMessageException("The outer signature is missing certifcates"); } //The subject is the same as the outer result.Subject = outer.Subject; signerCert = DotNetUtilities.FromX509Certificate(result.Subject.Certificate); trace.TraceEvent(TraceEventType.Verbose, 0, "An already validated certificates was provided: {0}", signerCert.SubjectDN.ToString()); //Additional check, is the authentication certificate also valid for signatures? if (!DotNetUtilities.FromX509Certificate(result.Subject.Certificate).GetKeyUsage()[1]) { result.Subject.securityViolations.Add(CertSecurityViolation.NotValidForUsage); trace.TraceEvent(TraceEventType.Warning, 0, "The key usage did not have the correct usage flag set"); } } //verify the signature itself result.SignatureValue = signerInfo.GetSignature(); if (!signerInfo.Verify(signerCert.GetPublicKey())) { result.securityViolations.Add(SecurityViolation.NotSignatureValid); trace.TraceEvent(TraceEventType.Warning, 0, "The signature value was invalid"); } trace.TraceEvent(TraceEventType.Verbose, 0, "Signature value verification finished"); //Get the signing time bool hasSigningTime = false; DateTime signingTime = DateTime.UtcNow; if (signerInfo != null && signerInfo.SignedAttributes != null) { Org.BouncyCastle.Asn1.Cms.Attribute time = signerInfo.SignedAttributes[CmsAttributes.SigningTime]; if (time != null && time.AttrValues.Count > 0) { hasSigningTime = true; result.SigningTime = Org.BouncyCastle.Asn1.Cms.Time.GetInstance(time.AttrValues[0]).Date; signingTime = result.SigningTime.Value; trace.TraceEvent(TraceEventType.Verbose, 0, "The CMS message contains a signing time: {0}", result.SigningTime); } } //Validating signature info if (this.level == null && result.Subject == null) { if (outer == null) result.Subject = CertVerifier.VerifyAuth(signerCert, signingTime, certs, null, null, false, false); else result.Subject = CertVerifier.VerifySign(signerCert, signingTime, certs, null, null, false, false); return result; } //Get the embedded CRLs and OCSPs IList<CertificateList> crls = new List<CertificateList>(); IList<BasicOcspResponse> ocsps = new List<BasicOcspResponse>(); if (signerInfo != null && signerInfo.UnsignedAttributes != null) { trace.TraceEvent(TraceEventType.Verbose, 0, "The CMS message contains unsigned attributes"); Org.BouncyCastle.Asn1.Cms.Attribute revocationValuesList = signerInfo.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsRevocationValues]; if (revocationValuesList != null && revocationValuesList.AttrValues.Count > 0) { trace.TraceEvent(TraceEventType.Verbose, 0, "The CMS message contains Revocation Values"); RevocationValues revocationValues = RevocationValues.GetInstance(revocationValuesList.AttrValues[0]); if (revocationValues.GetCrlVals() != null) { crls = new List<CertificateList>(revocationValues.GetCrlVals()); trace.TraceEvent(TraceEventType.Verbose, 0, "Found {0} CRL's in the message", crls.Count); } if (revocationValues.GetOcspVals() != null) { ocsps = new List<BasicOcspResponse>(revocationValues.GetOcspVals()); trace.TraceEvent(TraceEventType.Verbose, 0, "Found {0} OCSP's in the message", ocsps.Count); } } } //check for a time-stamp, even if not required DateTime validationTime; TimeStampToken tst = null; bool isSigingTimeValidated; if (signerInfo != null && signerInfo.UnsignedAttributes != null) { trace.TraceEvent(TraceEventType.Verbose, 0, "The CMS message contains unsigned attributes"); Org.BouncyCastle.Asn1.Cms.Attribute tstList = signerInfo.UnsignedAttributes[PkcsObjectIdentifiers.IdAASignatureTimeStampToken]; if (tstList != null && tstList.AttrValues.Count > 0) { trace.TraceEvent(TraceEventType.Verbose, 0, "The CMS message contains the Signature Time Stamp Token: {0}", Convert.ToBase64String(tstList.AttrValues[0].GetEncoded())); tst = tstList.AttrValues[0].GetEncoded().ToTimeStampToken(); } } if (tst == null) { //Retrieve the time-mark if needed by the level only if ((this.level & Level.T_Level) == Level.T_Level) { if (outer == null) { //we are in the outer signature, so we need a time-mark (or time-stamp, but we checked that already) if (timemarkauthority == null) { trace.TraceEvent(TraceEventType.Error, 0, "Not time-mark authority is provided while there is not embedded time-stamp, the level includes T-Level and it isn't an inner signature"); throw new InvalidMessageException("The message does not contain a time-stamp and there is not time-mark authority provided while T-Level is required"); } trace.TraceEvent(TraceEventType.Verbose, 0, "Requesting time-mark for message signed by {0}, signed on {1} and with signature value {2}", signerCert.SubjectDN, signingTime, signerInfo.GetSignature()); validationTime = timemarkauthority.GetTimemark(new X509Certificate2(signerCert.GetEncoded()), signingTime, signerInfo.GetSignature()).ToUniversalTime(); trace.TraceEvent(TraceEventType.Verbose, 0, "The validated time is the return time-mark which is: {0}", validationTime); } else { //we are in the inner signature, we check the signing time against the outer signatures signing time validationTime = outer.SigningTime.Value; trace.TraceEvent(TraceEventType.Verbose, 0, "The validated time is the outer signature singing time which is: {0}", validationTime); } } else { isSigingTimeValidated = false; validationTime = signingTime; trace.TraceEvent(TraceEventType.Verbose, 0, "There is not validated provided, nor is it retrieved because of the level"); } } else { //Check the time-stamp if (!tst.IsMatch(new MemoryStream(signerInfo.GetSignature()))) { trace.TraceEvent(TraceEventType.Warning, 0, "The time-stamp does not match the message"); result.securityViolations.Add(SecurityViolation.InvalidTimestamp); } Timestamp stamp; if ((this.level & Level.A_level) == Level.A_level) { //TODO::follow the chain of A-timestamps until the root (now we assume the signature time-stamp is the root) trace.TraceEvent(TraceEventType.Verbose, 0, "Validating the time-stamp against the current time for arbitration reasons"); stamp = tst.Validate(ref crls, ref ocsps, null); } else { trace.TraceEvent(TraceEventType.Verbose, 0, "Validating the time-stamp against the time-stamp time since no arbitration is needed"); stamp = tst.Validate(ref crls, ref ocsps); } result.TimestampRenewalTime = stamp.RenewalTime; trace.TraceEvent(TraceEventType.Verbose, 0, "The time-stamp must be renewed on {0}", result.TimestampRenewalTime); //we get the time from the time-stamp validationTime = stamp.Time; trace.TraceEvent(TraceEventType.Verbose, 0, "The validated time is the time-stamp time which is on {0}", validationTime); if (!hasSigningTime) { trace.TraceEvent(TraceEventType.Information, 0, "Implicit signing time {0} is replaced with time-stamp time {1}", signingTime, tst.TimeStampInfo.GenTime); signingTime = stamp.Time; } if (stamp.TimestampStatus.Count(x => x.Status != X509ChainStatusFlags.NoError) > 0) { trace.TraceEvent(TraceEventType.Warning, 0, "The time-stamp is invalid with {0} errors, including {1}: {2}", stamp.TimestampStatus.Count, stamp.TimestampStatus[0].Status, stamp.TimestampStatus[0].StatusInformation); isSigingTimeValidated = false; result.securityViolations.Add(SecurityViolation.InvalidTimestamp); } } //lest check if the signing time is in line with the validation time (obtained from time-mark, outer signature or time-stamp) if (validationTime > (signingTime + EteeActiveConfig.ClockSkewness + Settings.Default.TimestampGracePeriod) || validationTime < (signingTime - EteeActiveConfig.ClockSkewness)) { trace.TraceEvent(TraceEventType.Warning, 0, "The validated time {0} is not in line with the signing time {1} with a grace period of {2}", validationTime, signingTime, Settings.Default.TimestampGracePeriod); isSigingTimeValidated = false; result.securityViolations.Add(SecurityViolation.SealingTimeInvalid); } else { trace.TraceEvent(TraceEventType.Verbose, 0, "The validated time {0} is in line with the signing time {1}", validationTime, signingTime); isSigingTimeValidated = true; } //If the subject is already provided, so we don't have to do the next check if (result.Subject != null) return result; //check the status on the available info, for unseal it does not matter if it is B-Level or LT-Level. if (outer == null) result.Subject = CertVerifier.VerifyAuth(signerCert, signingTime, certs, crls, ocsps, true, isSigingTimeValidated); else result.Subject = CertVerifier.VerifySign(signerCert, signingTime, certs, crls, ocsps, true, isSigingTimeValidated); return result; }
// // signerInformation store replacement test. // private void CheckSignerStoreReplacement( CmsSignedData orig, SignerInformationStore signers) { CmsSignedData s = CmsSignedData.ReplaceSigners(orig, signers); IX509Store x509Certs = s.GetCertificates("Collection"); signers = s.GetSignerInfos(); ICollection c = signers.GetSigners(); foreach (SignerInformation signer in c) { ICollection certCollection = x509Certs.GetMatches(signer.SignerID); IEnumerator certEnum = certCollection.GetEnumerator(); certEnum.MoveNext(); X509Certificate cert = (X509Certificate) certEnum.Current; Assert.IsTrue(signer.Verify(cert)); } }
/** * Return a signer information object with passed in SignerInformationStore representing counter * signatures attached as an unsigned attribute. * * @param signerInformation the signerInfo to be used as the basis. * @param counterSigners signer info objects carrying counter signature. * @return a copy of the original SignerInformationObject with the changed attributes. */ public static SignerInformation AddCounterSigners( SignerInformation signerInformation, SignerInformationStore counterSigners) { // TODO Perform checks from RFC 3852 11.4 SignerInfo sInfo = signerInformation.info; Asn1.Cms.AttributeTable unsignedAttr = signerInformation.UnsignedAttributes; Asn1EncodableVector v; if (unsignedAttr != null) { v = unsignedAttr.ToAsn1EncodableVector(); } else { v = new Asn1EncodableVector(); } Asn1EncodableVector sigs = new Asn1EncodableVector(); foreach (SignerInformation sigInf in counterSigners.GetSigners()) { sigs.Add(sigInf.ToSignerInfo()); } v.Add(new Asn1.Cms.Attribute(CmsAttributes.CounterSignature, new DerSet(sigs))); return new SignerInformation( new SignerInfo( sInfo.SignerID, sInfo.DigestAlgorithm, sInfo.AuthenticatedAttributes, sInfo.DigestEncryptionAlgorithm, sInfo.EncryptedDigest, new DerSet(v)), signerInformation.contentType, signerInformation.content, null); }
public static SignerInformation AddCounterSigners(SignerInformation signerInformation, SignerInformationStore counterSigners) { Org.BouncyCastle.Asn1.Cms.SignerInfo signerInfo = signerInformation.info; Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = signerInformation.UnsignedAttributes; Asn1EncodableVector asn1EncodableVector; if (unsignedAttributes != null) { asn1EncodableVector = unsignedAttributes.ToAsn1EncodableVector(); } else { asn1EncodableVector = new Asn1EncodableVector(new Asn1Encodable[0]); } Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(new Asn1Encodable[0]); foreach (SignerInformation signerInformation2 in counterSigners.GetSigners()) { asn1EncodableVector2.Add(new Asn1Encodable[] { signerInformation2.ToSignerInfo() }); } asn1EncodableVector.Add(new Asn1Encodable[] { new Org.BouncyCastle.Asn1.Cms.Attribute(CmsAttributes.CounterSignature, new DerSet(asn1EncodableVector2)) }); return(new SignerInformation(new Org.BouncyCastle.Asn1.Cms.SignerInfo(signerInfo.SignerID, signerInfo.DigestAlgorithm, signerInfo.AuthenticatedAttributes, signerInfo.DigestEncryptionAlgorithm, signerInfo.EncryptedDigest, new DerSet(asn1EncodableVector)), signerInformation.contentType, signerInformation.content, null)); }
public static SignerInformation AddCounterSigners(SignerInformation signerInformation, SignerInformationStore counterSigners) { Org.BouncyCastle.Asn1.Cms.SignerInfo signerInfo = signerInformation.info; Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = signerInformation.UnsignedAttributes; Asn1EncodableVector asn1EncodableVector = ((unsignedAttributes == null) ? new Asn1EncodableVector() : unsignedAttributes.ToAsn1EncodableVector()); Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(); global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)counterSigners.GetSigners()).GetEnumerator(); try { while (enumerator.MoveNext()) { SignerInformation signerInformation2 = (SignerInformation)enumerator.get_Current(); asn1EncodableVector2.Add(signerInformation2.ToSignerInfo()); } } finally { global::System.IDisposable disposable = enumerator as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } asn1EncodableVector.Add(new Attribute(CmsAttributes.CounterSignature, new DerSet(asn1EncodableVector2))); return(new SignerInformation(new Org.BouncyCastle.Asn1.Cms.SignerInfo(signerInfo.SignerID, signerInfo.DigestAlgorithm, signerInfo.AuthenticatedAttributes, signerInfo.DigestEncryptionAlgorithm, signerInfo.EncryptedDigest, new DerSet(asn1EncodableVector)), signerInformation.contentType, signerInformation.content, null)); }
/** * 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; }
/** * 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; }
/** * return the collection of signers that are associated with the * signatures for the message. */ public SignerInformationStore GetSignerInfos() { if (signerInfoStore == null) { IList signerInfos = Platform.CreateArrayList(); Asn1Set s = signedData.SignerInfos; foreach (object obj in s) { SignerInfo info = SignerInfo.GetInstance(obj); DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType; if (hashes == null) { signerInfos.Add(new SignerInformation(info, contentType, signedContent, null)); } else { byte[] hash = (byte[]) hashes[info.DigestAlgorithm.ObjectID.Id]; signerInfos.Add(new SignerInformation(info, contentType, null, new BaseDigestCalculator(hash))); } } signerInfoStore = new SignerInformationStore(signerInfos); } return signerInfoStore; }