init commit
This commit is contained in:
@@ -0,0 +1,387 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Misc;
|
||||
using Org.BouncyCastle.Asn1.Utilities;
|
||||
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;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509Certificate : X509ExtensionBase
|
||||
{
|
||||
private readonly X509CertificateStructure c;
|
||||
|
||||
private readonly BasicConstraints basicConstraints;
|
||||
|
||||
private readonly bool[] keyUsage;
|
||||
|
||||
private bool hashValueSet;
|
||||
|
||||
private int hashValue;
|
||||
|
||||
public virtual X509CertificateStructure CertificateStructure => c;
|
||||
|
||||
public virtual bool IsValidNow => IsValid(DateTime.UtcNow);
|
||||
|
||||
public virtual int Version => c.Version;
|
||||
|
||||
public virtual BigInteger SerialNumber => c.SerialNumber.Value;
|
||||
|
||||
public virtual X509Name IssuerDN => c.Issuer;
|
||||
|
||||
public virtual X509Name SubjectDN => c.Subject;
|
||||
|
||||
public virtual DateTime NotBefore => c.StartDate.ToDateTime();
|
||||
|
||||
public virtual DateTime NotAfter => c.EndDate.ToDateTime();
|
||||
|
||||
public virtual string SigAlgName => SignerUtilities.GetEncodingName(c.SignatureAlgorithm.Algorithm);
|
||||
|
||||
public virtual string SigAlgOid => c.SignatureAlgorithm.Algorithm.Id;
|
||||
|
||||
public virtual DerBitString IssuerUniqueID => c.TbsCertificate.IssuerUniqueID;
|
||||
|
||||
public virtual DerBitString SubjectUniqueID => c.TbsCertificate.SubjectUniqueID;
|
||||
|
||||
protected X509Certificate()
|
||||
{
|
||||
}
|
||||
|
||||
public X509Certificate(X509CertificateStructure c)
|
||||
{
|
||||
this.c = c;
|
||||
try
|
||||
{
|
||||
Asn1OctetString extensionValue = GetExtensionValue(new DerObjectIdentifier("2.5.29.19"));
|
||||
if (extensionValue != null)
|
||||
{
|
||||
basicConstraints = BasicConstraints.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateParsingException("cannot construct BasicConstraints: " + ex);
|
||||
}
|
||||
try
|
||||
{
|
||||
Asn1OctetString extensionValue2 = GetExtensionValue(new DerObjectIdentifier("2.5.29.15"));
|
||||
if (extensionValue2 != null)
|
||||
{
|
||||
DerBitString instance = DerBitString.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue2));
|
||||
byte[] bytes = instance.GetBytes();
|
||||
int num = bytes.Length * 8 - instance.PadBits;
|
||||
keyUsage = new bool[(num < 9) ? 9 : num];
|
||||
for (int i = 0; i != num; i++)
|
||||
{
|
||||
keyUsage[i] = (bytes[i / 8] & (128 >> i % 8)) != 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUsage = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
throw new CertificateParsingException("cannot construct KeyUsage: " + ex2);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsValid(DateTime time)
|
||||
{
|
||||
if (time.CompareTo((object?)NotBefore) >= 0)
|
||||
{
|
||||
return time.CompareTo((object?)NotAfter) <= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void CheckValidity()
|
||||
{
|
||||
CheckValidity(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
public virtual void CheckValidity(DateTime time)
|
||||
{
|
||||
if (time.CompareTo((object?)NotAfter) > 0)
|
||||
{
|
||||
throw new CertificateExpiredException("certificate expired on " + c.EndDate.GetTime());
|
||||
}
|
||||
if (time.CompareTo((object?)NotBefore) < 0)
|
||||
{
|
||||
throw new CertificateNotYetValidException("certificate not valid until " + c.StartDate.GetTime());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] GetTbsCertificate()
|
||||
{
|
||||
return c.TbsCertificate.GetDerEncoded();
|
||||
}
|
||||
|
||||
public virtual byte[] GetSignature()
|
||||
{
|
||||
return c.GetSignatureOctets();
|
||||
}
|
||||
|
||||
public virtual byte[] GetSigAlgParams()
|
||||
{
|
||||
if (c.SignatureAlgorithm.Parameters != null)
|
||||
{
|
||||
return c.SignatureAlgorithm.Parameters.GetDerEncoded();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool[] GetKeyUsage()
|
||||
{
|
||||
if (keyUsage != null)
|
||||
{
|
||||
return (bool[])keyUsage.Clone();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual IList GetExtendedKeyUsage()
|
||||
{
|
||||
Asn1OctetString extensionValue = GetExtensionValue(new DerObjectIdentifier("2.5.29.37"));
|
||||
if (extensionValue == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
Asn1Sequence instance = Asn1Sequence.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue));
|
||||
IList list = Platform.CreateArrayList();
|
||||
foreach (DerObjectIdentifier item in instance)
|
||||
{
|
||||
list.Add(item.Id);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new CertificateParsingException("error processing extended key usage extension", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetBasicConstraints()
|
||||
{
|
||||
if (basicConstraints != null && basicConstraints.IsCA())
|
||||
{
|
||||
if (basicConstraints.PathLenConstraint == null)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
return basicConstraints.PathLenConstraint.IntValue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public virtual ICollection GetSubjectAlternativeNames()
|
||||
{
|
||||
return GetAlternativeNames("2.5.29.17");
|
||||
}
|
||||
|
||||
public virtual ICollection GetIssuerAlternativeNames()
|
||||
{
|
||||
return GetAlternativeNames("2.5.29.18");
|
||||
}
|
||||
|
||||
protected virtual ICollection GetAlternativeNames(string oid)
|
||||
{
|
||||
Asn1OctetString extensionValue = GetExtensionValue(new DerObjectIdentifier(oid));
|
||||
if (extensionValue == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Asn1Object obj = X509ExtensionUtilities.FromExtensionValue(extensionValue);
|
||||
GeneralNames instance = GeneralNames.GetInstance(obj);
|
||||
IList list = Platform.CreateArrayList();
|
||||
GeneralName[] names = instance.GetNames();
|
||||
foreach (GeneralName generalName in names)
|
||||
{
|
||||
IList list2 = Platform.CreateArrayList();
|
||||
list2.Add(generalName.TagNo);
|
||||
list2.Add(generalName.Name.ToString());
|
||||
list.Add(list2);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override X509Extensions GetX509Extensions()
|
||||
{
|
||||
if (c.Version < 3)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return c.TbsCertificate.Extensions;
|
||||
}
|
||||
|
||||
public virtual AsymmetricKeyParameter GetPublicKey()
|
||||
{
|
||||
return PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo);
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
return c.GetDerEncoded();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is X509Certificate x509Certificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return c.Equals(x509Certificate.c);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!hashValueSet)
|
||||
{
|
||||
hashValue = c.GetHashCode();
|
||||
hashValueSet = true;
|
||||
}
|
||||
}
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string newLine = Platform.NewLine;
|
||||
stringBuilder.Append(" [0] Version: ").Append(Version).Append(newLine);
|
||||
stringBuilder.Append(" SerialNumber: ").Append(SerialNumber).Append(newLine);
|
||||
stringBuilder.Append(" IssuerDN: ").Append(IssuerDN).Append(newLine);
|
||||
stringBuilder.Append(" Start Date: ").Append(NotBefore).Append(newLine);
|
||||
stringBuilder.Append(" Final Date: ").Append(NotAfter).Append(newLine);
|
||||
stringBuilder.Append(" SubjectDN: ").Append(SubjectDN).Append(newLine);
|
||||
stringBuilder.Append(" Public Key: ").Append(GetPublicKey()).Append(newLine);
|
||||
stringBuilder.Append(" Signature Algorithm: ").Append(SigAlgName).Append(newLine);
|
||||
byte[] signature = GetSignature();
|
||||
stringBuilder.Append(" Signature: ").Append(Hex.ToHexString(signature, 0, 20)).Append(newLine);
|
||||
for (int i = 20; i < signature.Length; i += 20)
|
||||
{
|
||||
int length = System.Math.Min(20, signature.Length - i);
|
||||
stringBuilder.Append(" ").Append(Hex.ToHexString(signature, i, length)).Append(newLine);
|
||||
}
|
||||
X509Extensions extensions = c.TbsCertificate.Extensions;
|
||||
if (extensions != null)
|
||||
{
|
||||
IEnumerator enumerator = extensions.ExtensionOids.GetEnumerator();
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
stringBuilder.Append(" Extensions: \n");
|
||||
}
|
||||
do
|
||||
{
|
||||
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)enumerator.Current;
|
||||
X509Extension extension = extensions.GetExtension(derObjectIdentifier);
|
||||
if (extension.Value != null)
|
||||
{
|
||||
byte[] octets = extension.Value.GetOctets();
|
||||
Asn1Object asn1Object = Asn1Object.FromByteArray(octets);
|
||||
stringBuilder.Append(" critical(").Append(extension.IsCritical).Append(") ");
|
||||
try
|
||||
{
|
||||
if (derObjectIdentifier.Equals(X509Extensions.BasicConstraints))
|
||||
{
|
||||
stringBuilder.Append(BasicConstraints.GetInstance(asn1Object));
|
||||
}
|
||||
else if (derObjectIdentifier.Equals(X509Extensions.KeyUsage))
|
||||
{
|
||||
stringBuilder.Append(KeyUsage.GetInstance(asn1Object));
|
||||
}
|
||||
else if (derObjectIdentifier.Equals(MiscObjectIdentifiers.NetscapeCertType))
|
||||
{
|
||||
stringBuilder.Append(new NetscapeCertType((DerBitString)asn1Object));
|
||||
}
|
||||
else if (derObjectIdentifier.Equals(MiscObjectIdentifiers.NetscapeRevocationUrl))
|
||||
{
|
||||
stringBuilder.Append(new NetscapeRevocationUrl((DerIA5String)asn1Object));
|
||||
}
|
||||
else if (derObjectIdentifier.Equals(MiscObjectIdentifiers.VerisignCzagExtension))
|
||||
{
|
||||
stringBuilder.Append(new VerisignCzagExtension((DerIA5String)asn1Object));
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(derObjectIdentifier.Id);
|
||||
stringBuilder.Append(" value = ").Append(Asn1Dump.DumpAsString(asn1Object));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
stringBuilder.Append(derObjectIdentifier.Id);
|
||||
stringBuilder.Append(" value = ").Append("*****");
|
||||
}
|
||||
}
|
||||
stringBuilder.Append(newLine);
|
||||
}
|
||||
while (enumerator.MoveNext());
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public virtual void Verify(AsymmetricKeyParameter key)
|
||||
{
|
||||
CheckSignature(new Asn1VerifierFactory(c.SignatureAlgorithm, key));
|
||||
}
|
||||
|
||||
public virtual void Verify(IVerifierFactoryProvider verifierProvider)
|
||||
{
|
||||
CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm));
|
||||
}
|
||||
|
||||
protected virtual void CheckSignature(IVerifierFactory verifier)
|
||||
{
|
||||
if (!IsAlgIDEqual(c.SignatureAlgorithm, c.TbsCertificate.Signature))
|
||||
{
|
||||
throw new CertificateException("signature algorithm in TBS cert not same as outer cert");
|
||||
}
|
||||
_ = c.SignatureAlgorithm.Parameters;
|
||||
IStreamCalculator streamCalculator = verifier.CreateCalculator();
|
||||
byte[] tbsCertificate = GetTbsCertificate();
|
||||
streamCalculator.Stream.Write(tbsCertificate, 0, tbsCertificate.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
if (!((IVerifier)streamCalculator.GetResult()).IsVerified(GetSignature()))
|
||||
{
|
||||
throw new InvalidKeyException("Public key presented not for certificate signature");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsAlgIDEqual(AlgorithmIdentifier id1, AlgorithmIdentifier id2)
|
||||
{
|
||||
if (!id1.Algorithm.Equals(id2.Algorithm))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Asn1Encodable parameters = id1.Parameters;
|
||||
Asn1Encodable parameters2 = id2.Parameters;
|
||||
if (parameters == null == (parameters2 == null))
|
||||
{
|
||||
return object.Equals(parameters, parameters2);
|
||||
}
|
||||
if (parameters != null)
|
||||
{
|
||||
return parameters.ToAsn1Object() is Asn1Null;
|
||||
}
|
||||
return parameters2.ToAsn1Object() is Asn1Null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user