public TimeStampToken( CmsSignedData signedData) { this.tsToken = signedData; if (!this.tsToken.SignedContentTypeOid.Equals(PkcsObjectIdentifiers.IdCTTstInfo.Id)) { throw new TspValidationException("ContentInfo object not for a time stamp."); } ICollection signers = tsToken.GetSignerInfos().GetSigners(); if (signers.Count != 1) { throw new ArgumentException("Time-stamp token signed by " + signers.Count + " signers, but it must contain just the TSA signature."); } IEnumerator signerEnum = signers.GetEnumerator(); signerEnum.MoveNext(); tsaSignerInfo = (SignerInformation) signerEnum.Current; try { CmsProcessable content = tsToken.SignedContent; MemoryStream bOut = new MemoryStream(); content.Write(bOut); this.tstInfo = new TimeStampTokenInfo( TstInfo.GetInstance( Asn1Object.FromByteArray(bOut.ToArray()))); Asn1.Cms.Attribute attr = tsaSignerInfo.SignedAttributes[ PkcsObjectIdentifiers.IdAASigningCertificate]; if (attr == null) { throw new TspValidationException( "no signing certificate attribute found, time stamp invalid."); } SigningCertificate signCert = SigningCertificate.GetInstance( attr.AttrValues[0]); this.certID = EssCertID.GetInstance(signCert.GetCerts()[0]); } catch (CmsException e) { throw new TspException(e.Message, e.InnerException); } }
private static X509Certificate GetCertificate(SignerInformation signer, IX509Store cmsCertificates) { X509Certificate cert = null; // Create a selector with the information necessary to // find the signer certificate X509CertStoreSelector sel = new X509CertStoreSelector(); sel.Issuer = signer.SignerID.Issuer; sel.SerialNumber = signer.SignerID.SerialNumber; // Try find a match IList certificatesFound = new ArrayList( cmsCertificates.GetMatches(sel) ); if (certificatesFound.Count > 0) // Match found { // Load certificate from CMS Console.WriteLine("Loading signer's certificate from CMS..."); cert = (X509Certificate)certificatesFound[0]; } else { // Load certificate from file Console.WriteLine("Loading signer's certificate from file..."); ReadCertificate("..\\..\\example.cer"); } return cert; }
/// <exception cref="System.IO.IOException"></exception> protected internal override SignerInformation ExtendCMSSignature(CmsSignedData signedData , SignerInformation si, SignatureParameters parameters, Document originalData) { if (this.signatureTsa == null) { throw new ConfigurationException(ConfigurationException.MSG.CONFIGURE_TSP_SERVER); } LOG.Info("Extend signature with id " + si.SignerID); BcCms.AttributeTable unsigned = si.UnsignedAttributes; //IDictionary<DerObjectIdentifier, Attribute> unsignedAttrHash = null; IDictionary unsignedAttrHash = null; if (unsigned == null) { unsignedAttrHash = new Dictionary<DerObjectIdentifier, Attribute>(); } else { unsignedAttrHash = si.UnsignedAttributes.ToDictionary(); } //TODO jbonilla - ¿Qué ocurre si ya es CAdES-T? No se debería volver a extender. Attribute signatureTimeStamp = GetTimeStampAttribute(PkcsObjectIdentifiers.IdAASignatureTimeStampToken , this.signatureTsa, digestAlgorithm, si.GetSignature()); //unsignedAttrHash.Put(PkcsObjectIdentifiers.IdAASignatureTimeStampToken, signatureTimeStamp); unsignedAttrHash.Add(PkcsObjectIdentifiers.IdAASignatureTimeStampToken, signatureTimeStamp); SignerInformation newsi = SignerInformation.ReplaceUnsignedAttributes(si, new BcCms.AttributeTable (unsignedAttrHash)); return newsi; }
private readonly IDictionary table = Platform.CreateHashtable(); // Hashtable[SignerID, ArrayList[SignerInformation]] /** * Create a store containing a single SignerInformation object. * * @param signerInfo the signer information to contain. */ public SignerInformationStore( SignerInformation signerInfo) { this.all = Platform.CreateArrayList(1); this.all.Add(signerInfo); SignerID sid = signerInfo.SignerID; table[sid] = all; }
/// <exception cref="System.IO.IOException"></exception> protected internal override SignerInformation ExtendCMSSignature(CmsSignedData cmsSignedData , SignerInformation si, SignatureParameters parameters, Document originalDocument ) { si = base.ExtendCMSSignature(cmsSignedData, si, parameters, originalDocument); CAdESSignature signature = new CAdESSignature(cmsSignedData, si); //IDictionary<DerObjectIdentifier, Attribute> unsignedAttrHash = si.UnsignedAttributes.ToDictionary(); IDictionary unsignedAttrHash = si.UnsignedAttributes.ToDictionary(); Attribute archiveTimeStamp = GetTimeStampAttribute(CAdESProfileA.id_aa_ets_archiveTimestampV2 , GetSignatureTsa(), digestAlgorithm, signature.GetArchiveTimestampData(0, originalDocument )); //unsignedAttrHash.Put(CAdESProfileA.id_aa_ets_archiveTimestampV2, archiveTimeStamp); unsignedAttrHash.Add(CAdESProfileA.id_aa_ets_archiveTimestampV2, archiveTimeStamp); SignerInformation newsi = SignerInformation.ReplaceUnsignedAttributes(si, new AttributeTable (unsignedAttrHash)); return newsi; }
/** * Fetches the signature time-stamp attributes from a SignerInformation object. * Checks that the MessageImprint for each time-stamp matches the signature field. * (see RFC 3161 Appendix A). * * @param signerInfo a SignerInformation to search for time-stamps * @return a collection of TimeStampToken objects * @throws TSPValidationException */ public static ICollection GetSignatureTimestamps( SignerInformation signerInfo) { IList timestamps = Platform.CreateArrayList(); Asn1.Cms.AttributeTable unsignedAttrs = signerInfo.UnsignedAttributes; if (unsignedAttrs != null) { foreach (Asn1.Cms.Attribute tsAttr in unsignedAttrs.GetAll( PkcsObjectIdentifiers.IdAASignatureTimeStampToken)) { foreach (Asn1Encodable asn1 in tsAttr.AttrValues) { try { Asn1.Cms.ContentInfo contentInfo = Asn1.Cms.ContentInfo.GetInstance( asn1.ToAsn1Object()); TimeStampToken timeStampToken = new TimeStampToken(contentInfo); TimeStampTokenInfo tstInfo = timeStampToken.TimeStampInfo; byte[] expectedDigest = DigestUtilities.CalculateDigest( GetDigestAlgName(tstInfo.MessageImprintAlgOid), signerInfo.GetSignature()); if (!Arrays.ConstantTimeAreEqual(expectedDigest, tstInfo.GetMessageImprintDigest())) throw new TspValidationException("Incorrect digest in message imprint"); timestamps.Add(timeStampToken); } catch (SecurityUtilityException) { throw new TspValidationException("Unknown hash algorithm specified in timestamp"); } catch (Exception) { throw new TspValidationException("Timestamp could not be parsed"); } } } } return timestamps; }
/** * 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)); }
/** * 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); }
/** * 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); }
internal override void AddSignerCallback( SignerInformation si) { // For precalculated signers, just need to register the algorithm, not configure a digest RegisterDigestOid(si.DigestAlgOid); }
/// <exception cref="System.IO.IOException"></exception> protected internal override SignerInformation ExtendCMSSignature(CmsSignedData signedData , SignerInformation si, SignatureParameters parameters, Document originalData) { si = base.ExtendCMSSignature(signedData, si, parameters, originalData); //IDictionary<DerObjectIdentifier, Asn1Encodable> unsignedAttrs = si.UnsignedAttributes.ToDictionary(); IDictionary unsignedAttrs = si.UnsignedAttributes.ToDictionary(); CAdESSignature signature = new CAdESSignature(signedData, si.SignerID); DateTime signingTime = signature.GetSigningTime().Value; if (signingTime == null) { signingTime = parameters.SigningDate; } if (signingTime == null) { signingTime = DateTime.Now; } unsignedAttrs = ExtendUnsignedAttributes(unsignedAttrs, signature.GetSigningCertificate (), signingTime, signature.GetCertificateSource()); SignerInformation newsi = SignerInformation.ReplaceUnsignedAttributes(si, new BcCms.AttributeTable (unsignedAttrs)); return newsi; }
/// <exception cref="System.IO.IOException"></exception> protected internal abstract SignerInformation ExtendCMSSignature(CmsSignedData signedData , SignerInformation si, SignatureParameters parameters, Document originalData);
/** * 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 CmsSignedData Generate( // FIXME Avoid accessing more than once to support CmsProcessableInputStream ICmsTypedData content, bool encapsulate) { // TODO // if (signerInfs.isEmpty()) // { // /* RFC 3852 5.2 // * "In the degenerate case where there are no signers, the // * EncapsulatedContentInfo value being "signed" is irrelevant. In this // * case, the content type within the EncapsulatedContentInfo value being // * "signed" MUST be id-data (as defined in section 4), and the content // * field of the EncapsulatedContentInfo value MUST be omitted." // */ // if (encapsulate) // { // throw new IllegalArgumentException("no signers, encapsulate must be false"); // } // if (!DATA.equals(eContentType)) // { // throw new IllegalArgumentException("no signers, eContentType must be id-data"); // } // } // // if (!DATA.equals(eContentType)) // { // /* RFC 3852 5.3 // * [The 'signedAttrs']... // * field is optional, but it MUST be present if the content type of // * the EncapsulatedContentInfo value being signed is not id-data. // */ // // TODO signedAttrs must be present for all signers // } Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); Asn1EncodableVector signerInfos = new Asn1EncodableVector(); _digests.Clear(); // clear the current preserved digest state // // add the precalculated SignerInfo objects. // for (IEnumerator it = _signers.GetEnumerator(); it.MoveNext();) { SignerInformation signer = (SignerInformation)it.Current; digestAlgs.Add(CmsUtilities.fixAlgID(signer.DigestAlgorithmID)); // TODO Verify the content type and calculated digest match the precalculated SignerInfo signerInfos.Add(signer.ToAsn1Structure()); } // // add the SignerInfo objects // DerObjectIdentifier contentTypeOID = content.ContentType; Asn1OctetString octs = null; if (content.GetContent() != null) { MemoryOutputStream bOut = null; if (encapsulate) { bOut = new MemoryOutputStream(); } Stream cOut = CmsUtilities.attachSignersToOutputStream(_signerGens, bOut); // Just in case it's unencapsulated and there are no signers! cOut = CmsUtilities.getSafeOutputStream(cOut); try { content.Write(cOut); cOut.Close(); } catch (IOException e) { throw new CmsException("data processing exception: " + e.Message, e); } if (encapsulate) { octs = new BerOctetString(bOut.ToArray()); } } for (IEnumerator it = _signerGens.GetEnumerator(); it.MoveNext();) { SignerInfoGenerator sGen = (SignerInfoGenerator)it.Current; SignerInfo inf = sGen.Generate(contentTypeOID); digestAlgs.Add(inf.DigestAlgorithm); signerInfos.Add(inf); byte[] calcDigest = sGen.getCalculatedDigest(); if (calcDigest != null) { _digests.Add(inf.DigestAlgorithm.Algorithm.Id, calcDigest); } } Asn1Set certificates = null; if (_certs.Count != 0) { certificates = CmsUtilities.CreateBerSetFromList(_certs); } Asn1Set certrevlist = null; if (_crls.Count != 0) { certrevlist = CmsUtilities.CreateBerSetFromList(_crls); } ContentInfo encInfo = new ContentInfo(contentTypeOID, octs); SignedData sd = new SignedData( new DerSet(digestAlgs), encInfo, certificates, certrevlist, new DerSet(signerInfos)); ContentInfo contentInfo = new ContentInfo( CmsObjectIdentifiers.SignedData, sd); return(new CmsSignedData(content, contentInfo)); }
public CmsSignedData Generate(string signedContentType, CmsProcessable content, bool encapsulate) { //IL_0113: Expected O, but got Unknown //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01c6: Expected O, but got Unknown Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(); Asn1EncodableVector asn1EncodableVector2 = new Asn1EncodableVector(); _digests.Clear(); global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)_signers).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(); } } DerObjectIdentifier contentType = ((signedContentType == null) ? null : new DerObjectIdentifier(signedContentType)); enumerator = ((global::System.Collections.IEnumerable)signerInfs).GetEnumerator(); try { while (enumerator.MoveNext()) { SignerInf signerInf = (SignerInf)enumerator.get_Current(); try { asn1EncodableVector.Add(signerInf.DigestAlgorithmID); asn1EncodableVector2.Add(signerInf.ToSignerInfo(contentType, content, rand)); } catch (IOException val) { IOException e = val; throw new CmsException("encoding error.", (global::System.Exception)(object) e); } catch (InvalidKeyException e2) { throw new CmsException("key inappropriate for signature.", e2); } catch (SignatureException e3) { throw new CmsException("error creating signature.", e3); } catch (CertificateEncodingException e4) { throw new CmsException("error creating sid.", e4); } } } finally { global::System.IDisposable disposable2 = enumerator as global::System.IDisposable; if (disposable2 != null) { disposable2.Dispose(); } } Asn1Set certificates = null; if (((global::System.Collections.ICollection)_certs).get_Count() != 0) { certificates = CmsUtilities.CreateBerSetFromList(_certs); } Asn1Set crls = null; if (((global::System.Collections.ICollection)_crls).get_Count() != 0) { crls = CmsUtilities.CreateBerSetFromList(_crls); } Asn1OctetString content2 = null; if (encapsulate) { MemoryStream val2 = new MemoryStream(); if (content != null) { try { content.Write((Stream)(object)val2); } catch (IOException val3) { IOException e5 = val3; throw new CmsException("encapsulation error.", (global::System.Exception)(object) e5); } } content2 = new BerOctetString(val2.ToArray()); } ContentInfo contentInfo = new ContentInfo(contentType, content2); SignedData content3 = new SignedData(new DerSet(asn1EncodableVector), contentInfo, certificates, crls, new DerSet(asn1EncodableVector2)); ContentInfo sigData = new ContentInfo(CmsObjectIdentifiers.SignedData, content3); return(new CmsSignedData(content, sigData)); }
internal override void AddSignerCallback(SignerInformation si) { this.RegisterDigestOid(si.DigestAlgorithmID.ObjectID.Id); }
internal SecureMimeDigitalSignature (SignerInformation signerInfo) { SignerInfo = signerInfo; }
/** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. * * @param signer the signer to be countersigned * @param sigProvider the provider to be used for counter signing. * @return a store containing the signers. */ public SignerInformationStore GenerateCounterSigners( SignerInformation signer) { return this.Generate(null, new CmsProcessableByteArray(signer.GetSignature()), false).GetSignerInfos(); }
internal virtual void AddSignerCallback( SignerInformation si) { }
private void DoClose() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) Platform.Dispose(_out); _eiGen.Close(); outer._digests.Clear(); if (((global::System.Collections.ICollection)outer._certs).get_Count() > 0) { Asn1Set obj = CmsUtilities.CreateBerSetFromList(outer._certs); WriteToGenerator(_sigGen, new BerTaggedObject(explicitly: false, 0, obj)); } if (((global::System.Collections.ICollection)outer._crls).get_Count() > 0) { Asn1Set obj2 = CmsUtilities.CreateBerSetFromList(outer._crls); WriteToGenerator(_sigGen, new BerTaggedObject(explicitly: false, 1, obj2)); } IDictionaryEnumerator enumerator = outer._messageDigests.GetEnumerator(); try { while (((global::System.Collections.IEnumerator)enumerator).MoveNext()) { DictionaryEntry val = (DictionaryEntry)((global::System.Collections.IEnumerator)enumerator).get_Current(); outer._messageHashes.Add(((DictionaryEntry)(ref val)).get_Key(), (object)DigestUtilities.DoFinal((IDigest)((DictionaryEntry)(ref val)).get_Value())); } } finally { (enumerator as global::System.IDisposable)?.Dispose(); } Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(); global::System.Collections.IEnumerator enumerator2 = ((global::System.Collections.IEnumerable)outer._signerInfs).GetEnumerator(); try { while (enumerator2.MoveNext()) { DigestAndSignerInfoGeneratorHolder digestAndSignerInfoGeneratorHolder = (DigestAndSignerInfoGeneratorHolder)enumerator2.get_Current(); AlgorithmIdentifier digestAlgorithm = digestAndSignerInfoGeneratorHolder.DigestAlgorithm; byte[] array = (byte[])outer._messageHashes.get_Item((object)Helper.GetDigestAlgName(digestAndSignerInfoGeneratorHolder.digestOID)); outer._digests.set_Item((object)digestAndSignerInfoGeneratorHolder.digestOID, ((global::System.Array)array).Clone()); asn1EncodableVector.Add(digestAndSignerInfoGeneratorHolder.signerInf.Generate(_contentOID, digestAlgorithm, array)); } } finally { global::System.IDisposable disposable = enumerator2 as global::System.IDisposable; if (disposable != null) { disposable.Dispose(); } } enumerator2 = ((global::System.Collections.IEnumerable)outer._signers).GetEnumerator(); try { while (enumerator2.MoveNext()) { SignerInformation signerInformation = (SignerInformation)enumerator2.get_Current(); asn1EncodableVector.Add(signerInformation.ToSignerInfo()); } } finally { global::System.IDisposable disposable2 = enumerator2 as global::System.IDisposable; if (disposable2 != null) { disposable2.Dispose(); } } WriteToGenerator(_sigGen, new DerSet(asn1EncodableVector)); _sigGen.Close(); _sGen.Close(); }
/** * generate a set of one or more SignerInformation objects representing counter signatures on * the passed in SignerInformation object. * * @param signer the signer to be countersigned * @param sigProvider the provider to be used for counter signing. * @return a store containing the signers. */ public SignerInformationStore GenerateCounterSigners( SignerInformation signer) { return(this.Generate(null, new CmsProcessableByteArray(signer.GetSignature()), false).GetSignerInfos()); }
internal override void AddSignerCallback( SignerInformation si) { // FIXME If there were parameters in si.DigestAlgorithmID.Parameters, they are lost // NB: Would need to call FixAlgID on the DigestAlgorithmID // For precalculated signers, just need to register the algorithm, not configure a digest RegisterDigestOid(si.DigestAlgorithmID.ObjectID.Id); }
/// <exception cref="System.IO.IOException"></exception> protected internal override SignerInformation ExtendCMSSignature(CmsSignedData signedData , SignerInformation si, SignatureParameters parameters, Document originalData) { si = base.ExtendCMSSignature(signedData, si, parameters, originalData); DerObjectIdentifier attributeId = null; ByteArrayOutputStream toTimestamp = new ByteArrayOutputStream(); switch (GetExtendedValidationType()) { case 1: { attributeId = PkcsObjectIdentifiers.IdAAEtsEscTimeStamp; toTimestamp.Write(si.GetSignature()); // We don't include the outer SEQUENCE, only the attrType and attrValues as stated by the TS §6.3.5, // NOTE 2) toTimestamp.Write(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAASignatureTimeStampToken] .AttrType.GetDerEncoded()); toTimestamp.Write(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAASignatureTimeStampToken] .AttrValues.GetDerEncoded()); break; } case 2: { attributeId = PkcsObjectIdentifiers.IdAAEtsCertCrlTimestamp; break; } default: { throw new InvalidOperationException("CAdES-X Profile: Extended validation is set but no valid type (1 or 2)" ); } } toTimestamp.Write(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsCertificateRefs] .AttrType.GetDerEncoded()); toTimestamp.Write(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsCertificateRefs] .AttrValues.GetDerEncoded()); toTimestamp.Write(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsRevocationRefs] .AttrType.GetDerEncoded()); toTimestamp.Write(si.UnsignedAttributes[PkcsObjectIdentifiers.IdAAEtsRevocationRefs] .AttrValues.GetDerEncoded()); //IDictionary<DerObjectIdentifier, Attribute> unsignedAttrHash = si.UnsignedAttributes.ToDictionary(); IDictionary unsignedAttrHash = si.UnsignedAttributes.ToDictionary(); BcCms.Attribute extendedTimeStamp = GetTimeStampAttribute(attributeId, GetSignatureTsa( ), digestAlgorithm, toTimestamp.ToByteArray()); //unsignedAttrHash.Put(attributeId, extendedTimeStamp); unsignedAttrHash.Add(attributeId, extendedTimeStamp); return SignerInformation.ReplaceUnsignedAttributes(si, new BcCms.AttributeTable(unsignedAttrHash )); }