123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.Collections;
- 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.X509;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
- 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.");
- }
- 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 signerEnum = signers.GetEnumerator();
- signerEnum.MoveNext();
- tsaSignerInfo = (SignerInformation) 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 IX509Store GetCertificates(
- string type)
- {
- return tsToken.GetCertificates(type);
- }
- public IX509Store GetCrls(
- string type)
- {
- return tsToken.GetCrls(type);
- }
- public IX509Store GetCertificates()
- {
- return tsToken.GetCertificates();
- }
- public IX509Store GetAttributeCertificates(
- string type)
- {
- return tsToken.GetAttributeCertificates(type);
- }
- /**
- * 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
|