From 076c7d0b81f6dac6255bf5a171fc53c2fc7ab169 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 1 Aug 2014 17:35:44 +0200 Subject: [PATCH] Configure default Hostname Verifiers --- .../android/AndroidSmackInitializer.java | 33 +++++++ .../initializer/SimpleSmackInitializer.java | 17 +++- .../org.jivesoftware.smack/smack-config.xml | 2 + .../smack/java7/Java7HostnameVerifier.java | 88 +++++++++++++++++++ .../smack/java7/Java7SmackInitializer.java | 32 +++++++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java rename smack-java7/src/main/java/org/jivesoftware/smack/SmackJava7Dummy.java => smack-core/src/main/java/org/jivesoftware/smack/initializer/SimpleSmackInitializer.java (61%) create mode 100644 smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7HostnameVerifier.java create mode 100644 smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java diff --git a/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java b/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java new file mode 100644 index 000000000..f13a4b309 --- /dev/null +++ b/smack-android/src/main/java/org/jivesoftware/smack/android/AndroidSmackInitializer.java @@ -0,0 +1,33 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.android; + +import java.util.List; + +import org.apache.http.conn.ssl.StrictHostnameVerifier; +import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.initializer.SimpleSmackInitializer; + +public class AndroidSmackInitializer extends SimpleSmackInitializer { + + @Override + public List initialize() { + SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier()); + return null; + } + +} diff --git a/smack-java7/src/main/java/org/jivesoftware/smack/SmackJava7Dummy.java b/smack-core/src/main/java/org/jivesoftware/smack/initializer/SimpleSmackInitializer.java similarity index 61% rename from smack-java7/src/main/java/org/jivesoftware/smack/SmackJava7Dummy.java rename to smack-core/src/main/java/org/jivesoftware/smack/initializer/SimpleSmackInitializer.java index dc26a41ca..52e1789d5 100644 --- a/smack-java7/src/main/java/org/jivesoftware/smack/SmackJava7Dummy.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/initializer/SimpleSmackInitializer.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014 the original author or authors + * Copyright 2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,3 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package org.jivesoftware.smack.initializer; + +import java.util.List; + +public abstract class SimpleSmackInitializer implements SmackInitializer { + + @Override + public abstract List initialize(); + + @Override + public List initialize(ClassLoader classLoader) { + return initialize(); + } + +} diff --git a/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml b/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml index e10003e36..57c0b33ac 100644 --- a/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml +++ b/smack-core/src/main/resources/org.jivesoftware.smack/smack-config.xml @@ -14,5 +14,7 @@ org.jivesoftware.smack.initializer.legacy.LegacyInitializer org.jivesoftware.smack.sasl.javax.SASLJavaXSmackInitializer org.jivesoftware.smack.sasl.provided.SASLProvidedSmackInitializer + org.jivesoftware.smack.android.AndroidSmackInitializer + org.jivesoftware.smack.java7.Java7SmackInitializer diff --git a/smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7HostnameVerifier.java b/smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7HostnameVerifier.java new file mode 100644 index 000000000..2d682acb1 --- /dev/null +++ b/smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7HostnameVerifier.java @@ -0,0 +1,88 @@ +/** + * + * Copyright 2014 the original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jivesoftware.smack.java7; + +import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.security.auth.kerberos.KerberosPrincipal; + +import sun.security.util.HostnameChecker; + +/** + *

+ * HostnameVerifier implementation which implements the same policy as the Java built-in + * pre-HostnameVerifier policy. + *

+ *

+ * Based on the work by Kevin + * Locke (released under CC0 1.0 Universal / Public Domain Dedication). + *

+ */ +public class Java7HostnameVerifier implements HostnameVerifier { + + @Override + public boolean verify(String hostname, SSLSession session) { + HostnameChecker checker = HostnameChecker.getInstance(HostnameChecker.TYPE_TLS); + + boolean validCertificate = false, validPrincipal = false; + try { + Certificate[] peerCertificates = session.getPeerCertificates(); + + if (peerCertificates.length > 0 && peerCertificates[0] instanceof X509Certificate) { + X509Certificate peerCertificate = (X509Certificate) peerCertificates[0]; + + try { + checker.match(hostname, peerCertificate); + // Certificate matches hostname + validCertificate = true; + } + catch (CertificateException ex) { + // Certificate does not match hostname + } + } + else { + // Peer does not have any certificates or they aren't X.509 + } + } + catch (SSLPeerUnverifiedException ex) { + // Not using certificates for peers, try verifying the principal + try { + Principal peerPrincipal = session.getPeerPrincipal(); + if (peerPrincipal instanceof KerberosPrincipal) { + validPrincipal = HostnameChecker.match(hostname, + (KerberosPrincipal) peerPrincipal); + } + else { + // Can't verify principal, not Kerberos + } + } + catch (SSLPeerUnverifiedException ex2) { + // Can't verify principal, no principal + } + } + + return validCertificate || validPrincipal; + } +} diff --git a/smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java b/smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java new file mode 100644 index 000000000..548528f9b --- /dev/null +++ b/smack-java7/src/main/java/org/jivesoftware/smack/java7/Java7SmackInitializer.java @@ -0,0 +1,32 @@ +/** + * + * Copyright 2014 the original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.java7; + +import java.util.List; + +import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.initializer.SimpleSmackInitializer; + +public class Java7SmackInitializer extends SimpleSmackInitializer { + + @Override + public List initialize() { + SmackConfiguration.setDefaultHostnameVerifier(new Java7HostnameVerifier()); + return null; + } + +}