init commit
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using Org.BouncyCastle.Asn1.Ess;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Oiw;
|
||||
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.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.Tsp;
|
||||
|
||||
public class TimeStampToken
|
||||
{
|
||||
private class CertID
|
||||
{
|
||||
private EssCertID certID;
|
||||
|
||||
private EssCertIDv2 certIDv2;
|
||||
|
||||
public IssuerSerial IssuerSerial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (certID == null)
|
||||
{
|
||||
return certIDv2.IssuerSerial;
|
||||
}
|
||||
return certID.IssuerSerial;
|
||||
}
|
||||
}
|
||||
|
||||
internal CertID(EssCertID certID)
|
||||
{
|
||||
this.certID = certID;
|
||||
certIDv2 = null;
|
||||
}
|
||||
|
||||
internal CertID(EssCertIDv2 certID)
|
||||
{
|
||||
certIDv2 = certID;
|
||||
this.certID = null;
|
||||
}
|
||||
|
||||
public string GetHashAlgorithmName()
|
||||
{
|
||||
if (certID != null)
|
||||
{
|
||||
return "SHA-1";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha256.Equals(certIDv2.HashAlgorithm.Algorithm))
|
||||
{
|
||||
return "SHA-256";
|
||||
}
|
||||
return certIDv2.HashAlgorithm.Algorithm.Id;
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier GetHashAlgorithm()
|
||||
{
|
||||
if (certID == null)
|
||||
{
|
||||
return certIDv2.HashAlgorithm;
|
||||
}
|
||||
return new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1);
|
||||
}
|
||||
|
||||
public byte[] GetCertHash()
|
||||
{
|
||||
if (certID == null)
|
||||
{
|
||||
return certIDv2.GetCertHash();
|
||||
}
|
||||
return certID.GetCertHash();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly CmsSignedData tsToken;
|
||||
|
||||
private readonly SignerInformation tsaSignerInfo;
|
||||
|
||||
private readonly TimeStampTokenInfo tstInfo;
|
||||
|
||||
private readonly CertID certID;
|
||||
|
||||
public TimeStampTokenInfo TimeStampInfo => tstInfo;
|
||||
|
||||
public SignerID SignerID => tsaSignerInfo.SignerID;
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable SignedAttributes => tsaSignerInfo.SignedAttributes;
|
||||
|
||||
public Org.BouncyCastle.Asn1.Cms.AttributeTable UnsignedAttributes => tsaSignerInfo.UnsignedAttributes;
|
||||
|
||||
public TimeStampToken(Org.BouncyCastle.Asn1.Cms.ContentInfo contentInfo)
|
||||
: this(new CmsSignedData(contentInfo))
|
||||
{
|
||||
}
|
||||
|
||||
public TimeStampToken(CmsSignedData signedData)
|
||||
{
|
||||
tsToken = signedData;
|
||||
if (!tsToken.SignedContentType.Equals(PkcsObjectIdentifiers.IdCTTstInfo))
|
||||
{
|
||||
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 enumerator = signers.GetEnumerator();
|
||||
enumerator.MoveNext();
|
||||
tsaSignerInfo = (SignerInformation)enumerator.Current;
|
||||
try
|
||||
{
|
||||
CmsProcessable signedContent = tsToken.SignedContent;
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
signedContent.Write(memoryStream);
|
||||
tstInfo = new TimeStampTokenInfo(TstInfo.GetInstance(Asn1Object.FromByteArray(memoryStream.ToArray())));
|
||||
Org.BouncyCastle.Asn1.Cms.Attribute attribute = tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate];
|
||||
if (attribute != null)
|
||||
{
|
||||
SigningCertificate instance = SigningCertificate.GetInstance(attribute.AttrValues[0]);
|
||||
certID = new CertID(EssCertID.GetInstance(instance.GetCerts()[0]));
|
||||
return;
|
||||
}
|
||||
attribute = tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2];
|
||||
if (attribute == null)
|
||||
{
|
||||
throw new TspValidationException("no signing certificate attribute found, time stamp invalid.");
|
||||
}
|
||||
SigningCertificateV2 instance2 = SigningCertificateV2.GetInstance(attribute.AttrValues[0]);
|
||||
certID = new CertID(EssCertIDv2.GetInstance(instance2.GetCerts()[0]));
|
||||
}
|
||||
catch (CmsException ex)
|
||||
{
|
||||
throw new TspException(ex.Message, ex.InnerException);
|
||||
}
|
||||
}
|
||||
|
||||
public IX509Store GetCertificates(string type)
|
||||
{
|
||||
return tsToken.GetCertificates(type);
|
||||
}
|
||||
|
||||
public IX509Store GetCrls(string type)
|
||||
{
|
||||
return tsToken.GetCrls(type);
|
||||
}
|
||||
|
||||
public IX509Store GetAttributeCertificates(string type)
|
||||
{
|
||||
return tsToken.GetAttributeCertificates(type);
|
||||
}
|
||||
|
||||
public void Validate(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] b = DigestUtilities.CalculateDigest(certID.GetHashAlgorithmName(), cert.GetEncoded());
|
||||
if (!Arrays.ConstantTimeAreEqual(certID.GetCertHash(), b))
|
||||
{
|
||||
throw new TspValidationException("certificate hash does not match certID hash.");
|
||||
}
|
||||
if (certID.IssuerSerial != null)
|
||||
{
|
||||
if (!certID.IssuerSerial.Serial.Value.Equals(cert.SerialNumber))
|
||||
{
|
||||
throw new TspValidationException("certificate serial number does not match certID for signature.");
|
||||
}
|
||||
GeneralName[] names = certID.IssuerSerial.Issuer.GetNames();
|
||||
X509Name issuerX509Principal = PrincipalUtilities.GetIssuerX509Principal(cert);
|
||||
bool flag = false;
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
if (names[i].TagNo == 4 && X509Name.GetInstance(names[i].Name).Equivalent(issuerX509Principal))
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
throw new TspValidationException("certificate name does not match certID for signature. ");
|
||||
}
|
||||
}
|
||||
TspUtil.ValidateCertificate(cert);
|
||||
cert.CheckValidity(tstInfo.GenTime);
|
||||
if (!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, ex);
|
||||
}
|
||||
catch (CertificateEncodingException ex2)
|
||||
{
|
||||
throw new TspException("problem processing certificate: " + ex2, ex2);
|
||||
}
|
||||
catch (SecurityUtilityException ex3)
|
||||
{
|
||||
throw new TspException("cannot find algorithm: " + ex3.Message, ex3);
|
||||
}
|
||||
}
|
||||
|
||||
public CmsSignedData ToCmsSignedData()
|
||||
{
|
||||
return tsToken;
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return tsToken.GetEncoded();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user