From e482016aec10588a96bba6b71358e3daab4482ae Mon Sep 17 00:00:00 2001 From: Marc Nuri Date: Sat, 19 Dec 2020 08:18:15 +0100 Subject: [PATCH] Verify IPv6 hostnames [3.14.x] Backport of d59266778d888ec0ea1f48729b122de4d81f7b91 --- .../internal/tls/HostnameVerifierTest.java | 36 +++++++++++++++++++ .../internal/tls/OkHostnameVerifier.java | 4 ++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/okhttp-tests/src/test/java/okhttp3/internal/tls/HostnameVerifierTest.java b/okhttp-tests/src/test/java/okhttp3/internal/tls/HostnameVerifierTest.java index 9a878f1c416d..6f0ab0eec80c 100644 --- a/okhttp-tests/src/test/java/okhttp3/internal/tls/HostnameVerifierTest.java +++ b/okhttp-tests/src/test/java/okhttp3/internal/tls/HostnameVerifierTest.java @@ -516,6 +516,42 @@ public final class HostnameVerifierTest { assertThat(verifier.verify("quux.com", session)).isFalse(); } + @Test public void subjectAltNameWithIPAddresses() throws Exception { + // $ cat ./cert.cnf + // [req] + // distinguished_name=distinguished_name + // req_extensions=req_extensions + // x509_extensions=x509_extensions + // [distinguished_name] + // [req_extensions] + // [x509_extensions] + // subjectAltName=IP:0:0:0:0:0:0:0:1,IP:2a03:2880:f003:c07:face:b00c::2,IP:0::5,IP:192.168.1.1 + // + // $ openssl req -x509 -nodes -days 36500 -subj '/CN=foo.com' -config ./cert.cnf \ + // -newkey rsa:512 -out cert.pem + SSLSession session = session("" + + "-----BEGIN CERTIFICATE-----\n" + + "MIIBaDCCARKgAwIBAgIJALxN+AOBVGwQMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" + + "BAMMB2Zvby5jb20wIBcNMjAwMzIyMTEwNDI4WhgPMjEyMDAyMjcxMTA0MjhaMBIx\n" + + "EDAOBgNVBAMMB2Zvby5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAlnVbVfQ9\n" + + "4aYjrPCcFuxOpjXuvyOc9Hcha4K7TfXyfsrjhAvCjCBIT/TiLOUVF3sx4yoCAtX8\n" + + "wmt404tTbKD6UwIDAQABo0kwRzBFBgNVHREEPjA8hxAAAAAAAAAAAAAAAAAAAAAB\n" + + "hxAqAyiA8AMMB/rOsAwAAAAChxAAAAAAAAAAAAAAAAAAAAAFhwTAqAEBMA0GCSqG\n" + + "SIb3DQEBCwUAA0EAPSOYHJh7hB4ElBqTCAFW+T5Y7mXsv9nQjBJ7w0YIw83V2PEI\n" + + "3KbBIyGTrqHD6lG8QGZy+yNkIcRlodG8OfQRUg==\n" + + "-----END CERTIFICATE-----"); + assertThat(verifier.verify("foo.com", session)).isFalse(); + assertThat(verifier.verify("::1", session)).isTrue(); + assertThat(verifier.verify("::2", session)).isFalse(); + assertThat(verifier.verify("::5", session)).isTrue(); + assertThat(verifier.verify("2a03:2880:f003:c07:face:b00c::2", session)).isTrue(); + assertThat(verifier.verify("2a03:2880:f003:c07:face:b00c:0:2", session)).isTrue(); + assertThat(verifier.verify("2a03:2880:f003:c07:FACE:B00C:0:2", session)).isTrue(); + assertThat(verifier.verify("2a03:2880:f003:c07:face:b00c:0:3", session)).isFalse(); + assertThat(verifier.verify("127.0.0.1", session)).isFalse(); + assertThat(verifier.verify("192.168.1.1", session)).isTrue(); + } + @Test public void verifyAsIpAddress() { // IPv4 assertThat(Util.verifyAsIpAddress("127.0.0.1")).isTrue(); diff --git a/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java b/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java index 36ac5b3813d3..6c77c4243a76 100644 --- a/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java +++ b/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java @@ -28,6 +28,7 @@ import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; +import static okhttp3.internal.Util.canonicalizeHost; import static okhttp3.internal.Util.verifyAsIpAddress; /** @@ -60,9 +61,10 @@ public boolean verify(String host, X509Certificate certificate) { /** Returns true if {@code certificate} matches {@code ipAddress}. */ private boolean verifyIpAddress(String ipAddress, X509Certificate certificate) { + String canonicalIpAddress = canonicalizeHost(ipAddress); List altNames = getSubjectAltNames(certificate, ALT_IPA_NAME); for (int i = 0, size = altNames.size(); i < size; i++) { - if (ipAddress.equalsIgnoreCase(altNames.get(i))) { + if (canonicalIpAddress.equals(canonicalizeHost(altNames.get(i)))) { return true; } }