up
This commit is contained in:
31
Assets/BestHTTP/SecureProtocol/x509/IX509Extension.cs
Normal file
31
Assets/BestHTTP/SecureProtocol/x509/IX509Extension.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
public interface IX509Extension
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all critical extension values, by oid
|
||||
/// </summary>
|
||||
/// <returns>IDictionary with string (OID) keys and Asn1OctetString values</returns>
|
||||
ISet GetCriticalExtensionOids();
|
||||
|
||||
/// <summary>
|
||||
/// Get all non-critical extension values, by oid
|
||||
/// </summary>
|
||||
/// <returns>IDictionary with string (OID) keys and Asn1OctetString values</returns>
|
||||
ISet GetNonCriticalExtensionOids();
|
||||
|
||||
[Obsolete("Use version taking a DerObjectIdentifier instead")]
|
||||
Asn1OctetString GetExtensionValue(string oid);
|
||||
|
||||
Asn1OctetString GetExtensionValue(DerObjectIdentifier oid);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/BestHTTP/SecureProtocol/x509/IX509Extension.cs.meta
Normal file
11
Assets/BestHTTP/SecureProtocol/x509/IX509Extension.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd52255644bc34f198678b88791eeb52
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
99
Assets/BestHTTP/SecureProtocol/x509/PEMParser.cs
Normal file
99
Assets/BestHTTP/SecureProtocol/x509/PEMParser.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
class PemParser
|
||||
{
|
||||
private readonly string _header1;
|
||||
private readonly string _header2;
|
||||
private readonly string _footer1;
|
||||
private readonly string _footer2;
|
||||
|
||||
internal PemParser(
|
||||
string type)
|
||||
{
|
||||
_header1 = "-----BEGIN " + type + "-----";
|
||||
_header2 = "-----BEGIN X509 " + type + "-----";
|
||||
_footer1 = "-----END " + type + "-----";
|
||||
_footer2 = "-----END X509 " + type + "-----";
|
||||
}
|
||||
|
||||
private string ReadLine(
|
||||
Stream inStream)
|
||||
{
|
||||
int c;
|
||||
StringBuilder l = new StringBuilder();
|
||||
|
||||
do
|
||||
{
|
||||
while (((c = inStream.ReadByte()) != '\r') && c != '\n' && (c >= 0))
|
||||
{
|
||||
if (c == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
l.Append((char)c);
|
||||
}
|
||||
}
|
||||
while (c >= 0 && l.Length == 0);
|
||||
|
||||
if (c < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return l.ToString();
|
||||
}
|
||||
|
||||
internal Asn1Sequence ReadPemObject(
|
||||
Stream inStream)
|
||||
{
|
||||
string line;
|
||||
StringBuilder pemBuf = new StringBuilder();
|
||||
|
||||
while ((line = ReadLine(inStream)) != null)
|
||||
{
|
||||
if (Platform.StartsWith(line, _header1) || Platform.StartsWith(line, _header2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while ((line = ReadLine(inStream)) != null)
|
||||
{
|
||||
if (Platform.StartsWith(line, _footer1) || Platform.StartsWith(line, _footer2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pemBuf.Append(line);
|
||||
}
|
||||
|
||||
if (pemBuf.Length != 0)
|
||||
{
|
||||
Asn1Object o = Asn1Object.FromByteArray(Base64.Decode(pemBuf.ToString()));
|
||||
|
||||
if (!(o is Asn1Sequence))
|
||||
{
|
||||
throw new IOException("malformed PEM data encountered");
|
||||
}
|
||||
|
||||
return (Asn1Sequence) o;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
11
Assets/BestHTTP/SecureProtocol/x509/PEMParser.cs.meta
Normal file
11
Assets/BestHTTP/SecureProtocol/x509/PEMParser.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7923553217cff40aab3b134be27c83a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
608
Assets/BestHTTP/SecureProtocol/x509/X509Certificate.cs
Normal file
608
Assets/BestHTTP/SecureProtocol/x509/X509Certificate.cs
Normal file
@@ -0,0 +1,608 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
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.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
using Org.BouncyCastle.Crypto.Operators;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
/// <summary>
|
||||
/// An Object representing an X509 Certificate.
|
||||
/// Has static methods for loading Certificates encoded in many forms that return X509Certificate Objects.
|
||||
/// </summary>
|
||||
public class X509Certificate
|
||||
: X509ExtensionBase
|
||||
// , PKCS12BagAttributeCarrier
|
||||
{
|
||||
private readonly X509CertificateStructure c;
|
||||
// private Hashtable pkcs12Attributes = new Hashtable();
|
||||
// private ArrayList pkcs12Ordering = new ArrayList();
|
||||
private readonly BasicConstraints basicConstraints;
|
||||
private readonly bool[] keyUsage;
|
||||
|
||||
private bool hashValueSet;
|
||||
private int hashValue;
|
||||
|
||||
protected X509Certificate()
|
||||
{
|
||||
}
|
||||
|
||||
public X509Certificate(
|
||||
X509CertificateStructure c)
|
||||
{
|
||||
this.c = c;
|
||||
|
||||
try
|
||||
{
|
||||
Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.19"));
|
||||
|
||||
if (str != null)
|
||||
{
|
||||
basicConstraints = BasicConstraints.GetInstance(
|
||||
X509ExtensionUtilities.FromExtensionValue(str));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateParsingException("cannot construct BasicConstraints: " + e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.15"));
|
||||
|
||||
if (str != null)
|
||||
{
|
||||
DerBitString bits = DerBitString.GetInstance(
|
||||
X509ExtensionUtilities.FromExtensionValue(str));
|
||||
|
||||
byte[] bytes = bits.GetBytes();
|
||||
int length = (bytes.Length * 8) - bits.PadBits;
|
||||
|
||||
keyUsage = new bool[(length < 9) ? 9 : length];
|
||||
|
||||
for (int i = 0; i != length; i++)
|
||||
{
|
||||
// keyUsage[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
|
||||
keyUsage[i] = (bytes[i / 8] & (0x80 >> (i % 8))) != 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUsage = null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateParsingException("cannot construct KeyUsage: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
// internal X509Certificate(
|
||||
// Asn1Sequence seq)
|
||||
// {
|
||||
// this.c = X509CertificateStructure.GetInstance(seq);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Load certificate from byte array.
|
||||
// /// </summary>
|
||||
// /// <param name="encoded">Byte array containing encoded X509Certificate.</param>
|
||||
// public X509Certificate(
|
||||
// byte[] encoded)
|
||||
// : this((Asn1Sequence) new Asn1InputStream(encoded).ReadObject())
|
||||
// {
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Load certificate from Stream.
|
||||
// /// Must be positioned at start of certificate.
|
||||
// /// </summary>
|
||||
// /// <param name="input"></param>
|
||||
// public X509Certificate(
|
||||
// Stream input)
|
||||
// : this((Asn1Sequence) new Asn1InputStream(input).ReadObject())
|
||||
// {
|
||||
// }
|
||||
|
||||
public virtual X509CertificateStructure CertificateStructure
|
||||
{
|
||||
get { return c; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if the current time is within the start and end times nominated on the certificate.
|
||||
/// </summary>
|
||||
/// <returns>true id certificate is valid for the current time.</returns>
|
||||
public virtual bool IsValidNow
|
||||
{
|
||||
get { return IsValid(DateTime.UtcNow); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if the nominated time is within the start and end times nominated on the certificate.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to test validity against.</param>
|
||||
/// <returns>True if certificate is valid for nominated time.</returns>
|
||||
public virtual bool IsValid(
|
||||
DateTime time)
|
||||
{
|
||||
return time.CompareTo(NotBefore) >= 0 && time.CompareTo(NotAfter) <= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current date is within certificate's validity period.
|
||||
/// </summary>
|
||||
public virtual void CheckValidity()
|
||||
{
|
||||
this.CheckValidity(DateTime.UtcNow);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given date is within certificate's validity period.
|
||||
/// </summary>
|
||||
/// <exception cref="CertificateExpiredException">if the certificate is expired by given date</exception>
|
||||
/// <exception cref="CertificateNotYetValidException">if the certificate is not yet valid on given date</exception>
|
||||
public virtual void CheckValidity(
|
||||
DateTime time)
|
||||
{
|
||||
if (time.CompareTo(NotAfter) > 0)
|
||||
throw new CertificateExpiredException("certificate expired on " + c.EndDate.GetTime());
|
||||
if (time.CompareTo(NotBefore) < 0)
|
||||
throw new CertificateNotYetValidException("certificate not valid until " + c.StartDate.GetTime());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the certificate's version.
|
||||
/// </summary>
|
||||
/// <returns>An integer whose value Equals the version of the cerficate.</returns>
|
||||
public virtual int Version
|
||||
{
|
||||
get { return c.Version; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a <see cref="Org.BouncyCastle.Math.BigInteger">BigInteger</see> containing the serial number.
|
||||
/// </summary>
|
||||
/// <returns>The Serial number.</returns>
|
||||
public virtual BigInteger SerialNumber
|
||||
{
|
||||
get { return c.SerialNumber.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Issuer Distinguished Name. (Who signed the certificate.)
|
||||
/// </summary>
|
||||
/// <returns>And X509Object containing name and value pairs.</returns>
|
||||
// public IPrincipal IssuerDN
|
||||
public virtual X509Name IssuerDN
|
||||
{
|
||||
get { return c.Issuer; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the subject of this certificate.
|
||||
/// </summary>
|
||||
/// <returns>An X509Name object containing name and value pairs.</returns>
|
||||
// public IPrincipal SubjectDN
|
||||
public virtual X509Name SubjectDN
|
||||
{
|
||||
get { return c.Subject; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The time that this certificate is valid from.
|
||||
/// </summary>
|
||||
/// <returns>A DateTime object representing that time in the local time zone.</returns>
|
||||
public virtual DateTime NotBefore
|
||||
{
|
||||
get { return c.StartDate.ToDateTime(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The time that this certificate is valid up to.
|
||||
/// </summary>
|
||||
/// <returns>A DateTime object representing that time in the local time zone.</returns>
|
||||
public virtual DateTime NotAfter
|
||||
{
|
||||
get { return c.EndDate.ToDateTime(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Der encoded TbsCertificate data.
|
||||
/// This is the certificate component less the signature.
|
||||
/// To Get the whole certificate call the GetEncoded() member.
|
||||
/// </summary>
|
||||
/// <returns>A byte array containing the Der encoded Certificate component.</returns>
|
||||
public virtual byte[] GetTbsCertificate()
|
||||
{
|
||||
return c.TbsCertificate.GetDerEncoded();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The signature.
|
||||
/// </summary>
|
||||
/// <returns>A byte array containg the signature of the certificate.</returns>
|
||||
public virtual byte[] GetSignature()
|
||||
{
|
||||
return c.GetSignatureOctets();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A meaningful version of the Signature Algorithm. (EG SHA1WITHRSA)
|
||||
/// </summary>
|
||||
/// <returns>A sting representing the signature algorithm.</returns>
|
||||
public virtual string SigAlgName
|
||||
{
|
||||
get { return SignerUtilities.GetEncodingName(c.SignatureAlgorithm.Algorithm); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Signature Algorithms Object ID.
|
||||
/// </summary>
|
||||
/// <returns>A string containg a '.' separated object id.</returns>
|
||||
public virtual string SigAlgOid
|
||||
{
|
||||
get { return c.SignatureAlgorithm.Algorithm.Id; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the signature algorithms parameters. (EG DSA Parameters)
|
||||
/// </summary>
|
||||
/// <returns>A byte array containing the Der encoded version of the parameters or null if there are none.</returns>
|
||||
public virtual byte[] GetSigAlgParams()
|
||||
{
|
||||
if (c.SignatureAlgorithm.Parameters != null)
|
||||
{
|
||||
return c.SignatureAlgorithm.Parameters.GetDerEncoded();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the issuers UID.
|
||||
/// </summary>
|
||||
/// <returns>A DerBitString.</returns>
|
||||
public virtual DerBitString IssuerUniqueID
|
||||
{
|
||||
get { return c.TbsCertificate.IssuerUniqueID; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the subjects UID.
|
||||
/// </summary>
|
||||
/// <returns>A DerBitString.</returns>
|
||||
public virtual DerBitString SubjectUniqueID
|
||||
{
|
||||
get { return c.TbsCertificate.SubjectUniqueID; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a key usage guidlines.
|
||||
/// </summary>
|
||||
public virtual bool[] GetKeyUsage()
|
||||
{
|
||||
return keyUsage == null ? null : (bool[]) keyUsage.Clone();
|
||||
}
|
||||
|
||||
// TODO Replace with something that returns a list of DerObjectIdentifier
|
||||
public virtual IList GetExtendedKeyUsage()
|
||||
{
|
||||
Asn1OctetString str = this.GetExtensionValue(new DerObjectIdentifier("2.5.29.37"));
|
||||
|
||||
if (str == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
Asn1Sequence seq = Asn1Sequence.GetInstance(
|
||||
X509ExtensionUtilities.FromExtensionValue(str));
|
||||
|
||||
IList list = Platform.CreateArrayList();
|
||||
|
||||
foreach (DerObjectIdentifier oid in seq)
|
||||
{
|
||||
list.Add(oid.Id);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateParsingException("error processing extended key usage extension", e);
|
||||
}
|
||||
}
|
||||
|
||||
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 altNames = GetExtensionValue(new DerObjectIdentifier(oid));
|
||||
|
||||
if (altNames == null)
|
||||
return null;
|
||||
|
||||
Asn1Object asn1Object = X509ExtensionUtilities.FromExtensionValue(altNames);
|
||||
|
||||
GeneralNames gns = GeneralNames.GetInstance(asn1Object);
|
||||
|
||||
IList result = Platform.CreateArrayList();
|
||||
foreach (GeneralName gn in gns.GetNames())
|
||||
{
|
||||
IList entry = Platform.CreateArrayList();
|
||||
entry.Add(gn.TagNo);
|
||||
entry.Add(gn.Name.ToString());
|
||||
result.Add(entry);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override X509Extensions GetX509Extensions()
|
||||
{
|
||||
return c.Version >= 3
|
||||
? c.TbsCertificate.Extensions
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the public key of the subject of the certificate.
|
||||
/// </summary>
|
||||
/// <returns>The public key parameters.</returns>
|
||||
public virtual AsymmetricKeyParameter GetPublicKey()
|
||||
{
|
||||
return PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a Der encoded version of this certificate.
|
||||
/// </summary>
|
||||
/// <returns>A byte array.</returns>
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
return c.GetDerEncoded();
|
||||
}
|
||||
|
||||
public override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
X509Certificate other = obj as X509Certificate;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return c.Equals(other.c);
|
||||
|
||||
// NB: May prefer this implementation of Equals if more than one certificate implementation in play
|
||||
// return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded());
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!hashValueSet)
|
||||
{
|
||||
hashValue = c.GetHashCode();
|
||||
hashValueSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
// public void setBagAttribute(
|
||||
// DERObjectIdentifier oid,
|
||||
// DEREncodable attribute)
|
||||
// {
|
||||
// pkcs12Attributes.put(oid, attribute);
|
||||
// pkcs12Ordering.addElement(oid);
|
||||
// }
|
||||
//
|
||||
// public DEREncodable getBagAttribute(
|
||||
// DERObjectIdentifier oid)
|
||||
// {
|
||||
// return (DEREncodable)pkcs12Attributes.get(oid);
|
||||
// }
|
||||
//
|
||||
// public Enumeration getBagAttributeKeys()
|
||||
// {
|
||||
// return pkcs12Ordering.elements();
|
||||
// }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
string nl = Platform.NewLine;
|
||||
|
||||
buf.Append(" [0] Version: ").Append(this.Version).Append(nl);
|
||||
buf.Append(" SerialNumber: ").Append(this.SerialNumber).Append(nl);
|
||||
buf.Append(" IssuerDN: ").Append(this.IssuerDN).Append(nl);
|
||||
buf.Append(" Start Date: ").Append(this.NotBefore).Append(nl);
|
||||
buf.Append(" Final Date: ").Append(this.NotAfter).Append(nl);
|
||||
buf.Append(" SubjectDN: ").Append(this.SubjectDN).Append(nl);
|
||||
buf.Append(" Public Key: ").Append(this.GetPublicKey()).Append(nl);
|
||||
buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).Append(nl);
|
||||
|
||||
byte[] sig = this.GetSignature();
|
||||
buf.Append(" Signature: ").Append(Hex.ToHexString(sig, 0, 20)).Append(nl);
|
||||
|
||||
for (int i = 20; i < sig.Length; i += 20)
|
||||
{
|
||||
int len = System.Math.Min(20, sig.Length - i);
|
||||
buf.Append(" ").Append(Hex.ToHexString(sig, i, len)).Append(nl);
|
||||
}
|
||||
|
||||
X509Extensions extensions = c.TbsCertificate.Extensions;
|
||||
|
||||
if (extensions != null)
|
||||
{
|
||||
IEnumerator e = extensions.ExtensionOids.GetEnumerator();
|
||||
|
||||
if (e.MoveNext())
|
||||
{
|
||||
buf.Append(" Extensions: \n");
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
DerObjectIdentifier oid = (DerObjectIdentifier)e.Current;
|
||||
X509Extension ext = extensions.GetExtension(oid);
|
||||
|
||||
if (ext.Value != null)
|
||||
{
|
||||
byte[] octs = ext.Value.GetOctets();
|
||||
Asn1Object obj = Asn1Object.FromByteArray(octs);
|
||||
buf.Append(" critical(").Append(ext.IsCritical).Append(") ");
|
||||
try
|
||||
{
|
||||
if (oid.Equals(X509Extensions.BasicConstraints))
|
||||
{
|
||||
buf.Append(BasicConstraints.GetInstance(obj));
|
||||
}
|
||||
else if (oid.Equals(X509Extensions.KeyUsage))
|
||||
{
|
||||
buf.Append(KeyUsage.GetInstance(obj));
|
||||
}
|
||||
else if (oid.Equals(MiscObjectIdentifiers.NetscapeCertType))
|
||||
{
|
||||
buf.Append(new NetscapeCertType((DerBitString) obj));
|
||||
}
|
||||
else if (oid.Equals(MiscObjectIdentifiers.NetscapeRevocationUrl))
|
||||
{
|
||||
buf.Append(new NetscapeRevocationUrl((DerIA5String) obj));
|
||||
}
|
||||
else if (oid.Equals(MiscObjectIdentifiers.VerisignCzagExtension))
|
||||
{
|
||||
buf.Append(new VerisignCzagExtension((DerIA5String) obj));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.Append(oid.Id);
|
||||
buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj));
|
||||
//buf.Append(" value = ").Append("*****").Append(nl);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
buf.Append(oid.Id);
|
||||
//buf.Append(" value = ").Append(new string(Hex.encode(ext.getValue().getOctets()))).Append(nl);
|
||||
buf.Append(" value = ").Append("*****");
|
||||
}
|
||||
}
|
||||
|
||||
buf.Append(nl);
|
||||
}
|
||||
while (e.MoveNext());
|
||||
}
|
||||
|
||||
return buf.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify the certificate's signature using the nominated public key.
|
||||
/// </summary>
|
||||
/// <param name="key">An appropriate public key parameter object, RsaPublicKeyParameters, DsaPublicKeyParameters or ECDsaPublicKeyParameters</param>
|
||||
/// <returns>True if the signature is valid.</returns>
|
||||
/// <exception cref="Exception">If key submitted is not of the above nominated types.</exception>
|
||||
public virtual void Verify(
|
||||
AsymmetricKeyParameter key)
|
||||
{
|
||||
CheckSignature(new Asn1VerifierFactory(c.SignatureAlgorithm, key));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify the certificate's signature using a verifier created using the passed in verifier provider.
|
||||
/// </summary>
|
||||
/// <param name="verifierProvider">An appropriate provider for verifying the certificate's signature.</param>
|
||||
/// <returns>True if the signature is valid.</returns>
|
||||
/// <exception cref="Exception">If verifier provider is not appropriate or the certificate algorithm is invalid.</exception>
|
||||
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");
|
||||
|
||||
//Asn1Encodable parameters = c.SignatureAlgorithm.Parameters;
|
||||
|
||||
IStreamCalculator streamCalculator = verifier.CreateCalculator();
|
||||
|
||||
byte[] b = this.GetTbsCertificate();
|
||||
|
||||
streamCalculator.Stream.Write(b, 0, b.Length);
|
||||
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
|
||||
if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.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 p1 = id1.Parameters;
|
||||
Asn1Encodable p2 = id2.Parameters;
|
||||
|
||||
if ((p1 == null) == (p2 == null))
|
||||
return Platform.Equals(p1, p2);
|
||||
|
||||
// Exactly one of p1, p2 is null at this point
|
||||
return p1 == null
|
||||
? p2.ToAsn1Object() is Asn1Null
|
||||
: p1.ToAsn1Object() is Asn1Null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/BestHTTP/SecureProtocol/x509/X509Certificate.cs.meta
Normal file
11
Assets/BestHTTP/SecureProtocol/x509/X509Certificate.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d01e942dc1884e7b9a558c738cfd2a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
187
Assets/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs
Normal file
187
Assets/BestHTTP/SecureProtocol/x509/X509CertificateParser.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
/**
|
||||
* class for dealing with X509 certificates.
|
||||
* <p>
|
||||
* At the moment this will deal with "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----"
|
||||
* base 64 encoded certs, as well as the BER binaries of certificates and some classes of PKCS#7
|
||||
* objects.</p>
|
||||
*/
|
||||
public class X509CertificateParser
|
||||
{
|
||||
private static readonly PemParser PemCertParser = new PemParser("CERTIFICATE");
|
||||
|
||||
private Asn1Set sData;
|
||||
private int sDataObjectCount;
|
||||
private Stream currentStream;
|
||||
|
||||
private X509Certificate ReadDerCertificate(
|
||||
Asn1InputStream dIn)
|
||||
{
|
||||
Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject();
|
||||
|
||||
if (seq.Count > 1 && seq[0] is DerObjectIdentifier)
|
||||
{
|
||||
if (seq[0].Equals(PkcsObjectIdentifiers.SignedData))
|
||||
{
|
||||
sData = SignedData.GetInstance(
|
||||
Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Certificates;
|
||||
|
||||
return GetCertificate();
|
||||
}
|
||||
}
|
||||
|
||||
return CreateX509Certificate(X509CertificateStructure.GetInstance(seq));
|
||||
}
|
||||
|
||||
private X509Certificate GetCertificate()
|
||||
{
|
||||
if (sData != null)
|
||||
{
|
||||
while (sDataObjectCount < sData.Count)
|
||||
{
|
||||
object obj = sData[sDataObjectCount++];
|
||||
|
||||
if (obj is Asn1Sequence)
|
||||
{
|
||||
return CreateX509Certificate(
|
||||
X509CertificateStructure.GetInstance(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private X509Certificate ReadPemCertificate(
|
||||
Stream inStream)
|
||||
{
|
||||
Asn1Sequence seq = PemCertParser.ReadPemObject(inStream);
|
||||
|
||||
return seq == null
|
||||
? null
|
||||
: CreateX509Certificate(X509CertificateStructure.GetInstance(seq));
|
||||
}
|
||||
|
||||
protected virtual X509Certificate CreateX509Certificate(
|
||||
X509CertificateStructure c)
|
||||
{
|
||||
return new X509Certificate(c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create loading data from byte array.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
public X509Certificate ReadCertificate(
|
||||
byte[] input)
|
||||
{
|
||||
return ReadCertificate(new MemoryStream(input, false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create loading data from byte array.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
public ICollection ReadCertificates(
|
||||
byte[] input)
|
||||
{
|
||||
return ReadCertificates(new MemoryStream(input, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a certificate object and initializes it with the data
|
||||
* read from the input stream inStream.
|
||||
*/
|
||||
public X509Certificate ReadCertificate(
|
||||
Stream inStream)
|
||||
{
|
||||
if (inStream == null)
|
||||
throw new ArgumentNullException("inStream");
|
||||
if (!inStream.CanRead)
|
||||
throw new ArgumentException("inStream must be read-able", "inStream");
|
||||
|
||||
if (currentStream == null)
|
||||
{
|
||||
currentStream = inStream;
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
}
|
||||
else if (currentStream != inStream) // reset if input stream has changed
|
||||
{
|
||||
currentStream = inStream;
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (sData != null)
|
||||
{
|
||||
if (sDataObjectCount != sData.Count)
|
||||
{
|
||||
return GetCertificate();
|
||||
}
|
||||
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
return null;
|
||||
}
|
||||
|
||||
PushbackStream pis = new PushbackStream(inStream);
|
||||
int tag = pis.ReadByte();
|
||||
|
||||
if (tag < 0)
|
||||
return null;
|
||||
|
||||
pis.Unread(tag);
|
||||
|
||||
if (tag != 0x30) // assume ascii PEM encoded.
|
||||
{
|
||||
return ReadPemCertificate(pis);
|
||||
}
|
||||
|
||||
return ReadDerCertificate(new Asn1InputStream(pis));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateException("Failed to read certificate", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a (possibly empty) collection view of the certificates
|
||||
* read from the given input stream inStream.
|
||||
*/
|
||||
public ICollection ReadCertificates(
|
||||
Stream inStream)
|
||||
{
|
||||
X509Certificate cert;
|
||||
IList certs = Platform.CreateArrayList();
|
||||
|
||||
while ((cert = ReadCertificate(inStream)) != null)
|
||||
{
|
||||
certs.Add(cert);
|
||||
}
|
||||
|
||||
return certs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f6e8c7e5a98249db9e740de3885cd3e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
430
Assets/BestHTTP/SecureProtocol/x509/X509Crl.cs
Normal file
430
Assets/BestHTTP/SecureProtocol/x509/X509Crl.cs
Normal file
@@ -0,0 +1,430 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Utilities;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
using Org.BouncyCastle.Crypto.Operators;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
/**
|
||||
* The following extensions are listed in RFC 2459 as relevant to CRLs
|
||||
*
|
||||
* Authority Key Identifier
|
||||
* Issuer Alternative Name
|
||||
* CRL Number
|
||||
* Delta CRL Indicator (critical)
|
||||
* Issuing Distribution Point (critical)
|
||||
*/
|
||||
public class X509Crl
|
||||
: X509ExtensionBase
|
||||
// TODO Add interface Crl?
|
||||
{
|
||||
private readonly CertificateList c;
|
||||
private readonly string sigAlgName;
|
||||
private readonly byte[] sigAlgParams;
|
||||
private readonly bool isIndirect;
|
||||
|
||||
public X509Crl(
|
||||
CertificateList c)
|
||||
{
|
||||
this.c = c;
|
||||
|
||||
try
|
||||
{
|
||||
this.sigAlgName = X509SignatureUtilities.GetSignatureName(c.SignatureAlgorithm);
|
||||
|
||||
if (c.SignatureAlgorithm.Parameters != null)
|
||||
{
|
||||
this.sigAlgParams = ((Asn1Encodable)c.SignatureAlgorithm.Parameters).GetDerEncoded();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.sigAlgParams = null;
|
||||
}
|
||||
|
||||
this.isIndirect = IsIndirectCrl;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CrlException("CRL contents invalid: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
protected override X509Extensions GetX509Extensions()
|
||||
{
|
||||
return c.Version >= 2
|
||||
? c.TbsCertList.Extensions
|
||||
: null;
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.GetDerEncoded();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CrlException(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Verify(
|
||||
AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
Verify(new Asn1VerifierFactoryProvider(publicKey));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify the CRL's signature using a verifier created using the passed in verifier provider.
|
||||
/// </summary>
|
||||
/// <param name="verifierProvider">An appropriate provider for verifying the CRL's signature.</param>
|
||||
/// <returns>True if the signature is valid.</returns>
|
||||
/// <exception cref="Exception">If verifier provider is not appropriate or the CRL algorithm is invalid.</exception>
|
||||
public virtual void Verify(
|
||||
IVerifierFactoryProvider verifierProvider)
|
||||
{
|
||||
CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm));
|
||||
}
|
||||
|
||||
protected virtual void CheckSignature(
|
||||
IVerifierFactory verifier)
|
||||
{
|
||||
if (!c.SignatureAlgorithm.Equals(c.TbsCertList.Signature))
|
||||
{
|
||||
throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList.");
|
||||
}
|
||||
|
||||
//Asn1Encodable parameters = c.SignatureAlgorithm.Parameters;
|
||||
|
||||
IStreamCalculator streamCalculator = verifier.CreateCalculator();
|
||||
|
||||
byte[] b = this.GetTbsCertList();
|
||||
|
||||
streamCalculator.Stream.Write(b, 0, b.Length);
|
||||
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
|
||||
if (!((IVerifier)streamCalculator.GetResult()).IsVerified(this.GetSignature()))
|
||||
{
|
||||
throw new InvalidKeyException("CRL does not verify with supplied public key.");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int Version
|
||||
{
|
||||
get { return c.Version; }
|
||||
}
|
||||
|
||||
public virtual X509Name IssuerDN
|
||||
{
|
||||
get { return c.Issuer; }
|
||||
}
|
||||
|
||||
public virtual DateTime ThisUpdate
|
||||
{
|
||||
get { return c.ThisUpdate.ToDateTime(); }
|
||||
}
|
||||
|
||||
public virtual DateTimeObject NextUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
return c.NextUpdate == null
|
||||
? null
|
||||
: new DateTimeObject(c.NextUpdate.ToDateTime());
|
||||
}
|
||||
}
|
||||
|
||||
private ISet LoadCrlEntries()
|
||||
{
|
||||
ISet entrySet = new HashSet();
|
||||
IEnumerable certs = c.GetRevokedCertificateEnumeration();
|
||||
|
||||
X509Name previousCertificateIssuer = IssuerDN;
|
||||
foreach (CrlEntry entry in certs)
|
||||
{
|
||||
X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer);
|
||||
entrySet.Add(crlEntry);
|
||||
previousCertificateIssuer = crlEntry.GetCertificateIssuer();
|
||||
}
|
||||
|
||||
return entrySet;
|
||||
}
|
||||
|
||||
public virtual X509CrlEntry GetRevokedCertificate(
|
||||
BigInteger serialNumber)
|
||||
{
|
||||
IEnumerable certs = c.GetRevokedCertificateEnumeration();
|
||||
|
||||
X509Name previousCertificateIssuer = IssuerDN;
|
||||
foreach (CrlEntry entry in certs)
|
||||
{
|
||||
X509CrlEntry crlEntry = new X509CrlEntry(entry, isIndirect, previousCertificateIssuer);
|
||||
|
||||
if (serialNumber.Equals(entry.UserCertificate.Value))
|
||||
{
|
||||
return crlEntry;
|
||||
}
|
||||
|
||||
previousCertificateIssuer = crlEntry.GetCertificateIssuer();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ISet GetRevokedCertificates()
|
||||
{
|
||||
ISet entrySet = LoadCrlEntries();
|
||||
|
||||
if (entrySet.Count > 0)
|
||||
{
|
||||
return entrySet; // TODO? Collections.unmodifiableSet(entrySet);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual byte[] GetTbsCertList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.TbsCertList.GetDerEncoded();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CrlException(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] GetSignature()
|
||||
{
|
||||
return c.GetSignatureOctets();
|
||||
}
|
||||
|
||||
public virtual string SigAlgName
|
||||
{
|
||||
get { return sigAlgName; }
|
||||
}
|
||||
|
||||
public virtual string SigAlgOid
|
||||
{
|
||||
get { return c.SignatureAlgorithm.Algorithm.Id; }
|
||||
}
|
||||
|
||||
public virtual byte[] GetSigAlgParams()
|
||||
{
|
||||
return Arrays.Clone(sigAlgParams);
|
||||
}
|
||||
|
||||
public override bool Equals(
|
||||
object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
X509Crl other = obj as X509Crl;
|
||||
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return c.Equals(other.c);
|
||||
|
||||
// NB: May prefer this implementation of Equals if more than one certificate implementation in play
|
||||
//return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded());
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return c.GetHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this CRL.
|
||||
*
|
||||
* @return a string representation of this CRL.
|
||||
*/
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
string nl = Platform.NewLine;
|
||||
|
||||
buf.Append(" Version: ").Append(this.Version).Append(nl);
|
||||
buf.Append(" IssuerDN: ").Append(this.IssuerDN).Append(nl);
|
||||
buf.Append(" This update: ").Append(this.ThisUpdate).Append(nl);
|
||||
buf.Append(" Next update: ").Append(this.NextUpdate).Append(nl);
|
||||
buf.Append(" Signature Algorithm: ").Append(this.SigAlgName).Append(nl);
|
||||
|
||||
byte[] sig = this.GetSignature();
|
||||
|
||||
buf.Append(" Signature: ");
|
||||
buf.Append(Hex.ToHexString(sig, 0, 20)).Append(nl);
|
||||
|
||||
for (int i = 20; i < sig.Length; i += 20)
|
||||
{
|
||||
int count = System.Math.Min(20, sig.Length - i);
|
||||
buf.Append(" ");
|
||||
buf.Append(Hex.ToHexString(sig, i, count)).Append(nl);
|
||||
}
|
||||
|
||||
X509Extensions extensions = c.TbsCertList.Extensions;
|
||||
|
||||
if (extensions != null)
|
||||
{
|
||||
IEnumerator e = extensions.ExtensionOids.GetEnumerator();
|
||||
|
||||
if (e.MoveNext())
|
||||
{
|
||||
buf.Append(" Extensions: ").Append(nl);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
DerObjectIdentifier oid = (DerObjectIdentifier) e.Current;
|
||||
X509Extension ext = extensions.GetExtension(oid);
|
||||
|
||||
if (ext.Value != null)
|
||||
{
|
||||
Asn1Object asn1Value = X509ExtensionUtilities.FromExtensionValue(ext.Value);
|
||||
|
||||
buf.Append(" critical(").Append(ext.IsCritical).Append(") ");
|
||||
try
|
||||
{
|
||||
if (oid.Equals(X509Extensions.CrlNumber))
|
||||
{
|
||||
buf.Append(new CrlNumber(DerInteger.GetInstance(asn1Value).PositiveValue)).Append(nl);
|
||||
}
|
||||
else if (oid.Equals(X509Extensions.DeltaCrlIndicator))
|
||||
{
|
||||
buf.Append(
|
||||
"Base CRL: "
|
||||
+ new CrlNumber(DerInteger.GetInstance(
|
||||
asn1Value).PositiveValue))
|
||||
.Append(nl);
|
||||
}
|
||||
else if (oid.Equals(X509Extensions.IssuingDistributionPoint))
|
||||
{
|
||||
buf.Append(IssuingDistributionPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl);
|
||||
}
|
||||
else if (oid.Equals(X509Extensions.CrlDistributionPoints))
|
||||
{
|
||||
buf.Append(CrlDistPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl);
|
||||
}
|
||||
else if (oid.Equals(X509Extensions.FreshestCrl))
|
||||
{
|
||||
buf.Append(CrlDistPoint.GetInstance((Asn1Sequence) asn1Value)).Append(nl);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.Append(oid.Id);
|
||||
buf.Append(" value = ").Append(
|
||||
Asn1Dump.DumpAsString(asn1Value))
|
||||
.Append(nl);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
buf.Append(oid.Id);
|
||||
buf.Append(" value = ").Append("*****").Append(nl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.Append(nl);
|
||||
}
|
||||
}
|
||||
while (e.MoveNext());
|
||||
}
|
||||
|
||||
ISet certSet = GetRevokedCertificates();
|
||||
if (certSet != null)
|
||||
{
|
||||
foreach (X509CrlEntry entry in certSet)
|
||||
{
|
||||
buf.Append(entry);
|
||||
buf.Append(nl);
|
||||
}
|
||||
}
|
||||
|
||||
return buf.ToString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given certificate is on this CRL.
|
||||
*
|
||||
* @param cert the certificate to check for.
|
||||
* @return true if the given certificate is on this CRL,
|
||||
* false otherwise.
|
||||
*/
|
||||
// public bool IsRevoked(
|
||||
// Certificate cert)
|
||||
// {
|
||||
// if (!cert.getType().Equals("X.509"))
|
||||
// {
|
||||
// throw new RuntimeException("X.509 CRL used with non X.509 Cert");
|
||||
// }
|
||||
public virtual bool IsRevoked(
|
||||
X509Certificate cert)
|
||||
{
|
||||
CrlEntry[] certs = c.GetRevokedCertificates();
|
||||
|
||||
if (certs != null)
|
||||
{
|
||||
// BigInteger serial = ((X509Certificate)cert).SerialNumber;
|
||||
BigInteger serial = cert.SerialNumber;
|
||||
|
||||
for (int i = 0; i < certs.Length; i++)
|
||||
{
|
||||
if (certs[i].UserCertificate.Value.Equals(serial))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool IsIndirectCrl
|
||||
{
|
||||
get
|
||||
{
|
||||
Asn1OctetString idp = GetExtensionValue(X509Extensions.IssuingDistributionPoint);
|
||||
bool isIndirect = false;
|
||||
|
||||
try
|
||||
{
|
||||
if (idp != null)
|
||||
{
|
||||
isIndirect = IssuingDistributionPoint.GetInstance(
|
||||
X509ExtensionUtilities.FromExtensionValue(idp)).IsIndirectCrl;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO
|
||||
// throw new ExtCrlException("Exception reading IssuingDistributionPoint", e);
|
||||
throw new CrlException("Exception reading IssuingDistributionPoint" + e);
|
||||
}
|
||||
|
||||
return isIndirect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/BestHTTP/SecureProtocol/x509/X509Crl.cs.meta
Normal file
11
Assets/BestHTTP/SecureProtocol/x509/X509Crl.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5640cd564ded422f91e8b8622ac9e7e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
205
Assets/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs
Normal file
205
Assets/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Utilities;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
/**
|
||||
* The following extensions are listed in RFC 2459 as relevant to CRL Entries
|
||||
*
|
||||
* ReasonCode Hode Instruction Code Invalidity Date Certificate Issuer
|
||||
* (critical)
|
||||
*/
|
||||
public class X509CrlEntry
|
||||
: X509ExtensionBase
|
||||
{
|
||||
private CrlEntry c;
|
||||
private bool isIndirect;
|
||||
private X509Name previousCertificateIssuer;
|
||||
private X509Name certificateIssuer;
|
||||
|
||||
public X509CrlEntry(
|
||||
CrlEntry c)
|
||||
{
|
||||
this.c = c;
|
||||
this.certificateIssuer = loadCertificateIssuer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for CRLEntries of indirect CRLs. If <code>isIndirect</code>
|
||||
* is <code>false</code> {@link #getCertificateIssuer()} will always
|
||||
* return <code>null</code>, <code>previousCertificateIssuer</code> is
|
||||
* ignored. If this <code>isIndirect</code> is specified and this CrlEntry
|
||||
* has no certificate issuer CRL entry extension
|
||||
* <code>previousCertificateIssuer</code> is returned by
|
||||
* {@link #getCertificateIssuer()}.
|
||||
*
|
||||
* @param c
|
||||
* TbsCertificateList.CrlEntry object.
|
||||
* @param isIndirect
|
||||
* <code>true</code> if the corresponding CRL is a indirect
|
||||
* CRL.
|
||||
* @param previousCertificateIssuer
|
||||
* Certificate issuer of the previous CrlEntry.
|
||||
*/
|
||||
public X509CrlEntry(
|
||||
CrlEntry c,
|
||||
bool isIndirect,
|
||||
X509Name previousCertificateIssuer)
|
||||
{
|
||||
this.c = c;
|
||||
this.isIndirect = isIndirect;
|
||||
this.previousCertificateIssuer = previousCertificateIssuer;
|
||||
this.certificateIssuer = loadCertificateIssuer();
|
||||
}
|
||||
|
||||
private X509Name loadCertificateIssuer()
|
||||
{
|
||||
if (!isIndirect)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Asn1OctetString ext = GetExtensionValue(X509Extensions.CertificateIssuer);
|
||||
if (ext == null)
|
||||
{
|
||||
return previousCertificateIssuer;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GeneralName[] names = GeneralNames.GetInstance(
|
||||
X509ExtensionUtilities.FromExtensionValue(ext)).GetNames();
|
||||
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (names[i].TagNo == GeneralName.DirectoryName)
|
||||
{
|
||||
return X509Name.GetInstance(names[i].Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public X509Name GetCertificateIssuer()
|
||||
{
|
||||
return certificateIssuer;
|
||||
}
|
||||
|
||||
protected override X509Extensions GetX509Extensions()
|
||||
{
|
||||
return c.Extensions;
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.GetDerEncoded();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CrlException(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger SerialNumber
|
||||
{
|
||||
get { return c.UserCertificate.Value; }
|
||||
}
|
||||
|
||||
public DateTime RevocationDate
|
||||
{
|
||||
get { return c.RevocationDate.ToDateTime(); }
|
||||
}
|
||||
|
||||
public bool HasExtensions
|
||||
{
|
||||
get { return c.Extensions != null; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
string nl = Platform.NewLine;
|
||||
|
||||
buf.Append(" userCertificate: ").Append(this.SerialNumber).Append(nl);
|
||||
buf.Append(" revocationDate: ").Append(this.RevocationDate).Append(nl);
|
||||
buf.Append(" certificateIssuer: ").Append(this.GetCertificateIssuer()).Append(nl);
|
||||
|
||||
X509Extensions extensions = c.Extensions;
|
||||
|
||||
if (extensions != null)
|
||||
{
|
||||
IEnumerator e = extensions.ExtensionOids.GetEnumerator();
|
||||
if (e.MoveNext())
|
||||
{
|
||||
buf.Append(" crlEntryExtensions:").Append(nl);
|
||||
|
||||
do
|
||||
{
|
||||
DerObjectIdentifier oid = (DerObjectIdentifier)e.Current;
|
||||
X509Extension ext = extensions.GetExtension(oid);
|
||||
|
||||
if (ext.Value != null)
|
||||
{
|
||||
Asn1Object obj = Asn1Object.FromByteArray(ext.Value.GetOctets());
|
||||
|
||||
buf.Append(" critical(")
|
||||
.Append(ext.IsCritical)
|
||||
.Append(") ");
|
||||
try
|
||||
{
|
||||
if (oid.Equals(X509Extensions.ReasonCode))
|
||||
{
|
||||
buf.Append(new CrlReason(DerEnumerated.GetInstance(obj)));
|
||||
}
|
||||
else if (oid.Equals(X509Extensions.CertificateIssuer))
|
||||
{
|
||||
buf.Append("Certificate issuer: ").Append(
|
||||
GeneralNames.GetInstance((Asn1Sequence)obj));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.Append(oid.Id);
|
||||
buf.Append(" value = ").Append(Asn1Dump.DumpAsString(obj));
|
||||
}
|
||||
buf.Append(nl);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
buf.Append(oid.Id);
|
||||
buf.Append(" value = ").Append("*****").Append(nl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.Append(nl);
|
||||
}
|
||||
}
|
||||
while (e.MoveNext());
|
||||
}
|
||||
}
|
||||
|
||||
return buf.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs.meta
Normal file
11
Assets/BestHTTP/SecureProtocol/x509/X509CrlEntry.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d1dcce56c23c4d89bd5256d31aad3dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
199
Assets/BestHTTP/SecureProtocol/x509/X509CrlParser.cs
Normal file
199
Assets/BestHTTP/SecureProtocol/x509/X509CrlParser.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
public class X509CrlParser
|
||||
{
|
||||
private static readonly PemParser PemCrlParser = new PemParser("CRL");
|
||||
|
||||
private readonly bool lazyAsn1;
|
||||
|
||||
private Asn1Set sCrlData;
|
||||
private int sCrlDataObjectCount;
|
||||
private Stream currentCrlStream;
|
||||
|
||||
public X509CrlParser()
|
||||
: this(false)
|
||||
{
|
||||
}
|
||||
|
||||
public X509CrlParser(
|
||||
bool lazyAsn1)
|
||||
{
|
||||
this.lazyAsn1 = lazyAsn1;
|
||||
}
|
||||
|
||||
private X509Crl ReadPemCrl(
|
||||
Stream inStream)
|
||||
{
|
||||
Asn1Sequence seq = PemCrlParser.ReadPemObject(inStream);
|
||||
|
||||
return seq == null
|
||||
? null
|
||||
: CreateX509Crl(CertificateList.GetInstance(seq));
|
||||
}
|
||||
|
||||
private X509Crl ReadDerCrl(
|
||||
Asn1InputStream dIn)
|
||||
{
|
||||
Asn1Sequence seq = (Asn1Sequence)dIn.ReadObject();
|
||||
|
||||
if (seq.Count > 1 && seq[0] is DerObjectIdentifier)
|
||||
{
|
||||
if (seq[0].Equals(PkcsObjectIdentifiers.SignedData))
|
||||
{
|
||||
sCrlData = SignedData.GetInstance(
|
||||
Asn1Sequence.GetInstance((Asn1TaggedObject) seq[1], true)).Crls;
|
||||
|
||||
return GetCrl();
|
||||
}
|
||||
}
|
||||
|
||||
return CreateX509Crl(CertificateList.GetInstance(seq));
|
||||
}
|
||||
|
||||
private X509Crl GetCrl()
|
||||
{
|
||||
if (sCrlData == null || sCrlDataObjectCount >= sCrlData.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreateX509Crl(
|
||||
CertificateList.GetInstance(
|
||||
sCrlData[sCrlDataObjectCount++]));
|
||||
}
|
||||
|
||||
protected virtual X509Crl CreateX509Crl(
|
||||
CertificateList c)
|
||||
{
|
||||
return new X509Crl(c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create loading data from byte array.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
public X509Crl ReadCrl(
|
||||
byte[] input)
|
||||
{
|
||||
return ReadCrl(new MemoryStream(input, false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create loading data from byte array.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
public ICollection ReadCrls(
|
||||
byte[] input)
|
||||
{
|
||||
return ReadCrls(new MemoryStream(input, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a certificate revocation list (CRL) object and initializes
|
||||
* it with the data read from the input stream inStream.
|
||||
*/
|
||||
public X509Crl ReadCrl(
|
||||
Stream inStream)
|
||||
{
|
||||
if (inStream == null)
|
||||
throw new ArgumentNullException("inStream");
|
||||
if (!inStream.CanRead)
|
||||
throw new ArgumentException("inStream must be read-able", "inStream");
|
||||
|
||||
if (currentCrlStream == null)
|
||||
{
|
||||
currentCrlStream = inStream;
|
||||
sCrlData = null;
|
||||
sCrlDataObjectCount = 0;
|
||||
}
|
||||
else if (currentCrlStream != inStream) // reset if input stream has changed
|
||||
{
|
||||
currentCrlStream = inStream;
|
||||
sCrlData = null;
|
||||
sCrlDataObjectCount = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (sCrlData != null)
|
||||
{
|
||||
if (sCrlDataObjectCount != sCrlData.Count)
|
||||
{
|
||||
return GetCrl();
|
||||
}
|
||||
|
||||
sCrlData = null;
|
||||
sCrlDataObjectCount = 0;
|
||||
return null;
|
||||
}
|
||||
|
||||
PushbackStream pis = new PushbackStream(inStream);
|
||||
int tag = pis.ReadByte();
|
||||
|
||||
if (tag < 0)
|
||||
return null;
|
||||
|
||||
pis.Unread(tag);
|
||||
|
||||
if (tag != 0x30) // assume ascii PEM encoded.
|
||||
{
|
||||
return ReadPemCrl(pis);
|
||||
}
|
||||
|
||||
Asn1InputStream asn1 = lazyAsn1
|
||||
? new LazyAsn1InputStream(pis)
|
||||
: new Asn1InputStream(pis);
|
||||
|
||||
return ReadDerCrl(asn1);
|
||||
}
|
||||
catch (CrlException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CrlException(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a (possibly empty) collection view of the CRLs read from
|
||||
* the given input stream inStream.
|
||||
*
|
||||
* The inStream may contain a sequence of DER-encoded CRLs, or
|
||||
* a PKCS#7 CRL set. This is a PKCS#7 SignedData object, with the
|
||||
* only significant field being crls. In particular the signature
|
||||
* and the contents are ignored.
|
||||
*/
|
||||
public ICollection ReadCrls(
|
||||
Stream inStream)
|
||||
{
|
||||
X509Crl crl;
|
||||
IList crls = Platform.CreateArrayList();
|
||||
|
||||
while ((crl = ReadCrl(inStream)) != null)
|
||||
{
|
||||
crls.Add(crl);
|
||||
}
|
||||
|
||||
return crls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
11
Assets/BestHTTP/SecureProtocol/x509/X509CrlParser.cs.meta
Normal file
11
Assets/BestHTTP/SecureProtocol/x509/X509CrlParser.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fea83c929667c4235a73fc2439db4a7e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
86
Assets/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs
Normal file
86
Assets/BestHTTP/SecureProtocol/x509/X509ExtensionBase.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
public abstract class X509ExtensionBase
|
||||
: IX509Extension
|
||||
{
|
||||
protected abstract X509Extensions GetX509Extensions();
|
||||
|
||||
protected virtual ISet GetExtensionOids(
|
||||
bool critical)
|
||||
{
|
||||
X509Extensions extensions = GetX509Extensions();
|
||||
if (extensions != null)
|
||||
{
|
||||
HashSet set = new HashSet();
|
||||
foreach (DerObjectIdentifier oid in extensions.ExtensionOids)
|
||||
{
|
||||
X509Extension ext = extensions.GetExtension(oid);
|
||||
if (ext.IsCritical == critical)
|
||||
{
|
||||
set.Add(oid.Id);
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get non critical extensions.
|
||||
/// </summary>
|
||||
/// <returns>A set of non critical extension oids.</returns>
|
||||
public virtual ISet GetNonCriticalExtensionOids()
|
||||
{
|
||||
return GetExtensionOids(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get any critical extensions.
|
||||
/// </summary>
|
||||
/// <returns>A sorted list of critical entension.</returns>
|
||||
public virtual ISet GetCriticalExtensionOids()
|
||||
{
|
||||
return GetExtensionOids(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of a given extension.
|
||||
/// </summary>
|
||||
/// <param name="oid">The object ID of the extension. </param>
|
||||
/// <returns>An Asn1OctetString object if that extension is found or null if not.</returns>
|
||||
[Obsolete("Use version taking a DerObjectIdentifier instead")]
|
||||
public Asn1OctetString GetExtensionValue(
|
||||
string oid)
|
||||
{
|
||||
return GetExtensionValue(new DerObjectIdentifier(oid));
|
||||
}
|
||||
|
||||
public virtual Asn1OctetString GetExtensionValue(
|
||||
DerObjectIdentifier oid)
|
||||
{
|
||||
X509Extensions exts = GetX509Extensions();
|
||||
if (exts != null)
|
||||
{
|
||||
X509Extension ext = exts.GetExtension(oid);
|
||||
if (ext != null)
|
||||
{
|
||||
return ext.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 514b768996e0e49099d074066c8f7540
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
132
Assets/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs
Normal file
132
Assets/BestHTTP/SecureProtocol/x509/X509SignatureUtil.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Org.BouncyCastle.Asn1.Nist;
|
||||
using Org.BouncyCastle.Asn1.Oiw;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.TeleTrust;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
|
||||
namespace Org.BouncyCastle.X509
|
||||
{
|
||||
internal class X509SignatureUtilities
|
||||
{
|
||||
private static readonly Asn1Null derNull = DerNull.Instance;
|
||||
|
||||
internal static void SetSignatureParameters(
|
||||
ISigner signature,
|
||||
Asn1Encodable parameters)
|
||||
{
|
||||
if (parameters != null && !derNull.Equals(parameters))
|
||||
{
|
||||
// TODO Put back in
|
||||
// AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm());
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// sigParams.Init(parameters.ToAsn1Object().GetDerEncoded());
|
||||
// }
|
||||
// catch (IOException e)
|
||||
// {
|
||||
// throw new SignatureException("IOException decoding parameters: " + e.Message);
|
||||
// }
|
||||
//
|
||||
// if (Platform.EndsWith(signature.getAlgorithm(), "MGF1"))
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class));
|
||||
// }
|
||||
// catch (GeneralSecurityException e)
|
||||
// {
|
||||
// throw new SignatureException("Exception extracting parameters: " + e.Message);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetSignatureName(
|
||||
AlgorithmIdentifier sigAlgId)
|
||||
{
|
||||
Asn1Encodable parameters = sigAlgId.Parameters;
|
||||
|
||||
if (parameters != null && !derNull.Equals(parameters))
|
||||
{
|
||||
if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
|
||||
{
|
||||
RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(parameters);
|
||||
|
||||
return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1";
|
||||
}
|
||||
if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2))
|
||||
{
|
||||
Asn1Sequence ecDsaParams = Asn1Sequence.GetInstance(parameters);
|
||||
|
||||
return GetDigestAlgName((DerObjectIdentifier)ecDsaParams[0]) + "withECDSA";
|
||||
}
|
||||
}
|
||||
|
||||
return sigAlgId.Algorithm.Id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the digest algorithm using one of the standard JCA string
|
||||
* representations rather than the algorithm identifier (if possible).
|
||||
*/
|
||||
private static string GetDigestAlgName(
|
||||
DerObjectIdentifier digestAlgOID)
|
||||
{
|
||||
if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID))
|
||||
{
|
||||
return "MD5";
|
||||
}
|
||||
else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA1";
|
||||
}
|
||||
else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA224";
|
||||
}
|
||||
else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA256";
|
||||
}
|
||||
else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA384";
|
||||
}
|
||||
else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA512";
|
||||
}
|
||||
else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD128";
|
||||
}
|
||||
else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD160";
|
||||
}
|
||||
else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD256";
|
||||
}
|
||||
else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID))
|
||||
{
|
||||
return "GOST3411";
|
||||
}
|
||||
else
|
||||
{
|
||||
return digestAlgOID.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2cc429d9864a5455a8bcc5713ca486a6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/BestHTTP/SecureProtocol/x509/extension.meta
Normal file
8
Assets/BestHTTP/SecureProtocol/x509/extension.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08fd6882c73c8461abc34dfbffa516e8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,93 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Extension
|
||||
{
|
||||
public class X509ExtensionUtilities
|
||||
{
|
||||
public static Asn1Object FromExtensionValue(
|
||||
Asn1OctetString extensionValue)
|
||||
{
|
||||
return Asn1Object.FromByteArray(extensionValue.GetOctets());
|
||||
}
|
||||
|
||||
public static ICollection GetIssuerAlternativeNames(
|
||||
X509Certificate cert)
|
||||
{
|
||||
Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName);
|
||||
|
||||
return GetAlternativeName(extVal);
|
||||
}
|
||||
|
||||
public static ICollection GetSubjectAlternativeNames(
|
||||
X509Certificate cert)
|
||||
{
|
||||
Asn1OctetString extVal = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName);
|
||||
|
||||
return GetAlternativeName(extVal);
|
||||
}
|
||||
|
||||
private static ICollection GetAlternativeName(
|
||||
Asn1OctetString extVal)
|
||||
{
|
||||
IList temp = Platform.CreateArrayList();
|
||||
|
||||
if (extVal != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Asn1Sequence seq = DerSequence.GetInstance(FromExtensionValue(extVal));
|
||||
|
||||
foreach (GeneralName genName in seq)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
list.Add(genName.TagNo);
|
||||
|
||||
switch (genName.TagNo)
|
||||
{
|
||||
case GeneralName.EdiPartyName:
|
||||
case GeneralName.X400Address:
|
||||
case GeneralName.OtherName:
|
||||
list.Add(genName.Name.ToAsn1Object());
|
||||
break;
|
||||
case GeneralName.DirectoryName:
|
||||
list.Add(X509Name.GetInstance(genName.Name).ToString());
|
||||
break;
|
||||
case GeneralName.DnsName:
|
||||
case GeneralName.Rfc822Name:
|
||||
case GeneralName.UniformResourceIdentifier:
|
||||
list.Add(((IAsn1String)genName.Name).GetString());
|
||||
break;
|
||||
case GeneralName.RegisteredID:
|
||||
list.Add(DerObjectIdentifier.GetInstance(genName.Name).Id);
|
||||
break;
|
||||
case GeneralName.IPAddress:
|
||||
list.Add(DerOctetString.GetInstance(genName.Name).GetOctets());
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Bad tag number: " + genName.TagNo);
|
||||
}
|
||||
|
||||
temp.Add(list);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateParsingException(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc162f7bef9ee46959cb3d70c8b5531f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user