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;
using System.IO;
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 {
CmsProcessable signedContent = m_tsToken.SignedContent;
MemoryStream memoryStream = new MemoryStream();
signedContent.Write(memoryStream);
m_tstInfo = new TimeStampTokenInfo(TstInfo.GetInstance(memoryStream.ToArray()));
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.GetCertHash(), 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.");
GeneralName[] names = issuerSerial.Issuer.GetNames();
bool flag = false;
for (int i = 0; i != names.Length; i++) {
if (names[i].TagNo == 4 && X509Name.GetInstance(names[i].Name).Equivalent(certificateStructure.Issuer)) {
flag = true;
break;
}
}
if (!flag)
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);
}
}
}