222 lines
5.5 KiB
C#
222 lines
5.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using Org.BouncyCastle.Asn1;
|
|
using Org.BouncyCastle.Asn1.X509;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Crypto.Operators;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Security;
|
|
using Org.BouncyCastle.Security.Certificates;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
namespace Org.BouncyCastle.X509;
|
|
|
|
public class X509V2AttributeCertificate : X509ExtensionBase, IX509AttributeCertificate, IX509Extension
|
|
{
|
|
private readonly AttributeCertificate cert;
|
|
|
|
private readonly DateTime notBefore;
|
|
|
|
private readonly DateTime notAfter;
|
|
|
|
public virtual int Version => cert.ACInfo.Version.Value.IntValue + 1;
|
|
|
|
public virtual BigInteger SerialNumber => cert.ACInfo.SerialNumber.Value;
|
|
|
|
public virtual AttributeCertificateHolder Holder => new AttributeCertificateHolder((Asn1Sequence)cert.ACInfo.Holder.ToAsn1Object());
|
|
|
|
public virtual AttributeCertificateIssuer Issuer => new AttributeCertificateIssuer(cert.ACInfo.Issuer);
|
|
|
|
public virtual DateTime NotBefore => notBefore;
|
|
|
|
public virtual DateTime NotAfter => notAfter;
|
|
|
|
public virtual bool IsValidNow => IsValid(DateTime.UtcNow);
|
|
|
|
public virtual AlgorithmIdentifier SignatureAlgorithm => cert.SignatureAlgorithm;
|
|
|
|
private static AttributeCertificate GetObject(Stream input)
|
|
{
|
|
try
|
|
{
|
|
return AttributeCertificate.GetInstance(Asn1Object.FromStream(input));
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
catch (Exception innerException)
|
|
{
|
|
throw new IOException("exception decoding certificate structure", innerException);
|
|
}
|
|
}
|
|
|
|
public X509V2AttributeCertificate(Stream encIn)
|
|
: this(GetObject(encIn))
|
|
{
|
|
}
|
|
|
|
public X509V2AttributeCertificate(byte[] encoded)
|
|
: this(new MemoryStream(encoded, writable: false))
|
|
{
|
|
}
|
|
|
|
internal X509V2AttributeCertificate(AttributeCertificate cert)
|
|
{
|
|
this.cert = cert;
|
|
try
|
|
{
|
|
notAfter = cert.ACInfo.AttrCertValidityPeriod.NotAfterTime.ToDateTime();
|
|
notBefore = cert.ACInfo.AttrCertValidityPeriod.NotBeforeTime.ToDateTime();
|
|
}
|
|
catch (Exception innerException)
|
|
{
|
|
throw new IOException("invalid data structure in certificate!", innerException);
|
|
}
|
|
}
|
|
|
|
public virtual bool[] GetIssuerUniqueID()
|
|
{
|
|
DerBitString issuerUniqueID = cert.ACInfo.IssuerUniqueID;
|
|
if (issuerUniqueID != null)
|
|
{
|
|
byte[] bytes = issuerUniqueID.GetBytes();
|
|
bool[] array = new bool[bytes.Length * 8 - issuerUniqueID.PadBits];
|
|
for (int i = 0; i != array.Length; i++)
|
|
{
|
|
array[i] = (bytes[i / 8] & (128 >> i % 8)) != 0;
|
|
}
|
|
return array;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public virtual bool IsValid(DateTime date)
|
|
{
|
|
if (date.CompareTo((object?)NotBefore) >= 0)
|
|
{
|
|
return date.CompareTo((object?)NotAfter) <= 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public virtual void CheckValidity()
|
|
{
|
|
CheckValidity(DateTime.UtcNow);
|
|
}
|
|
|
|
public virtual void CheckValidity(DateTime date)
|
|
{
|
|
if (date.CompareTo((object?)NotAfter) > 0)
|
|
{
|
|
throw new CertificateExpiredException("certificate expired on " + NotAfter);
|
|
}
|
|
if (date.CompareTo((object?)NotBefore) < 0)
|
|
{
|
|
throw new CertificateNotYetValidException("certificate not valid until " + NotBefore);
|
|
}
|
|
}
|
|
|
|
public virtual byte[] GetSignature()
|
|
{
|
|
return cert.GetSignatureOctets();
|
|
}
|
|
|
|
public virtual void Verify(AsymmetricKeyParameter key)
|
|
{
|
|
CheckSignature(new Asn1VerifierFactory(cert.SignatureAlgorithm, key));
|
|
}
|
|
|
|
public virtual void Verify(IVerifierFactoryProvider verifierProvider)
|
|
{
|
|
CheckSignature(verifierProvider.CreateVerifierFactory(cert.SignatureAlgorithm));
|
|
}
|
|
|
|
protected virtual void CheckSignature(IVerifierFactory verifier)
|
|
{
|
|
if (!cert.SignatureAlgorithm.Equals(cert.ACInfo.Signature))
|
|
{
|
|
throw new CertificateException("Signature algorithm in certificate info not same as outer certificate");
|
|
}
|
|
IStreamCalculator streamCalculator = verifier.CreateCalculator();
|
|
try
|
|
{
|
|
byte[] encoded = cert.ACInfo.GetEncoded();
|
|
streamCalculator.Stream.Write(encoded, 0, encoded.Length);
|
|
Platform.Dispose(streamCalculator.Stream);
|
|
}
|
|
catch (IOException exception)
|
|
{
|
|
throw new SignatureException("Exception encoding certificate info object", exception);
|
|
}
|
|
if (!((IVerifier)streamCalculator.GetResult()).IsVerified(GetSignature()))
|
|
{
|
|
throw new InvalidKeyException("Public key presented not for certificate signature");
|
|
}
|
|
}
|
|
|
|
public virtual byte[] GetEncoded()
|
|
{
|
|
return cert.GetEncoded();
|
|
}
|
|
|
|
protected override X509Extensions GetX509Extensions()
|
|
{
|
|
return cert.ACInfo.Extensions;
|
|
}
|
|
|
|
public virtual X509Attribute[] GetAttributes()
|
|
{
|
|
Asn1Sequence attributes = cert.ACInfo.Attributes;
|
|
X509Attribute[] array = new X509Attribute[attributes.Count];
|
|
for (int i = 0; i != attributes.Count; i++)
|
|
{
|
|
array[i] = new X509Attribute(attributes[i]);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public virtual X509Attribute[] GetAttributes(string oid)
|
|
{
|
|
Asn1Sequence attributes = cert.ACInfo.Attributes;
|
|
IList list = Platform.CreateArrayList();
|
|
for (int i = 0; i != attributes.Count; i++)
|
|
{
|
|
X509Attribute x509Attribute = new X509Attribute(attributes[i]);
|
|
if (x509Attribute.Oid.Equals(oid))
|
|
{
|
|
list.Add(x509Attribute);
|
|
}
|
|
}
|
|
if (list.Count < 1)
|
|
{
|
|
return null;
|
|
}
|
|
X509Attribute[] array = new X509Attribute[list.Count];
|
|
for (int j = 0; j < list.Count; j++)
|
|
{
|
|
array[j] = (X509Attribute)list[j];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj == this)
|
|
{
|
|
return true;
|
|
}
|
|
if (!(obj is X509V2AttributeCertificate x509V2AttributeCertificate))
|
|
{
|
|
return false;
|
|
}
|
|
return cert.Equals(x509V2AttributeCertificate.cert);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return cert.GetHashCode();
|
|
}
|
|
}
|