mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-16 02:58:25 +00:00
提交Unity 联机Pro
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
public class GenTimeAccuracy
|
||||
{
|
||||
private Accuracy accuracy;
|
||||
|
||||
public GenTimeAccuracy(
|
||||
Accuracy accuracy)
|
||||
{
|
||||
this.accuracy = accuracy;
|
||||
}
|
||||
|
||||
public int Seconds { get { return GetTimeComponent(accuracy.Seconds); } }
|
||||
|
||||
public int Millis { get { return GetTimeComponent(accuracy.Millis); } }
|
||||
|
||||
public int Micros { get { return GetTimeComponent(accuracy.Micros); } }
|
||||
|
||||
private int GetTimeComponent(
|
||||
DerInteger time)
|
||||
{
|
||||
return time == null ? 0 : time.IntValueExact;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Seconds + "." + Millis.ToString("000") + Micros.ToString("000");
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b121e50e39f7eae438bd60a8c88d8aab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.GM;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Rosstandart;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.TeleTrust;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
/**
|
||||
* Recognised hash algorithms for the time stamp protocol.
|
||||
*/
|
||||
public static class TspAlgorithms
|
||||
{
|
||||
public static readonly string MD5 = PkcsObjectIdentifiers.MD5.Id;
|
||||
|
||||
public static readonly string Sha1 = OiwObjectIdentifiers.IdSha1.Id;
|
||||
|
||||
public static readonly string Sha224 = NistObjectIdentifiers.IdSha224.Id;
|
||||
public static readonly string Sha256 = NistObjectIdentifiers.IdSha256.Id;
|
||||
public static readonly string Sha384 = NistObjectIdentifiers.IdSha384.Id;
|
||||
public static readonly string Sha512 = NistObjectIdentifiers.IdSha512.Id;
|
||||
|
||||
public static readonly string RipeMD128 = TeleTrusTObjectIdentifiers.RipeMD128.Id;
|
||||
public static readonly string RipeMD160 = TeleTrusTObjectIdentifiers.RipeMD160.Id;
|
||||
public static readonly string RipeMD256 = TeleTrusTObjectIdentifiers.RipeMD256.Id;
|
||||
|
||||
public static readonly string Gost3411 = CryptoProObjectIdentifiers.GostR3411.Id;
|
||||
public static readonly string Gost3411_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256.Id;
|
||||
public static readonly string Gost3411_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512.Id;
|
||||
|
||||
public static readonly string SM3 = GMObjectIdentifiers.sm3.Id;
|
||||
|
||||
public static readonly IList<string> Allowed;
|
||||
|
||||
static TspAlgorithms()
|
||||
{
|
||||
Allowed = CollectionUtilities.ReadOnly(new List<string>()
|
||||
{
|
||||
Gost3411, Gost3411_2012_256, Gost3411_2012_512, MD5, RipeMD128, RipeMD160, RipeMD256, Sha1, Sha224,
|
||||
Sha256, Sha384, Sha512, SM3
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 499a88718c5a4bc4f83dbb4ea7aa4ed9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
[Serializable]
|
||||
public class TspException
|
||||
: Exception
|
||||
{
|
||||
public TspException()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public TspException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public TspException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected TspException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7656ac180275ac84f835935c4731b5b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,206 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.GM;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Rosstandart;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.TeleTrust;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Cms;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
public class TspUtil
|
||||
{
|
||||
private static readonly Dictionary<string, int> DigestLengths = new Dictionary<string, int>();
|
||||
private static readonly Dictionary<string, string> DigestNames = new Dictionary<string, string>();
|
||||
|
||||
static TspUtil()
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 IList<TimeStampToken> GetSignatureTimestamps(
|
||||
SignerInformation signerInfo)
|
||||
{
|
||||
var timestamps = new List<TimeStampToken>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the passed in certificate as being of the correct type to be used
|
||||
* for time stamping. To be valid it must have an ExtendedKeyUsage extension
|
||||
* which has a key purpose identifier of id-kp-timeStamping.
|
||||
*
|
||||
* @param cert the certificate of interest.
|
||||
* @throws TspValidationException if the certicate fails on one of the check points.
|
||||
*/
|
||||
public static void ValidateCertificate(
|
||||
X509Certificate cert)
|
||||
{
|
||||
if (cert.Version != 3)
|
||||
throw new ArgumentException("Certificate must have an ExtendedKeyUsage extension.");
|
||||
|
||||
Asn1OctetString ext = cert.GetExtensionValue(X509Extensions.ExtendedKeyUsage);
|
||||
if (ext == 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 extKey = ExtendedKeyUsage.GetInstance(
|
||||
Asn1Object.FromByteArray(ext.GetOctets()));
|
||||
|
||||
if (!extKey.HasKeyPurposeId(KeyPurposeID.id_kp_timeStamping) || extKey.Count != 1)
|
||||
throw new TspValidationException("ExtendedKeyUsage not solely time stamping.");
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
throw new TspValidationException("cannot process ExtendedKeyUsage extension");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the digest algorithm using one of the standard JCA string
|
||||
/// representations rather than the algorithm identifier (if possible).
|
||||
/// </summary>
|
||||
internal static string GetDigestAlgName(string digestAlgOid)
|
||||
{
|
||||
return CollectionUtilities.GetValueOrKey(DigestNames, digestAlgOid);
|
||||
}
|
||||
|
||||
internal static int GetDigestLength(string digestAlgOid)
|
||||
{
|
||||
if (!DigestLengths.TryGetValue(digestAlgOid, out int length))
|
||||
throw new TspException("digest algorithm cannot be found.");
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
internal static IDigest CreateDigestInstance(string digestAlgOID)
|
||||
{
|
||||
string digestName = GetDigestAlgName(digestAlgOID);
|
||||
|
||||
return DigestUtilities.GetDigest(digestName);
|
||||
}
|
||||
|
||||
internal static ISet<DerObjectIdentifier> GetCriticalExtensionOids(X509Extensions extensions)
|
||||
{
|
||||
return extensions == null
|
||||
? new HashSet<DerObjectIdentifier>()
|
||||
: new HashSet<DerObjectIdentifier>(extensions.GetCriticalExtensionOids());
|
||||
}
|
||||
|
||||
internal static ISet<DerObjectIdentifier> GetNonCriticalExtensionOids(X509Extensions extensions)
|
||||
{
|
||||
return extensions == null
|
||||
? new HashSet<DerObjectIdentifier>()
|
||||
: new HashSet<DerObjectIdentifier>(extensions.GetNonCriticalExtensionOids());
|
||||
}
|
||||
|
||||
internal static IList<DerObjectIdentifier> GetExtensionOids(X509Extensions extensions)
|
||||
{
|
||||
return extensions == null
|
||||
? new List<DerObjectIdentifier>()
|
||||
: new List<DerObjectIdentifier>(extensions.GetExtensionOids());
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac5ae719ecc37554b9cf608fb87fef41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,51 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
/**
|
||||
* Exception thrown if a TSP request or response fails to validate.
|
||||
* <p>
|
||||
* If a failure code is associated with the exception it can be retrieved using
|
||||
* the getFailureCode() method.</p>
|
||||
*/
|
||||
[Serializable]
|
||||
public class TspValidationException
|
||||
: TspException
|
||||
{
|
||||
protected readonly int m_failureCode;
|
||||
|
||||
public TspValidationException(string message)
|
||||
: this(message, -1)
|
||||
{
|
||||
}
|
||||
|
||||
public TspValidationException(string message, int failureCode)
|
||||
: base(message)
|
||||
{
|
||||
m_failureCode = failureCode;
|
||||
}
|
||||
|
||||
protected TspValidationException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
m_failureCode = info.GetInt32("failureCode");
|
||||
}
|
||||
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("failureCode", m_failureCode);
|
||||
}
|
||||
|
||||
/// <returns>The failure code associated with this exception, if one is set.</returns>
|
||||
public int FailureCode
|
||||
{
|
||||
get { return m_failureCode; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17b0d10ccf7ab7c4c815f6d81d87f6bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,185 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
/**
|
||||
* Base class for an RFC 3161 Time Stamp Request.
|
||||
*/
|
||||
public class TimeStampRequest
|
||||
: X509ExtensionBase
|
||||
{
|
||||
private TimeStampReq req;
|
||||
private X509Extensions extensions;
|
||||
|
||||
public TimeStampRequest(
|
||||
TimeStampReq req)
|
||||
{
|
||||
this.req = req;
|
||||
this.extensions = req.Extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TimeStampRequest from the past in byte array.
|
||||
*
|
||||
* @param req byte array containing the request.
|
||||
* @throws IOException if the request is malformed.
|
||||
*/
|
||||
public TimeStampRequest(
|
||||
byte[] req)
|
||||
: this(new Asn1InputStream(req))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TimeStampRequest from the past in input stream.
|
||||
*
|
||||
* @param in input stream containing the request.
|
||||
* @throws IOException if the request is malformed.
|
||||
*/
|
||||
public TimeStampRequest(
|
||||
Stream input)
|
||||
: this(new Asn1InputStream(input))
|
||||
{
|
||||
}
|
||||
|
||||
private TimeStampRequest(
|
||||
Asn1InputStream str)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.req = TimeStampReq.GetInstance(str.ReadObject());
|
||||
}
|
||||
catch (InvalidCastException e)
|
||||
{
|
||||
throw new IOException("malformed request: " + e);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new IOException("malformed request: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public int Version
|
||||
{
|
||||
get { return req.Version.IntValueExact; }
|
||||
}
|
||||
|
||||
public string MessageImprintAlgOid
|
||||
{
|
||||
get { return req.MessageImprint.HashAlgorithm.Algorithm.Id; }
|
||||
}
|
||||
|
||||
public byte[] GetMessageImprintDigest()
|
||||
{
|
||||
return req.MessageImprint.GetHashedMessage();
|
||||
}
|
||||
|
||||
public string ReqPolicy
|
||||
{
|
||||
get
|
||||
{
|
||||
return req.ReqPolicy == null
|
||||
? null
|
||||
: req.ReqPolicy.Id;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger Nonce
|
||||
{
|
||||
get
|
||||
{
|
||||
return req.Nonce == null
|
||||
? null
|
||||
: req.Nonce.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CertReq
|
||||
{
|
||||
get
|
||||
{
|
||||
return req.CertReq == null
|
||||
? false
|
||||
: req.CertReq.IsTrue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the timestamp request, checking the digest to see if it is of an
|
||||
* accepted type and whether it is of the correct length for the algorithm specified.
|
||||
*
|
||||
* @param algorithms a set of string OIDS giving accepted algorithms.
|
||||
* @param policies if non-null a set of policies we are willing to sign under.
|
||||
* @param extensions if non-null a set of extensions we are willing to accept.
|
||||
* @throws TspException if the request is invalid, or processing fails.
|
||||
*/
|
||||
public void Validate(IList<string> algorithms, IList<string> policies, IList<string> extensions)
|
||||
{
|
||||
if (!algorithms.Contains(this.MessageImprintAlgOid))
|
||||
throw new TspValidationException("request contains unknown algorithm", PkiFailureInfo.BadAlg);
|
||||
|
||||
if (policies != null && this.ReqPolicy != null && !policies.Contains(this.ReqPolicy))
|
||||
throw new TspValidationException("request contains unknown policy", PkiFailureInfo.UnacceptedPolicy);
|
||||
|
||||
if (this.Extensions != null && extensions != null)
|
||||
{
|
||||
foreach (DerObjectIdentifier oid in this.Extensions.ExtensionOids)
|
||||
{
|
||||
if (!extensions.Contains(oid.Id))
|
||||
throw new TspValidationException("request contains unknown extension", PkiFailureInfo.UnacceptedExtension);
|
||||
}
|
||||
}
|
||||
|
||||
int digestLength = TspUtil.GetDigestLength(this.MessageImprintAlgOid);
|
||||
|
||||
if (digestLength != this.GetMessageImprintDigest().Length)
|
||||
throw new TspValidationException("imprint digest the wrong length", PkiFailureInfo.BadDataFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the ASN.1 encoded representation of this object.
|
||||
*/
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return req.GetEncoded();
|
||||
}
|
||||
|
||||
internal X509Extensions Extensions
|
||||
{
|
||||
get { return req.Extensions; }
|
||||
}
|
||||
|
||||
public virtual bool HasExtensions
|
||||
{
|
||||
get { return extensions != null; }
|
||||
}
|
||||
|
||||
public virtual X509Extension GetExtension(DerObjectIdentifier oid)
|
||||
{
|
||||
return extensions == null ? null : extensions.GetExtension(oid);
|
||||
}
|
||||
|
||||
public virtual IList<DerObjectIdentifier> GetExtensionOids()
|
||||
{
|
||||
return TspUtil.GetExtensionOids(extensions);
|
||||
}
|
||||
|
||||
protected override X509Extensions GetX509Extensions()
|
||||
{
|
||||
return Extensions;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3f95e3ff8f9fee4d8c530f910ce5104
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,98 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
/**
|
||||
* Generator for RFC 3161 Time Stamp Request objects.
|
||||
*/
|
||||
public class TimeStampRequestGenerator
|
||||
{
|
||||
private DerObjectIdentifier reqPolicy;
|
||||
|
||||
private DerBoolean certReq;
|
||||
|
||||
private Dictionary<DerObjectIdentifier, X509Extension> m_extensions =
|
||||
new Dictionary<DerObjectIdentifier, X509Extension>();
|
||||
private List<DerObjectIdentifier> m_ordering = new List<DerObjectIdentifier>();
|
||||
|
||||
public void SetReqPolicy(string reqPolicy)
|
||||
{
|
||||
this.reqPolicy = new DerObjectIdentifier(reqPolicy);
|
||||
}
|
||||
|
||||
public void SetCertReq(bool certReq)
|
||||
{
|
||||
this.certReq = DerBoolean.GetInstance(certReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* add a given extension field for the standard extensions tag (tag 3)
|
||||
* @throws IOException
|
||||
*/
|
||||
public virtual void AddExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable extValue)
|
||||
{
|
||||
this.AddExtension(oid, critical, extValue.GetEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* add a given extension field for the standard extensions tag
|
||||
* The value parameter becomes the contents of the octet string associated
|
||||
* with the extension.
|
||||
*/
|
||||
public virtual void AddExtension(DerObjectIdentifier oid, bool critical, byte[] extValue)
|
||||
{
|
||||
m_extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue)));
|
||||
m_ordering.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 digestAlgOid = new DerObjectIdentifier(digestAlgorithmOid);
|
||||
|
||||
AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOid, DerNull.Instance);
|
||||
MessageImprint messageImprint = new MessageImprint(algID, digest);
|
||||
|
||||
X509Extensions ext = null;
|
||||
|
||||
if (m_ordering.Count > 0)
|
||||
{
|
||||
ext = new X509Extensions(m_ordering, m_extensions);
|
||||
}
|
||||
|
||||
DerInteger derNonce = nonce == null ? null : new DerInteger(nonce);
|
||||
|
||||
return new TimeStampRequest(
|
||||
new TimeStampReq(messageImprint, reqPolicy, derNonce, certReq, ext));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cb85a8797248f249a9b03c64d756801
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,188 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
/**
|
||||
* Base class for an RFC 3161 Time Stamp Response object.
|
||||
*/
|
||||
public class TimeStampResponse
|
||||
{
|
||||
private TimeStampResp resp;
|
||||
private TimeStampToken timeStampToken;
|
||||
|
||||
public TimeStampResponse(
|
||||
TimeStampResp resp)
|
||||
{
|
||||
this.resp = resp;
|
||||
|
||||
if (resp.TimeStampToken != null)
|
||||
{
|
||||
timeStampToken = new TimeStampToken(resp.TimeStampToken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TimeStampResponse from a byte array containing an ASN.1 encoding.
|
||||
*
|
||||
* @param resp the byte array containing the encoded response.
|
||||
* @throws TspException if the response is malformed.
|
||||
* @throws IOException if the byte array doesn't represent an ASN.1 encoding.
|
||||
*/
|
||||
public TimeStampResponse(
|
||||
byte[] resp)
|
||||
: this(readTimeStampResp(new Asn1InputStream(resp)))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TimeStampResponse from an input stream containing an ASN.1 encoding.
|
||||
*
|
||||
* @param input the input stream containing the encoded response.
|
||||
* @throws TspException if the response is malformed.
|
||||
* @throws IOException if the stream doesn't represent an ASN.1 encoding.
|
||||
*/
|
||||
public TimeStampResponse(
|
||||
Stream input)
|
||||
: this(readTimeStampResp(new Asn1InputStream(input)))
|
||||
{
|
||||
}
|
||||
|
||||
private static TimeStampResp readTimeStampResp(
|
||||
Asn1InputStream input)
|
||||
{
|
||||
try
|
||||
{
|
||||
return TimeStampResp.GetInstance(input.ReadObject());
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new TspException("malformed timestamp response: " + e, e);
|
||||
}
|
||||
catch (InvalidCastException e)
|
||||
{
|
||||
throw new TspException("malformed timestamp response: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
public int Status
|
||||
{
|
||||
get { return resp.Status.Status.IntValue; }
|
||||
}
|
||||
|
||||
public string GetStatusString()
|
||||
{
|
||||
if (resp.Status.StatusString == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder statusStringBuf = new StringBuilder();
|
||||
PkiFreeText text = resp.Status.StatusString;
|
||||
for (int i = 0; i != text.Count; i++)
|
||||
{
|
||||
statusStringBuf.Append(text[i].GetString());
|
||||
}
|
||||
|
||||
return statusStringBuf.ToString();
|
||||
}
|
||||
|
||||
public PkiFailureInfo GetFailInfo()
|
||||
{
|
||||
if (resp.Status.FailInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new PkiFailureInfo(resp.Status.FailInfo);
|
||||
}
|
||||
|
||||
public TimeStampToken TimeStampToken
|
||||
{
|
||||
get { return timeStampToken; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Check this response against to see if it a well formed response for
|
||||
* the passed in request. Validation will include checking the time stamp
|
||||
* token if the response status is GRANTED or GRANTED_WITH_MODS.
|
||||
*
|
||||
* @param request the request to be checked against
|
||||
* @throws TspException if the request can not match this response.
|
||||
*/
|
||||
public void Validate(
|
||||
TimeStampRequest request)
|
||||
{
|
||||
TimeStampToken tok = this.TimeStampToken;
|
||||
|
||||
if (tok != null)
|
||||
{
|
||||
TimeStampTokenInfo tstInfo = tok.TimeStampInfo;
|
||||
|
||||
if (request.Nonce != null && !request.Nonce.Equals(tstInfo.Nonce))
|
||||
{
|
||||
throw new TspValidationException("response contains wrong nonce value.");
|
||||
}
|
||||
|
||||
if (this.Status != (int) PkiStatus.Granted && this.Status != (int) PkiStatus.GrantedWithMods)
|
||||
{
|
||||
throw new TspValidationException("time stamp token found in failed request.");
|
||||
}
|
||||
|
||||
if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest()))
|
||||
{
|
||||
throw new TspValidationException("response for different message imprint digest.");
|
||||
}
|
||||
|
||||
if (!tstInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid))
|
||||
{
|
||||
throw new TspValidationException("response for different message imprint algorithm.");
|
||||
}
|
||||
|
||||
Asn1.Cms.Attribute scV1 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate];
|
||||
Asn1.Cms.Attribute scV2 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2];
|
||||
|
||||
if (scV1 == null && scV2 == null)
|
||||
{
|
||||
throw new TspValidationException("no signing certificate attribute present.");
|
||||
}
|
||||
|
||||
if (scV1 != null && scV2 != null)
|
||||
{
|
||||
/*
|
||||
* RFC 5035 5.4. If both attributes exist in a single message,
|
||||
* they are independently evaluated.
|
||||
*/
|
||||
}
|
||||
|
||||
if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy))
|
||||
{
|
||||
throw new TspValidationException("TSA policy wrong for request.");
|
||||
}
|
||||
}
|
||||
else if (this.Status == (int) PkiStatus.Granted || this.Status == (int) PkiStatus.GrantedWithMods)
|
||||
{
|
||||
throw new TspValidationException("no time stamp token found and one expected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the ASN.1 encoded representation of this object.
|
||||
*/
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return resp.GetEncoded();
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b7d9336b3bad4448a81aa956426c6d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,259 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
/**
|
||||
* Generator for RFC 3161 Time Stamp Responses.
|
||||
*/
|
||||
public class TimeStampResponseGenerator
|
||||
{
|
||||
private PkiStatus status;
|
||||
|
||||
private Asn1EncodableVector statusStrings;
|
||||
|
||||
private int failInfo;
|
||||
private TimeStampTokenGenerator tokenGenerator;
|
||||
private IList<string> acceptedAlgorithms;
|
||||
private IList<string> acceptedPolicies;
|
||||
private IList<string> acceptedExtensions;
|
||||
|
||||
public TimeStampResponseGenerator(
|
||||
TimeStampTokenGenerator tokenGenerator,
|
||||
IList<string> acceptedAlgorithms)
|
||||
: this(tokenGenerator, acceptedAlgorithms, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public TimeStampResponseGenerator(
|
||||
TimeStampTokenGenerator tokenGenerator,
|
||||
IList<string> acceptedAlgorithms,
|
||||
IList<string> acceptedPolicy)
|
||||
: this(tokenGenerator, acceptedAlgorithms, acceptedPolicy, null)
|
||||
{
|
||||
}
|
||||
|
||||
public TimeStampResponseGenerator(
|
||||
TimeStampTokenGenerator tokenGenerator,
|
||||
IList<string> acceptedAlgorithms,
|
||||
IList<string> acceptedPolicies,
|
||||
IList<string> 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 v = new Asn1EncodableVector(
|
||||
new DerInteger((int)status));
|
||||
|
||||
if (statusStrings.Count > 0)
|
||||
{
|
||||
v.Add(new PkiFreeText(new DerSequence(statusStrings)));
|
||||
}
|
||||
|
||||
if (failInfo != 0)
|
||||
{
|
||||
v.Add(new FailInfo(failInfo));
|
||||
}
|
||||
|
||||
return new PkiStatusInfo(new DerSequence(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an appropriate TimeStampResponse.
|
||||
* <p>
|
||||
* If genTime is null a timeNotAvailable error response will be returned.
|
||||
*
|
||||
* @param request the request this response is for.
|
||||
* @param serialNumber serial number for the response token.
|
||||
* @param genTime generation time for the response token.
|
||||
* @param provider provider to use for signature calculation.
|
||||
* @return
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws NoSuchProviderException
|
||||
* @throws TSPException
|
||||
* </p>
|
||||
*/
|
||||
public TimeStampResponse Generate(TimeStampRequest request, BigInteger serialNumber, DateTime? genTime)
|
||||
{
|
||||
TimeStampResp resp;
|
||||
|
||||
try
|
||||
{
|
||||
if (genTime == null)
|
||||
throw new TspValidationException("The time source is not available.",
|
||||
PkiFailureInfo.TimeNotAvailable);
|
||||
|
||||
request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions);
|
||||
|
||||
this.status = PkiStatus.Granted;
|
||||
this.AddStatusString("Operation Okay");
|
||||
|
||||
PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
|
||||
|
||||
ContentInfo tstTokenContentInfo;
|
||||
try
|
||||
{
|
||||
TimeStampToken token = tokenGenerator.Generate(request, serialNumber, genTime.Value);
|
||||
byte[] encoded = token.ToCmsSignedData().GetEncoded();
|
||||
|
||||
tstTokenContentInfo = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TspException("Timestamp token received cannot be converted to ContentInfo", e);
|
||||
}
|
||||
|
||||
resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo);
|
||||
}
|
||||
catch (TspValidationException e)
|
||||
{
|
||||
status = PkiStatus.Rejection;
|
||||
|
||||
this.SetFailInfoField(e.FailureCode);
|
||||
this.AddStatusString(e.Message);
|
||||
|
||||
PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
|
||||
|
||||
resp = new TimeStampResp(pkiStatusInfo, null);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new TimeStampResponse(resp);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TspException("created badly formatted response!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public TimeStampResponse GenerateGrantedResponse(TimeStampRequest request, BigInteger serialNumber,
|
||||
DateTime? genTime, string statusString, X509Extensions additionalExtensions)
|
||||
{
|
||||
TimeStampResp resp;
|
||||
|
||||
try
|
||||
{
|
||||
if (genTime == null)
|
||||
throw new TspValidationException("The time source is not available.",
|
||||
PkiFailureInfo.TimeNotAvailable);
|
||||
|
||||
request.Validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions);
|
||||
|
||||
this.status = PkiStatus.Granted;
|
||||
this.AddStatusString(statusString);
|
||||
|
||||
PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
|
||||
|
||||
ContentInfo tstTokenContentInfo;
|
||||
try
|
||||
{
|
||||
TimeStampToken token = tokenGenerator.Generate(request, serialNumber, genTime.Value,additionalExtensions);
|
||||
byte[] encoded = token.ToCmsSignedData().GetEncoded();
|
||||
|
||||
tstTokenContentInfo = ContentInfo.GetInstance(Asn1Object.FromByteArray(encoded));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TspException("Timestamp token received cannot be converted to ContentInfo", e);
|
||||
}
|
||||
|
||||
resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo);
|
||||
}
|
||||
catch (TspValidationException e)
|
||||
{
|
||||
status = PkiStatus.Rejection;
|
||||
|
||||
this.SetFailInfoField(e.FailureCode);
|
||||
this.AddStatusString(e.Message);
|
||||
|
||||
PkiStatusInfo pkiStatusInfo = GetPkiStatusInfo();
|
||||
|
||||
resp = new TimeStampResp(pkiStatusInfo, null);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return new TimeStampResponse(resp);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TspException("created badly formatted response!", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class FailInfo
|
||||
: DerBitString
|
||||
{
|
||||
internal FailInfo(int failInfoValue)
|
||||
: base(failInfoValue)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a TimeStampResponse with chosen status and FailInfoField.
|
||||
*
|
||||
* @param status the PKIStatus to set.
|
||||
* @param failInfoField the FailInfoField to set.
|
||||
* @param statusString an optional string describing the failure.
|
||||
* @return a TimeStampResponse with a failInfoField and optional statusString
|
||||
* @throws TSPException in case the response could not be created
|
||||
*/
|
||||
public TimeStampResponse GenerateFailResponse(PkiStatus status, int failInfoField, string statusString)
|
||||
{
|
||||
this.status = status;
|
||||
|
||||
this.SetFailInfoField(failInfoField);
|
||||
|
||||
if (statusString != null)
|
||||
{
|
||||
this.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31244340abddb5d4ca611f3cc612ee24
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,308 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Ess;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Cms;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
public class TimeStampToken
|
||||
{
|
||||
private readonly CmsSignedData tsToken;
|
||||
private readonly SignerInformation tsaSignerInfo;
|
||||
// private readonly DateTime genTime;
|
||||
private readonly TimeStampTokenInfo tstInfo;
|
||||
private readonly CertID certID;
|
||||
|
||||
public TimeStampToken(
|
||||
Asn1.Cms.ContentInfo contentInfo)
|
||||
: this(new CmsSignedData(contentInfo))
|
||||
{
|
||||
}
|
||||
|
||||
public TimeStampToken(
|
||||
CmsSignedData signedData)
|
||||
{
|
||||
this.tsToken = signedData;
|
||||
|
||||
if (!this.tsToken.SignedContentType.Equals(PkcsObjectIdentifiers.IdCTTstInfo))
|
||||
{
|
||||
throw new TspValidationException("ContentInfo object not for a time stamp.");
|
||||
}
|
||||
|
||||
var 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.");
|
||||
}
|
||||
|
||||
|
||||
var signerEnum = signers.GetEnumerator();
|
||||
|
||||
signerEnum.MoveNext();
|
||||
tsaSignerInfo = 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]);
|
||||
|
||||
if (attr != null)
|
||||
{
|
||||
|
||||
if (attr.AttrValues[0] is SigningCertificateV2)
|
||||
{
|
||||
SigningCertificateV2 signCert = SigningCertificateV2.GetInstance(attr.AttrValues[0]);
|
||||
this.certID = new CertID(EssCertIDv2.GetInstance(signCert.GetCerts()[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
SigningCertificate signCert = SigningCertificate.GetInstance(attr.AttrValues[0]);
|
||||
this.certID = new CertID(EssCertID.GetInstance(signCert.GetCerts()[0]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attr = tsaSignerInfo.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2];
|
||||
|
||||
if (attr == null)
|
||||
throw new TspValidationException("no signing certificate attribute found, time stamp invalid.");
|
||||
|
||||
SigningCertificateV2 signCertV2 = SigningCertificateV2.GetInstance(attr.AttrValues[0]);
|
||||
|
||||
this.certID = new CertID(EssCertIDv2.GetInstance(signCertV2.GetCerts()[0]));
|
||||
}
|
||||
}
|
||||
catch (CmsException e)
|
||||
{
|
||||
throw new TspException(e.Message, e.InnerException);
|
||||
}
|
||||
}
|
||||
|
||||
public TimeStampTokenInfo TimeStampInfo
|
||||
{
|
||||
get { return tstInfo; }
|
||||
}
|
||||
|
||||
public SignerID SignerID
|
||||
{
|
||||
get { return tsaSignerInfo.SignerID; }
|
||||
}
|
||||
|
||||
public Asn1.Cms.AttributeTable SignedAttributes
|
||||
{
|
||||
get { return tsaSignerInfo.SignedAttributes; }
|
||||
}
|
||||
|
||||
public Asn1.Cms.AttributeTable UnsignedAttributes
|
||||
{
|
||||
get { return tsaSignerInfo.UnsignedAttributes; }
|
||||
}
|
||||
|
||||
public IStore<X509V2AttributeCertificate> GetAttributeCertificates() => tsToken.GetAttributeCertificates();
|
||||
|
||||
public IStore<X509Certificate> GetCertificates() => tsToken.GetCertificates();
|
||||
|
||||
public IStore<X509Crl> GetCrls() => tsToken.GetCrls();
|
||||
|
||||
/**
|
||||
* Validate the time stamp token.
|
||||
* <p>
|
||||
* To be valid the token must be signed by the passed in certificate and
|
||||
* the certificate must be the one referred to by the SigningCertificate
|
||||
* attribute included in the hashed attributes of the token. The
|
||||
* certificate must also have the ExtendedKeyUsageExtension with only
|
||||
* KeyPurposeID.IdKPTimeStamping and have been valid at the time the
|
||||
* timestamp was created.
|
||||
* </p>
|
||||
* <p>
|
||||
* A successful call to validate means all the above are true.
|
||||
* </p>
|
||||
*/
|
||||
public void Validate(
|
||||
X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] hash = DigestUtilities.CalculateDigest(
|
||||
certID.GetHashAlgorithmName(), cert.GetEncoded());
|
||||
|
||||
if (!Arrays.ConstantTimeAreEqual(certID.GetCertHash(), hash))
|
||||
throw new TspValidationException("certificate hash does not match certID hash.");
|
||||
|
||||
if (certID.IssuerSerial != null)
|
||||
{
|
||||
if (!certID.IssuerSerial.Serial.HasValue(cert.SerialNumber))
|
||||
throw new TspValidationException("certificate serial number does not match certID for signature.");
|
||||
|
||||
GeneralName[] names = certID.IssuerSerial.Issuer.GetNames();
|
||||
X509Name principal = PrincipalUtilities.GetIssuerX509Principal(cert);
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
if (names[i].TagNo == 4
|
||||
&& X509Name.GetInstance(names[i].Name).Equivalent(principal))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
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 e)
|
||||
{
|
||||
if (e.InnerException != null)
|
||||
{
|
||||
throw new TspException(e.Message, e.InnerException);
|
||||
}
|
||||
|
||||
throw new TspException("CMS exception: " + e, e);
|
||||
}
|
||||
catch (CertificateEncodingException e)
|
||||
{
|
||||
throw new TspException("problem processing certificate: " + e, e);
|
||||
}
|
||||
catch (SecurityUtilityException e)
|
||||
{
|
||||
throw new TspException("cannot find algorithm: " + e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying CmsSignedData object.
|
||||
*
|
||||
* @return the underlying CMS structure.
|
||||
*/
|
||||
public CmsSignedData ToCmsSignedData()
|
||||
{
|
||||
return tsToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a ASN.1 encoded byte stream representing the encoded object.
|
||||
*
|
||||
* @throws IOException if encoding fails.
|
||||
*/
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return tsToken.GetEncoded(Asn1Encodable.Der);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the ASN.1 encoded representation of this object using the specified encoding.
|
||||
*
|
||||
* @param encoding the ASN.1 encoding format to use ("BER" or "DER").
|
||||
*/
|
||||
public byte[] GetEncoded(string encoding)
|
||||
{
|
||||
return tsToken.GetEncoded(encoding);
|
||||
}
|
||||
|
||||
// perhaps this should be done using an interface on the ASN.1 classes...
|
||||
private class CertID
|
||||
{
|
||||
private EssCertID certID;
|
||||
private EssCertIDv2 certIDv2;
|
||||
|
||||
internal CertID(EssCertID certID)
|
||||
{
|
||||
this.certID = certID;
|
||||
this.certIDv2 = null;
|
||||
}
|
||||
|
||||
internal CertID(EssCertIDv2 certID)
|
||||
{
|
||||
this.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()
|
||||
{
|
||||
return (certID != null)
|
||||
? new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1)
|
||||
: certIDv2.HashAlgorithm;
|
||||
}
|
||||
|
||||
public byte[] GetCertHash()
|
||||
{
|
||||
return certID != null
|
||||
? certID.GetCertHash()
|
||||
: certIDv2.GetCertHash();
|
||||
}
|
||||
|
||||
public IssuerSerial IssuerSerial
|
||||
{
|
||||
get
|
||||
{
|
||||
return certID != null
|
||||
? certID.IssuerSerial
|
||||
: certIDv2.IssuerSerial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e001862fca691964183bd415e4c373b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,452 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Ess;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Cms;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Operators;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Date;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
public enum Resolution
|
||||
{
|
||||
R_SECONDS, R_TENTHS_OF_SECONDS, R_HUNDREDTHS_OF_SECONDS, R_MILLISECONDS
|
||||
}
|
||||
|
||||
public class TimeStampTokenGenerator
|
||||
{
|
||||
private int accuracySeconds = -1;
|
||||
private int accuracyMillis = -1;
|
||||
private int accuracyMicros = -1;
|
||||
private bool ordering = false;
|
||||
private GeneralName tsa = null;
|
||||
private DerObjectIdentifier tsaPolicyOID;
|
||||
|
||||
private IStore<X509Certificate> x509Certs;
|
||||
private IStore<X509Crl> x509Crls;
|
||||
private IStore<X509V2AttributeCertificate> x509AttrCerts;
|
||||
// TODO Port changes from bc-java
|
||||
//private Dictionary<> otherRevoc = new Dictionary<>();
|
||||
private SignerInfoGenerator signerInfoGenerator;
|
||||
IDigestFactory digestCalculator;
|
||||
|
||||
private Resolution resolution = Resolution.R_SECONDS;
|
||||
|
||||
public Resolution Resolution
|
||||
{
|
||||
get { return resolution; }
|
||||
set { resolution = value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* basic creation - only the default attributes will be included here.
|
||||
*/
|
||||
public TimeStampTokenGenerator(
|
||||
AsymmetricKeyParameter key,
|
||||
X509Certificate cert,
|
||||
string digestOID,
|
||||
string tsaPolicyOID)
|
||||
: this(key, cert, digestOID, tsaPolicyOID, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public TimeStampTokenGenerator(
|
||||
SignerInfoGenerator signerInfoGen,
|
||||
IDigestFactory digestCalculator,
|
||||
DerObjectIdentifier tsaPolicy,
|
||||
bool isIssuerSerialIncluded)
|
||||
{
|
||||
this.signerInfoGenerator = signerInfoGen;
|
||||
this.digestCalculator = digestCalculator;
|
||||
this.tsaPolicyOID = tsaPolicy;
|
||||
|
||||
if (signerInfoGenerator.certificate == null)
|
||||
throw new ArgumentException("SignerInfoGenerator must have an associated certificate");
|
||||
|
||||
X509Certificate assocCert = signerInfoGenerator.certificate;
|
||||
TspUtil.ValidateCertificate(assocCert);
|
||||
|
||||
try
|
||||
{
|
||||
byte[] certEnc = assocCert.GetEncoded();
|
||||
|
||||
IStreamCalculator<IBlockResult> calculator = digestCalculator.CreateCalculator();
|
||||
|
||||
using (var stream = calculator.Stream)
|
||||
{
|
||||
stream.Write(certEnc, 0, certEnc.Length);
|
||||
}
|
||||
|
||||
if (((AlgorithmIdentifier)digestCalculator.AlgorithmDetails).Algorithm.Equals(OiwObjectIdentifiers.IdSha1))
|
||||
{
|
||||
EssCertID essCertID = new EssCertID(
|
||||
calculator.GetResult().Collect(),
|
||||
isIssuerSerialIncluded ?
|
||||
new IssuerSerial(
|
||||
new GeneralNames(
|
||||
new GeneralName(assocCert.IssuerDN)),
|
||||
new DerInteger(assocCert.SerialNumber)) : null);
|
||||
|
||||
this.signerInfoGenerator = signerInfoGen.NewBuilder()
|
||||
.WithSignedAttributeGenerator(new TableGen(signerInfoGen, essCertID))
|
||||
.Build(signerInfoGen.contentSigner, signerInfoGen.certificate);
|
||||
}
|
||||
else
|
||||
{
|
||||
AlgorithmIdentifier digestAlgID = new AlgorithmIdentifier(
|
||||
((AlgorithmIdentifier)digestCalculator.AlgorithmDetails).Algorithm);
|
||||
|
||||
EssCertIDv2 essCertID = new EssCertIDv2(
|
||||
calculator.GetResult().Collect(),
|
||||
isIssuerSerialIncluded ?
|
||||
new IssuerSerial(
|
||||
new GeneralNames(
|
||||
new GeneralName(assocCert.IssuerDN)),
|
||||
new DerInteger(assocCert.SerialNumber)) : null);
|
||||
|
||||
this.signerInfoGenerator = signerInfoGen.NewBuilder()
|
||||
.WithSignedAttributeGenerator(new TableGen2(signerInfoGen, essCertID))
|
||||
.Build(signerInfoGen.contentSigner, signerInfoGen.certificate);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new TspException("Exception processing certificate", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create with a signer with extra signed/unsigned attributes.
|
||||
*/
|
||||
public TimeStampTokenGenerator(
|
||||
AsymmetricKeyParameter key,
|
||||
X509Certificate cert,
|
||||
string digestOID,
|
||||
string tsaPolicyOID,
|
||||
Asn1.Cms.AttributeTable signedAttr,
|
||||
Asn1.Cms.AttributeTable unsignedAttr) : this(
|
||||
makeInfoGenerator(key, cert, digestOID, signedAttr, unsignedAttr),
|
||||
Asn1DigestFactory.Get(OiwObjectIdentifiers.IdSha1),
|
||||
tsaPolicyOID != null ? new DerObjectIdentifier(tsaPolicyOID):null, false)
|
||||
{
|
||||
}
|
||||
|
||||
internal static SignerInfoGenerator makeInfoGenerator(
|
||||
AsymmetricKeyParameter key,
|
||||
X509Certificate cert,
|
||||
string digestOID,
|
||||
Asn1.Cms.AttributeTable signedAttr,
|
||||
Asn1.Cms.AttributeTable unsignedAttr)
|
||||
{
|
||||
TspUtil.ValidateCertificate(cert);
|
||||
|
||||
//
|
||||
// Add the ESSCertID attribute
|
||||
//
|
||||
IDictionary<DerObjectIdentifier, object> signedAttrs;
|
||||
if (signedAttr != null)
|
||||
{
|
||||
signedAttrs = signedAttr.ToDictionary();
|
||||
}
|
||||
else
|
||||
{
|
||||
signedAttrs = new Dictionary<DerObjectIdentifier, object>();
|
||||
}
|
||||
|
||||
//try
|
||||
//{
|
||||
// byte[] hash = DigestUtilities.CalculateDigest("SHA-1", cert.GetEncoded());
|
||||
|
||||
// EssCertID essCertid = new EssCertID(hash);
|
||||
|
||||
// Asn1.Cms.Attribute attr = new Asn1.Cms.Attribute(
|
||||
// PkcsObjectIdentifiers.IdAASigningCertificate,
|
||||
// new DerSet(new SigningCertificate(essCertid)));
|
||||
|
||||
// signedAttrs[attr.AttrType] = attr;
|
||||
//}
|
||||
//catch (CertificateEncodingException e)
|
||||
//{
|
||||
// throw new TspException("Exception processing certificate.", e);
|
||||
//}
|
||||
//catch (SecurityUtilityException e)
|
||||
//{
|
||||
// throw new TspException("Can't find a SHA-1 implementation.", e);
|
||||
//}
|
||||
|
||||
string digestName = CmsSignedHelper.Instance.GetDigestAlgName(digestOID);
|
||||
string signatureName = digestName + "with" + CmsSignedHelper.Instance.GetEncryptionAlgName(CmsSignedHelper.Instance.GetEncOid(key, digestOID));
|
||||
|
||||
Asn1SignatureFactory sigfact = new Asn1SignatureFactory(signatureName, key);
|
||||
return new SignerInfoGeneratorBuilder()
|
||||
.WithSignedAttributeGenerator(
|
||||
new DefaultSignedAttributeTableGenerator(
|
||||
new Asn1.Cms.AttributeTable(signedAttrs)))
|
||||
.WithUnsignedAttributeGenerator(
|
||||
new SimpleAttributeTableGenerator(unsignedAttr))
|
||||
.Build(sigfact, cert);
|
||||
}
|
||||
|
||||
public void SetAttributeCertificates(IStore<X509V2AttributeCertificate> attributeCertificates)
|
||||
{
|
||||
this.x509AttrCerts = attributeCertificates;
|
||||
}
|
||||
|
||||
public void SetCertificates(IStore<X509Certificate> certificates)
|
||||
{
|
||||
this.x509Certs = certificates;
|
||||
}
|
||||
|
||||
public void SetCrls(IStore<X509Crl> crls)
|
||||
{
|
||||
this.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)
|
||||
{
|
||||
return Generate(request, serialNumber, genTime, null);
|
||||
}
|
||||
|
||||
|
||||
public TimeStampToken Generate(
|
||||
TimeStampRequest request,
|
||||
BigInteger serialNumber,
|
||||
DateTime genTime, X509Extensions additionalExtensions)
|
||||
{
|
||||
DerObjectIdentifier digestAlgOID = new DerObjectIdentifier(request.MessageImprintAlgOid);
|
||||
|
||||
AlgorithmIdentifier algID = new AlgorithmIdentifier(digestAlgOID, DerNull.Instance);
|
||||
MessageImprint messageImprint = new MessageImprint(algID, 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 derOrdering = null;
|
||||
if (ordering)
|
||||
{
|
||||
derOrdering = DerBoolean.GetInstance(ordering);
|
||||
}
|
||||
|
||||
DerInteger nonce = null;
|
||||
if (request.Nonce != null)
|
||||
{
|
||||
nonce = new DerInteger(request.Nonce);
|
||||
}
|
||||
|
||||
DerObjectIdentifier tsaPolicy = tsaPolicyOID;
|
||||
if (request.ReqPolicy != null)
|
||||
{
|
||||
tsaPolicy = new DerObjectIdentifier(request.ReqPolicy);
|
||||
}
|
||||
|
||||
if (tsaPolicy == null)
|
||||
{
|
||||
throw new TspValidationException("request contains no policy", PkiFailureInfo.UnacceptedPolicy);
|
||||
}
|
||||
|
||||
X509Extensions respExtensions = request.Extensions;
|
||||
if (additionalExtensions != null)
|
||||
{
|
||||
X509ExtensionsGenerator extGen = new X509ExtensionsGenerator();
|
||||
|
||||
if (respExtensions != null)
|
||||
{
|
||||
foreach(object oid in respExtensions.ExtensionOids)
|
||||
{
|
||||
DerObjectIdentifier id = DerObjectIdentifier.GetInstance(oid);
|
||||
extGen.AddExtension(id, respExtensions.GetExtension(DerObjectIdentifier.GetInstance(id)));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (object oid in additionalExtensions.ExtensionOids)
|
||||
{
|
||||
DerObjectIdentifier id = DerObjectIdentifier.GetInstance(oid);
|
||||
extGen.AddExtension(id, additionalExtensions.GetExtension(DerObjectIdentifier.GetInstance(id)));
|
||||
|
||||
}
|
||||
|
||||
respExtensions = extGen.Generate();
|
||||
}
|
||||
|
||||
var timeStampTime = new Asn1GeneralizedTime(WithResolution(genTime, resolution));
|
||||
|
||||
TstInfo tstInfo = new TstInfo(tsaPolicy, messageImprint,
|
||||
new DerInteger(serialNumber), timeStampTime, accuracy,
|
||||
derOrdering, nonce, tsa, respExtensions);
|
||||
|
||||
try
|
||||
{
|
||||
CmsSignedDataGenerator signedDataGenerator = new CmsSignedDataGenerator();
|
||||
|
||||
byte[] derEncodedTstInfo = tstInfo.GetDerEncoded();
|
||||
|
||||
if (request.CertReq)
|
||||
{
|
||||
signedDataGenerator.AddCertificates(x509Certs);
|
||||
signedDataGenerator.AddAttributeCertificates(x509AttrCerts);
|
||||
}
|
||||
|
||||
signedDataGenerator.AddCrls(x509Crls);
|
||||
|
||||
signedDataGenerator.AddSignerInfoGenerator(signerInfoGenerator);
|
||||
|
||||
CmsSignedData signedData = signedDataGenerator.Generate(
|
||||
PkcsObjectIdentifiers.IdCTTstInfo.Id,
|
||||
new CmsProcessableByteArray(derEncodedTstInfo),
|
||||
true);
|
||||
|
||||
return new TimeStampToken(signedData);
|
||||
}
|
||||
catch (CmsException cmsEx)
|
||||
{
|
||||
throw new TspException("Error generating time-stamp token", cmsEx);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new TspException("Exception encoding info", e);
|
||||
}
|
||||
//catch (InvalidAlgorithmParameterException e)
|
||||
//{
|
||||
// throw new TspException("Exception handling CertStore CRLs", e);
|
||||
//}
|
||||
}
|
||||
|
||||
private static DateTime WithResolution(DateTime dateTime, Resolution resolution)
|
||||
{
|
||||
switch (resolution)
|
||||
{
|
||||
case Resolution.R_SECONDS:
|
||||
return DateTimeUtilities.WithPrecisionSecond(dateTime);
|
||||
case Resolution.R_TENTHS_OF_SECONDS:
|
||||
return DateTimeUtilities.WithPrecisionDecisecond(dateTime);
|
||||
case Resolution.R_HUNDREDTHS_OF_SECONDS:
|
||||
return DateTimeUtilities.WithPrecisionCentisecond(dateTime);
|
||||
case Resolution.R_MILLISECONDS:
|
||||
return DateTimeUtilities.WithPrecisionMillisecond(dateTime);
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private class TableGen
|
||||
: CmsAttributeTableGenerator
|
||||
{
|
||||
private readonly SignerInfoGenerator infoGen;
|
||||
private readonly EssCertID essCertID;
|
||||
|
||||
|
||||
public TableGen(SignerInfoGenerator infoGen, EssCertID essCertID)
|
||||
{
|
||||
this.infoGen = infoGen;
|
||||
this.essCertID = essCertID;
|
||||
}
|
||||
|
||||
public Asn1.Cms.AttributeTable GetAttributes(IDictionary<CmsAttributeTableParameter, object> parameters)
|
||||
{
|
||||
Asn1.Cms.AttributeTable tab = infoGen.signedGen.GetAttributes(parameters);
|
||||
if (tab[PkcsObjectIdentifiers.IdAASigningCertificate] == null)
|
||||
{
|
||||
return tab.Add(PkcsObjectIdentifiers.IdAASigningCertificate, new SigningCertificate(essCertID));
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
|
||||
private class TableGen2
|
||||
: CmsAttributeTableGenerator
|
||||
{
|
||||
private readonly SignerInfoGenerator infoGen;
|
||||
private readonly EssCertIDv2 essCertID;
|
||||
|
||||
|
||||
public TableGen2(SignerInfoGenerator infoGen, EssCertIDv2 essCertID)
|
||||
{
|
||||
this.infoGen = infoGen;
|
||||
this.essCertID = essCertID;
|
||||
}
|
||||
|
||||
public Asn1.Cms.AttributeTable GetAttributes(IDictionary<CmsAttributeTableParameter, object> parameters)
|
||||
{
|
||||
Asn1.Cms.AttributeTable tab = infoGen.signedGen.GetAttributes(parameters);
|
||||
if (tab[PkcsObjectIdentifiers.IdAASigningCertificateV2] == null)
|
||||
{
|
||||
return tab.Add(PkcsObjectIdentifiers.IdAASigningCertificateV2, new SigningCertificateV2(essCertID));
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d1991286d37694478ba89a7c392c9bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||||
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp
|
||||
{
|
||||
public class TimeStampTokenInfo
|
||||
{
|
||||
private static TstInfo ParseTstInfo(byte[] tstInfoEncoding)
|
||||
{
|
||||
try
|
||||
{
|
||||
return TstInfo.GetInstance(tstInfoEncoding);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new TspException("unable to parse TstInfo encoding: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private TstInfo tstInfo;
|
||||
private DateTime genTime;
|
||||
|
||||
public TimeStampTokenInfo(byte[] tstInfoEncoding)
|
||||
: this(ParseTstInfo(tstInfoEncoding))
|
||||
{
|
||||
}
|
||||
|
||||
public TimeStampTokenInfo(
|
||||
TstInfo tstInfo)
|
||||
{
|
||||
this.tstInfo = tstInfo;
|
||||
|
||||
try
|
||||
{
|
||||
this.genTime = tstInfo.GenTime.ToDateTime();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new TspException("unable to parse genTime field: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOrdered
|
||||
{
|
||||
get { return tstInfo.Ordering.IsTrue; }
|
||||
}
|
||||
|
||||
public Accuracy Accuracy
|
||||
{
|
||||
get { return tstInfo.Accuracy; }
|
||||
}
|
||||
|
||||
public DateTime GenTime
|
||||
{
|
||||
get { return genTime; }
|
||||
}
|
||||
|
||||
public GenTimeAccuracy GenTimeAccuracy
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Accuracy == null
|
||||
? null
|
||||
: new GenTimeAccuracy(this.Accuracy);
|
||||
}
|
||||
}
|
||||
|
||||
public string Policy
|
||||
{
|
||||
get { return tstInfo.Policy.Id; }
|
||||
}
|
||||
|
||||
public BigInteger SerialNumber
|
||||
{
|
||||
get { return tstInfo.SerialNumber.Value; }
|
||||
}
|
||||
|
||||
public GeneralName Tsa
|
||||
{
|
||||
get { return tstInfo.Tsa; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nonce value, null if there isn't one.
|
||||
*/
|
||||
public BigInteger Nonce
|
||||
{
|
||||
get
|
||||
{
|
||||
return tstInfo.Nonce == null
|
||||
? null
|
||||
: tstInfo.Nonce.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier HashAlgorithm
|
||||
{
|
||||
get { return tstInfo.MessageImprint.HashAlgorithm; }
|
||||
}
|
||||
|
||||
public string MessageImprintAlgOid
|
||||
{
|
||||
get { return tstInfo.MessageImprint.HashAlgorithm.Algorithm.Id; }
|
||||
}
|
||||
|
||||
public byte[] GetMessageImprintDigest()
|
||||
{
|
||||
return tstInfo.MessageImprint.GetHashedMessage();
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
return tstInfo.GetEncoded();
|
||||
}
|
||||
|
||||
public TstInfo TstInfo
|
||||
{
|
||||
get { return tstInfo; }
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb197672beb7bd749971431ab1bb00bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user