init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Tsp;
namespace Org.BouncyCastle.Tsp;
public class GenTimeAccuracy
{
private Accuracy accuracy;
public int Seconds => GetTimeComponent(accuracy.Seconds);
public int Millis => GetTimeComponent(accuracy.Millis);
public int Micros => GetTimeComponent(accuracy.Micros);
public GenTimeAccuracy(Accuracy accuracy)
{
this.accuracy = accuracy;
}
private int GetTimeComponent(DerInteger time)
{
return time?.Value.IntValue ?? 0;
}
public override string ToString()
{
return Seconds + "." + Millis.ToString("000") + Micros.ToString("000");
}
}

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Tsp;
public class TimeStampRequest : X509ExtensionBase
{
private TimeStampReq req;
private X509Extensions extensions;
public int Version => req.Version.Value.IntValue;
public string MessageImprintAlgOid => req.MessageImprint.HashAlgorithm.Algorithm.Id;
public string ReqPolicy
{
get
{
if (req.ReqPolicy != null)
{
return req.ReqPolicy.Id;
}
return null;
}
}
public BigInteger Nonce
{
get
{
if (req.Nonce != null)
{
return req.Nonce.Value;
}
return null;
}
}
public bool CertReq
{
get
{
if (req.CertReq != null)
{
return req.CertReq.IsTrue;
}
return false;
}
}
internal X509Extensions Extensions => req.Extensions;
public virtual bool HasExtensions => extensions != null;
public TimeStampRequest(TimeStampReq req)
{
this.req = req;
extensions = req.Extensions;
}
public TimeStampRequest(byte[] req)
: this(new Asn1InputStream(req))
{
}
public TimeStampRequest(Stream input)
: this(new Asn1InputStream(input))
{
}
private TimeStampRequest(Asn1InputStream str)
{
try
{
req = TimeStampReq.GetInstance(str.ReadObject());
}
catch (InvalidCastException ex)
{
throw new IOException("malformed request: " + ex);
}
catch (ArgumentException ex2)
{
throw new IOException("malformed request: " + ex2);
}
}
public byte[] GetMessageImprintDigest()
{
return req.MessageImprint.GetHashedMessage();
}
public void Validate(IList algorithms, IList policies, IList extensions)
{
if (!algorithms.Contains(MessageImprintAlgOid))
{
throw new TspValidationException("request contains unknown algorithm", 128);
}
if (policies != null && ReqPolicy != null && !policies.Contains(ReqPolicy))
{
throw new TspValidationException("request contains unknown policy", 256);
}
if (Extensions != null && extensions != null)
{
foreach (DerObjectIdentifier extensionOid in Extensions.ExtensionOids)
{
if (!extensions.Contains(extensionOid.Id))
{
throw new TspValidationException("request contains unknown extension", 8388608);
}
}
}
int digestLength = TspUtil.GetDigestLength(MessageImprintAlgOid);
if (digestLength != GetMessageImprintDigest().Length)
{
throw new TspValidationException("imprint digest the wrong length", 4);
}
}
public byte[] GetEncoded()
{
return req.GetEncoded();
}
public virtual X509Extension GetExtension(DerObjectIdentifier oid)
{
if (extensions != null)
{
return extensions.GetExtension(oid);
}
return null;
}
public virtual IList GetExtensionOids()
{
return TspUtil.GetExtensionOids(extensions);
}
protected override X509Extensions GetX509Extensions()
{
return Extensions;
}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Tsp;
public class TimeStampRequestGenerator
{
private DerObjectIdentifier reqPolicy;
private DerBoolean certReq;
private IDictionary extensions = Platform.CreateHashtable();
private IList extOrdering = Platform.CreateArrayList();
public void SetReqPolicy(string reqPolicy)
{
this.reqPolicy = new DerObjectIdentifier(reqPolicy);
}
public void SetCertReq(bool certReq)
{
this.certReq = DerBoolean.GetInstance(certReq);
}
[Obsolete("Use method taking DerObjectIdentifier")]
public void AddExtension(string oid, bool critical, Asn1Encodable value)
{
AddExtension(oid, critical, value.GetEncoded());
}
[Obsolete("Use method taking DerObjectIdentifier")]
public void AddExtension(string oid, bool critical, byte[] value)
{
DerObjectIdentifier derObjectIdentifier = new DerObjectIdentifier(oid);
extensions[derObjectIdentifier] = new X509Extension(critical, new DerOctetString(value));
extOrdering.Add(derObjectIdentifier);
}
public virtual void AddExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable extValue)
{
AddExtension(oid, critical, extValue.GetEncoded());
}
public virtual void AddExtension(DerObjectIdentifier oid, bool critical, byte[] extValue)
{
extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue)));
extOrdering.Add(oid);
}
public TimeStampRequest Generate(string digestAlgorithm, byte[] digest)
{
return Generate(digestAlgorithm, digest, null);
}
public TimeStampRequest Generate(string digestAlgorithmOid, byte[] digest, BigInteger nonce)
{
if (digestAlgorithmOid == null)
{
throw new ArgumentException("No digest algorithm specified");
}
DerObjectIdentifier algorithm = new DerObjectIdentifier(digestAlgorithmOid);
AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(algorithm, DerNull.Instance);
MessageImprint messageImprint = new MessageImprint(hashAlgorithm, digest);
X509Extensions x509Extensions = null;
if (extOrdering.Count != 0)
{
x509Extensions = new X509Extensions(extOrdering, extensions);
}
DerInteger nonce2 = ((nonce == null) ? null : new DerInteger(nonce));
return new TimeStampRequest(new TimeStampReq(messageImprint, reqPolicy, nonce2, certReq, x509Extensions));
}
public virtual TimeStampRequest Generate(DerObjectIdentifier digestAlgorithm, byte[] digest)
{
return Generate(digestAlgorithm.Id, digest);
}
public virtual TimeStampRequest Generate(DerObjectIdentifier digestAlgorithm, byte[] digest, BigInteger nonce)
{
return Generate(digestAlgorithm.Id, digest, nonce);
}
}

View File

@@ -0,0 +1,128 @@
using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Tsp;
public class TimeStampResponse
{
private TimeStampResp resp;
private TimeStampToken timeStampToken;
public int Status => resp.Status.Status.IntValue;
public TimeStampToken TimeStampToken => timeStampToken;
public TimeStampResponse(TimeStampResp resp)
{
this.resp = resp;
if (resp.TimeStampToken != null)
{
timeStampToken = new TimeStampToken(resp.TimeStampToken);
}
}
public TimeStampResponse(byte[] resp)
: this(readTimeStampResp(new Asn1InputStream(resp)))
{
}
public TimeStampResponse(Stream input)
: this(readTimeStampResp(new Asn1InputStream(input)))
{
}
private static TimeStampResp readTimeStampResp(Asn1InputStream input)
{
try
{
return TimeStampResp.GetInstance(input.ReadObject());
}
catch (ArgumentException ex)
{
throw new TspException("malformed timestamp response: " + ex, ex);
}
catch (InvalidCastException ex2)
{
throw new TspException("malformed timestamp response: " + ex2, ex2);
}
}
public string GetStatusString()
{
if (resp.Status.StatusString == null)
{
return null;
}
StringBuilder stringBuilder = new StringBuilder();
PkiFreeText statusString = resp.Status.StatusString;
for (int i = 0; i != statusString.Count; i++)
{
stringBuilder.Append(statusString[i].GetString());
}
return stringBuilder.ToString();
}
public PkiFailureInfo GetFailInfo()
{
if (resp.Status.FailInfo == null)
{
return null;
}
return new PkiFailureInfo(resp.Status.FailInfo);
}
public void Validate(TimeStampRequest request)
{
TimeStampToken timeStampToken = TimeStampToken;
if (timeStampToken != null)
{
TimeStampTokenInfo timeStampInfo = timeStampToken.TimeStampInfo;
if (request.Nonce != null && !request.Nonce.Equals(timeStampInfo.Nonce))
{
throw new TspValidationException("response contains wrong nonce value.");
}
if (Status != 0 && Status != 1)
{
throw new TspValidationException("time stamp token found in failed request.");
}
if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), timeStampInfo.GetMessageImprintDigest()))
{
throw new TspValidationException("response for different message imprint digest.");
}
if (!timeStampInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid))
{
throw new TspValidationException("response for different message imprint algorithm.");
}
Org.BouncyCastle.Asn1.Cms.Attribute attribute = timeStampToken.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate];
Org.BouncyCastle.Asn1.Cms.Attribute attribute2 = timeStampToken.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2];
if (attribute == null && attribute2 == null)
{
throw new TspValidationException("no signing certificate attribute present.");
}
if (attribute != null)
{
}
if (request.ReqPolicy != null && !request.ReqPolicy.Equals(timeStampInfo.Policy))
{
throw new TspValidationException("TSA policy wrong for request.");
}
}
else if (Status == 0 || Status == 1)
{
throw new TspValidationException("no time stamp token found and one expected.");
}
}
public byte[] GetEncoded()
{
return resp.GetEncoded();
}
}

View File

@@ -0,0 +1,148 @@
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cmp;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities.Date;
namespace Org.BouncyCastle.Tsp;
public class TimeStampResponseGenerator
{
private class FailInfo : DerBitString
{
internal FailInfo(int failInfoValue)
: base(failInfoValue)
{
}
}
private PkiStatus status;
private Asn1EncodableVector statusStrings;
private int failInfo;
private TimeStampTokenGenerator tokenGenerator;
private IList acceptedAlgorithms;
private IList acceptedPolicies;
private IList acceptedExtensions;
public TimeStampResponseGenerator(TimeStampTokenGenerator tokenGenerator, IList acceptedAlgorithms)
: this(tokenGenerator, acceptedAlgorithms, null, null)
{
}
public TimeStampResponseGenerator(TimeStampTokenGenerator tokenGenerator, IList acceptedAlgorithms, IList acceptedPolicy)
: this(tokenGenerator, acceptedAlgorithms, acceptedPolicy, null)
{
}
public TimeStampResponseGenerator(TimeStampTokenGenerator tokenGenerator, IList acceptedAlgorithms, IList acceptedPolicies, IList acceptedExtensions)
{
this.tokenGenerator = tokenGenerator;
this.acceptedAlgorithms = acceptedAlgorithms;
this.acceptedPolicies = acceptedPolicies;
this.acceptedExtensions = acceptedExtensions;
statusStrings = new Asn1EncodableVector();
}
private void AddStatusString(string statusString)
{
statusStrings.Add(new DerUtf8String(statusString));
}
private void SetFailInfoField(int field)
{
failInfo |= field;
}
private PkiStatusInfo GetPkiStatusInfo()
{
Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(new DerInteger((int)status));
if (statusStrings.Count > 0)
{
asn1EncodableVector.Add(new PkiFreeText(new DerSequence(statusStrings)));
}
if (failInfo != 0)
{
asn1EncodableVector.Add(new FailInfo(failInfo));
}
return new PkiStatusInfo(new DerSequence(asn1EncodableVector));
}
public TimeStampResponse Generate(TimeStampRequest request, BigInteger serialNumber, DateTime genTime)
{
return Generate(request, serialNumber, new DateTimeObject(genTime));
}
public TimeStampResponse Generate(TimeStampRequest request, BigInteger serialNumber, DateTimeObject genTime)
{
TimeStampResp resp;
try
{
if (genTime == null)
{
throw new TspValidationException("The time source is not available.", 512);
}
request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions);
status = PkiStatus.Granted;
AddStatusString("Operation Okay");
PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
ContentInfo instance;
try
{
TimeStampToken timeStampToken = tokenGenerator.Generate(request, serialNumber, genTime.Value);
byte[] encoded = timeStampToken.ToCmsSignedData().GetEncoded();
instance = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded));
}
catch (IOException e)
{
throw new TspException("Timestamp token received cannot be converted to ContentInfo", e);
}
resp = new TimeStampResp(pkiStatusInfo, instance);
}
catch (TspValidationException ex)
{
status = PkiStatus.Rejection;
SetFailInfoField(ex.FailureCode);
AddStatusString(ex.Message);
PkiStatusInfo pkiStatusInfo2 = GetPkiStatusInfo();
resp = new TimeStampResp(pkiStatusInfo2, null);
}
try
{
return new TimeStampResponse(resp);
}
catch (IOException e2)
{
throw new TspException("created badly formatted response!", e2);
}
}
public TimeStampResponse GenerateFailResponse(PkiStatus status, int failInfoField, string statusString)
{
this.status = status;
SetFailInfoField(failInfoField);
if (statusString != null)
{
AddStatusString(statusString);
}
PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
TimeStampResp resp = new TimeStampResp(pkiStatusInfo, null);
try
{
return new TimeStampResponse(resp);
}
catch (IOException e)
{
throw new TspException("created badly formatted response!", e);
}
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,183 @@
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.Pkcs;
using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Math;
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 TimeStampTokenGenerator
{
private int accuracySeconds = -1;
private int accuracyMillis = -1;
private int accuracyMicros = -1;
private bool ordering = false;
private GeneralName tsa = null;
private string tsaPolicyOID;
private AsymmetricKeyParameter key;
private X509Certificate cert;
private string digestOID;
private Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr;
private Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr;
private IX509Store x509Certs;
private IX509Store x509Crls;
public TimeStampTokenGenerator(AsymmetricKeyParameter key, X509Certificate cert, string digestOID, string tsaPolicyOID)
: this(key, cert, digestOID, tsaPolicyOID, null, null)
{
}
public TimeStampTokenGenerator(AsymmetricKeyParameter key, X509Certificate cert, string digestOID, string tsaPolicyOID, Org.BouncyCastle.Asn1.Cms.AttributeTable signedAttr, Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttr)
{
this.key = key;
this.cert = cert;
this.digestOID = digestOID;
this.tsaPolicyOID = tsaPolicyOID;
this.unsignedAttr = unsignedAttr;
TspUtil.ValidateCertificate(cert);
IDictionary dictionary = ((signedAttr == null) ? Platform.CreateHashtable() : signedAttr.ToDictionary());
try
{
byte[] hash = DigestUtilities.CalculateDigest("SHA-1", cert.GetEncoded());
EssCertID essCertID = new EssCertID(hash);
Org.BouncyCastle.Asn1.Cms.Attribute attribute = new Org.BouncyCastle.Asn1.Cms.Attribute(PkcsObjectIdentifiers.IdAASigningCertificate, new DerSet(new SigningCertificate(essCertID)));
dictionary[attribute.AttrType] = attribute;
}
catch (CertificateEncodingException e)
{
throw new TspException("Exception processing certificate.", e);
}
catch (SecurityUtilityException e2)
{
throw new TspException("Can't find a SHA-1 implementation.", e2);
}
this.signedAttr = new Org.BouncyCastle.Asn1.Cms.AttributeTable(dictionary);
}
public void SetCertificates(IX509Store certificates)
{
x509Certs = certificates;
}
public void SetCrls(IX509Store crls)
{
x509Crls = crls;
}
public void SetAccuracySeconds(int accuracySeconds)
{
this.accuracySeconds = accuracySeconds;
}
public void SetAccuracyMillis(int accuracyMillis)
{
this.accuracyMillis = accuracyMillis;
}
public void SetAccuracyMicros(int accuracyMicros)
{
this.accuracyMicros = accuracyMicros;
}
public void SetOrdering(bool ordering)
{
this.ordering = ordering;
}
public void SetTsa(GeneralName tsa)
{
this.tsa = tsa;
}
public TimeStampToken Generate(TimeStampRequest request, BigInteger serialNumber, DateTime genTime)
{
DerObjectIdentifier algorithm = new DerObjectIdentifier(request.MessageImprintAlgOid);
AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(algorithm, DerNull.Instance);
MessageImprint messageImprint = new MessageImprint(hashAlgorithm, request.GetMessageImprintDigest());
Accuracy accuracy = null;
if (accuracySeconds > 0 || accuracyMillis > 0 || accuracyMicros > 0)
{
DerInteger seconds = null;
if (accuracySeconds > 0)
{
seconds = new DerInteger(accuracySeconds);
}
DerInteger millis = null;
if (accuracyMillis > 0)
{
millis = new DerInteger(accuracyMillis);
}
DerInteger micros = null;
if (accuracyMicros > 0)
{
micros = new DerInteger(accuracyMicros);
}
accuracy = new Accuracy(seconds, millis, micros);
}
DerBoolean derBoolean = null;
if (ordering)
{
derBoolean = DerBoolean.GetInstance(ordering);
}
DerInteger nonce = null;
if (request.Nonce != null)
{
nonce = new DerInteger(request.Nonce);
}
DerObjectIdentifier tsaPolicyId = new DerObjectIdentifier(tsaPolicyOID);
if (request.ReqPolicy != null)
{
tsaPolicyId = new DerObjectIdentifier(request.ReqPolicy);
}
TstInfo tstInfo = new TstInfo(tsaPolicyId, messageImprint, new DerInteger(serialNumber), new DerGeneralizedTime(genTime), accuracy, derBoolean, nonce, tsa, request.Extensions);
try
{
CmsSignedDataGenerator cmsSignedDataGenerator = new CmsSignedDataGenerator();
byte[] derEncoded = tstInfo.GetDerEncoded();
if (request.CertReq)
{
cmsSignedDataGenerator.AddCertificates(x509Certs);
}
cmsSignedDataGenerator.AddCrls(x509Crls);
cmsSignedDataGenerator.AddSigner(key, cert, digestOID, signedAttr, unsignedAttr);
CmsSignedData signedData = cmsSignedDataGenerator.Generate(PkcsObjectIdentifiers.IdCTTstInfo.Id, new CmsProcessableByteArray(derEncoded), encapsulate: true);
return new TimeStampToken(signedData);
}
catch (CmsException e)
{
throw new TspException("Error generating time-stamp token", e);
}
catch (IOException e2)
{
throw new TspException("Exception encoding info", e2);
}
catch (X509StoreException e3)
{
throw new TspException("Exception handling CertStore", e3);
}
}
}

View File

@@ -0,0 +1,78 @@
using System;
using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Tsp;
public class TimeStampTokenInfo
{
private TstInfo tstInfo;
private DateTime genTime;
public bool IsOrdered => tstInfo.Ordering.IsTrue;
public Accuracy Accuracy => tstInfo.Accuracy;
public DateTime GenTime => genTime;
public GenTimeAccuracy GenTimeAccuracy
{
get
{
if (Accuracy != null)
{
return new GenTimeAccuracy(Accuracy);
}
return null;
}
}
public string Policy => tstInfo.Policy.Id;
public BigInteger SerialNumber => tstInfo.SerialNumber.Value;
public GeneralName Tsa => tstInfo.Tsa;
public BigInteger Nonce
{
get
{
if (tstInfo.Nonce != null)
{
return tstInfo.Nonce.Value;
}
return null;
}
}
public AlgorithmIdentifier HashAlgorithm => tstInfo.MessageImprint.HashAlgorithm;
public string MessageImprintAlgOid => tstInfo.MessageImprint.HashAlgorithm.Algorithm.Id;
public TstInfo TstInfo => tstInfo;
public TimeStampTokenInfo(TstInfo tstInfo)
{
this.tstInfo = tstInfo;
try
{
genTime = tstInfo.GenTime.ToDateTime();
}
catch (Exception ex)
{
throw new TspException("unable to parse genTime field: " + ex.Message);
}
}
public byte[] GetMessageImprintDigest()
{
return tstInfo.MessageImprint.GetHashedMessage();
}
public byte[] GetEncoded()
{
return tstInfo.GetEncoded();
}
}

View File

@@ -0,0 +1,70 @@
using System.Collections;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Rosstandart;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Tsp;
public abstract class TspAlgorithms
{
public static readonly string MD5;
public static readonly string Sha1;
public static readonly string Sha224;
public static readonly string Sha256;
public static readonly string Sha384;
public static readonly string Sha512;
public static readonly string RipeMD128;
public static readonly string RipeMD160;
public static readonly string RipeMD256;
public static readonly string Gost3411;
public static readonly string Gost3411_2012_256;
public static readonly string Gost3411_2012_512;
public static readonly string SM3;
public static readonly IList Allowed;
static TspAlgorithms()
{
MD5 = PkcsObjectIdentifiers.MD5.Id;
Sha1 = OiwObjectIdentifiers.IdSha1.Id;
Sha224 = NistObjectIdentifiers.IdSha224.Id;
Sha256 = NistObjectIdentifiers.IdSha256.Id;
Sha384 = NistObjectIdentifiers.IdSha384.Id;
Sha512 = NistObjectIdentifiers.IdSha512.Id;
RipeMD128 = TeleTrusTObjectIdentifiers.RipeMD128.Id;
RipeMD160 = TeleTrusTObjectIdentifiers.RipeMD160.Id;
RipeMD256 = TeleTrusTObjectIdentifiers.RipeMD256.Id;
Gost3411 = CryptoProObjectIdentifiers.GostR3411.Id;
Gost3411_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id;
Gost3411_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id;
SM3 = GMObjectIdentifiers.sm3.Id;
string[] array = new string[13]
{
Gost3411, Gost3411_2012_256, Gost3411_2012_512, MD5, RipeMD128, RipeMD160, RipeMD256, Sha1, Sha224, Sha256,
Sha384, Sha512, SM3
};
Allowed = Platform.CreateArrayList();
string[] array2 = array;
foreach (string value in array2)
{
Allowed.Add(value);
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace Org.BouncyCastle.Tsp;
[Serializable]
public class TspException : Exception
{
public TspException()
{
}
public TspException(string message)
: base(message)
{
}
public TspException(string message, Exception e)
: base(message, e)
{
}
}

View File

@@ -0,0 +1,192 @@
using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Cms;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Rosstandart;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Tsp;
public class TspUtil
{
private static ISet EmptySet;
private static IList EmptyList;
private static readonly IDictionary digestLengths;
private static readonly IDictionary digestNames;
static TspUtil()
{
EmptySet = CollectionUtilities.ReadOnly(new HashSet());
EmptyList = CollectionUtilities.ReadOnly(Platform.CreateArrayList());
digestLengths = Platform.CreateHashtable();
digestNames = Platform.CreateHashtable();
digestLengths.Add(PkcsObjectIdentifiers.MD5.Id, 16);
digestLengths.Add(OiwObjectIdentifiers.IdSha1.Id, 20);
digestLengths.Add(NistObjectIdentifiers.IdSha224.Id, 28);
digestLengths.Add(NistObjectIdentifiers.IdSha256.Id, 32);
digestLengths.Add(NistObjectIdentifiers.IdSha384.Id, 48);
digestLengths.Add(NistObjectIdentifiers.IdSha512.Id, 64);
digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, 16);
digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, 20);
digestLengths.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, 32);
digestLengths.Add(CryptoProObjectIdentifiers.GostR3411.Id, 32);
digestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, 32);
digestLengths.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, 64);
digestLengths.Add(GMObjectIdentifiers.sm3.Id, 32);
digestNames.Add(PkcsObjectIdentifiers.MD5.Id, "MD5");
digestNames.Add(OiwObjectIdentifiers.IdSha1.Id, "SHA1");
digestNames.Add(NistObjectIdentifiers.IdSha224.Id, "SHA224");
digestNames.Add(NistObjectIdentifiers.IdSha256.Id, "SHA256");
digestNames.Add(NistObjectIdentifiers.IdSha384.Id, "SHA384");
digestNames.Add(NistObjectIdentifiers.IdSha512.Id, "SHA512");
digestNames.Add(PkcsObjectIdentifiers.MD5WithRsaEncryption.Id, "MD5");
digestNames.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id, "SHA1");
digestNames.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id, "SHA224");
digestNames.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id, "SHA256");
digestNames.Add(PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id, "SHA384");
digestNames.Add(PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id, "SHA512");
digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD128.Id, "RIPEMD128");
digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD160.Id, "RIPEMD160");
digestNames.Add(TeleTrusTObjectIdentifiers.RipeMD256.Id, "RIPEMD256");
digestNames.Add(CryptoProObjectIdentifiers.GostR3411.Id, "GOST3411");
digestNames.Add(OiwObjectIdentifiers.DsaWithSha1.Id, "SHA1");
digestNames.Add(OiwObjectIdentifiers.Sha1WithRsa.Id, "SHA1");
digestNames.Add(OiwObjectIdentifiers.MD5WithRsa.Id, "MD5");
digestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id, "GOST3411-2012-256");
digestNames.Add(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id, "GOST3411-2012-512");
digestNames.Add(GMObjectIdentifiers.sm3.Id, "SM3");
}
public static ICollection GetSignatureTimestamps(SignerInformation signerInfo)
{
IList list = Platform.CreateArrayList();
Org.BouncyCastle.Asn1.Cms.AttributeTable unsignedAttributes = signerInfo.UnsignedAttributes;
if (unsignedAttributes != null)
{
foreach (Org.BouncyCastle.Asn1.Cms.Attribute item in unsignedAttributes.GetAll(PkcsObjectIdentifiers.IdAASignatureTimeStampToken))
{
foreach (Asn1Encodable attrValue in item.AttrValues)
{
try
{
Org.BouncyCastle.Asn1.Cms.ContentInfo instance = Org.BouncyCastle.Asn1.Cms.ContentInfo.GetInstance(attrValue.ToAsn1Object());
TimeStampToken timeStampToken = new TimeStampToken(instance);
TimeStampTokenInfo timeStampInfo = timeStampToken.TimeStampInfo;
byte[] a = DigestUtilities.CalculateDigest(GetDigestAlgName(timeStampInfo.MessageImprintAlgOid), signerInfo.GetSignature());
if (!Arrays.ConstantTimeAreEqual(a, timeStampInfo.GetMessageImprintDigest()))
{
throw new TspValidationException("Incorrect digest in message imprint");
}
list.Add(timeStampToken);
}
catch (SecurityUtilityException)
{
throw new TspValidationException("Unknown hash algorithm specified in timestamp");
}
catch (Exception)
{
throw new TspValidationException("Timestamp could not be parsed");
}
}
}
}
return list;
}
public static void ValidateCertificate(X509Certificate cert)
{
if (cert.Version != 3)
{
throw new ArgumentException("Certificate must have an ExtendedKeyUsage extension.");
}
Asn1OctetString extensionValue = cert.GetExtensionValue(X509Extensions.ExtendedKeyUsage);
if (extensionValue == null)
{
throw new TspValidationException("Certificate must have an ExtendedKeyUsage extension.");
}
if (!cert.GetCriticalExtensionOids().Contains(X509Extensions.ExtendedKeyUsage.Id))
{
throw new TspValidationException("Certificate must have an ExtendedKeyUsage extension marked as critical.");
}
try
{
ExtendedKeyUsage instance = ExtendedKeyUsage.GetInstance(Asn1Object.FromByteArray(extensionValue.GetOctets()));
if (!instance.HasKeyPurposeId(KeyPurposeID.IdKPTimeStamping) || instance.Count != 1)
{
throw new TspValidationException("ExtendedKeyUsage not solely time stamping.");
}
}
catch (IOException)
{
throw new TspValidationException("cannot process ExtendedKeyUsage extension");
}
}
internal static string GetDigestAlgName(string digestAlgOID)
{
string text = (string)digestNames[digestAlgOID];
if (text == null)
{
return digestAlgOID;
}
return text;
}
internal static int GetDigestLength(string digestAlgOID)
{
if (!digestLengths.Contains(digestAlgOID))
{
throw new TspException("digest algorithm cannot be found.");
}
return (int)digestLengths[digestAlgOID];
}
internal static IDigest CreateDigestInstance(string digestAlgOID)
{
string digestAlgName = GetDigestAlgName(digestAlgOID);
return DigestUtilities.GetDigest(digestAlgName);
}
internal static ISet GetCriticalExtensionOids(X509Extensions extensions)
{
if (extensions == null)
{
return EmptySet;
}
return CollectionUtilities.ReadOnly(new HashSet(extensions.GetCriticalExtensionOids()));
}
internal static ISet GetNonCriticalExtensionOids(X509Extensions extensions)
{
if (extensions == null)
{
return EmptySet;
}
return CollectionUtilities.ReadOnly(new HashSet(extensions.GetNonCriticalExtensionOids()));
}
internal static IList GetExtensionOids(X509Extensions extensions)
{
if (extensions == null)
{
return EmptyList;
}
return CollectionUtilities.ReadOnly(Platform.CreateArrayList(extensions.GetExtensionOids()));
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace Org.BouncyCastle.Tsp;
[Serializable]
public class TspValidationException : TspException
{
private int failureCode;
public int FailureCode => failureCode;
public TspValidationException(string message)
: base(message)
{
failureCode = -1;
}
public TspValidationException(string message, int failureCode)
: base(message)
{
this.failureCode = failureCode;
}
}