PkixNameConstraintValidator
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X500;
using Org.BouncyCastle.Asn1.X500.Style;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections.Generic;
using System.Text;
namespace Org.BouncyCastle.Pkix
{
public class PkixNameConstraintValidator
{
private static readonly DerObjectIdentifier SerialNumberOid = X509Name.SerialNumber;
private HashSet<Asn1Sequence> excludedSubtreesDN = new HashSet<Asn1Sequence>();
private HashSet<string> excludedSubtreesDns = new HashSet<string>();
private HashSet<string> excludedSubtreesEmail = new HashSet<string>();
private HashSet<string> excludedSubtreesUri = new HashSet<string>();
private HashSet<byte[]> excludedSubtreesIP = new HashSet<byte[]>();
private HashSet<OtherName> excludedSubtreesOtherName = new HashSet<OtherName>();
private HashSet<Asn1Sequence> permittedSubtreesDN;
private HashSet<string> permittedSubtreesDns;
private HashSet<string> permittedSubtreesEmail;
private HashSet<string> permittedSubtreesUri;
private HashSet<byte[]> permittedSubtreesIP;
private HashSet<OtherName> permittedSubtreesOtherName;
private static bool WithinDNSubtree(Asn1Sequence dns, Asn1Sequence subtree)
{
if (subtree.Count < 1 || subtree.Count > dns.Count)
return false;
int num = 0;
Rdn instance = Rdn.GetInstance(subtree[0]);
for (int i = 0; i < dns.Count; i++) {
num = i;
Rdn instance2 = Rdn.GetInstance(dns[i]);
if (IetfUtilities.RdnAreEqual(instance, instance2))
break;
}
if (subtree.Count > dns.Count - num)
return false;
for (int j = 0; j < subtree.Count; j++) {
Rdn instance3 = Rdn.GetInstance(subtree[j]);
Rdn instance4 = Rdn.GetInstance(dns[num + j]);
if (instance3.Count == 1 && instance4.Count == 1 && SerialNumberOid.Equals(instance3.GetFirst().Type) && SerialNumberOid.Equals(instance4.GetFirst().Type)) {
if (!Platform.StartsWith(instance4.GetFirst().Value.ToString(), instance3.GetFirst().Value.ToString()))
return false;
} else if (!IetfUtilities.RdnAreEqual(instance3, instance4)) {
return false;
}
}
return true;
}
public void CheckExcludedDN(Asn1Sequence dn)
{
CheckExcludedDN(excludedSubtreesDN, dn);
}
public void CheckPermittedDN(Asn1Sequence dn)
{
CheckPermittedDN(permittedSubtreesDN, dn);
}
private void CheckExcludedDN(HashSet<Asn1Sequence> excluded, Asn1Sequence directory)
{
if (IsDNConstrained(excluded, directory))
throw new PkixNameConstraintValidatorException("Subject distinguished name is from an excluded subtree");
}
private void CheckPermittedDN(HashSet<Asn1Sequence> permitted, Asn1Sequence directory)
{
if (permitted != null && (directory.Count != 0 || permitted.Count >= 1) && !IsDNConstrained(permitted, directory))
throw new PkixNameConstraintValidatorException("Subject distinguished name is not from a permitted subtree");
}
private bool IsDNConstrained(HashSet<Asn1Sequence> constraints, Asn1Sequence directory)
{
foreach (Asn1Sequence constraint in constraints) {
if (WithinDNSubtree(directory, constraint))
return true;
}
return false;
}
private HashSet<Asn1Sequence> IntersectDN(HashSet<Asn1Sequence> permitted, HashSet<GeneralSubtree> dns)
{
HashSet<Asn1Sequence> hashSet = new HashSet<Asn1Sequence>();
foreach (GeneralSubtree dn in dns) {
Asn1Sequence instance = Asn1Sequence.GetInstance(dn.Base.Name);
if (permitted == null) {
if (instance != null)
hashSet.Add(instance);
} else {
foreach (Asn1Sequence item in permitted) {
if (WithinDNSubtree(instance, item))
hashSet.Add(instance);
else if (WithinDNSubtree(item, instance)) {
hashSet.Add(item);
}
}
}
}
return hashSet;
}
private HashSet<Asn1Sequence> UnionDN(HashSet<Asn1Sequence> excluded, Asn1Sequence dn)
{
if (excluded.Count < 1) {
if (dn == null)
return excluded;
excluded.Add(dn);
return excluded;
}
HashSet<Asn1Sequence> hashSet = new HashSet<Asn1Sequence>();
foreach (Asn1Sequence item in excluded) {
if (WithinDNSubtree(dn, item))
hashSet.Add(item);
else if (WithinDNSubtree(item, dn)) {
hashSet.Add(dn);
} else {
hashSet.Add(item);
hashSet.Add(dn);
}
}
return hashSet;
}
private void CheckExcludedOtherName(HashSet<OtherName> excluded, OtherName name)
{
if (IsOtherNameConstrained(excluded, name))
throw new PkixNameConstraintValidatorException("OtherName is from an excluded subtree.");
}
private void CheckPermittedOtherName(HashSet<OtherName> permitted, OtherName name)
{
if (permitted != null && !IsOtherNameConstrained(permitted, name))
throw new PkixNameConstraintValidatorException("Subject OtherName is not from a permitted subtree.");
}
private bool IsOtherNameConstrained(HashSet<OtherName> constraints, OtherName otherName)
{
foreach (OtherName constraint in constraints) {
if (IsOtherNameConstrained(constraint, otherName))
return true;
}
return false;
}
private bool IsOtherNameConstrained(OtherName constraint, OtherName otherName)
{
return constraint.Equals(otherName);
}
private HashSet<OtherName> IntersectOtherName(HashSet<OtherName> permitted, HashSet<GeneralSubtree> otherNames)
{
HashSet<OtherName> hashSet = new HashSet<OtherName>();
foreach (GeneralSubtree otherName in otherNames) {
OtherName instance = OtherName.GetInstance(otherName.Base.Name);
if (instance != null) {
if (permitted == null)
hashSet.Add(instance);
else {
foreach (OtherName item in permitted) {
IntersectOtherName(instance, item, hashSet);
}
}
}
}
return hashSet;
}
private void IntersectOtherName(OtherName otherName1, OtherName otherName2, HashSet<OtherName> intersect)
{
if (otherName1.Equals(otherName2))
intersect.Add(otherName1);
}
private HashSet<OtherName> UnionOtherName(HashSet<OtherName> permitted, OtherName otherName)
{
HashSet<OtherName> obj = (permitted != null) ? new HashSet<OtherName>(permitted) : new HashSet<OtherName>();
obj.Add(otherName);
return obj;
}
private void CheckExcludedEmail(HashSet<string> excluded, string email)
{
if (IsEmailConstrained(excluded, email))
throw new PkixNameConstraintValidatorException("Email address is from an excluded subtree.");
}
private void CheckPermittedEmail(HashSet<string> permitted, string email)
{
if (permitted != null && (email.Length != 0 || permitted.Count >= 1) && !IsEmailConstrained(permitted, email))
throw new PkixNameConstraintValidatorException("Subject email address is not from a permitted subtree.");
}
private bool IsEmailConstrained(HashSet<string> constraints, string email)
{
foreach (string constraint in constraints) {
if (IsEmailConstrained(constraint, email))
return true;
}
return false;
}
private bool IsEmailConstrained(string constraint, string email)
{
string text = email.Substring(email.IndexOf('@') + 1);
if (constraint.IndexOf('@') != -1) {
if (string.Equals(email, constraint, StringComparison.OrdinalIgnoreCase))
return true;
} else if (constraint[0] != '.') {
if (string.Equals(text, constraint, StringComparison.OrdinalIgnoreCase))
return true;
} else if (WithinDomain(text, constraint)) {
return true;
}
return false;
}
private HashSet<string> IntersectEmail(HashSet<string> permitted, HashSet<GeneralSubtree> emails)
{
HashSet<string> hashSet = new HashSet<string>();
foreach (GeneralSubtree email in emails) {
string text = ExtractNameAsString(email.Base);
if (permitted == null) {
if (text != null)
hashSet.Add(text);
} else {
foreach (string item in permitted) {
IntersectEmail(text, item, hashSet);
}
}
}
return hashSet;
}
private void IntersectEmail(string email1, string email2, HashSet<string> intersect)
{
if (email1.IndexOf('@') != -1) {
string text = email1.Substring(email1.IndexOf('@') + 1);
if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email1, email2))
intersect.Add(email1);
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(text, email2))
intersect.Add(email1);
} else if (Platform.EqualsIgnoreCase(text, email2)) {
intersect.Add(email1);
}
} else if (Platform.StartsWith(email1, ".")) {
if (email2.IndexOf('@') != -1) {
string testDomain = email2.Substring(email1.IndexOf('@') + 1);
if (WithinDomain(testDomain, email1))
intersect.Add(email2);
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2))
intersect.Add(email1);
else if (WithinDomain(email2, email1)) {
intersect.Add(email2);
}
} else if (WithinDomain(email2, email1)) {
intersect.Add(email2);
}
} else if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email2.Substring(email2.IndexOf('@') + 1), email1))
intersect.Add(email2);
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2))
intersect.Add(email1);
} else if (Platform.EqualsIgnoreCase(email1, email2)) {
intersect.Add(email1);
}
}
private HashSet<string> UnionEmail(HashSet<string> excluded, string email)
{
if (excluded.Count < 1) {
if (email == null)
return excluded;
excluded.Add(email);
return excluded;
}
HashSet<string> hashSet = new HashSet<string>();
foreach (string item in excluded) {
UnionEmail(item, email, hashSet);
}
return hashSet;
}
private void UnionEmail(string email1, string email2, HashSet<string> union)
{
if (email1.IndexOf('@') != -1) {
string text = email1.Substring(email1.IndexOf('@') + 1);
if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email1, email2))
union.Add(email1);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(text, email2))
union.Add(email2);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.EqualsIgnoreCase(text, email2)) {
union.Add(email2);
} else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email1, ".")) {
if (email2.IndexOf('@') != -1) {
string testDomain = email2.Substring(email1.IndexOf('@') + 1);
if (WithinDomain(testDomain, email1))
union.Add(email1);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2))
union.Add(email2);
else if (WithinDomain(email2, email1)) {
union.Add(email1);
} else {
union.Add(email1);
union.Add(email2);
}
} else if (WithinDomain(email2, email1)) {
union.Add(email1);
} else {
union.Add(email1);
union.Add(email2);
}
} else if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email2.Substring(email1.IndexOf('@') + 1), email1))
union.Add(email1);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2))
union.Add(email2);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.EqualsIgnoreCase(email1, email2)) {
union.Add(email1);
} else {
union.Add(email1);
union.Add(email2);
}
}
private void CheckExcludedIP(HashSet<byte[]> excluded, byte[] ip)
{
if (IsIPConstrained(excluded, ip))
throw new PkixNameConstraintValidatorException("IP is from an excluded subtree.");
}
private void CheckPermittedIP(HashSet<byte[]> permitted, byte[] ip)
{
if (permitted != null && (ip.Length != 0 || permitted.Count >= 1) && !IsIPConstrained(permitted, ip))
throw new PkixNameConstraintValidatorException("IP is not from a permitted subtree.");
}
private bool IsIPConstrained(HashSet<byte[]> constraints, byte[] ip)
{
foreach (byte[] constraint in constraints) {
if (IsIPConstrained(constraint, ip))
return true;
}
return false;
}
private bool IsIPConstrained(byte[] constraint, byte[] ip)
{
int num = ip.Length;
if (num != constraint.Length / 2)
return false;
byte[] array = new byte[num];
Array.Copy(constraint, num, array, 0, num);
byte[] array2 = new byte[num];
byte[] array3 = new byte[num];
for (int i = 0; i < num; i++) {
array2[i] = (byte)(constraint[i] & array[i]);
array3[i] = (byte)(ip[i] & array[i]);
}
return Arrays.AreEqual(array2, array3);
}
private HashSet<byte[]> IntersectIP(HashSet<byte[]> permitted, HashSet<GeneralSubtree> ips)
{
HashSet<byte[]> hashSet = new HashSet<byte[]>();
foreach (GeneralSubtree ip in ips) {
byte[] octets = Asn1OctetString.GetInstance(ip.Base.Name).GetOctets();
if (permitted == null) {
if (octets != null)
hashSet.Add(octets);
} else {
foreach (byte[] item in permitted) {
hashSet.UnionWith(IntersectIPRange(item, octets));
}
}
}
return hashSet;
}
private HashSet<byte[]> IntersectIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
{
if (ipWithSubmask1.Length != ipWithSubmask2.Length)
return new HashSet<byte[]>();
byte[][] array = ExtractIPsAndSubnetMasks(ipWithSubmask1, ipWithSubmask2);
byte[] ip = array[0];
byte[] array2 = array[1];
byte[] ip2 = array[2];
byte[] array3 = array[3];
byte[][] array4 = MinMaxIPs(ip, array2, ip2, array3);
byte[] ip3 = Min(array4[1], array4[3]);
if (CompareTo(Max(array4[0], array4[2]), ip3) == 1)
return new HashSet<byte[]>();
byte[] ip4 = Or(array4[0], array4[2]);
byte[] subnetMask = Or(array2, array3);
return new HashSet<byte[]> {
IpWithSubnetMask(ip4, subnetMask)
};
}
private HashSet<byte[]> UnionIP(HashSet<byte[]> excluded, byte[] ip)
{
if (excluded.Count < 1) {
if (ip == null)
return excluded;
excluded.Add(ip);
return excluded;
}
HashSet<byte[]> hashSet = new HashSet<byte[]>();
foreach (byte[] item in excluded) {
hashSet.UnionWith(UnionIPRange(item, ip));
}
return hashSet;
}
private HashSet<byte[]> UnionIPRange(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
{
HashSet<byte[]> hashSet = new HashSet<byte[]>();
if (Arrays.AreEqual(ipWithSubmask1, ipWithSubmask2))
hashSet.Add(ipWithSubmask1);
else {
hashSet.Add(ipWithSubmask1);
hashSet.Add(ipWithSubmask2);
}
return hashSet;
}
private byte[] IpWithSubnetMask(byte[] ip, byte[] subnetMask)
{
int num = ip.Length;
byte[] array = new byte[num * 2];
Array.Copy(ip, 0, array, 0, num);
Array.Copy(subnetMask, 0, array, num, num);
return array;
}
private byte[][] ExtractIPsAndSubnetMasks(byte[] ipWithSubmask1, byte[] ipWithSubmask2)
{
int num = ipWithSubmask1.Length / 2;
byte[] array = new byte[num];
byte[] array2 = new byte[num];
Array.Copy(ipWithSubmask1, 0, array, 0, num);
Array.Copy(ipWithSubmask1, num, array2, 0, num);
byte[] array3 = new byte[num];
byte[] array4 = new byte[num];
Array.Copy(ipWithSubmask2, 0, array3, 0, num);
Array.Copy(ipWithSubmask2, num, array4, 0, num);
return new byte[4][] {
array,
array2,
array3,
array4
};
}
private byte[][] MinMaxIPs(byte[] ip1, byte[] subnetmask1, byte[] ip2, byte[] subnetmask2)
{
int num = ip1.Length;
byte[] array = new byte[num];
byte[] array2 = new byte[num];
byte[] array3 = new byte[num];
byte[] array4 = new byte[num];
for (int i = 0; i < num; i++) {
array[i] = (byte)(ip1[i] & subnetmask1[i]);
array2[i] = (byte)((ip1[i] & subnetmask1[i]) | ~subnetmask1[i]);
array3[i] = (byte)(ip2[i] & subnetmask2[i]);
array4[i] = (byte)((ip2[i] & subnetmask2[i]) | ~subnetmask2[i]);
}
return new byte[4][] {
array,
array2,
array3,
array4
};
}
private static byte[] Max(byte[] ip1, byte[] ip2)
{
for (int i = 0; i < ip1.Length; i++) {
if (ip1[i] > ip2[i])
return ip1;
}
return ip2;
}
private static byte[] Min(byte[] ip1, byte[] ip2)
{
for (int i = 0; i < ip1.Length; i++) {
if (ip1[i] < ip2[i])
return ip1;
}
return ip2;
}
private static int CompareTo(byte[] ip1, byte[] ip2)
{
if (Arrays.AreEqual(ip1, ip2))
return 0;
if (Arrays.AreEqual(Max(ip1, ip2), ip1))
return 1;
return -1;
}
private static byte[] Or(byte[] ip1, byte[] ip2)
{
byte[] array = new byte[ip1.Length];
for (int i = 0; i < ip1.Length; i++) {
array[i] = (byte)(ip1[i] | ip2[i]);
}
return array;
}
private void CheckExcludedDns(HashSet<string> excluded, string dns)
{
if (IsDnsConstrained(excluded, dns))
throw new PkixNameConstraintValidatorException("DNS is from an excluded subtree.");
}
private void CheckPermittedDns(HashSet<string> permitted, string dns)
{
if (permitted != null && (dns.Length != 0 || permitted.Count >= 1) && !IsDnsConstrained(permitted, dns))
throw new PkixNameConstraintValidatorException("DNS is not from a permitted subtree.");
}
private bool IsDnsConstrained(HashSet<string> constraints, string dns)
{
foreach (string constraint in constraints) {
if (IsDnsConstrained(constraint, dns))
return true;
}
return false;
}
private bool IsDnsConstrained(string constraint, string dns)
{
if (!WithinDomain(dns, constraint))
return Platform.EqualsIgnoreCase(dns, constraint);
return true;
}
private HashSet<string> IntersectDns(HashSet<string> permitted, HashSet<GeneralSubtree> dnss)
{
HashSet<string> hashSet = new HashSet<string>();
foreach (GeneralSubtree item in dnss) {
string text = ExtractNameAsString(item.Base);
if (permitted == null) {
if (text != null)
hashSet.Add(text);
} else {
foreach (string item2 in permitted) {
if (WithinDomain(item2, text))
hashSet.Add(item2);
else if (WithinDomain(text, item2)) {
hashSet.Add(text);
}
}
}
}
return hashSet;
}
private HashSet<string> UnionDns(HashSet<string> excluded, string dns)
{
if (excluded.Count < 1) {
if (dns == null)
return excluded;
excluded.Add(dns);
return excluded;
}
HashSet<string> hashSet = new HashSet<string>();
foreach (string item in excluded) {
if (WithinDomain(item, dns))
hashSet.Add(dns);
else if (WithinDomain(dns, item)) {
hashSet.Add(item);
} else {
hashSet.Add(item);
hashSet.Add(dns);
}
}
return hashSet;
}
private void CheckExcludedUri(HashSet<string> excluded, string uri)
{
if (IsUriConstrained(excluded, uri))
throw new PkixNameConstraintValidatorException("URI is from an excluded subtree.");
}
private void CheckPermittedUri(HashSet<string> permitted, string uri)
{
if (permitted != null && (uri.Length != 0 || permitted.Count >= 1) && !IsUriConstrained(permitted, uri))
throw new PkixNameConstraintValidatorException("URI is not from a permitted subtree.");
}
private bool IsUriConstrained(HashSet<string> constraints, string uri)
{
foreach (string constraint in constraints) {
if (IsUriConstrained(constraint, uri))
return true;
}
return false;
}
private bool IsUriConstrained(string constraint, string uri)
{
string text = ExtractHostFromURL(uri);
if (Platform.StartsWith(constraint, "."))
return WithinDomain(text, constraint);
return Platform.EqualsIgnoreCase(text, constraint);
}
private HashSet<string> IntersectUri(HashSet<string> permitted, HashSet<GeneralSubtree> uris)
{
HashSet<string> hashSet = new HashSet<string>();
foreach (GeneralSubtree uri in uris) {
string text = ExtractNameAsString(uri.Base);
if (permitted == null) {
if (text != null)
hashSet.Add(text);
} else {
foreach (string item in permitted) {
IntersectUri(item, text, hashSet);
}
}
}
return hashSet;
}
private void IntersectUri(string email1, string email2, HashSet<string> intersect)
{
if (email1.IndexOf('@') != -1) {
string text = email1.Substring(email1.IndexOf('@') + 1);
if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email1, email2))
intersect.Add(email1);
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(text, email2))
intersect.Add(email1);
} else if (Platform.EqualsIgnoreCase(text, email2)) {
intersect.Add(email1);
}
} else if (Platform.StartsWith(email1, ".")) {
if (email2.IndexOf('@') != -1) {
string testDomain = email2.Substring(email1.IndexOf('@') + 1);
if (WithinDomain(testDomain, email1))
intersect.Add(email2);
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2))
intersect.Add(email1);
else if (WithinDomain(email2, email1)) {
intersect.Add(email2);
}
} else if (WithinDomain(email2, email1)) {
intersect.Add(email2);
}
} else if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email2.Substring(email2.IndexOf('@') + 1), email1))
intersect.Add(email2);
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2))
intersect.Add(email1);
} else if (Platform.EqualsIgnoreCase(email1, email2)) {
intersect.Add(email1);
}
}
private HashSet<string> UnionUri(HashSet<string> excluded, string uri)
{
if (excluded.Count < 1) {
if (uri == null)
return excluded;
excluded.Add(uri);
return excluded;
}
HashSet<string> hashSet = new HashSet<string>();
foreach (string item in excluded) {
UnionUri(item, uri, hashSet);
}
return hashSet;
}
private void UnionUri(string email1, string email2, HashSet<string> union)
{
if (email1.IndexOf('@') != -1) {
string text = email1.Substring(email1.IndexOf('@') + 1);
if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email1, email2))
union.Add(email1);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(text, email2))
union.Add(email2);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.EqualsIgnoreCase(text, email2)) {
union.Add(email2);
} else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email1, ".")) {
if (email2.IndexOf('@') != -1) {
string testDomain = email2.Substring(email1.IndexOf('@') + 1);
if (WithinDomain(testDomain, email1))
union.Add(email1);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2) || Platform.EqualsIgnoreCase(email1, email2))
union.Add(email2);
else if (WithinDomain(email2, email1)) {
union.Add(email1);
} else {
union.Add(email1);
union.Add(email2);
}
} else if (WithinDomain(email2, email1)) {
union.Add(email1);
} else {
union.Add(email1);
union.Add(email2);
}
} else if (email2.IndexOf('@') != -1) {
if (Platform.EqualsIgnoreCase(email2.Substring(email1.IndexOf('@') + 1), email1))
union.Add(email1);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.StartsWith(email2, ".")) {
if (WithinDomain(email1, email2))
union.Add(email2);
else {
union.Add(email1);
union.Add(email2);
}
} else if (Platform.EqualsIgnoreCase(email1, email2)) {
union.Add(email1);
} else {
union.Add(email1);
union.Add(email2);
}
}
private static string ExtractHostFromURL(string url)
{
string text = url.Substring(url.IndexOf(':') + 1);
int num = Platform.IndexOf(text, "//");
if (num != -1)
text = text.Substring(num + 2);
if (text.LastIndexOf(':') != -1)
text = text.Substring(0, text.LastIndexOf(':'));
text = text.Substring(text.IndexOf(':') + 1);
text = text.Substring(text.IndexOf('@') + 1);
if (text.IndexOf('/') != -1)
text = text.Substring(0, text.IndexOf('/'));
return text;
}
private bool WithinDomain(string testDomain, string domain)
{
string text = domain;
if (Platform.StartsWith(text, "."))
text = text.Substring(1);
string[] array = text.Split(new char[1] {
'.'
});
string[] array2 = testDomain.Split(new char[1] {
'.'
});
if (array2.Length <= array.Length)
return false;
int num = array2.Length - array.Length;
for (int i = -1; i < array.Length; i++) {
if (i == -1) {
if (array2[i + num].Length < 1)
return false;
} else if (!Platform.EqualsIgnoreCase(array2[i + num], array[i])) {
return false;
}
}
return true;
}
[Obsolete("Use 'CheckPermittedName' instead")]
public void checkPermitted(GeneralName name)
{
CheckPermittedName(name);
}
public void CheckPermittedName(GeneralName name)
{
switch (name.TagNo) {
case 3:
case 5:
break;
case 0:
CheckPermittedOtherName(permittedSubtreesOtherName, OtherName.GetInstance(name.Name));
break;
case 1:
CheckPermittedEmail(permittedSubtreesEmail, ExtractNameAsString(name));
break;
case 2:
CheckPermittedDns(permittedSubtreesDns, ExtractNameAsString(name));
break;
case 4:
CheckPermittedDN(Asn1Sequence.GetInstance(name.Name.ToAsn1Object()));
break;
case 6:
CheckPermittedUri(permittedSubtreesUri, ExtractNameAsString(name));
break;
case 7:
CheckPermittedIP(permittedSubtreesIP, Asn1OctetString.GetInstance(name.Name).GetOctets());
break;
}
}
[Obsolete("Use 'CheckExcludedName' instead")]
public void checkExcluded(GeneralName name)
{
CheckExcludedName(name);
}
public void CheckExcludedName(GeneralName name)
{
switch (name.TagNo) {
case 3:
case 5:
break;
case 0:
CheckExcludedOtherName(excludedSubtreesOtherName, OtherName.GetInstance(name.Name));
break;
case 1:
CheckExcludedEmail(excludedSubtreesEmail, ExtractNameAsString(name));
break;
case 2:
CheckExcludedDns(excludedSubtreesDns, ExtractNameAsString(name));
break;
case 4:
CheckExcludedDN(Asn1Sequence.GetInstance(name.Name.ToAsn1Object()));
break;
case 6:
CheckExcludedUri(excludedSubtreesUri, ExtractNameAsString(name));
break;
case 7:
CheckExcludedIP(excludedSubtreesIP, Asn1OctetString.GetInstance(name.Name).GetOctets());
break;
}
}
public void IntersectPermittedSubtree(Asn1Sequence permitted)
{
Dictionary<int, HashSet<GeneralSubtree>> dictionary = new Dictionary<int, HashSet<GeneralSubtree>>();
foreach (Asn1Encodable item in permitted) {
GeneralSubtree instance = GeneralSubtree.GetInstance(item);
int tagNo = instance.Base.TagNo;
if (!dictionary.TryGetValue(tagNo, out HashSet<GeneralSubtree> value))
value = (dictionary[tagNo] = new HashSet<GeneralSubtree>());
value.Add(instance);
}
foreach (KeyValuePair<int, HashSet<GeneralSubtree>> item2 in dictionary) {
switch (item2.Key) {
case 0:
permittedSubtreesOtherName = IntersectOtherName(permittedSubtreesOtherName, item2.Value);
break;
case 1:
permittedSubtreesEmail = IntersectEmail(permittedSubtreesEmail, item2.Value);
break;
case 2:
permittedSubtreesDns = IntersectDns(permittedSubtreesDns, item2.Value);
break;
case 4:
permittedSubtreesDN = IntersectDN(permittedSubtreesDN, item2.Value);
break;
case 6:
permittedSubtreesUri = IntersectUri(permittedSubtreesUri, item2.Value);
break;
case 7:
permittedSubtreesIP = IntersectIP(permittedSubtreesIP, item2.Value);
break;
}
}
}
private string ExtractNameAsString(GeneralName name)
{
return DerIA5String.GetInstance(name.Name).GetString();
}
public void IntersectEmptyPermittedSubtree(int nameType)
{
switch (nameType) {
case 3:
case 5:
break;
case 0:
permittedSubtreesOtherName = new HashSet<OtherName>();
break;
case 1:
permittedSubtreesEmail = new HashSet<string>();
break;
case 2:
permittedSubtreesDns = new HashSet<string>();
break;
case 4:
permittedSubtreesDN = new HashSet<Asn1Sequence>();
break;
case 6:
permittedSubtreesUri = new HashSet<string>();
break;
case 7:
permittedSubtreesIP = new HashSet<byte[]>();
break;
}
}
public void AddExcludedSubtree(GeneralSubtree subtree)
{
GeneralName base = subtree.Base;
switch (base.TagNo) {
case 3:
case 5:
break;
case 0:
excludedSubtreesOtherName = UnionOtherName(excludedSubtreesOtherName, OtherName.GetInstance(base.Name));
break;
case 1:
excludedSubtreesEmail = UnionEmail(excludedSubtreesEmail, ExtractNameAsString(base));
break;
case 2:
excludedSubtreesDns = UnionDns(excludedSubtreesDns, ExtractNameAsString(base));
break;
case 4:
excludedSubtreesDN = UnionDN(excludedSubtreesDN, (Asn1Sequence)base.Name.ToAsn1Object());
break;
case 6:
excludedSubtreesUri = UnionUri(excludedSubtreesUri, ExtractNameAsString(base));
break;
case 7:
excludedSubtreesIP = UnionIP(excludedSubtreesIP, Asn1OctetString.GetInstance(base.Name).GetOctets());
break;
}
}
public override int GetHashCode()
{
return HashCollection(excludedSubtreesDN) + HashCollection(excludedSubtreesDns) + HashCollection(excludedSubtreesEmail) + HashCollection(excludedSubtreesIP) + HashCollection(excludedSubtreesUri) + HashCollection(excludedSubtreesOtherName) + HashCollection(permittedSubtreesDN) + HashCollection(permittedSubtreesDns) + HashCollection(permittedSubtreesEmail) + HashCollection(permittedSubtreesIP) + HashCollection(permittedSubtreesUri) + HashCollection(permittedSubtreesOtherName);
}
private int HashCollection(HashSet<byte[]> c)
{
int num = 0;
if (c != null) {
foreach (byte[] item in c) {
num += Arrays.GetHashCode(item);
}
return num;
}
return num;
}
private int HashCollection<T>(HashSet<T> c)
{
int num = 0;
if (c != null) {
foreach (T item in c) {
num += item.GetHashCode();
}
return num;
}
return num;
}
public override bool Equals(object o)
{
PkixNameConstraintValidator pkixNameConstraintValidator = o as PkixNameConstraintValidator;
if (pkixNameConstraintValidator == null)
return false;
if (AreEqualSets(pkixNameConstraintValidator.excludedSubtreesDN, excludedSubtreesDN) && AreEqualSets(pkixNameConstraintValidator.excludedSubtreesDns, excludedSubtreesDns) && AreEqualSets(pkixNameConstraintValidator.excludedSubtreesEmail, excludedSubtreesEmail) && AreEqualSets(pkixNameConstraintValidator.excludedSubtreesIP, excludedSubtreesIP) && AreEqualSets(pkixNameConstraintValidator.excludedSubtreesUri, excludedSubtreesUri) && AreEqualSets(pkixNameConstraintValidator.excludedSubtreesOtherName, excludedSubtreesOtherName) && AreEqualSets(pkixNameConstraintValidator.permittedSubtreesDN, permittedSubtreesDN) && AreEqualSets(pkixNameConstraintValidator.permittedSubtreesDns, permittedSubtreesDns) && AreEqualSets(pkixNameConstraintValidator.permittedSubtreesEmail, permittedSubtreesEmail) && AreEqualSets(pkixNameConstraintValidator.permittedSubtreesIP, permittedSubtreesIP) && AreEqualSets(pkixNameConstraintValidator.permittedSubtreesUri, permittedSubtreesUri))
return AreEqualSets(pkixNameConstraintValidator.permittedSubtreesOtherName, permittedSubtreesOtherName);
return false;
}
private bool AreEqualSets(HashSet<byte[]> set1, HashSet<byte[]> set2)
{
if (set1 == set2)
return true;
if (set1 == null || set2 == null || set1.Count != set2.Count)
return false;
foreach (byte[] item in set1) {
bool flag = false;
foreach (byte[] item2 in set2) {
if (Arrays.AreEqual(item, item2)) {
flag = true;
break;
}
}
if (!flag)
return false;
}
return true;
}
private bool AreEqualSets<T>(HashSet<T> set1, HashSet<T> set2)
{
if (set1 == set2)
return true;
if (set1 == null || set2 == null || set1.Count != set2.Count)
return false;
foreach (T item in set1) {
if (!set2.Contains(item))
return false;
}
return true;
}
private string StringifyIP(byte[] ip)
{
string text = "";
int num;
for (int i = 0; i < ip.Length / 2; i++) {
string str = text;
num = (ip[i] & 255);
text = str + num.ToString() + ".";
}
text = text.Substring(0, text.Length - 1);
text += "/";
for (int j = ip.Length / 2; j < ip.Length; j++) {
string str2 = text;
num = (ip[j] & 255);
text = str2 + num.ToString() + ".";
}
return text.Substring(0, text.Length - 1);
}
private string StringifyIPCollection(HashSet<byte[]> ips)
{
string str = "";
str += "[";
foreach (byte[] ip in ips) {
str = str + StringifyIP(ip) + ",";
}
if (str.Length > 1)
str = str.Substring(0, str.Length - 1);
return str + "]";
}
private string StringifyOtherNameCollection(HashSet<OtherName> otherNames)
{
StringBuilder stringBuilder = new StringBuilder(91);
foreach (OtherName otherName in otherNames) {
if (stringBuilder.Length > 1)
stringBuilder.Append(',');
stringBuilder.Append(otherName.TypeID.Id);
stringBuilder.Append(':');
stringBuilder.Append(Hex.ToHexString(otherName.Value.GetEncoded()));
}
stringBuilder.Append(']');
return stringBuilder.ToString();
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder("permitted:");
stringBuilder.AppendLine();
if (permittedSubtreesDN != null)
Append(stringBuilder, "DN", permittedSubtreesDN);
if (permittedSubtreesDns != null)
Append(stringBuilder, "DNS", permittedSubtreesDns);
if (permittedSubtreesEmail != null)
Append(stringBuilder, "Email", permittedSubtreesEmail);
if (permittedSubtreesUri != null)
Append(stringBuilder, "URI", permittedSubtreesUri);
if (permittedSubtreesIP != null)
Append(stringBuilder, "IP", StringifyIPCollection(permittedSubtreesIP));
if (permittedSubtreesOtherName != null)
Append(stringBuilder, "OtherName", StringifyOtherNameCollection(permittedSubtreesOtherName));
stringBuilder.AppendLine("excluded:");
if (excludedSubtreesDN.Count > 0)
Append(stringBuilder, "DN", excludedSubtreesDN);
if (excludedSubtreesDns.Count > 0)
Append(stringBuilder, "DNS", excludedSubtreesDns);
if (excludedSubtreesEmail.Count > 0)
Append(stringBuilder, "Email", excludedSubtreesEmail);
if (excludedSubtreesUri.Count > 0)
Append(stringBuilder, "URI", excludedSubtreesUri);
if (excludedSubtreesIP.Count > 0)
Append(stringBuilder, "IP", StringifyIPCollection(excludedSubtreesIP));
if (excludedSubtreesOtherName.Count > 0)
Append(stringBuilder, "OtherName", StringifyOtherNameCollection(excludedSubtreesOtherName));
return stringBuilder.ToString();
}
private static void Append(StringBuilder sb, string name, object value)
{
sb.Append(name);
sb.AppendLine(":");
sb.Append(value);
sb.AppendLine();
}
}
}