init commit
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
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.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class AttributeCertificateHolder : IX509Selector, ICloneable
|
||||
{
|
||||
internal readonly Holder holder;
|
||||
|
||||
public int DigestedObjectType => holder.ObjectDigestInfo?.DigestedObjectType.Value.IntValue ?? (-1);
|
||||
|
||||
public string DigestAlgorithm => holder.ObjectDigestInfo?.DigestAlgorithm.Algorithm.Id;
|
||||
|
||||
public string OtherObjectTypeID => holder.ObjectDigestInfo?.OtherObjectTypeID.Id;
|
||||
|
||||
public BigInteger SerialNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
if (holder.BaseCertificateID != null)
|
||||
{
|
||||
return holder.BaseCertificateID.Serial.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal AttributeCertificateHolder(Asn1Sequence seq)
|
||||
{
|
||||
holder = Holder.GetInstance(seq);
|
||||
}
|
||||
|
||||
public AttributeCertificateHolder(X509Name issuerName, BigInteger serialNumber)
|
||||
{
|
||||
holder = new Holder(new IssuerSerial(GenerateGeneralNames(issuerName), new DerInteger(serialNumber)));
|
||||
}
|
||||
|
||||
public AttributeCertificateHolder(X509Certificate cert)
|
||||
{
|
||||
X509Name issuerX509Principal;
|
||||
try
|
||||
{
|
||||
issuerX509Principal = PrincipalUtilities.GetIssuerX509Principal(cert);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateParsingException(ex.Message);
|
||||
}
|
||||
holder = new Holder(new IssuerSerial(GenerateGeneralNames(issuerX509Principal), new DerInteger(cert.SerialNumber)));
|
||||
}
|
||||
|
||||
public AttributeCertificateHolder(X509Name principal)
|
||||
{
|
||||
holder = new Holder(GenerateGeneralNames(principal));
|
||||
}
|
||||
|
||||
public AttributeCertificateHolder(int digestedObjectType, string digestAlgorithm, string otherObjectTypeID, byte[] objectDigest)
|
||||
{
|
||||
holder = new Holder(new ObjectDigestInfo(digestedObjectType, otherObjectTypeID, new AlgorithmIdentifier(new DerObjectIdentifier(digestAlgorithm)), Arrays.Clone(objectDigest)));
|
||||
}
|
||||
|
||||
public byte[] GetObjectDigest()
|
||||
{
|
||||
return holder.ObjectDigestInfo?.ObjectDigest.GetBytes();
|
||||
}
|
||||
|
||||
private GeneralNames GenerateGeneralNames(X509Name principal)
|
||||
{
|
||||
return new GeneralNames(new GeneralName(principal));
|
||||
}
|
||||
|
||||
private bool MatchesDN(X509Name subject, GeneralNames targets)
|
||||
{
|
||||
GeneralName[] names = targets.GetNames();
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
GeneralName generalName = names[i];
|
||||
if (generalName.TagNo != 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (X509Name.GetInstance(generalName.Name).Equivalent(subject))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private object[] GetNames(GeneralName[] names)
|
||||
{
|
||||
int num = 0;
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
if (names[i].TagNo == 4)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
object[] array = new object[num];
|
||||
int num2 = 0;
|
||||
for (int j = 0; j != names.Length; j++)
|
||||
{
|
||||
if (names[j].TagNo == 4)
|
||||
{
|
||||
array[num2++] = X509Name.GetInstance(names[j].Name);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private X509Name[] GetPrincipals(GeneralNames names)
|
||||
{
|
||||
object[] names2 = GetNames(names.GetNames());
|
||||
int num = 0;
|
||||
for (int i = 0; i != names2.Length; i++)
|
||||
{
|
||||
if (names2[i] is X509Name)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
X509Name[] array = new X509Name[num];
|
||||
int num2 = 0;
|
||||
for (int j = 0; j != names2.Length; j++)
|
||||
{
|
||||
if (names2[j] is X509Name)
|
||||
{
|
||||
array[num2++] = (X509Name)names2[j];
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public X509Name[] GetEntityNames()
|
||||
{
|
||||
if (holder.EntityName != null)
|
||||
{
|
||||
return GetPrincipals(holder.EntityName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public X509Name[] GetIssuer()
|
||||
{
|
||||
if (holder.BaseCertificateID != null)
|
||||
{
|
||||
return GetPrincipals(holder.BaseCertificateID.Issuer);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new AttributeCertificateHolder((Asn1Sequence)holder.ToAsn1Object());
|
||||
}
|
||||
|
||||
public bool Match(X509Certificate x509Cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (holder.BaseCertificateID != null)
|
||||
{
|
||||
return holder.BaseCertificateID.Serial.Value.Equals(x509Cert.SerialNumber) && MatchesDN(PrincipalUtilities.GetIssuerX509Principal(x509Cert), holder.BaseCertificateID.Issuer);
|
||||
}
|
||||
if (holder.EntityName != null && MatchesDN(PrincipalUtilities.GetSubjectX509Principal(x509Cert), holder.EntityName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (holder.ObjectDigestInfo != null)
|
||||
{
|
||||
IDigest digest = null;
|
||||
try
|
||||
{
|
||||
digest = DigestUtilities.GetDigest(DigestAlgorithm);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
switch (DigestedObjectType)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
byte[] encoded2 = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(x509Cert.GetPublicKey()).GetEncoded();
|
||||
digest.BlockUpdate(encoded2, 0, encoded2.Length);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
byte[] encoded = x509Cert.GetEncoded();
|
||||
digest.BlockUpdate(encoded, 0, encoded.Length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!Arrays.AreEqual(DigestUtilities.DoFinal(digest), GetObjectDigest()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CertificateEncodingException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is AttributeCertificateHolder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AttributeCertificateHolder attributeCertificateHolder = (AttributeCertificateHolder)obj;
|
||||
return holder.Equals(attributeCertificateHolder.holder);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return holder.GetHashCode();
|
||||
}
|
||||
|
||||
public bool Match(object obj)
|
||||
{
|
||||
if (!(obj is X509Certificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Match((X509Certificate)obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.X509.Store;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class AttributeCertificateIssuer : IX509Selector, ICloneable
|
||||
{
|
||||
internal readonly Asn1Encodable form;
|
||||
|
||||
public AttributeCertificateIssuer(AttCertIssuer issuer)
|
||||
{
|
||||
form = issuer.Issuer;
|
||||
}
|
||||
|
||||
public AttributeCertificateIssuer(X509Name principal)
|
||||
{
|
||||
form = new V2Form(new GeneralNames(new GeneralName(principal)));
|
||||
}
|
||||
|
||||
private object[] GetNames()
|
||||
{
|
||||
GeneralNames generalNames = ((!(form is V2Form)) ? ((GeneralNames)form) : ((V2Form)form).IssuerName);
|
||||
GeneralName[] names = generalNames.GetNames();
|
||||
int num = 0;
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
if (names[i].TagNo == 4)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
object[] array = new object[num];
|
||||
int num2 = 0;
|
||||
for (int j = 0; j != names.Length; j++)
|
||||
{
|
||||
if (names[j].TagNo == 4)
|
||||
{
|
||||
array[num2++] = X509Name.GetInstance(names[j].Name);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public X509Name[] GetPrincipals()
|
||||
{
|
||||
object[] names = GetNames();
|
||||
int num = 0;
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
if (names[i] is X509Name)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
X509Name[] array = new X509Name[num];
|
||||
int num2 = 0;
|
||||
for (int j = 0; j != names.Length; j++)
|
||||
{
|
||||
if (names[j] is X509Name)
|
||||
{
|
||||
array[num2++] = (X509Name)names[j];
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private bool MatchesDN(X509Name subject, GeneralNames targets)
|
||||
{
|
||||
GeneralName[] names = targets.GetNames();
|
||||
for (int i = 0; i != names.Length; i++)
|
||||
{
|
||||
GeneralName generalName = names[i];
|
||||
if (generalName.TagNo != 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (X509Name.GetInstance(generalName.Name).Equivalent(subject))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new AttributeCertificateIssuer(AttCertIssuer.GetInstance(form));
|
||||
}
|
||||
|
||||
public bool Match(X509Certificate x509Cert)
|
||||
{
|
||||
if (form is V2Form)
|
||||
{
|
||||
V2Form v2Form = (V2Form)form;
|
||||
if (v2Form.BaseCertificateID != null)
|
||||
{
|
||||
if (v2Form.BaseCertificateID.Serial.Value.Equals(x509Cert.SerialNumber))
|
||||
{
|
||||
return MatchesDN(x509Cert.IssuerDN, v2Form.BaseCertificateID.Issuer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return MatchesDN(x509Cert.SubjectDN, v2Form.IssuerName);
|
||||
}
|
||||
return MatchesDN(x509Cert.SubjectDN, (GeneralNames)form);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is AttributeCertificateIssuer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AttributeCertificateIssuer attributeCertificateIssuer = (AttributeCertificateIssuer)obj;
|
||||
return form.Equals(attributeCertificateIssuer.form);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return form.GetHashCode();
|
||||
}
|
||||
|
||||
public bool Match(object obj)
|
||||
{
|
||||
if (!(obj is X509Certificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Match((X509Certificate)obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Extension;
|
||||
|
||||
public class AuthorityKeyIdentifierStructure : AuthorityKeyIdentifier
|
||||
{
|
||||
public AuthorityKeyIdentifierStructure(Asn1OctetString encodedValue)
|
||||
: base((Asn1Sequence)X509ExtensionUtilities.FromExtensionValue(encodedValue))
|
||||
{
|
||||
}
|
||||
|
||||
private static Asn1Sequence FromCertificate(X509Certificate certificate)
|
||||
{
|
||||
try
|
||||
{
|
||||
GeneralName name = new GeneralName(PrincipalUtilities.GetIssuerX509Principal(certificate));
|
||||
if (certificate.Version == 3)
|
||||
{
|
||||
Asn1OctetString extensionValue = certificate.GetExtensionValue(X509Extensions.SubjectKeyIdentifier);
|
||||
if (extensionValue != null)
|
||||
{
|
||||
Asn1OctetString asn1OctetString = (Asn1OctetString)X509ExtensionUtilities.FromExtensionValue(extensionValue);
|
||||
return (Asn1Sequence)new AuthorityKeyIdentifier(asn1OctetString.GetOctets(), new GeneralNames(name), certificate.SerialNumber).ToAsn1Object();
|
||||
}
|
||||
}
|
||||
SubjectPublicKeyInfo spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(certificate.GetPublicKey());
|
||||
return (Asn1Sequence)new AuthorityKeyIdentifier(spki, new GeneralNames(name), certificate.SerialNumber).ToAsn1Object();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new CertificateParsingException("Exception extracting certificate details", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static Asn1Sequence FromKey(AsymmetricKeyParameter pubKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
SubjectPublicKeyInfo spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);
|
||||
return (Asn1Sequence)new AuthorityKeyIdentifier(spki).ToAsn1Object();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidKeyException("can't process key: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
public AuthorityKeyIdentifierStructure(X509Certificate certificate)
|
||||
: base(FromCertificate(certificate))
|
||||
{
|
||||
}
|
||||
|
||||
public AuthorityKeyIdentifierStructure(AsymmetricKeyParameter pubKey)
|
||||
: base(FromKey(pubKey))
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Extension;
|
||||
|
||||
public class SubjectKeyIdentifierStructure : SubjectKeyIdentifier
|
||||
{
|
||||
public SubjectKeyIdentifierStructure(Asn1OctetString encodedValue)
|
||||
: base((Asn1OctetString)X509ExtensionUtilities.FromExtensionValue(encodedValue))
|
||||
{
|
||||
}
|
||||
|
||||
private static Asn1OctetString FromPublicKey(AsymmetricKeyParameter pubKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
SubjectPublicKeyInfo spki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);
|
||||
return (Asn1OctetString)new SubjectKeyIdentifier(spki).ToAsn1Object();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateParsingException("Exception extracting certificate details: " + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public SubjectKeyIdentifierStructure(AsymmetricKeyParameter pubKey)
|
||||
: base(FromPublicKey(pubKey))
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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 extensionValue = cert.GetExtensionValue(X509Extensions.IssuerAlternativeName);
|
||||
return GetAlternativeName(extensionValue);
|
||||
}
|
||||
|
||||
public static ICollection GetSubjectAlternativeNames(X509Certificate cert)
|
||||
{
|
||||
Asn1OctetString extensionValue = cert.GetExtensionValue(X509Extensions.SubjectAlternativeName);
|
||||
return GetAlternativeName(extensionValue);
|
||||
}
|
||||
|
||||
private static ICollection GetAlternativeName(Asn1OctetString extVal)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
if (extVal != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Asn1Sequence instance = Asn1Sequence.GetInstance(FromExtensionValue(extVal));
|
||||
foreach (Asn1Encodable item in instance)
|
||||
{
|
||||
IList list2 = Platform.CreateArrayList();
|
||||
GeneralName instance2 = GeneralName.GetInstance(item);
|
||||
list2.Add(instance2.TagNo);
|
||||
switch (instance2.TagNo)
|
||||
{
|
||||
case 0:
|
||||
case 3:
|
||||
case 5:
|
||||
list2.Add(instance2.Name.ToAsn1Object());
|
||||
break;
|
||||
case 4:
|
||||
list2.Add(X509Name.GetInstance(instance2.Name).ToString());
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 6:
|
||||
list2.Add(((IAsn1String)instance2.Name).GetString());
|
||||
break;
|
||||
case 8:
|
||||
list2.Add(DerObjectIdentifier.GetInstance(instance2.Name).Id);
|
||||
break;
|
||||
case 7:
|
||||
list2.Add(Asn1OctetString.GetInstance(instance2.Name).GetOctets());
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Bad tag number: " + instance2.TagNo);
|
||||
}
|
||||
list.Add(list2);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateParsingException(ex.Message);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public interface IX509AttributeCertificate : IX509Extension
|
||||
{
|
||||
int Version { get; }
|
||||
|
||||
BigInteger SerialNumber { get; }
|
||||
|
||||
DateTime NotBefore { get; }
|
||||
|
||||
DateTime NotAfter { get; }
|
||||
|
||||
AttributeCertificateHolder Holder { get; }
|
||||
|
||||
AttributeCertificateIssuer Issuer { get; }
|
||||
|
||||
bool IsValidNow { get; }
|
||||
|
||||
X509Attribute[] GetAttributes();
|
||||
|
||||
X509Attribute[] GetAttributes(string oid);
|
||||
|
||||
bool[] GetIssuerUniqueID();
|
||||
|
||||
bool IsValid(DateTime date);
|
||||
|
||||
void CheckValidity();
|
||||
|
||||
void CheckValidity(DateTime date);
|
||||
|
||||
byte[] GetSignature();
|
||||
|
||||
void Verify(AsymmetricKeyParameter publicKey);
|
||||
|
||||
byte[] GetEncoded();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public interface IX509Extension
|
||||
{
|
||||
ISet GetCriticalExtensionOids();
|
||||
|
||||
ISet GetNonCriticalExtensionOids();
|
||||
|
||||
[Obsolete("Use version taking a DerObjectIdentifier instead")]
|
||||
Asn1OctetString GetExtensionValue(string oid);
|
||||
|
||||
Asn1OctetString GetExtensionValue(DerObjectIdentifier oid);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
internal 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)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
int num;
|
||||
while (true)
|
||||
{
|
||||
if ((num = inStream.ReadByte()) != 13 && num != 10 && num >= 0)
|
||||
{
|
||||
if (num != 13)
|
||||
{
|
||||
stringBuilder.Append((char)num);
|
||||
}
|
||||
}
|
||||
else if (num < 0 || stringBuilder.Length != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
internal Asn1Sequence ReadPemObject(Stream inStream)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string source;
|
||||
while ((source = ReadLine(inStream)) != null && !Platform.StartsWith(source, _header1) && !Platform.StartsWith(source, _header2))
|
||||
{
|
||||
}
|
||||
while ((source = ReadLine(inStream)) != null && !Platform.StartsWith(source, _footer1) && !Platform.StartsWith(source, _footer2))
|
||||
{
|
||||
stringBuilder.Append(source);
|
||||
}
|
||||
if (stringBuilder.Length != 0)
|
||||
{
|
||||
Asn1Object asn1Object = Asn1Object.FromByteArray(Base64.Decode(stringBuilder.ToString()));
|
||||
if (!(asn1Object is Asn1Sequence))
|
||||
{
|
||||
throw new IOException("malformed PEM data encountered");
|
||||
}
|
||||
return (Asn1Sequence)asn1Object;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class PrincipalUtilities
|
||||
{
|
||||
public static X509Name GetIssuerX509Principal(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
TbsCertificateStructure instance = TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetTbsCertificate()));
|
||||
return instance.Issuer;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateEncodingException("Could not extract issuer", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static X509Name GetSubjectX509Principal(X509Certificate cert)
|
||||
{
|
||||
try
|
||||
{
|
||||
TbsCertificateStructure instance = TbsCertificateStructure.GetInstance(Asn1Object.FromByteArray(cert.GetTbsCertificate()));
|
||||
return instance.Subject;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateEncodingException("Could not extract subject", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static X509Name GetIssuerX509Principal(X509Crl crl)
|
||||
{
|
||||
try
|
||||
{
|
||||
TbsCertificateList instance = TbsCertificateList.GetInstance(Asn1Object.FromByteArray(crl.GetTbsCertList()));
|
||||
return instance.Issuer;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CrlException("Could not extract issuer", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public interface IX509Selector : ICloneable
|
||||
{
|
||||
bool Match(object obj);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public interface IX509Store
|
||||
{
|
||||
ICollection GetMatches(IX509Selector selector);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public interface IX509StoreParameters
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
[Serializable]
|
||||
public class NoSuchStoreException : X509StoreException
|
||||
{
|
||||
public NoSuchStoreException()
|
||||
{
|
||||
}
|
||||
|
||||
public NoSuchStoreException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public NoSuchStoreException(string message, Exception e)
|
||||
: base(message, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public class X509AttrCertStoreSelector : IX509Selector, ICloneable
|
||||
{
|
||||
private IX509AttributeCertificate attributeCert;
|
||||
|
||||
private DateTimeObject attributeCertificateValid;
|
||||
|
||||
private AttributeCertificateHolder holder;
|
||||
|
||||
private AttributeCertificateIssuer issuer;
|
||||
|
||||
private BigInteger serialNumber;
|
||||
|
||||
private ISet targetNames = new HashSet();
|
||||
|
||||
private ISet targetGroups = new HashSet();
|
||||
|
||||
public IX509AttributeCertificate AttributeCert
|
||||
{
|
||||
get
|
||||
{
|
||||
return attributeCert;
|
||||
}
|
||||
set
|
||||
{
|
||||
attributeCert = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use AttributeCertificateValid instead")]
|
||||
public DateTimeObject AttribueCertificateValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return attributeCertificateValid;
|
||||
}
|
||||
set
|
||||
{
|
||||
attributeCertificateValid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeObject AttributeCertificateValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return attributeCertificateValid;
|
||||
}
|
||||
set
|
||||
{
|
||||
attributeCertificateValid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public AttributeCertificateHolder Holder
|
||||
{
|
||||
get
|
||||
{
|
||||
return holder;
|
||||
}
|
||||
set
|
||||
{
|
||||
holder = value;
|
||||
}
|
||||
}
|
||||
|
||||
public AttributeCertificateIssuer Issuer
|
||||
{
|
||||
get
|
||||
{
|
||||
return issuer;
|
||||
}
|
||||
set
|
||||
{
|
||||
issuer = value;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger SerialNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return serialNumber;
|
||||
}
|
||||
set
|
||||
{
|
||||
serialNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509AttrCertStoreSelector()
|
||||
{
|
||||
}
|
||||
|
||||
private X509AttrCertStoreSelector(X509AttrCertStoreSelector o)
|
||||
{
|
||||
attributeCert = o.attributeCert;
|
||||
attributeCertificateValid = o.attributeCertificateValid;
|
||||
holder = o.holder;
|
||||
issuer = o.issuer;
|
||||
serialNumber = o.serialNumber;
|
||||
targetGroups = new HashSet(o.targetGroups);
|
||||
targetNames = new HashSet(o.targetNames);
|
||||
}
|
||||
|
||||
public bool Match(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException("obj");
|
||||
}
|
||||
if (!(obj is IX509AttributeCertificate iX509AttributeCertificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (attributeCert != null && !attributeCert.Equals(iX509AttributeCertificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (serialNumber != null && !iX509AttributeCertificate.SerialNumber.Equals(serialNumber))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (holder != null && !iX509AttributeCertificate.Holder.Equals(holder))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (issuer != null && !iX509AttributeCertificate.Issuer.Equals(issuer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (attributeCertificateValid != null && !iX509AttributeCertificate.IsValid(attributeCertificateValid.Value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (targetNames.Count > 0 || targetGroups.Count > 0)
|
||||
{
|
||||
Asn1OctetString extensionValue = iX509AttributeCertificate.GetExtensionValue(X509Extensions.TargetInformation);
|
||||
if (extensionValue != null)
|
||||
{
|
||||
TargetInformation instance;
|
||||
try
|
||||
{
|
||||
instance = TargetInformation.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Targets[] targetsObjects = instance.GetTargetsObjects();
|
||||
if (targetNames.Count > 0)
|
||||
{
|
||||
bool flag = false;
|
||||
for (int i = 0; i < targetsObjects.Length; i++)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Target[] targets = targetsObjects[i].GetTargets();
|
||||
for (int j = 0; j < targets.Length; j++)
|
||||
{
|
||||
GeneralName targetName = targets[j].TargetName;
|
||||
if (targetName != null && targetNames.Contains(targetName))
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (targetGroups.Count > 0)
|
||||
{
|
||||
bool flag2 = false;
|
||||
for (int k = 0; k < targetsObjects.Length; k++)
|
||||
{
|
||||
if (flag2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Target[] targets2 = targetsObjects[k].GetTargets();
|
||||
for (int l = 0; l < targets2.Length; l++)
|
||||
{
|
||||
GeneralName targetGroup = targets2[l].TargetGroup;
|
||||
if (targetGroup != null && targetGroups.Contains(targetGroup))
|
||||
{
|
||||
flag2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!flag2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new X509AttrCertStoreSelector(this);
|
||||
}
|
||||
|
||||
public void AddTargetName(GeneralName name)
|
||||
{
|
||||
targetNames.Add(name);
|
||||
}
|
||||
|
||||
public void AddTargetName(byte[] name)
|
||||
{
|
||||
AddTargetName(GeneralName.GetInstance(Asn1Object.FromByteArray(name)));
|
||||
}
|
||||
|
||||
public void SetTargetNames(IEnumerable names)
|
||||
{
|
||||
targetNames = ExtractGeneralNames(names);
|
||||
}
|
||||
|
||||
public IEnumerable GetTargetNames()
|
||||
{
|
||||
return new EnumerableProxy(targetNames);
|
||||
}
|
||||
|
||||
public void AddTargetGroup(GeneralName group)
|
||||
{
|
||||
targetGroups.Add(group);
|
||||
}
|
||||
|
||||
public void AddTargetGroup(byte[] name)
|
||||
{
|
||||
AddTargetGroup(GeneralName.GetInstance(Asn1Object.FromByteArray(name)));
|
||||
}
|
||||
|
||||
public void SetTargetGroups(IEnumerable names)
|
||||
{
|
||||
targetGroups = ExtractGeneralNames(names);
|
||||
}
|
||||
|
||||
public IEnumerable GetTargetGroups()
|
||||
{
|
||||
return new EnumerableProxy(targetGroups);
|
||||
}
|
||||
|
||||
private ISet ExtractGeneralNames(IEnumerable names)
|
||||
{
|
||||
ISet set = new HashSet();
|
||||
if (names != null)
|
||||
{
|
||||
foreach (object name in names)
|
||||
{
|
||||
if (name is GeneralName)
|
||||
{
|
||||
set.Add(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
set.Add(GeneralName.GetInstance(Asn1Object.FromByteArray((byte[])name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public class X509CertPairStoreSelector : IX509Selector, ICloneable
|
||||
{
|
||||
private X509CertificatePair certPair;
|
||||
|
||||
private X509CertStoreSelector forwardSelector;
|
||||
|
||||
private X509CertStoreSelector reverseSelector;
|
||||
|
||||
public X509CertificatePair CertPair
|
||||
{
|
||||
get
|
||||
{
|
||||
return certPair;
|
||||
}
|
||||
set
|
||||
{
|
||||
certPair = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509CertStoreSelector ForwardSelector
|
||||
{
|
||||
get
|
||||
{
|
||||
return CloneSelector(forwardSelector);
|
||||
}
|
||||
set
|
||||
{
|
||||
forwardSelector = CloneSelector(value);
|
||||
}
|
||||
}
|
||||
|
||||
public X509CertStoreSelector ReverseSelector
|
||||
{
|
||||
get
|
||||
{
|
||||
return CloneSelector(reverseSelector);
|
||||
}
|
||||
set
|
||||
{
|
||||
reverseSelector = CloneSelector(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static X509CertStoreSelector CloneSelector(X509CertStoreSelector s)
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
return (X509CertStoreSelector)s.Clone();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public X509CertPairStoreSelector()
|
||||
{
|
||||
}
|
||||
|
||||
private X509CertPairStoreSelector(X509CertPairStoreSelector o)
|
||||
{
|
||||
certPair = o.CertPair;
|
||||
forwardSelector = o.ForwardSelector;
|
||||
reverseSelector = o.ReverseSelector;
|
||||
}
|
||||
|
||||
public bool Match(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException("obj");
|
||||
}
|
||||
if (!(obj is X509CertificatePair x509CertificatePair))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (certPair != null && !certPair.Equals(x509CertificatePair))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (forwardSelector != null && !forwardSelector.Match(x509CertificatePair.Forward))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (reverseSelector != null && !reverseSelector.Match(x509CertificatePair.Reverse))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new X509CertPairStoreSelector(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public class X509CertStoreSelector : IX509Selector, ICloneable
|
||||
{
|
||||
private byte[] authorityKeyIdentifier;
|
||||
|
||||
private int basicConstraints = -1;
|
||||
|
||||
private X509Certificate certificate;
|
||||
|
||||
private DateTimeObject certificateValid;
|
||||
|
||||
private ISet extendedKeyUsage;
|
||||
|
||||
private bool ignoreX509NameOrdering;
|
||||
|
||||
private X509Name issuer;
|
||||
|
||||
private bool[] keyUsage;
|
||||
|
||||
private ISet policy;
|
||||
|
||||
private DateTimeObject privateKeyValid;
|
||||
|
||||
private BigInteger serialNumber;
|
||||
|
||||
private X509Name subject;
|
||||
|
||||
private byte[] subjectKeyIdentifier;
|
||||
|
||||
private SubjectPublicKeyInfo subjectPublicKey;
|
||||
|
||||
private DerObjectIdentifier subjectPublicKeyAlgID;
|
||||
|
||||
public byte[] AuthorityKeyIdentifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return Arrays.Clone(authorityKeyIdentifier);
|
||||
}
|
||||
set
|
||||
{
|
||||
authorityKeyIdentifier = Arrays.Clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
public int BasicConstraints
|
||||
{
|
||||
get
|
||||
{
|
||||
return basicConstraints;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < -2)
|
||||
{
|
||||
throw new ArgumentException("value can't be less than -2", "value");
|
||||
}
|
||||
basicConstraints = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509Certificate Certificate
|
||||
{
|
||||
get
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
set
|
||||
{
|
||||
certificate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeObject CertificateValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return certificateValid;
|
||||
}
|
||||
set
|
||||
{
|
||||
certificateValid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ISet ExtendedKeyUsage
|
||||
{
|
||||
get
|
||||
{
|
||||
return CopySet(extendedKeyUsage);
|
||||
}
|
||||
set
|
||||
{
|
||||
extendedKeyUsage = CopySet(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IgnoreX509NameOrdering
|
||||
{
|
||||
get
|
||||
{
|
||||
return ignoreX509NameOrdering;
|
||||
}
|
||||
set
|
||||
{
|
||||
ignoreX509NameOrdering = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509Name Issuer
|
||||
{
|
||||
get
|
||||
{
|
||||
return issuer;
|
||||
}
|
||||
set
|
||||
{
|
||||
issuer = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Avoid working with X509Name objects in string form")]
|
||||
public string IssuerAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (issuer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return issuer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public bool[] KeyUsage
|
||||
{
|
||||
get
|
||||
{
|
||||
return CopyBoolArray(keyUsage);
|
||||
}
|
||||
set
|
||||
{
|
||||
keyUsage = CopyBoolArray(value);
|
||||
}
|
||||
}
|
||||
|
||||
public ISet Policy
|
||||
{
|
||||
get
|
||||
{
|
||||
return CopySet(policy);
|
||||
}
|
||||
set
|
||||
{
|
||||
policy = CopySet(value);
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeObject PrivateKeyValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return privateKeyValid;
|
||||
}
|
||||
set
|
||||
{
|
||||
privateKeyValid = value;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger SerialNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return serialNumber;
|
||||
}
|
||||
set
|
||||
{
|
||||
serialNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509Name Subject
|
||||
{
|
||||
get
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
set
|
||||
{
|
||||
subject = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Avoid working with X509Name objects in string form")]
|
||||
public string SubjectAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (subject == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return subject.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] SubjectKeyIdentifier
|
||||
{
|
||||
get
|
||||
{
|
||||
return Arrays.Clone(subjectKeyIdentifier);
|
||||
}
|
||||
set
|
||||
{
|
||||
subjectKeyIdentifier = Arrays.Clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
public SubjectPublicKeyInfo SubjectPublicKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return subjectPublicKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
subjectPublicKey = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DerObjectIdentifier SubjectPublicKeyAlgID
|
||||
{
|
||||
get
|
||||
{
|
||||
return subjectPublicKeyAlgID;
|
||||
}
|
||||
set
|
||||
{
|
||||
subjectPublicKeyAlgID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509CertStoreSelector()
|
||||
{
|
||||
}
|
||||
|
||||
public X509CertStoreSelector(X509CertStoreSelector o)
|
||||
{
|
||||
authorityKeyIdentifier = o.AuthorityKeyIdentifier;
|
||||
basicConstraints = o.BasicConstraints;
|
||||
certificate = o.Certificate;
|
||||
certificateValid = o.CertificateValid;
|
||||
extendedKeyUsage = o.ExtendedKeyUsage;
|
||||
ignoreX509NameOrdering = o.IgnoreX509NameOrdering;
|
||||
issuer = o.Issuer;
|
||||
keyUsage = o.KeyUsage;
|
||||
policy = o.Policy;
|
||||
privateKeyValid = o.PrivateKeyValid;
|
||||
serialNumber = o.SerialNumber;
|
||||
subject = o.Subject;
|
||||
subjectKeyIdentifier = o.SubjectKeyIdentifier;
|
||||
subjectPublicKey = o.SubjectPublicKey;
|
||||
subjectPublicKeyAlgID = o.SubjectPublicKeyAlgID;
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
return new X509CertStoreSelector(this);
|
||||
}
|
||||
|
||||
public virtual bool Match(object obj)
|
||||
{
|
||||
if (!(obj is X509Certificate x509Certificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!MatchExtension(authorityKeyIdentifier, x509Certificate, X509Extensions.AuthorityKeyIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (basicConstraints != -1)
|
||||
{
|
||||
int num = x509Certificate.GetBasicConstraints();
|
||||
if (basicConstraints == -2)
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (num < basicConstraints)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (certificate != null && !certificate.Equals(x509Certificate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (certificateValid != null && !x509Certificate.IsValid(certificateValid.Value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (extendedKeyUsage != null)
|
||||
{
|
||||
IList list = x509Certificate.GetExtendedKeyUsage();
|
||||
if (list != null)
|
||||
{
|
||||
foreach (DerObjectIdentifier item in extendedKeyUsage)
|
||||
{
|
||||
if (!list.Contains(item.Id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (issuer != null && !issuer.Equivalent(x509Certificate.IssuerDN, !ignoreX509NameOrdering))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (keyUsage != null)
|
||||
{
|
||||
bool[] array = x509Certificate.GetKeyUsage();
|
||||
if (array != null)
|
||||
{
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
if (keyUsage[i] && !array[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (policy != null)
|
||||
{
|
||||
Asn1OctetString extensionValue = x509Certificate.GetExtensionValue(X509Extensions.CertificatePolicies);
|
||||
if (extensionValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Asn1Sequence instance = Asn1Sequence.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue));
|
||||
if (policy.Count < 1 && instance.Count < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool flag = false;
|
||||
foreach (PolicyInformation item2 in instance)
|
||||
{
|
||||
if (policy.Contains(item2.PolicyIdentifier))
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (privateKeyValid != null)
|
||||
{
|
||||
Asn1OctetString extensionValue2 = x509Certificate.GetExtensionValue(X509Extensions.PrivateKeyUsagePeriod);
|
||||
if (extensionValue2 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PrivateKeyUsagePeriod instance2 = PrivateKeyUsagePeriod.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue2));
|
||||
DateTime value = privateKeyValid.Value;
|
||||
DateTime dateTime = instance2.NotAfter.ToDateTime();
|
||||
DateTime dateTime2 = instance2.NotBefore.ToDateTime();
|
||||
if (value.CompareTo((object?)dateTime) > 0 || value.CompareTo((object?)dateTime2) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (serialNumber != null && !serialNumber.Equals(x509Certificate.SerialNumber))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (subject != null && !subject.Equivalent(x509Certificate.SubjectDN, !ignoreX509NameOrdering))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!MatchExtension(subjectKeyIdentifier, x509Certificate, X509Extensions.SubjectKeyIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (subjectPublicKey != null && !subjectPublicKey.Equals(GetSubjectPublicKey(x509Certificate)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (subjectPublicKeyAlgID != null && !subjectPublicKeyAlgID.Equals(GetSubjectPublicKey(x509Certificate).AlgorithmID))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool IssuersMatch(X509Name a, X509Name b)
|
||||
{
|
||||
return a?.Equivalent(b, inOrder: true) ?? (b == null);
|
||||
}
|
||||
|
||||
private static bool[] CopyBoolArray(bool[] b)
|
||||
{
|
||||
if (b != null)
|
||||
{
|
||||
return (bool[])b.Clone();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ISet CopySet(ISet s)
|
||||
{
|
||||
if (s != null)
|
||||
{
|
||||
return new HashSet(s);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static SubjectPublicKeyInfo GetSubjectPublicKey(X509Certificate c)
|
||||
{
|
||||
return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(c.GetPublicKey());
|
||||
}
|
||||
|
||||
private static bool MatchExtension(byte[] b, X509Certificate c, DerObjectIdentifier oid)
|
||||
{
|
||||
if (b == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
Asn1OctetString extensionValue = c.GetExtensionValue(oid);
|
||||
if (extensionValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Arrays.AreEqual(b, extensionValue.GetOctets());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
internal class X509CollectionStore : IX509Store
|
||||
{
|
||||
private ICollection _local;
|
||||
|
||||
internal X509CollectionStore(ICollection collection)
|
||||
{
|
||||
_local = Platform.CreateArrayList(collection);
|
||||
}
|
||||
|
||||
public ICollection GetMatches(IX509Selector selector)
|
||||
{
|
||||
if (selector == null)
|
||||
{
|
||||
return Platform.CreateArrayList(_local);
|
||||
}
|
||||
IList list = Platform.CreateArrayList();
|
||||
foreach (object item in _local)
|
||||
{
|
||||
if (selector.Match(item))
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public class X509CollectionStoreParameters : IX509StoreParameters
|
||||
{
|
||||
private readonly IList collection;
|
||||
|
||||
public X509CollectionStoreParameters(ICollection collection)
|
||||
{
|
||||
if (collection == null)
|
||||
{
|
||||
throw new ArgumentNullException("collection");
|
||||
}
|
||||
this.collection = Platform.CreateArrayList(collection);
|
||||
}
|
||||
|
||||
public ICollection GetCollection()
|
||||
{
|
||||
return Platform.CreateArrayList(collection);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append("X509CollectionStoreParameters: [\n");
|
||||
stringBuilder.Append(string.Concat(" collection: ", collection, "\n"));
|
||||
stringBuilder.Append("]");
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Date;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public class X509CrlStoreSelector : IX509Selector, ICloneable
|
||||
{
|
||||
private X509Certificate certificateChecking;
|
||||
|
||||
private DateTimeObject dateAndTime;
|
||||
|
||||
private ICollection issuers;
|
||||
|
||||
private BigInteger maxCrlNumber;
|
||||
|
||||
private BigInteger minCrlNumber;
|
||||
|
||||
private IX509AttributeCertificate attrCertChecking;
|
||||
|
||||
private bool completeCrlEnabled;
|
||||
|
||||
private bool deltaCrlIndicatorEnabled;
|
||||
|
||||
private byte[] issuingDistributionPoint;
|
||||
|
||||
private bool issuingDistributionPointEnabled;
|
||||
|
||||
private BigInteger maxBaseCrlNumber;
|
||||
|
||||
public X509Certificate CertificateChecking
|
||||
{
|
||||
get
|
||||
{
|
||||
return certificateChecking;
|
||||
}
|
||||
set
|
||||
{
|
||||
certificateChecking = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeObject DateAndTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return dateAndTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
dateAndTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection Issuers
|
||||
{
|
||||
get
|
||||
{
|
||||
return Platform.CreateArrayList(issuers);
|
||||
}
|
||||
set
|
||||
{
|
||||
issuers = Platform.CreateArrayList(value);
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger MaxCrlNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return maxCrlNumber;
|
||||
}
|
||||
set
|
||||
{
|
||||
maxCrlNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger MinCrlNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return minCrlNumber;
|
||||
}
|
||||
set
|
||||
{
|
||||
minCrlNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IX509AttributeCertificate AttrCertChecking
|
||||
{
|
||||
get
|
||||
{
|
||||
return attrCertChecking;
|
||||
}
|
||||
set
|
||||
{
|
||||
attrCertChecking = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CompleteCrlEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return completeCrlEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
completeCrlEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeltaCrlIndicatorEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return deltaCrlIndicatorEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
deltaCrlIndicatorEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] IssuingDistributionPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return Arrays.Clone(issuingDistributionPoint);
|
||||
}
|
||||
set
|
||||
{
|
||||
issuingDistributionPoint = Arrays.Clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IssuingDistributionPointEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return issuingDistributionPointEnabled;
|
||||
}
|
||||
set
|
||||
{
|
||||
issuingDistributionPointEnabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger MaxBaseCrlNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return maxBaseCrlNumber;
|
||||
}
|
||||
set
|
||||
{
|
||||
maxBaseCrlNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
public X509CrlStoreSelector()
|
||||
{
|
||||
}
|
||||
|
||||
public X509CrlStoreSelector(X509CrlStoreSelector o)
|
||||
{
|
||||
certificateChecking = o.CertificateChecking;
|
||||
dateAndTime = o.DateAndTime;
|
||||
issuers = o.Issuers;
|
||||
maxCrlNumber = o.MaxCrlNumber;
|
||||
minCrlNumber = o.MinCrlNumber;
|
||||
deltaCrlIndicatorEnabled = o.DeltaCrlIndicatorEnabled;
|
||||
completeCrlEnabled = o.CompleteCrlEnabled;
|
||||
maxBaseCrlNumber = o.MaxBaseCrlNumber;
|
||||
attrCertChecking = o.AttrCertChecking;
|
||||
issuingDistributionPointEnabled = o.IssuingDistributionPointEnabled;
|
||||
issuingDistributionPoint = o.IssuingDistributionPoint;
|
||||
}
|
||||
|
||||
public virtual object Clone()
|
||||
{
|
||||
return new X509CrlStoreSelector(this);
|
||||
}
|
||||
|
||||
public virtual bool Match(object obj)
|
||||
{
|
||||
if (!(obj is X509Crl x509Crl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (dateAndTime != null)
|
||||
{
|
||||
DateTime value = dateAndTime.Value;
|
||||
DateTime thisUpdate = x509Crl.ThisUpdate;
|
||||
DateTimeObject nextUpdate = x509Crl.NextUpdate;
|
||||
if (value.CompareTo((object?)thisUpdate) < 0 || nextUpdate == null || value.CompareTo((object?)nextUpdate.Value) >= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (issuers != null)
|
||||
{
|
||||
X509Name issuerDN = x509Crl.IssuerDN;
|
||||
bool flag = false;
|
||||
foreach (X509Name issuer in issuers)
|
||||
{
|
||||
if (issuer.Equivalent(issuerDN, inOrder: true))
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (maxCrlNumber != null || minCrlNumber != null)
|
||||
{
|
||||
Asn1OctetString extensionValue = x509Crl.GetExtensionValue(X509Extensions.CrlNumber);
|
||||
if (extensionValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BigInteger positiveValue = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue)).PositiveValue;
|
||||
if (maxCrlNumber != null && positiveValue.CompareTo(maxCrlNumber) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (minCrlNumber != null && positiveValue.CompareTo(minCrlNumber) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
DerInteger derInteger = null;
|
||||
try
|
||||
{
|
||||
Asn1OctetString extensionValue2 = x509Crl.GetExtensionValue(X509Extensions.DeltaCrlIndicator);
|
||||
if (extensionValue2 != null)
|
||||
{
|
||||
derInteger = DerInteger.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue2));
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (derInteger == null)
|
||||
{
|
||||
if (DeltaCrlIndicatorEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CompleteCrlEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (maxBaseCrlNumber != null && derInteger.PositiveValue.CompareTo(maxBaseCrlNumber) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (issuingDistributionPointEnabled)
|
||||
{
|
||||
Asn1OctetString extensionValue3 = x509Crl.GetExtensionValue(X509Extensions.IssuingDistributionPoint);
|
||||
if (issuingDistributionPoint == null)
|
||||
{
|
||||
if (extensionValue3 != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!Arrays.AreEqual(extensionValue3.GetOctets(), issuingDistributionPoint))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
[Serializable]
|
||||
public class X509StoreException : Exception
|
||||
{
|
||||
public X509StoreException()
|
||||
{
|
||||
}
|
||||
|
||||
public X509StoreException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public X509StoreException(string message, Exception e)
|
||||
: base(message, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.X509.Store;
|
||||
|
||||
public sealed class X509StoreFactory
|
||||
{
|
||||
private X509StoreFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public static IX509Store Create(string type, IX509StoreParameters parameters)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException("type");
|
||||
}
|
||||
string[] array = Platform.ToUpperInvariant(type).Split(new char[1] { '/' });
|
||||
if (array.Length < 2)
|
||||
{
|
||||
throw new ArgumentException("type");
|
||||
}
|
||||
if (array[1] != "COLLECTION")
|
||||
{
|
||||
throw new NoSuchStoreException("X.509 store type '" + type + "' not available.");
|
||||
}
|
||||
X509CollectionStoreParameters x509CollectionStoreParameters = (X509CollectionStoreParameters)parameters;
|
||||
ICollection collection = x509CollectionStoreParameters.GetCollection();
|
||||
switch (array[0])
|
||||
{
|
||||
case "ATTRIBUTECERTIFICATE":
|
||||
checkCorrectType(collection, typeof(IX509AttributeCertificate));
|
||||
break;
|
||||
case "CERTIFICATE":
|
||||
checkCorrectType(collection, typeof(X509Certificate));
|
||||
break;
|
||||
case "CERTIFICATEPAIR":
|
||||
checkCorrectType(collection, typeof(X509CertificatePair));
|
||||
break;
|
||||
case "CRL":
|
||||
checkCorrectType(collection, typeof(X509Crl));
|
||||
break;
|
||||
default:
|
||||
throw new NoSuchStoreException("X.509 store type '" + type + "' not available.");
|
||||
}
|
||||
return new X509CollectionStore(collection);
|
||||
}
|
||||
|
||||
private static void checkCorrectType(ICollection coll, Type t)
|
||||
{
|
||||
foreach (object item in coll)
|
||||
{
|
||||
if (!t.IsInstanceOfType(item))
|
||||
{
|
||||
throw new InvalidCastException("Can't cast object to type: " + t.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Org.BouncyCastle.Asn1.EdEC;
|
||||
using Org.BouncyCastle.Asn1.Oiw;
|
||||
using Org.BouncyCastle.Asn1.Pkcs;
|
||||
using Org.BouncyCastle.Asn1.Rosstandart;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Asn1.X9;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Math.EC;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public sealed class SubjectPublicKeyInfoFactory
|
||||
{
|
||||
private SubjectPublicKeyInfoFactory()
|
||||
{
|
||||
}
|
||||
|
||||
public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
if (publicKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("publicKey");
|
||||
}
|
||||
if (publicKey.IsPrivate)
|
||||
{
|
||||
throw new ArgumentException("Private key passed - public key expected.", "publicKey");
|
||||
}
|
||||
if (publicKey is ElGamalPublicKeyParameters)
|
||||
{
|
||||
ElGamalPublicKeyParameters elGamalPublicKeyParameters = (ElGamalPublicKeyParameters)publicKey;
|
||||
ElGamalParameters parameters = elGamalPublicKeyParameters.Parameters;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(parameters.P, parameters.G).ToAsn1Object()), new DerInteger(elGamalPublicKeyParameters.Y));
|
||||
}
|
||||
if (publicKey is DsaPublicKeyParameters)
|
||||
{
|
||||
DsaPublicKeyParameters dsaPublicKeyParameters = (DsaPublicKeyParameters)publicKey;
|
||||
DsaParameters parameters2 = dsaPublicKeyParameters.Parameters;
|
||||
Asn1Encodable parameters3 = ((parameters2 == null) ? null : new DsaParameter(parameters2.P, parameters2.Q, parameters2.G).ToAsn1Object());
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, parameters3), new DerInteger(dsaPublicKeyParameters.Y));
|
||||
}
|
||||
if (publicKey is DHPublicKeyParameters)
|
||||
{
|
||||
DHPublicKeyParameters dHPublicKeyParameters = (DHPublicKeyParameters)publicKey;
|
||||
DHParameters parameters4 = dHPublicKeyParameters.Parameters;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(dHPublicKeyParameters.AlgorithmOid, new DHParameter(parameters4.P, parameters4.G, parameters4.L).ToAsn1Object()), new DerInteger(dHPublicKeyParameters.Y));
|
||||
}
|
||||
if (publicKey is RsaKeyParameters)
|
||||
{
|
||||
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)publicKey;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), new RsaPublicKeyStructure(rsaKeyParameters.Modulus, rsaKeyParameters.Exponent).ToAsn1Object());
|
||||
}
|
||||
if (publicKey is ECPublicKeyParameters)
|
||||
{
|
||||
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)publicKey;
|
||||
if (eCPublicKeyParameters.Parameters is ECGost3410Parameters)
|
||||
{
|
||||
ECGost3410Parameters eCGost3410Parameters = (ECGost3410Parameters)eCPublicKeyParameters.Parameters;
|
||||
BigInteger bigInteger = eCPublicKeyParameters.Q.AffineXCoord.ToBigInteger();
|
||||
BigInteger bI = eCPublicKeyParameters.Q.AffineYCoord.ToBigInteger();
|
||||
bool flag = bigInteger.BitLength > 256;
|
||||
Gost3410PublicKeyAlgParameters parameters5 = new Gost3410PublicKeyAlgParameters(eCGost3410Parameters.PublicKeyParamSet, eCGost3410Parameters.DigestParamSet, eCGost3410Parameters.EncryptionParamSet);
|
||||
int num;
|
||||
int offSet;
|
||||
DerObjectIdentifier algorithm;
|
||||
if (flag)
|
||||
{
|
||||
num = 128;
|
||||
offSet = 64;
|
||||
algorithm = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 64;
|
||||
offSet = 32;
|
||||
algorithm = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
|
||||
}
|
||||
byte[] array = new byte[num];
|
||||
ExtractBytes(array, num / 2, 0, bigInteger);
|
||||
ExtractBytes(array, num / 2, offSet, bI);
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(algorithm, parameters5), new DerOctetString(array));
|
||||
}
|
||||
if (eCPublicKeyParameters.AlgorithmName == "ECGOST3410")
|
||||
{
|
||||
if (eCPublicKeyParameters.PublicKeyParamSet == null)
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
|
||||
}
|
||||
ECPoint eCPoint = eCPublicKeyParameters.Q.Normalize();
|
||||
BigInteger bI2 = eCPoint.AffineXCoord.ToBigInteger();
|
||||
BigInteger bI3 = eCPoint.AffineYCoord.ToBigInteger();
|
||||
byte[] array2 = new byte[64];
|
||||
ExtractBytes(array2, 0, bI2);
|
||||
ExtractBytes(array2, 32, bI3);
|
||||
Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters = new Gost3410PublicKeyAlgParameters(eCPublicKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
|
||||
AlgorithmIdentifier algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gost3410PublicKeyAlgParameters.ToAsn1Object());
|
||||
return new SubjectPublicKeyInfo(algID, new DerOctetString(array2));
|
||||
}
|
||||
X962Parameters x962Parameters;
|
||||
if (eCPublicKeyParameters.PublicKeyParamSet == null)
|
||||
{
|
||||
ECDomainParameters parameters6 = eCPublicKeyParameters.Parameters;
|
||||
X9ECParameters ecParameters = new X9ECParameters(parameters6.Curve, parameters6.G, parameters6.N, parameters6.H, parameters6.GetSeed());
|
||||
x962Parameters = new X962Parameters(ecParameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
x962Parameters = new X962Parameters(eCPublicKeyParameters.PublicKeyParamSet);
|
||||
}
|
||||
byte[] encoded = eCPublicKeyParameters.Q.GetEncoded(compressed: false);
|
||||
AlgorithmIdentifier algID2 = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962Parameters.ToAsn1Object());
|
||||
return new SubjectPublicKeyInfo(algID2, encoded);
|
||||
}
|
||||
if (publicKey is Gost3410PublicKeyParameters)
|
||||
{
|
||||
Gost3410PublicKeyParameters gost3410PublicKeyParameters = (Gost3410PublicKeyParameters)publicKey;
|
||||
if (gost3410PublicKeyParameters.PublicKeyParamSet == null)
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
|
||||
}
|
||||
byte[] array3 = gost3410PublicKeyParameters.Y.ToByteArrayUnsigned();
|
||||
byte[] array4 = new byte[array3.Length];
|
||||
for (int i = 0; i != array4.Length; i++)
|
||||
{
|
||||
array4[i] = array3[array3.Length - 1 - i];
|
||||
}
|
||||
Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters2 = new Gost3410PublicKeyAlgParameters(gost3410PublicKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
|
||||
AlgorithmIdentifier algID3 = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x94, gost3410PublicKeyAlgParameters2.ToAsn1Object());
|
||||
return new SubjectPublicKeyInfo(algID3, new DerOctetString(array4));
|
||||
}
|
||||
if (publicKey is X448PublicKeyParameters)
|
||||
{
|
||||
X448PublicKeyParameters x448PublicKeyParameters = (X448PublicKeyParameters)publicKey;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), x448PublicKeyParameters.GetEncoded());
|
||||
}
|
||||
if (publicKey is X25519PublicKeyParameters)
|
||||
{
|
||||
X25519PublicKeyParameters x25519PublicKeyParameters = (X25519PublicKeyParameters)publicKey;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), x25519PublicKeyParameters.GetEncoded());
|
||||
}
|
||||
if (publicKey is Ed448PublicKeyParameters)
|
||||
{
|
||||
Ed448PublicKeyParameters ed448PublicKeyParameters = (Ed448PublicKeyParameters)publicKey;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), ed448PublicKeyParameters.GetEncoded());
|
||||
}
|
||||
if (publicKey is Ed25519PublicKeyParameters)
|
||||
{
|
||||
Ed25519PublicKeyParameters ed25519PublicKeyParameters = (Ed25519PublicKeyParameters)publicKey;
|
||||
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), ed25519PublicKeyParameters.GetEncoded());
|
||||
}
|
||||
throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(publicKey));
|
||||
}
|
||||
|
||||
private static void ExtractBytes(byte[] encKey, int offset, BigInteger bI)
|
||||
{
|
||||
byte[] array = bI.ToByteArray();
|
||||
int num = (bI.BitLength + 7) / 8;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
encKey[offset + i] = array[array.Length - 1 - i];
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExtractBytes(byte[] encKey, int size, int offSet, BigInteger bI)
|
||||
{
|
||||
byte[] array = bI.ToByteArray();
|
||||
if (array.Length < size)
|
||||
{
|
||||
byte[] array2 = new byte[size];
|
||||
Array.Copy(array, 0, array2, array2.Length - array.Length, array.Length);
|
||||
array = array2;
|
||||
}
|
||||
for (int i = 0; i != size; i++)
|
||||
{
|
||||
encKey[offSet + i] = array[array.Length - 1 - i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
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.IO;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509AttrCertParser
|
||||
{
|
||||
private static readonly PemParser PemAttrCertParser = new PemParser("ATTRIBUTE CERTIFICATE");
|
||||
|
||||
private Asn1Set sData;
|
||||
|
||||
private int sDataObjectCount;
|
||||
|
||||
private Stream currentStream;
|
||||
|
||||
private IX509AttributeCertificate ReadDerCertificate(Asn1InputStream dIn)
|
||||
{
|
||||
Asn1Sequence asn1Sequence = (Asn1Sequence)dIn.ReadObject();
|
||||
if (asn1Sequence.Count > 1 && asn1Sequence[0] is DerObjectIdentifier && asn1Sequence[0].Equals(PkcsObjectIdentifiers.SignedData))
|
||||
{
|
||||
sData = SignedData.GetInstance(Asn1Sequence.GetInstance((Asn1TaggedObject)asn1Sequence[1], explicitly: true)).Certificates;
|
||||
return GetCertificate();
|
||||
}
|
||||
return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(asn1Sequence));
|
||||
}
|
||||
|
||||
private IX509AttributeCertificate GetCertificate()
|
||||
{
|
||||
if (sData != null)
|
||||
{
|
||||
while (sDataObjectCount < sData.Count)
|
||||
{
|
||||
object obj = sData[sDataObjectCount++];
|
||||
if (obj is Asn1TaggedObject && ((Asn1TaggedObject)obj).TagNo == 2)
|
||||
{
|
||||
return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(Asn1Sequence.GetInstance((Asn1TaggedObject)obj, explicitly: false)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private IX509AttributeCertificate ReadPemCertificate(Stream inStream)
|
||||
{
|
||||
Asn1Sequence asn1Sequence = PemAttrCertParser.ReadPemObject(inStream);
|
||||
if (asn1Sequence != null)
|
||||
{
|
||||
return new X509V2AttributeCertificate(AttributeCertificate.GetInstance(asn1Sequence));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IX509AttributeCertificate ReadAttrCert(byte[] input)
|
||||
{
|
||||
return ReadAttrCert(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
public ICollection ReadAttrCerts(byte[] input)
|
||||
{
|
||||
return ReadAttrCerts(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
public IX509AttributeCertificate ReadAttrCert(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)
|
||||
{
|
||||
currentStream = inStream;
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (sData != null)
|
||||
{
|
||||
if (sDataObjectCount != sData.Count)
|
||||
{
|
||||
return GetCertificate();
|
||||
}
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
return null;
|
||||
}
|
||||
PushbackStream pushbackStream = new PushbackStream(inStream);
|
||||
int num = pushbackStream.ReadByte();
|
||||
if (num < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
pushbackStream.Unread(num);
|
||||
if (num != 48)
|
||||
{
|
||||
return ReadPemCertificate(pushbackStream);
|
||||
}
|
||||
return ReadDerCertificate(new Asn1InputStream(pushbackStream));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateException(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection ReadAttrCerts(Stream inStream)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
IX509AttributeCertificate value;
|
||||
while ((value = ReadAttrCert(inStream)) != null)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509Attribute : Asn1Encodable
|
||||
{
|
||||
private readonly AttributeX509 attr;
|
||||
|
||||
public string Oid => attr.AttrType.Id;
|
||||
|
||||
internal X509Attribute(Asn1Encodable at)
|
||||
{
|
||||
attr = AttributeX509.GetInstance(at);
|
||||
}
|
||||
|
||||
public X509Attribute(string oid, Asn1Encodable value)
|
||||
{
|
||||
attr = new AttributeX509(new DerObjectIdentifier(oid), new DerSet(value));
|
||||
}
|
||||
|
||||
public X509Attribute(string oid, Asn1EncodableVector value)
|
||||
{
|
||||
attr = new AttributeX509(new DerObjectIdentifier(oid), new DerSet(value));
|
||||
}
|
||||
|
||||
public Asn1Encodable[] GetValues()
|
||||
{
|
||||
Asn1Set attrValues = attr.AttrValues;
|
||||
Asn1Encodable[] array = new Asn1Encodable[attrValues.Count];
|
||||
for (int i = 0; i != attrValues.Count; i++)
|
||||
{
|
||||
array[i] = attrValues[i];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public override Asn1Object ToAsn1Object()
|
||||
{
|
||||
return attr.ToAsn1Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
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;
|
||||
using Org.BouncyCastle.Utilities.IO;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509CertPairParser
|
||||
{
|
||||
private Stream currentStream;
|
||||
|
||||
private X509CertificatePair ReadDerCrossCertificatePair(Stream inStream)
|
||||
{
|
||||
Asn1InputStream asn1InputStream = new Asn1InputStream(inStream);
|
||||
Asn1Sequence obj = (Asn1Sequence)asn1InputStream.ReadObject();
|
||||
CertificatePair instance = CertificatePair.GetInstance(obj);
|
||||
return new X509CertificatePair(instance);
|
||||
}
|
||||
|
||||
public X509CertificatePair ReadCertPair(byte[] input)
|
||||
{
|
||||
return ReadCertPair(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
public ICollection ReadCertPairs(byte[] input)
|
||||
{
|
||||
return ReadCertPairs(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
public X509CertificatePair ReadCertPair(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;
|
||||
}
|
||||
else if (currentStream != inStream)
|
||||
{
|
||||
currentStream = inStream;
|
||||
}
|
||||
try
|
||||
{
|
||||
PushbackStream pushbackStream = new PushbackStream(inStream);
|
||||
int num = pushbackStream.ReadByte();
|
||||
if (num < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
pushbackStream.Unread(num);
|
||||
return ReadDerCrossCertificatePair(pushbackStream);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateException(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection ReadCertPairs(Stream inStream)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
X509CertificatePair value;
|
||||
while ((value = ReadCertPair(inStream)) != null)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509CertificatePair
|
||||
{
|
||||
private readonly X509Certificate forward;
|
||||
|
||||
private readonly X509Certificate reverse;
|
||||
|
||||
public X509Certificate Forward => forward;
|
||||
|
||||
public X509Certificate Reverse => reverse;
|
||||
|
||||
public X509CertificatePair(X509Certificate forward, X509Certificate reverse)
|
||||
{
|
||||
this.forward = forward;
|
||||
this.reverse = reverse;
|
||||
}
|
||||
|
||||
public X509CertificatePair(CertificatePair pair)
|
||||
{
|
||||
if (pair.Forward != null)
|
||||
{
|
||||
forward = new X509Certificate(pair.Forward);
|
||||
}
|
||||
if (pair.Reverse != null)
|
||||
{
|
||||
reverse = new X509Certificate(pair.Reverse);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
X509CertificateStructure x509CertificateStructure = null;
|
||||
X509CertificateStructure x509CertificateStructure2 = null;
|
||||
if (forward != null)
|
||||
{
|
||||
x509CertificateStructure = X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(forward.GetEncoded()));
|
||||
if (x509CertificateStructure == null)
|
||||
{
|
||||
throw new CertificateEncodingException("unable to get encoding for forward");
|
||||
}
|
||||
}
|
||||
if (reverse != null)
|
||||
{
|
||||
x509CertificateStructure2 = X509CertificateStructure.GetInstance(Asn1Object.FromByteArray(reverse.GetEncoded()));
|
||||
if (x509CertificateStructure2 == null)
|
||||
{
|
||||
throw new CertificateEncodingException("unable to get encoding for reverse");
|
||||
}
|
||||
}
|
||||
return new CertificatePair(x509CertificateStructure, x509CertificateStructure2).GetDerEncoded();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateEncodingException(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is X509CertificatePair x509CertificatePair))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (object.Equals(forward, x509CertificatePair.forward))
|
||||
{
|
||||
return object.Equals(reverse, x509CertificatePair.reverse);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int num = -1;
|
||||
if (forward != null)
|
||||
{
|
||||
num ^= forward.GetHashCode();
|
||||
}
|
||||
if (reverse != null)
|
||||
{
|
||||
num *= 17;
|
||||
num ^= reverse.GetHashCode();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
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.IO;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
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 asn1Sequence = (Asn1Sequence)dIn.ReadObject();
|
||||
if (asn1Sequence.Count > 1 && asn1Sequence[0] is DerObjectIdentifier && asn1Sequence[0].Equals(PkcsObjectIdentifiers.SignedData))
|
||||
{
|
||||
sData = SignedData.GetInstance(Asn1Sequence.GetInstance((Asn1TaggedObject)asn1Sequence[1], explicitly: true)).Certificates;
|
||||
return GetCertificate();
|
||||
}
|
||||
return CreateX509Certificate(X509CertificateStructure.GetInstance(asn1Sequence));
|
||||
}
|
||||
|
||||
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 asn1Sequence = PemCertParser.ReadPemObject(inStream);
|
||||
if (asn1Sequence != null)
|
||||
{
|
||||
return CreateX509Certificate(X509CertificateStructure.GetInstance(asn1Sequence));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual X509Certificate CreateX509Certificate(X509CertificateStructure c)
|
||||
{
|
||||
return new X509Certificate(c);
|
||||
}
|
||||
|
||||
public X509Certificate ReadCertificate(byte[] input)
|
||||
{
|
||||
return ReadCertificate(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
public ICollection ReadCertificates(byte[] input)
|
||||
{
|
||||
return ReadCertificates(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
currentStream = inStream;
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (sData != null)
|
||||
{
|
||||
if (sDataObjectCount != sData.Count)
|
||||
{
|
||||
return GetCertificate();
|
||||
}
|
||||
sData = null;
|
||||
sDataObjectCount = 0;
|
||||
return null;
|
||||
}
|
||||
PushbackStream pushbackStream = new PushbackStream(inStream);
|
||||
int num = pushbackStream.ReadByte();
|
||||
if (num < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
pushbackStream.Unread(num);
|
||||
if (num != 48)
|
||||
{
|
||||
return ReadPemCertificate(pushbackStream);
|
||||
}
|
||||
return ReadDerCertificate(new Asn1InputStream(pushbackStream));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new CertificateException("Failed to read certificate", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection ReadCertificates(Stream inStream)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
X509Certificate value;
|
||||
while ((value = ReadCertificate(inStream)) != null)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
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.Crypto.Operators;
|
||||
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;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509Crl : X509ExtensionBase
|
||||
{
|
||||
private readonly CertificateList c;
|
||||
|
||||
private readonly string sigAlgName;
|
||||
|
||||
private readonly byte[] sigAlgParams;
|
||||
|
||||
private readonly bool isIndirect;
|
||||
|
||||
public virtual int Version => c.Version;
|
||||
|
||||
public virtual X509Name IssuerDN => c.Issuer;
|
||||
|
||||
public virtual DateTime ThisUpdate => c.ThisUpdate.ToDateTime();
|
||||
|
||||
public virtual DateTimeObject NextUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (c.NextUpdate != null)
|
||||
{
|
||||
return new DateTimeObject(c.NextUpdate.ToDateTime());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string SigAlgName => sigAlgName;
|
||||
|
||||
public virtual string SigAlgOid => c.SignatureAlgorithm.Algorithm.Id;
|
||||
|
||||
protected virtual bool IsIndirectCrl
|
||||
{
|
||||
get
|
||||
{
|
||||
Asn1OctetString extensionValue = GetExtensionValue(X509Extensions.IssuingDistributionPoint);
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
if (extensionValue != null)
|
||||
{
|
||||
result = IssuingDistributionPoint.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue)).IsIndirectCrl;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CrlException("Exception reading IssuingDistributionPoint" + ex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public X509Crl(CertificateList c)
|
||||
{
|
||||
this.c = c;
|
||||
try
|
||||
{
|
||||
sigAlgName = X509SignatureUtilities.GetSignatureName(c.SignatureAlgorithm);
|
||||
if (c.SignatureAlgorithm.Parameters != null)
|
||||
{
|
||||
sigAlgParams = c.SignatureAlgorithm.Parameters.GetDerEncoded();
|
||||
}
|
||||
else
|
||||
{
|
||||
sigAlgParams = null;
|
||||
}
|
||||
isIndirect = IsIndirectCrl;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CrlException("CRL contents invalid: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected override X509Extensions GetX509Extensions()
|
||||
{
|
||||
if (c.Version < 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return c.TbsCertList.Extensions;
|
||||
}
|
||||
|
||||
public virtual byte[] GetEncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.GetDerEncoded();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CrlException(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Verify(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
Verify(new Asn1VerifierFactoryProvider(publicKey));
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
_ = c.SignatureAlgorithm.Parameters;
|
||||
IStreamCalculator streamCalculator = verifier.CreateCalculator();
|
||||
byte[] tbsCertList = GetTbsCertList();
|
||||
streamCalculator.Stream.Write(tbsCertList, 0, tbsCertList.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
if (!((IVerifier)streamCalculator.GetResult()).IsVerified(GetSignature()))
|
||||
{
|
||||
throw new InvalidKeyException("CRL does not verify with supplied public key.");
|
||||
}
|
||||
}
|
||||
|
||||
private ISet LoadCrlEntries()
|
||||
{
|
||||
ISet set = new HashSet();
|
||||
IEnumerable revokedCertificateEnumeration = c.GetRevokedCertificateEnumeration();
|
||||
X509Name previousCertificateIssuer = IssuerDN;
|
||||
foreach (CrlEntry item in revokedCertificateEnumeration)
|
||||
{
|
||||
X509CrlEntry x509CrlEntry = new X509CrlEntry(item, isIndirect, previousCertificateIssuer);
|
||||
set.Add(x509CrlEntry);
|
||||
previousCertificateIssuer = x509CrlEntry.GetCertificateIssuer();
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public virtual X509CrlEntry GetRevokedCertificate(BigInteger serialNumber)
|
||||
{
|
||||
IEnumerable revokedCertificateEnumeration = c.GetRevokedCertificateEnumeration();
|
||||
X509Name previousCertificateIssuer = IssuerDN;
|
||||
foreach (CrlEntry item in revokedCertificateEnumeration)
|
||||
{
|
||||
X509CrlEntry x509CrlEntry = new X509CrlEntry(item, isIndirect, previousCertificateIssuer);
|
||||
if (serialNumber.Equals(item.UserCertificate.Value))
|
||||
{
|
||||
return x509CrlEntry;
|
||||
}
|
||||
previousCertificateIssuer = x509CrlEntry.GetCertificateIssuer();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ISet GetRevokedCertificates()
|
||||
{
|
||||
ISet set = LoadCrlEntries();
|
||||
if (set.Count > 0)
|
||||
{
|
||||
return set;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual byte[] GetTbsCertList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.TbsCertList.GetDerEncoded();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CrlException(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] GetSignature()
|
||||
{
|
||||
return c.GetSignatureOctets();
|
||||
}
|
||||
|
||||
public virtual byte[] GetSigAlgParams()
|
||||
{
|
||||
return Arrays.Clone(sigAlgParams);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(obj is X509Crl x509Crl))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return c.Equals(x509Crl.c);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return c.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string newLine = Platform.NewLine;
|
||||
stringBuilder.Append(" Version: ").Append(Version).Append(newLine);
|
||||
stringBuilder.Append(" IssuerDN: ").Append(IssuerDN).Append(newLine);
|
||||
stringBuilder.Append(" This update: ").Append(ThisUpdate).Append(newLine);
|
||||
stringBuilder.Append(" Next update: ").Append(NextUpdate).Append(newLine);
|
||||
stringBuilder.Append(" Signature Algorithm: ").Append(SigAlgName).Append(newLine);
|
||||
byte[] signature = GetSignature();
|
||||
stringBuilder.Append(" Signature: ");
|
||||
stringBuilder.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(" ");
|
||||
stringBuilder.Append(Hex.ToHexString(signature, i, length)).Append(newLine);
|
||||
}
|
||||
X509Extensions extensions = c.TbsCertList.Extensions;
|
||||
if (extensions != null)
|
||||
{
|
||||
IEnumerator enumerator = extensions.ExtensionOids.GetEnumerator();
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
stringBuilder.Append(" Extensions: ").Append(newLine);
|
||||
}
|
||||
do
|
||||
{
|
||||
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)enumerator.Current;
|
||||
X509Extension extension = extensions.GetExtension(derObjectIdentifier);
|
||||
if (extension.Value != null)
|
||||
{
|
||||
Asn1Object asn1Object = X509ExtensionUtilities.FromExtensionValue(extension.Value);
|
||||
stringBuilder.Append(" critical(").Append(extension.IsCritical).Append(") ");
|
||||
try
|
||||
{
|
||||
if (derObjectIdentifier.Equals(X509Extensions.CrlNumber))
|
||||
{
|
||||
stringBuilder.Append(new CrlNumber(DerInteger.GetInstance(asn1Object).PositiveValue)).Append(newLine);
|
||||
continue;
|
||||
}
|
||||
if (derObjectIdentifier.Equals(X509Extensions.DeltaCrlIndicator))
|
||||
{
|
||||
stringBuilder.Append("Base CRL: " + new CrlNumber(DerInteger.GetInstance(asn1Object).PositiveValue)).Append(newLine);
|
||||
continue;
|
||||
}
|
||||
if (derObjectIdentifier.Equals(X509Extensions.IssuingDistributionPoint))
|
||||
{
|
||||
stringBuilder.Append(IssuingDistributionPoint.GetInstance((Asn1Sequence)asn1Object)).Append(newLine);
|
||||
continue;
|
||||
}
|
||||
if (derObjectIdentifier.Equals(X509Extensions.CrlDistributionPoints))
|
||||
{
|
||||
stringBuilder.Append(CrlDistPoint.GetInstance((Asn1Sequence)asn1Object)).Append(newLine);
|
||||
continue;
|
||||
}
|
||||
if (derObjectIdentifier.Equals(X509Extensions.FreshestCrl))
|
||||
{
|
||||
stringBuilder.Append(CrlDistPoint.GetInstance((Asn1Sequence)asn1Object)).Append(newLine);
|
||||
continue;
|
||||
}
|
||||
stringBuilder.Append(derObjectIdentifier.Id);
|
||||
stringBuilder.Append(" value = ").Append(Asn1Dump.DumpAsString(asn1Object)).Append(newLine);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
stringBuilder.Append(derObjectIdentifier.Id);
|
||||
stringBuilder.Append(" value = ").Append("*****").Append(newLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(newLine);
|
||||
}
|
||||
}
|
||||
while (enumerator.MoveNext());
|
||||
}
|
||||
ISet revokedCertificates = GetRevokedCertificates();
|
||||
if (revokedCertificates != null)
|
||||
{
|
||||
foreach (X509CrlEntry item in revokedCertificates)
|
||||
{
|
||||
stringBuilder.Append(item);
|
||||
stringBuilder.Append(newLine);
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public virtual bool IsRevoked(X509Certificate cert)
|
||||
{
|
||||
CrlEntry[] revokedCertificates = c.GetRevokedCertificates();
|
||||
if (revokedCertificates != null)
|
||||
{
|
||||
BigInteger serialNumber = cert.SerialNumber;
|
||||
for (int i = 0; i < revokedCertificates.Length; i++)
|
||||
{
|
||||
if (revokedCertificates[i].UserCertificate.Value.Equals(serialNumber))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
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.Math;
|
||||
using Org.BouncyCastle.Security.Certificates;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509CrlEntry : X509ExtensionBase
|
||||
{
|
||||
private CrlEntry c;
|
||||
|
||||
private bool isIndirect;
|
||||
|
||||
private X509Name previousCertificateIssuer;
|
||||
|
||||
private X509Name certificateIssuer;
|
||||
|
||||
public BigInteger SerialNumber => c.UserCertificate.Value;
|
||||
|
||||
public DateTime RevocationDate => c.RevocationDate.ToDateTime();
|
||||
|
||||
public bool HasExtensions => c.Extensions != null;
|
||||
|
||||
public X509CrlEntry(CrlEntry c)
|
||||
{
|
||||
this.c = c;
|
||||
certificateIssuer = loadCertificateIssuer();
|
||||
}
|
||||
|
||||
public X509CrlEntry(CrlEntry c, bool isIndirect, X509Name previousCertificateIssuer)
|
||||
{
|
||||
this.c = c;
|
||||
this.isIndirect = isIndirect;
|
||||
this.previousCertificateIssuer = previousCertificateIssuer;
|
||||
certificateIssuer = loadCertificateIssuer();
|
||||
}
|
||||
|
||||
private X509Name loadCertificateIssuer()
|
||||
{
|
||||
if (!isIndirect)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Asn1OctetString extensionValue = GetExtensionValue(X509Extensions.CertificateIssuer);
|
||||
if (extensionValue == null)
|
||||
{
|
||||
return previousCertificateIssuer;
|
||||
}
|
||||
try
|
||||
{
|
||||
GeneralName[] names = GeneralNames.GetInstance(X509ExtensionUtilities.FromExtensionValue(extensionValue)).GetNames();
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (names[i].TagNo == 4)
|
||||
{
|
||||
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 ex)
|
||||
{
|
||||
throw new CrlException(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string newLine = Platform.NewLine;
|
||||
stringBuilder.Append(" userCertificate: ").Append(SerialNumber).Append(newLine);
|
||||
stringBuilder.Append(" revocationDate: ").Append(RevocationDate).Append(newLine);
|
||||
stringBuilder.Append(" certificateIssuer: ").Append(GetCertificateIssuer()).Append(newLine);
|
||||
X509Extensions extensions = c.Extensions;
|
||||
if (extensions != null)
|
||||
{
|
||||
IEnumerator enumerator = extensions.ExtensionOids.GetEnumerator();
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
stringBuilder.Append(" crlEntryExtensions:").Append(newLine);
|
||||
do
|
||||
{
|
||||
DerObjectIdentifier derObjectIdentifier = (DerObjectIdentifier)enumerator.Current;
|
||||
X509Extension extension = extensions.GetExtension(derObjectIdentifier);
|
||||
if (extension.Value != null)
|
||||
{
|
||||
Asn1Object asn1Object = Asn1Object.FromByteArray(extension.Value.GetOctets());
|
||||
stringBuilder.Append(" critical(").Append(extension.IsCritical).Append(") ");
|
||||
try
|
||||
{
|
||||
if (derObjectIdentifier.Equals(X509Extensions.ReasonCode))
|
||||
{
|
||||
stringBuilder.Append(new CrlReason(DerEnumerated.GetInstance(asn1Object)));
|
||||
}
|
||||
else if (derObjectIdentifier.Equals(X509Extensions.CertificateIssuer))
|
||||
{
|
||||
stringBuilder.Append("Certificate issuer: ").Append(GeneralNames.GetInstance((Asn1Sequence)asn1Object));
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(derObjectIdentifier.Id);
|
||||
stringBuilder.Append(" value = ").Append(Asn1Dump.DumpAsString(asn1Object));
|
||||
}
|
||||
stringBuilder.Append(newLine);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
stringBuilder.Append(derObjectIdentifier.Id);
|
||||
stringBuilder.Append(" value = ").Append("*****").Append(newLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(newLine);
|
||||
}
|
||||
}
|
||||
while (enumerator.MoveNext());
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
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.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(lazyAsn1: false)
|
||||
{
|
||||
}
|
||||
|
||||
public X509CrlParser(bool lazyAsn1)
|
||||
{
|
||||
this.lazyAsn1 = lazyAsn1;
|
||||
}
|
||||
|
||||
private X509Crl ReadPemCrl(Stream inStream)
|
||||
{
|
||||
Asn1Sequence asn1Sequence = PemCrlParser.ReadPemObject(inStream);
|
||||
if (asn1Sequence != null)
|
||||
{
|
||||
return CreateX509Crl(CertificateList.GetInstance(asn1Sequence));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private X509Crl ReadDerCrl(Asn1InputStream dIn)
|
||||
{
|
||||
Asn1Sequence asn1Sequence = (Asn1Sequence)dIn.ReadObject();
|
||||
if (asn1Sequence.Count > 1 && asn1Sequence[0] is DerObjectIdentifier && asn1Sequence[0].Equals(PkcsObjectIdentifiers.SignedData))
|
||||
{
|
||||
sCrlData = SignedData.GetInstance(Asn1Sequence.GetInstance((Asn1TaggedObject)asn1Sequence[1], explicitly: true)).Crls;
|
||||
return GetCrl();
|
||||
}
|
||||
return CreateX509Crl(CertificateList.GetInstance(asn1Sequence));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public X509Crl ReadCrl(byte[] input)
|
||||
{
|
||||
return ReadCrl(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
public ICollection ReadCrls(byte[] input)
|
||||
{
|
||||
return ReadCrls(new MemoryStream(input, writable: false));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
currentCrlStream = inStream;
|
||||
sCrlData = null;
|
||||
sCrlDataObjectCount = 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (sCrlData != null)
|
||||
{
|
||||
if (sCrlDataObjectCount != sCrlData.Count)
|
||||
{
|
||||
return GetCrl();
|
||||
}
|
||||
sCrlData = null;
|
||||
sCrlDataObjectCount = 0;
|
||||
return null;
|
||||
}
|
||||
PushbackStream pushbackStream = new PushbackStream(inStream);
|
||||
int num = pushbackStream.ReadByte();
|
||||
if (num < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
pushbackStream.Unread(num);
|
||||
if (num != 48)
|
||||
{
|
||||
return ReadPemCrl(pushbackStream);
|
||||
}
|
||||
Asn1InputStream dIn = (lazyAsn1 ? new LazyAsn1InputStream(pushbackStream) : new Asn1InputStream(pushbackStream));
|
||||
return ReadDerCrl(dIn);
|
||||
}
|
||||
catch (CrlException ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
throw new CrlException(ex2.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection ReadCrls(Stream inStream)
|
||||
{
|
||||
IList list = Platform.CreateArrayList();
|
||||
X509Crl value;
|
||||
while ((value = ReadCrl(inStream)) != null)
|
||||
{
|
||||
list.Add(value);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
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 x509Extensions = GetX509Extensions();
|
||||
if (x509Extensions != null)
|
||||
{
|
||||
HashSet hashSet = new HashSet();
|
||||
{
|
||||
foreach (DerObjectIdentifier extensionOid in x509Extensions.ExtensionOids)
|
||||
{
|
||||
X509Extension extension = x509Extensions.GetExtension(extensionOid);
|
||||
if (extension.IsCritical == critical)
|
||||
{
|
||||
hashSet.Add(extensionOid.Id);
|
||||
}
|
||||
}
|
||||
return hashSet;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual ISet GetNonCriticalExtensionOids()
|
||||
{
|
||||
return GetExtensionOids(critical: false);
|
||||
}
|
||||
|
||||
public virtual ISet GetCriticalExtensionOids()
|
||||
{
|
||||
return GetExtensionOids(critical: true);
|
||||
}
|
||||
|
||||
[Obsolete("Use version taking a DerObjectIdentifier instead")]
|
||||
public Asn1OctetString GetExtensionValue(string oid)
|
||||
{
|
||||
return GetExtensionValue(new DerObjectIdentifier(oid));
|
||||
}
|
||||
|
||||
public virtual Asn1OctetString GetExtensionValue(DerObjectIdentifier oid)
|
||||
{
|
||||
X509Extensions x509Extensions = GetX509Extensions();
|
||||
if (x509Extensions != null)
|
||||
{
|
||||
X509Extension extension = x509Extensions.GetExtension(oid);
|
||||
if (extension != null)
|
||||
{
|
||||
return extension.Value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Org.BouncyCastle.Asn1;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509KeyUsage : Asn1Encodable
|
||||
{
|
||||
public const int DigitalSignature = 128;
|
||||
|
||||
public const int NonRepudiation = 64;
|
||||
|
||||
public const int KeyEncipherment = 32;
|
||||
|
||||
public const int DataEncipherment = 16;
|
||||
|
||||
public const int KeyAgreement = 8;
|
||||
|
||||
public const int KeyCertSign = 4;
|
||||
|
||||
public const int CrlSign = 2;
|
||||
|
||||
public const int EncipherOnly = 1;
|
||||
|
||||
public const int DecipherOnly = 32768;
|
||||
|
||||
private readonly int usage;
|
||||
|
||||
public X509KeyUsage(int usage)
|
||||
{
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public override Asn1Object ToAsn1Object()
|
||||
{
|
||||
return new KeyUsage(usage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string GetSignatureName(AlgorithmIdentifier sigAlgId)
|
||||
{
|
||||
Asn1Encodable parameters = sigAlgId.Parameters;
|
||||
if (parameters != null && !derNull.Equals(parameters))
|
||||
{
|
||||
if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss))
|
||||
{
|
||||
RsassaPssParameters instance = RsassaPssParameters.GetInstance(parameters);
|
||||
return GetDigestAlgName(instance.HashAlgorithm.Algorithm) + "withRSAandMGF1";
|
||||
}
|
||||
if (sigAlgId.Algorithm.Equals(X9ObjectIdentifiers.ECDsaWithSha2))
|
||||
{
|
||||
Asn1Sequence instance2 = Asn1Sequence.GetInstance(parameters);
|
||||
return GetDigestAlgName((DerObjectIdentifier)instance2[0]) + "withECDSA";
|
||||
}
|
||||
}
|
||||
return sigAlgId.Algorithm.Id;
|
||||
}
|
||||
|
||||
private static string GetDigestAlgName(DerObjectIdentifier digestAlgOID)
|
||||
{
|
||||
if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID))
|
||||
{
|
||||
return "MD5";
|
||||
}
|
||||
if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA1";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA224";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA256";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA384";
|
||||
}
|
||||
if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID))
|
||||
{
|
||||
return "SHA512";
|
||||
}
|
||||
if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD128";
|
||||
}
|
||||
if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD160";
|
||||
}
|
||||
if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID))
|
||||
{
|
||||
return "RIPEMD256";
|
||||
}
|
||||
if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID))
|
||||
{
|
||||
return "GOST3411";
|
||||
}
|
||||
return digestAlgOID.Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
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;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
internal class X509Utilities
|
||||
{
|
||||
private static readonly IDictionary algorithms;
|
||||
|
||||
private static readonly IDictionary exParams;
|
||||
|
||||
private static readonly ISet noParams;
|
||||
|
||||
static X509Utilities()
|
||||
{
|
||||
algorithms = Platform.CreateHashtable();
|
||||
exParams = Platform.CreateHashtable();
|
||||
noParams = new HashSet();
|
||||
algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption);
|
||||
algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption);
|
||||
algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption);
|
||||
algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption);
|
||||
algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
|
||||
algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption);
|
||||
algorithms.Add("SHA224WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
|
||||
algorithms.Add("SHA224WITHRSA", PkcsObjectIdentifiers.Sha224WithRsaEncryption);
|
||||
algorithms.Add("SHA256WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
|
||||
algorithms.Add("SHA256WITHRSA", PkcsObjectIdentifiers.Sha256WithRsaEncryption);
|
||||
algorithms.Add("SHA384WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
|
||||
algorithms.Add("SHA384WITHRSA", PkcsObjectIdentifiers.Sha384WithRsaEncryption);
|
||||
algorithms.Add("SHA512WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
|
||||
algorithms.Add("SHA512WITHRSA", PkcsObjectIdentifiers.Sha512WithRsaEncryption);
|
||||
algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss);
|
||||
algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
|
||||
algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160);
|
||||
algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
|
||||
algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128);
|
||||
algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
|
||||
algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256);
|
||||
algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1);
|
||||
algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1);
|
||||
algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224);
|
||||
algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256);
|
||||
algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384);
|
||||
algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512);
|
||||
algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1);
|
||||
algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1);
|
||||
algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224);
|
||||
algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256);
|
||||
algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384);
|
||||
algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512);
|
||||
algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
algorithms.Add("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384);
|
||||
noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512);
|
||||
noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha224);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha256);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha384);
|
||||
noParams.Add(NistObjectIdentifiers.DsaWithSha512);
|
||||
noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
|
||||
noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
|
||||
AlgorithmIdentifier hashAlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
|
||||
exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(hashAlgId, 20));
|
||||
AlgorithmIdentifier hashAlgId2 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance);
|
||||
exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(hashAlgId2, 28));
|
||||
AlgorithmIdentifier hashAlgId3 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
|
||||
exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(hashAlgId3, 32));
|
||||
AlgorithmIdentifier hashAlgId4 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
|
||||
exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(hashAlgId4, 48));
|
||||
AlgorithmIdentifier hashAlgId5 = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
|
||||
exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(hashAlgId5, 64));
|
||||
}
|
||||
|
||||
private static RsassaPssParameters CreatePssParams(AlgorithmIdentifier hashAlgId, int saltSize)
|
||||
{
|
||||
return new RsassaPssParameters(hashAlgId, new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), new DerInteger(saltSize), new DerInteger(1));
|
||||
}
|
||||
|
||||
internal static DerObjectIdentifier GetAlgorithmOid(string algorithmName)
|
||||
{
|
||||
algorithmName = Platform.ToUpperInvariant(algorithmName);
|
||||
if (algorithms.Contains(algorithmName))
|
||||
{
|
||||
return (DerObjectIdentifier)algorithms[algorithmName];
|
||||
}
|
||||
return new DerObjectIdentifier(algorithmName);
|
||||
}
|
||||
|
||||
internal static AlgorithmIdentifier GetSigAlgID(DerObjectIdentifier sigOid, string algorithmName)
|
||||
{
|
||||
if (noParams.Contains(sigOid))
|
||||
{
|
||||
return new AlgorithmIdentifier(sigOid);
|
||||
}
|
||||
algorithmName = Platform.ToUpperInvariant(algorithmName);
|
||||
if (exParams.Contains(algorithmName))
|
||||
{
|
||||
return new AlgorithmIdentifier(sigOid, (Asn1Encodable)exParams[algorithmName]);
|
||||
}
|
||||
return new AlgorithmIdentifier(sigOid, DerNull.Instance);
|
||||
}
|
||||
|
||||
internal static IEnumerable GetAlgNames()
|
||||
{
|
||||
return new EnumerableProxy(algorithms.Keys);
|
||||
}
|
||||
|
||||
internal static byte[] GetSignatureForObject(DerObjectIdentifier sigOid, string sigName, AsymmetricKeyParameter privateKey, SecureRandom random, Asn1Encodable ae)
|
||||
{
|
||||
if (sigOid == null)
|
||||
{
|
||||
throw new ArgumentNullException("sigOid");
|
||||
}
|
||||
ISigner signer = SignerUtilities.GetSigner(sigName);
|
||||
if (random != null)
|
||||
{
|
||||
signer.Init(forSigning: true, new ParametersWithRandom(privateKey, random));
|
||||
}
|
||||
else
|
||||
{
|
||||
signer.Init(forSigning: true, privateKey);
|
||||
}
|
||||
byte[] derEncoded = ae.GetDerEncoded();
|
||||
signer.BlockUpdate(derEncoded, 0, derEncoded.Length);
|
||||
return signer.GenerateSignature();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
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.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509V1CertificateGenerator
|
||||
{
|
||||
private V1TbsCertificateGenerator tbsGen;
|
||||
|
||||
private DerObjectIdentifier sigOID;
|
||||
|
||||
private AlgorithmIdentifier sigAlgId;
|
||||
|
||||
private string signatureAlgorithm;
|
||||
|
||||
public IEnumerable SignatureAlgNames => X509Utilities.GetAlgNames();
|
||||
|
||||
public X509V1CertificateGenerator()
|
||||
{
|
||||
tbsGen = new V1TbsCertificateGenerator();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
tbsGen = new V1TbsCertificateGenerator();
|
||||
}
|
||||
|
||||
public void SetSerialNumber(BigInteger serialNumber)
|
||||
{
|
||||
if (serialNumber.SignValue <= 0)
|
||||
{
|
||||
throw new ArgumentException("serial number must be a positive integer", "serialNumber");
|
||||
}
|
||||
tbsGen.SetSerialNumber(new DerInteger(serialNumber));
|
||||
}
|
||||
|
||||
public void SetIssuerDN(X509Name issuer)
|
||||
{
|
||||
tbsGen.SetIssuer(issuer);
|
||||
}
|
||||
|
||||
public void SetNotBefore(DateTime date)
|
||||
{
|
||||
tbsGen.SetStartDate(new Time(date));
|
||||
}
|
||||
|
||||
public void SetNotAfter(DateTime date)
|
||||
{
|
||||
tbsGen.SetEndDate(new Time(date));
|
||||
}
|
||||
|
||||
public void SetSubjectDN(X509Name subject)
|
||||
{
|
||||
tbsGen.SetSubject(subject);
|
||||
}
|
||||
|
||||
public void SetPublicKey(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
tbsGen.SetSubjectPublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ArgumentException("unable to process key - " + ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Not needed if Generate used with an ISignatureFactory")]
|
||||
public void SetSignatureAlgorithm(string signatureAlgorithm)
|
||||
{
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
try
|
||||
{
|
||||
sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ArgumentException("Unknown signature type requested", "signatureAlgorithm");
|
||||
}
|
||||
sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm);
|
||||
tbsGen.SetSignature(sigAlgId);
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public X509Certificate Generate(AsymmetricKeyParameter privateKey)
|
||||
{
|
||||
return Generate(privateKey, null);
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public X509Certificate Generate(AsymmetricKeyParameter privateKey, SecureRandom random)
|
||||
{
|
||||
return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random));
|
||||
}
|
||||
|
||||
public X509Certificate Generate(ISignatureFactory signatureCalculatorFactory)
|
||||
{
|
||||
tbsGen.SetSignature((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails);
|
||||
TbsCertificateStructure tbsCertificateStructure = tbsGen.GenerateTbsCertificate();
|
||||
IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator();
|
||||
byte[] derEncoded = tbsCertificateStructure.GetDerEncoded();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
return GenerateJcaObject(tbsCertificateStructure, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect());
|
||||
}
|
||||
|
||||
private X509Certificate GenerateJcaObject(TbsCertificateStructure tbsCert, AlgorithmIdentifier sigAlg, byte[] signature)
|
||||
{
|
||||
return new X509Certificate(new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
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 X509V2AttributeCertificateGenerator
|
||||
{
|
||||
private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator();
|
||||
|
||||
private V2AttributeCertificateInfoGenerator acInfoGen;
|
||||
|
||||
private DerObjectIdentifier sigOID;
|
||||
|
||||
private AlgorithmIdentifier sigAlgId;
|
||||
|
||||
private string signatureAlgorithm;
|
||||
|
||||
public IEnumerable SignatureAlgNames => X509Utilities.GetAlgNames();
|
||||
|
||||
public X509V2AttributeCertificateGenerator()
|
||||
{
|
||||
acInfoGen = new V2AttributeCertificateInfoGenerator();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
acInfoGen = new V2AttributeCertificateInfoGenerator();
|
||||
extGenerator.Reset();
|
||||
}
|
||||
|
||||
public void SetHolder(AttributeCertificateHolder holder)
|
||||
{
|
||||
acInfoGen.SetHolder(holder.holder);
|
||||
}
|
||||
|
||||
public void SetIssuer(AttributeCertificateIssuer issuer)
|
||||
{
|
||||
acInfoGen.SetIssuer(AttCertIssuer.GetInstance(issuer.form));
|
||||
}
|
||||
|
||||
public void SetSerialNumber(BigInteger serialNumber)
|
||||
{
|
||||
acInfoGen.SetSerialNumber(new DerInteger(serialNumber));
|
||||
}
|
||||
|
||||
public void SetNotBefore(DateTime date)
|
||||
{
|
||||
acInfoGen.SetStartDate(new DerGeneralizedTime(date));
|
||||
}
|
||||
|
||||
public void SetNotAfter(DateTime date)
|
||||
{
|
||||
acInfoGen.SetEndDate(new DerGeneralizedTime(date));
|
||||
}
|
||||
|
||||
[Obsolete("Not needed if Generate used with an ISignatureFactory")]
|
||||
public void SetSignatureAlgorithm(string signatureAlgorithm)
|
||||
{
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
try
|
||||
{
|
||||
sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ArgumentException("Unknown signature type requested");
|
||||
}
|
||||
sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm);
|
||||
acInfoGen.SetSignature(sigAlgId);
|
||||
}
|
||||
|
||||
public void AddAttribute(X509Attribute attribute)
|
||||
{
|
||||
acInfoGen.AddAttribute(AttributeX509.GetInstance(attribute.ToAsn1Object()));
|
||||
}
|
||||
|
||||
public void SetIssuerUniqueId(bool[] iui)
|
||||
{
|
||||
throw Platform.CreateNotImplementedException("SetIssuerUniqueId()");
|
||||
}
|
||||
|
||||
public void AddExtension(string oid, bool critical, Asn1Encodable extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue);
|
||||
}
|
||||
|
||||
public void AddExtension(string oid, bool critical, byte[] extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue);
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public IX509AttributeCertificate Generate(AsymmetricKeyParameter privateKey)
|
||||
{
|
||||
return Generate(privateKey, null);
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public IX509AttributeCertificate Generate(AsymmetricKeyParameter privateKey, SecureRandom random)
|
||||
{
|
||||
return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random));
|
||||
}
|
||||
|
||||
public IX509AttributeCertificate Generate(ISignatureFactory signatureCalculatorFactory)
|
||||
{
|
||||
if (!extGenerator.IsEmpty)
|
||||
{
|
||||
acInfoGen.SetExtensions(extGenerator.Generate());
|
||||
}
|
||||
AlgorithmIdentifier signature = (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails;
|
||||
acInfoGen.SetSignature(signature);
|
||||
AttributeCertificateInfo attributeCertificateInfo = acInfoGen.GenerateAttributeCertificateInfo();
|
||||
byte[] derEncoded = attributeCertificateInfo.GetDerEncoded();
|
||||
IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
try
|
||||
{
|
||||
DerBitString signatureValue = new DerBitString(((IBlockResult)streamCalculator.GetResult()).Collect());
|
||||
return new X509V2AttributeCertificate(new AttributeCertificate(attributeCertificateInfo, signature, signatureValue));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CertificateEncodingException("constructed invalid certificate", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
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;
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509V2CrlGenerator
|
||||
{
|
||||
private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator();
|
||||
|
||||
private V2TbsCertListGenerator tbsGen;
|
||||
|
||||
private DerObjectIdentifier sigOID;
|
||||
|
||||
private AlgorithmIdentifier sigAlgId;
|
||||
|
||||
private string signatureAlgorithm;
|
||||
|
||||
public IEnumerable SignatureAlgNames => X509Utilities.GetAlgNames();
|
||||
|
||||
public X509V2CrlGenerator()
|
||||
{
|
||||
tbsGen = new V2TbsCertListGenerator();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
tbsGen = new V2TbsCertListGenerator();
|
||||
extGenerator.Reset();
|
||||
}
|
||||
|
||||
public void SetIssuerDN(X509Name issuer)
|
||||
{
|
||||
tbsGen.SetIssuer(issuer);
|
||||
}
|
||||
|
||||
public void SetThisUpdate(DateTime date)
|
||||
{
|
||||
tbsGen.SetThisUpdate(new Time(date));
|
||||
}
|
||||
|
||||
public void SetNextUpdate(DateTime date)
|
||||
{
|
||||
tbsGen.SetNextUpdate(new Time(date));
|
||||
}
|
||||
|
||||
public void AddCrlEntry(BigInteger userCertificate, DateTime revocationDate, int reason)
|
||||
{
|
||||
tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), reason);
|
||||
}
|
||||
|
||||
public void AddCrlEntry(BigInteger userCertificate, DateTime revocationDate, int reason, DateTime invalidityDate)
|
||||
{
|
||||
tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), reason, new DerGeneralizedTime(invalidityDate));
|
||||
}
|
||||
|
||||
public void AddCrlEntry(BigInteger userCertificate, DateTime revocationDate, X509Extensions extensions)
|
||||
{
|
||||
tbsGen.AddCrlEntry(new DerInteger(userCertificate), new Time(revocationDate), extensions);
|
||||
}
|
||||
|
||||
public void AddCrl(X509Crl other)
|
||||
{
|
||||
if (other == null)
|
||||
{
|
||||
throw new ArgumentNullException("other");
|
||||
}
|
||||
ISet revokedCertificates = other.GetRevokedCertificates();
|
||||
if (revokedCertificates == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (X509CrlEntry item in revokedCertificates)
|
||||
{
|
||||
try
|
||||
{
|
||||
tbsGen.AddCrlEntry(Asn1Sequence.GetInstance(Asn1Object.FromByteArray(item.GetEncoded())));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CrlException("exception processing encoding of CRL", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Not needed if Generate used with an ISignatureFactory")]
|
||||
public void SetSignatureAlgorithm(string signatureAlgorithm)
|
||||
{
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
try
|
||||
{
|
||||
sigOID = X509Utilities.GetAlgorithmOid(signatureAlgorithm);
|
||||
}
|
||||
catch (Exception innerException)
|
||||
{
|
||||
throw new ArgumentException("Unknown signature type requested", innerException);
|
||||
}
|
||||
sigAlgId = X509Utilities.GetSigAlgID(sigOID, signatureAlgorithm);
|
||||
tbsGen.SetSignature(sigAlgId);
|
||||
}
|
||||
|
||||
public void AddExtension(string oid, bool critical, Asn1Encodable extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue);
|
||||
}
|
||||
|
||||
public void AddExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(oid, critical, extensionValue);
|
||||
}
|
||||
|
||||
public void AddExtension(string oid, bool critical, byte[] extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, new DerOctetString(extensionValue));
|
||||
}
|
||||
|
||||
public void AddExtension(DerObjectIdentifier oid, bool critical, byte[] extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(oid, critical, new DerOctetString(extensionValue));
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public X509Crl Generate(AsymmetricKeyParameter privateKey)
|
||||
{
|
||||
return Generate(privateKey, null);
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public X509Crl Generate(AsymmetricKeyParameter privateKey, SecureRandom random)
|
||||
{
|
||||
return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random));
|
||||
}
|
||||
|
||||
public X509Crl Generate(ISignatureFactory signatureCalculatorFactory)
|
||||
{
|
||||
tbsGen.SetSignature((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails);
|
||||
TbsCertificateList tbsCertificateList = GenerateCertList();
|
||||
IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator();
|
||||
byte[] derEncoded = tbsCertificateList.GetDerEncoded();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
return GenerateJcaObject(tbsCertificateList, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect());
|
||||
}
|
||||
|
||||
private TbsCertificateList GenerateCertList()
|
||||
{
|
||||
if (!extGenerator.IsEmpty)
|
||||
{
|
||||
tbsGen.SetExtensions(extGenerator.Generate());
|
||||
}
|
||||
return tbsGen.GenerateTbsCertList();
|
||||
}
|
||||
|
||||
private X509Crl GenerateJcaObject(TbsCertificateList tbsCrl, AlgorithmIdentifier algId, byte[] signature)
|
||||
{
|
||||
return new X509Crl(CertificateList.GetInstance(new DerSequence(tbsCrl, algId, new DerBitString(signature))));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
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;
|
||||
using Org.BouncyCastle.X509.Extension;
|
||||
|
||||
namespace Org.BouncyCastle.X509;
|
||||
|
||||
public class X509V3CertificateGenerator
|
||||
{
|
||||
private readonly X509ExtensionsGenerator extGenerator = new X509ExtensionsGenerator();
|
||||
|
||||
private V3TbsCertificateGenerator tbsGen;
|
||||
|
||||
private DerObjectIdentifier sigOid;
|
||||
|
||||
private AlgorithmIdentifier sigAlgId;
|
||||
|
||||
private string signatureAlgorithm;
|
||||
|
||||
public IEnumerable SignatureAlgNames => X509Utilities.GetAlgNames();
|
||||
|
||||
public X509V3CertificateGenerator()
|
||||
{
|
||||
tbsGen = new V3TbsCertificateGenerator();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
tbsGen = new V3TbsCertificateGenerator();
|
||||
extGenerator.Reset();
|
||||
}
|
||||
|
||||
public void SetSerialNumber(BigInteger serialNumber)
|
||||
{
|
||||
if (serialNumber.SignValue <= 0)
|
||||
{
|
||||
throw new ArgumentException("serial number must be a positive integer", "serialNumber");
|
||||
}
|
||||
tbsGen.SetSerialNumber(new DerInteger(serialNumber));
|
||||
}
|
||||
|
||||
public void SetIssuerDN(X509Name issuer)
|
||||
{
|
||||
tbsGen.SetIssuer(issuer);
|
||||
}
|
||||
|
||||
public void SetNotBefore(DateTime date)
|
||||
{
|
||||
tbsGen.SetStartDate(new Time(date));
|
||||
}
|
||||
|
||||
public void SetNotAfter(DateTime date)
|
||||
{
|
||||
tbsGen.SetEndDate(new Time(date));
|
||||
}
|
||||
|
||||
public void SetSubjectDN(X509Name subject)
|
||||
{
|
||||
tbsGen.SetSubject(subject);
|
||||
}
|
||||
|
||||
public void SetPublicKey(AsymmetricKeyParameter publicKey)
|
||||
{
|
||||
tbsGen.SetSubjectPublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey));
|
||||
}
|
||||
|
||||
[Obsolete("Not needed if Generate used with an ISignatureFactory")]
|
||||
public void SetSignatureAlgorithm(string signatureAlgorithm)
|
||||
{
|
||||
this.signatureAlgorithm = signatureAlgorithm;
|
||||
try
|
||||
{
|
||||
sigOid = X509Utilities.GetAlgorithmOid(signatureAlgorithm);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new ArgumentException("Unknown signature type requested: " + signatureAlgorithm);
|
||||
}
|
||||
sigAlgId = X509Utilities.GetSigAlgID(sigOid, signatureAlgorithm);
|
||||
tbsGen.SetSignature(sigAlgId);
|
||||
}
|
||||
|
||||
public void SetSubjectUniqueID(bool[] uniqueID)
|
||||
{
|
||||
tbsGen.SetSubjectUniqueID(booleanToBitString(uniqueID));
|
||||
}
|
||||
|
||||
public void SetIssuerUniqueID(bool[] uniqueID)
|
||||
{
|
||||
tbsGen.SetIssuerUniqueID(booleanToBitString(uniqueID));
|
||||
}
|
||||
|
||||
private DerBitString booleanToBitString(bool[] id)
|
||||
{
|
||||
byte[] array = new byte[(id.Length + 7) / 8];
|
||||
for (int i = 0; i != id.Length; i++)
|
||||
{
|
||||
if (id[i])
|
||||
{
|
||||
byte[] array3;
|
||||
byte[] array2 = (array3 = array);
|
||||
int num = i / 8;
|
||||
nint num2 = num;
|
||||
array2[num] = (byte)(array3[num2] | (byte)(1 << 7 - i % 8));
|
||||
}
|
||||
}
|
||||
int num3 = id.Length % 8;
|
||||
if (num3 == 0)
|
||||
{
|
||||
return new DerBitString(array);
|
||||
}
|
||||
return new DerBitString(array, 8 - num3);
|
||||
}
|
||||
|
||||
public void AddExtension(string oid, bool critical, Asn1Encodable extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, extensionValue);
|
||||
}
|
||||
|
||||
public void AddExtension(DerObjectIdentifier oid, bool critical, Asn1Encodable extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(oid, critical, extensionValue);
|
||||
}
|
||||
|
||||
public void AddExtension(string oid, bool critical, byte[] extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(new DerObjectIdentifier(oid), critical, new DerOctetString(extensionValue));
|
||||
}
|
||||
|
||||
public void AddExtension(DerObjectIdentifier oid, bool critical, byte[] extensionValue)
|
||||
{
|
||||
extGenerator.AddExtension(oid, critical, new DerOctetString(extensionValue));
|
||||
}
|
||||
|
||||
public void CopyAndAddExtension(string oid, bool critical, X509Certificate cert)
|
||||
{
|
||||
CopyAndAddExtension(new DerObjectIdentifier(oid), critical, cert);
|
||||
}
|
||||
|
||||
public void CopyAndAddExtension(DerObjectIdentifier oid, bool critical, X509Certificate cert)
|
||||
{
|
||||
Asn1OctetString extensionValue = cert.GetExtensionValue(oid);
|
||||
if (extensionValue == null)
|
||||
{
|
||||
throw new CertificateParsingException(string.Concat("extension ", oid, " not present"));
|
||||
}
|
||||
try
|
||||
{
|
||||
Asn1Encodable extensionValue2 = X509ExtensionUtilities.FromExtensionValue(extensionValue);
|
||||
AddExtension(oid, critical, extensionValue2);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new CertificateParsingException(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public X509Certificate Generate(AsymmetricKeyParameter privateKey)
|
||||
{
|
||||
return Generate(privateKey, null);
|
||||
}
|
||||
|
||||
[Obsolete("Use Generate with an ISignatureFactory")]
|
||||
public X509Certificate Generate(AsymmetricKeyParameter privateKey, SecureRandom random)
|
||||
{
|
||||
return Generate(new Asn1SignatureFactory(signatureAlgorithm, privateKey, random));
|
||||
}
|
||||
|
||||
public X509Certificate Generate(ISignatureFactory signatureCalculatorFactory)
|
||||
{
|
||||
tbsGen.SetSignature((AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails);
|
||||
if (!extGenerator.IsEmpty)
|
||||
{
|
||||
tbsGen.SetExtensions(extGenerator.Generate());
|
||||
}
|
||||
TbsCertificateStructure tbsCertificateStructure = tbsGen.GenerateTbsCertificate();
|
||||
IStreamCalculator streamCalculator = signatureCalculatorFactory.CreateCalculator();
|
||||
byte[] derEncoded = tbsCertificateStructure.GetDerEncoded();
|
||||
streamCalculator.Stream.Write(derEncoded, 0, derEncoded.Length);
|
||||
Platform.Dispose(streamCalculator.Stream);
|
||||
return GenerateJcaObject(tbsCertificateStructure, (AlgorithmIdentifier)signatureCalculatorFactory.AlgorithmDetails, ((IBlockResult)streamCalculator.GetResult()).Collect());
|
||||
}
|
||||
|
||||
private X509Certificate GenerateJcaObject(TbsCertificateStructure tbsCert, AlgorithmIdentifier sigAlg, byte[] signature)
|
||||
{
|
||||
return new X509Certificate(new X509CertificateStructure(tbsCert, sigAlg, new DerBitString(signature)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user