<PackageReference Include="BouncyCastle.Cryptography" Version="2.7.0-beta.98" />

TimeStampToken

public class TimeStampToken
using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.Ess; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Tsp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Cms; using Org.BouncyCastle.Security; using Org.BouncyCastle.Security.Certificates; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.X509; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Tsp { public class TimeStampToken { private readonly CmsSignedData m_tsToken; private readonly SignerInformation m_tsaSignerInfo; private readonly TimeStampTokenInfo m_tstInfo; private readonly EssCertIDv2 m_certID; public TimeStampTokenInfo TimeStampInfo => m_tstInfo; public SignerID SignerID => m_tsaSignerInfo.SignerID; public Org.BouncyCastle.Asn1.Cms.AttributeTable SignedAttributes => m_tsaSignerInfo.SignedAttributes; public Org.BouncyCastle.Asn1.Cms.AttributeTable UnsignedAttributes => m_tsaSignerInfo.UnsignedAttributes; public TimeStampToken(Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfo) : this(new CmsSignedData(contentInfo)) { } public TimeStampToken(CmsSignedData signedData) { m_tsToken = signedData; if (!PkcsObjectIdentifiers.IdCTTstInfo.Equals(m_tsToken.SignedContentType)) throw new TspValidationException("ContentInfo object not for a time stamp."); IList<SignerInformation> signers = m_tsToken.GetSignerInfos().GetSigners(); if (signers.Count != 1) throw new ArgumentException("Time-stamp token signed by " + signers.Count.ToString() + " signers, but it must contain just the TSA signature."); m_tsaSignerInfo = signers[0]; try { m_tstInfo = new TimeStampTokenInfo(TstInfo.GetInstance(CmsUtilities.GetByteArray(m_tsToken.SignedContent))); Org.BouncyCastle.Asn1.Cms.Attribute attribute = m_tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate]; if (attribute != null) { SigningCertificate instance = SigningCertificate.GetInstance(attribute.AttrValues[0]); m_certID = EssCertIDv2.From(EssCertID.GetInstance(instance.GetCerts()[0])); } else { Org.BouncyCastle.Asn1.Cms.Attribute attribute2 = m_tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2]; if (attribute2 == null) throw new TspValidationException("no signing certificate attribute found, time stamp invalid."); attribute = attribute2; SigningCertificateV2 instance2 = SigningCertificateV2.GetInstance(attribute.AttrValues[0]); m_certID = EssCertIDv2.GetInstance(instance2.GetCerts()[0]); } } catch (CmsException ex) { throw new TspException(ex.Message, ex.InnerException); } } public IStore<X509V2AttributeCertificate> GetAttributeCertificates() { return m_tsToken.GetAttributeCertificates(); } public IStore<X509Certificate> GetCertificates() { return m_tsToken.GetCertificates(); } public IStore<X509Crl> GetCrls() { return m_tsToken.GetCrls(); } public void Validate(X509Certificate cert) { try { byte[] b = DigestUtilities.CalculateDigest(m_certID.HashAlgorithm.Algorithm, cert.GetEncoded()); if (!Arrays.FixedTimeEquals(m_certID.CertHash.GetOctets(), b)) throw new TspValidationException("certificate hash does not match certID hash."); IssuerSerial issuerSerial = m_certID.IssuerSerial; if (issuerSerial != null) { X509CertificateStructure certificateStructure = cert.CertificateStructure; if (!issuerSerial.Serial.Equals(certificateStructure.SerialNumber)) throw new TspValidationException("certificate serial number does not match certID for signature."); if (!ValidateIssuer(issuerSerial.Issuer, certificateStructure.Issuer)) throw new TspValidationException("certificate name does not match certID for signature. "); } TspUtil.ValidateCertificate(cert); if (!cert.IsValid(m_tstInfo.GenTime)) throw new TspValidationException("certificate not valid when time stamp created."); if (!m_tsaSignerInfo.Verify(cert)) throw new TspValidationException("signature not created by certificate."); } catch (CmsException ex) { if (ex.InnerException != null) throw new TspException(ex.Message, ex.InnerException); throw new TspException("CMS exception: " + ex?.ToString(), ex); } catch (CertificateEncodingException ex2) { throw new TspException("problem processing certificate: " + ex2?.ToString(), ex2); } catch (SecurityUtilityException ex3) { throw new TspException("cannot find algorithm: " + ex3.Message, ex3); } } public CmsSignedData ToCmsSignedData() { return m_tsToken; } public byte[] GetEncoded() { return m_tsToken.GetEncoded("DL"); } public byte[] GetEncoded(string encoding) { return m_tsToken.GetEncoded(encoding); } private static bool ValidateIssuer(GeneralNames issuerNames, X509Name issuer) { GeneralName[] names = issuerNames.GetNames(); foreach (GeneralName generalName in names) { if (4 == generalName.TagNo && X509Name.GetInstance(generalName.Name).Equivalent(issuer)) return true; } return false; } } }