// Server identity checking is done according to RFC 2818: HTTP over TLS // Section 3.1 Server Identity private void checkURLSpoofing(HostnameVerifier hostnameVerifier) throws IOException { // // Get authenticated server name, if any // boolean done = false; String host = url.getHost(); // if IPv6 strip off the "[]" if (host != null && host.startsWith("[") && host.endsWith("]")) { host = host.substring(1, host.length() - 1); } Certificate[] peerCerts = null; try { // get the subject's certificate peerCerts = session.getPeerCertificates(); X509Certificate peerCert; if (peerCerts[0] instanceof java.security.cert.X509Certificate) { peerCert = (java.security.cert.X509Certificate) peerCerts[0]; } else { throw new SSLPeerUnverifiedException(""); } HostnameChecker checker = HostnameChecker.getInstance(HostnameChecker.TYPE_TLS); checker.match(host, peerCert); // if it doesn't throw an exception, we passed. Return. return; } catch (SSLPeerUnverifiedException e) { // // client explicitly changed default policy and enabled // anonymous ciphers; we can't check the standard policy // // ignore } catch (java.security.cert.CertificateException cpe) { // ignore } // Assume the peerCerts are already cloned. String cipher = session.getCipherSuite(); if ((cipher != null) && (cipher.indexOf("_anon_") != -1)) { return; } else if ((hostnameVerifier != null) && (hostnameVerifier.verify(host, session))) { return; } serverSocket.close(); session.invalidate(); throw new IOException("HTTPS hostname wrong: should be <" + url.getHost() + ">"); }
/** * Returns the certificate chain with which the server authenticated itself, or throw a * SSLPeerUnverifiedException if the server did not authenticate. */ java.security.cert.Certificate[] getServerCertificates() throws SSLPeerUnverifiedException { return session.getPeerCertificates(); }