// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.est.jcajce;

import org.bouncycastle.util.Strings;
import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import org.bouncycastle.asn1.x500.RDN;
import javax.security.auth.x500.X500Principal;
import java.util.Iterator;
import java.util.Collection;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.util.encoders.Hex;
import java.util.logging.Level;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.util.List;
import org.bouncycastle.util.IPAddress;
import java.io.IOException;
import org.bouncycastle.est.ESTException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLSession;
import java.util.Set;
import java.util.logging.Logger;

public class JsseDefaultHostnameAuthorizer implements JsseHostnameAuthorizer
{
    private static Logger LOG;
    private final Set<String> knownSuffixes;
    
    public JsseDefaultHostnameAuthorizer(final Set<String> knownSuffixes) {
        this.knownSuffixes = knownSuffixes;
    }
    
    @Override
    public boolean verified(final String s, final SSLSession sslSession) throws IOException {
        try {
            return this.verify(s, (X509Certificate)CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(sslSession.getPeerCertificates()[0].getEncoded())));
        }
        catch (final Exception ex) {
            if (ex instanceof ESTException) {
                throw (ESTException)ex;
            }
            throw new ESTException(ex.getMessage(), ex);
        }
    }
    
    public boolean verify(final String host, final X509Certificate x509Certificate) throws IOException {
        if (host == null) {
            throw new NullPointerException("'name' cannot be null");
        }
        boolean b = false;
        final boolean validIPv4 = IPAddress.isValidIPv4(host);
        final boolean b2 = !validIPv4 && IPAddress.isValidIPv6(host);
        final boolean b3 = validIPv4 || b2;
        try {
            final Collection<List<?>> subjectAlternativeNames = x509Certificate.getSubjectAlternativeNames();
            if (subjectAlternativeNames != null) {
                InetAddress byName = null;
                for (final List list : subjectAlternativeNames) {
                    final int intValue = (int)list.get(0);
                    switch (intValue) {
                        case 2: {
                            if (!b3 && isValidNameMatch(host, (String)list.get(1), this.knownSuffixes)) {
                                return true;
                            }
                            b = true;
                            continue;
                        }
                        case 7: {
                            if (!b3) {
                                continue;
                            }
                            final String s = (String)list.get(1);
                            if (host.equalsIgnoreCase(s)) {
                                return true;
                            }
                            if (!b2 || !IPAddress.isValidIPv6(s)) {
                                continue;
                            }
                            try {
                                if (byName == null) {
                                    byName = InetAddress.getByName(host);
                                }
                                if (byName.equals(InetAddress.getByName(s))) {
                                    return true;
                                }
                                continue;
                            }
                            catch (final UnknownHostException ex) {}
                            continue;
                        }
                        default: {
                            if (JsseDefaultHostnameAuthorizer.LOG.isLoggable(Level.INFO)) {
                                String str;
                                if (list.get(1) instanceof byte[]) {
                                    str = Hex.toHexString((byte[])list.get(1));
                                }
                                else {
                                    str = list.get(1).toString();
                                }
                                JsseDefaultHostnameAuthorizer.LOG.log(Level.INFO, "ignoring type " + intValue + " value = " + str);
                                continue;
                            }
                            continue;
                        }
                    }
                }
            }
        }
        catch (final Exception ex2) {
            throw new ESTException(ex2.getMessage(), ex2);
        }
        if (b3 || b) {
            return false;
        }
        final X500Principal subjectX500Principal = x509Certificate.getSubjectX500Principal();
        if (subjectX500Principal == null) {
            return false;
        }
        final RDN[] rdNs = X500Name.getInstance(subjectX500Principal.getEncoded()).getRDNs();
        for (int i = rdNs.length - 1; i >= 0; --i) {
            final AttributeTypeAndValue[] typesAndValues = rdNs[i].getTypesAndValues();
            for (int j = 0; j != typesAndValues.length; ++j) {
                final AttributeTypeAndValue attributeTypeAndValue = typesAndValues[j];
                if (BCStyle.CN.equals(attributeTypeAndValue.getType())) {
                    final ASN1Primitive asn1Primitive = attributeTypeAndValue.getValue().toASN1Primitive();
                    return asn1Primitive instanceof ASN1String && isValidNameMatch(host, ((ASN1String)asn1Primitive).getString(), this.knownSuffixes);
                }
            }
        }
        return false;
    }
    
    public static boolean isValidNameMatch(final String s, final String s2, final Set<String> set) throws IOException {
        if (!s2.contains("*")) {
            return s.equalsIgnoreCase(s2);
        }
        final int index = s2.indexOf(42);
        if (index != s2.lastIndexOf("*")) {
            return false;
        }
        if (s2.contains("..") || s2.charAt(s2.length() - 1) == '*') {
            return false;
        }
        final int index2 = s2.indexOf(46, index);
        if (set != null && set.contains(Strings.toLowerCase(s2.substring(index2)))) {
            throw new IOException("Wildcard `" + s2 + "` matches known public suffix.");
        }
        final String lowerCase = Strings.toLowerCase(s2.substring(index + 1));
        final String lowerCase2 = Strings.toLowerCase(s);
        if (lowerCase2.equals(lowerCase)) {
            return false;
        }
        if (lowerCase.length() > lowerCase2.length()) {
            return false;
        }
        if (index > 0) {
            return lowerCase2.startsWith(s2.substring(0, index)) && lowerCase2.endsWith(lowerCase) && lowerCase2.substring(index, lowerCase2.length() - lowerCase.length()).indexOf(46) < 0;
        }
        return lowerCase2.substring(0, lowerCase2.length() - lowerCase.length()).indexOf(46) <= 0 && lowerCase2.endsWith(lowerCase);
    }
    
    static {
        JsseDefaultHostnameAuthorizer.LOG = Logger.getLogger(JsseDefaultHostnameAuthorizer.class.getName());
    }
}
