summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/tls/ServerIdentityVerifier.java')
-rw-r--r--src/com/isode/stroke/tls/ServerIdentityVerifier.java88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/com/isode/stroke/tls/ServerIdentityVerifier.java b/src/com/isode/stroke/tls/ServerIdentityVerifier.java
new file mode 100644
index 0000000..903b296
--- /dev/null
+++ b/src/com/isode/stroke/tls/ServerIdentityVerifier.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.tls;
+
+import com.isode.stroke.idn.IDNA;
+import com.isode.stroke.jid.JID;
+import java.util.List;
+
+public class ServerIdentityVerifier {
+
+ public ServerIdentityVerifier(JID jid) {
+ domain = jid.getDomain();
+ encodedDomain = IDNA.getEncoded(domain);
+ }
+
+ public boolean certificateVerifies(Certificate certificate) {
+ boolean hasSAN = false;
+
+ // DNS names
+ List<String> dnsNames = certificate.getDNSNames();
+ for (String dnsName : dnsNames) {
+ if (matchesDomain(dnsName)) {
+ return true;
+ }
+ }
+ hasSAN |= !dnsNames.isEmpty();
+
+ // SRV names
+ List<String> srvNames = certificate.getSRVNames();
+ for (String srvName : srvNames) {
+ // Only match SRV names that begin with the service; this isn't required per
+ // spec, but we're being purist about this.
+ if (srvName.startsWith("_xmpp-client.") && matchesDomain(srvName.substring("_xmpp-client.".length()))) {
+ return true;
+ }
+ }
+ hasSAN |= !srvNames.isEmpty();
+
+ // XmppAddr
+ List<String> xmppAddresses = certificate.getXMPPAddresses();
+ for (String xmppAddress : xmppAddresses) {
+ if (matchesAddress(xmppAddress)) {
+ return true;
+ }
+ }
+ hasSAN |= !xmppAddresses.isEmpty();
+
+ // CommonNames. Only check this if there was no SAN (according to spec).
+ if (!hasSAN) {
+ List<String> commonNames = certificate.getCommonNames();
+ for (String commonName : commonNames) {
+ if (matchesDomain(commonName)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ boolean matchesDomain(String s) {
+ if (s.startsWith("*.")) {
+ String matchString = s.substring(2);
+ String matchDomain = encodedDomain;
+ int dotIndex = matchDomain.indexOf('.');
+ if (dotIndex >= 0) {
+ matchDomain = matchDomain.substring(dotIndex + 1);
+ }
+ return matchString.equals(matchDomain);
+ }
+ else {
+ return s.equals(encodedDomain);
+ }
+ }
+
+ boolean matchesAddress(String s) {
+ return s.equals(domain);
+ }
+ private String domain;
+ private String encodedDomain;
+}