summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2011-07-01 09:19:49 (GMT)
committerKevin Smith <git@kismith.co.uk>2011-07-01 09:19:49 (GMT)
commit2da71a8a85486a494343f1662d64fb5ae5a2a44e (patch)
tree23992f9f2a00bac23b345e5c2cc9c1194efc25be /src/com/isode/stroke/tls
downloadstroke-2da71a8a85486a494343f1662d64fb5ae5a2a44e.zip
stroke-2da71a8a85486a494343f1662d64fb5ae5a2a44e.tar.bz2
Initial import
Diffstat (limited to 'src/com/isode/stroke/tls')
-rw-r--r--src/com/isode/stroke/tls/Certificate.java47
-rw-r--r--src/com/isode/stroke/tls/CertificateFactory.java16
-rw-r--r--src/com/isode/stroke/tls/CertificateTrustChecker.java23
-rw-r--r--src/com/isode/stroke/tls/CertificateVerificationError.java39
-rw-r--r--src/com/isode/stroke/tls/PKCS12Certificate.java40
-rw-r--r--src/com/isode/stroke/tls/PlatformTLSFactories.java21
-rw-r--r--src/com/isode/stroke/tls/ServerIdentityVerifier.java88
-rw-r--r--src/com/isode/stroke/tls/TLSContext.java34
-rw-r--r--src/com/isode/stroke/tls/TLSContextFactory.java15
9 files changed, 323 insertions, 0 deletions
diff --git a/src/com/isode/stroke/tls/Certificate.java b/src/com/isode/stroke/tls/Certificate.java
new file mode 100644
index 0000000..ac7daed
--- /dev/null
+++ b/src/com/isode/stroke/tls/Certificate.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010 Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.tls;
+
+import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.stringcodecs.Hexify;
+import com.isode.stroke.stringcodecs.SHA1;
+import java.util.List;
+
+public abstract class Certificate {
+
+ /**
+ * Returns the textual representation of the full Subject
+ * name.
+ */
+ public abstract String getSubjectName();
+
+ public abstract List<String> getCommonNames();
+
+ public abstract List<String> getSRVNames();
+
+ public abstract List<String> getDNSNames();
+
+ public abstract List<String> getXMPPAddresses();
+
+ public abstract ByteArray toDER();
+
+ public String getSHA1Fingerprint() {
+ ByteArray hash = SHA1.getHash(toDER());
+ StringBuilder s = new StringBuilder();
+ for (int i = 0; i < hash.getSize(); ++i) {
+ if (i > 0) {
+ s.append(":");
+ }
+ s.append(Hexify.hexify(hash.getData()[i]));
+ }
+ return s.toString();
+ }
+ protected String ID_ON_XMPPADDR_OID = "1.3.6.1.5.5.7.8.5";
+ protected String ID_ON_DNSSRV_OID = "1.3.6.1.5.5.7.8.7";
+}
diff --git a/src/com/isode/stroke/tls/CertificateFactory.java b/src/com/isode/stroke/tls/CertificateFactory.java
new file mode 100644
index 0000000..a4c34db
--- /dev/null
+++ b/src/com/isode/stroke/tls/CertificateFactory.java
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010 Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.tls;
+
+import com.isode.stroke.base.ByteArray;
+
+public interface CertificateFactory {
+ Certificate createCertificateFromDER(ByteArray der);
+}
diff --git a/src/com/isode/stroke/tls/CertificateTrustChecker.java b/src/com/isode/stroke/tls/CertificateTrustChecker.java
new file mode 100644
index 0000000..08d4506
--- /dev/null
+++ b/src/com/isode/stroke/tls/CertificateTrustChecker.java
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+/**
+ * A class to implement a check for certificate trust.
+ */
+public interface CertificateTrustChecker {
+
+ /**
+ * This method is called to find out whether a certificate is
+ * trusted. This usually happens when a certificate's validation
+ * fails, to check whether to proceed with the connection or not.
+ */
+ boolean isCertificateTrusted(Certificate certificate);
+}
diff --git a/src/com/isode/stroke/tls/CertificateVerificationError.java b/src/com/isode/stroke/tls/CertificateVerificationError.java
new file mode 100644
index 0000000..a8309ca
--- /dev/null
+++ b/src/com/isode/stroke/tls/CertificateVerificationError.java
@@ -0,0 +1,39 @@
+/*
+ * 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.base.Error;
+
+public class CertificateVerificationError implements Error {
+
+ public enum Type {
+
+ UnknownError,
+ Expired,
+ NotYetValid,
+ SelfSigned,
+ Rejected,
+ Untrusted,
+ InvalidPurpose,
+ PathLengthExceeded,
+ InvalidSignature,
+ InvalidCA,
+ InvalidServerIdentity,
+ };
+
+ public CertificateVerificationError(Type type) {
+ if (type == null) {
+ throw new IllegalStateException();
+ }
+ this.type = type;
+ }
+ public final Type type;
+};
+
diff --git a/src/com/isode/stroke/tls/PKCS12Certificate.java b/src/com/isode/stroke/tls/PKCS12Certificate.java
new file mode 100644
index 0000000..af66545
--- /dev/null
+++ b/src/com/isode/stroke/tls/PKCS12Certificate.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010 Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.tls;
+
+import com.isode.stroke.base.ByteArray;
+
+public class PKCS12Certificate {
+
+ public PKCS12Certificate() {
+ }
+
+ public PKCS12Certificate(String filename, String password) {
+ password_ = password;
+ data_.readFromFile(filename);
+ }
+
+ public boolean isNull() {
+ return data_.isEmpty();
+ }
+
+ public ByteArray getData() {
+ return data_;
+ }
+
+ public void setData(ByteArray data) {
+ data_ = data;
+ }
+
+ public String getPassword() {
+ return password_;
+ }
+ private ByteArray data_;
+ private String password_;
+}
diff --git a/src/com/isode/stroke/tls/PlatformTLSFactories.java b/src/com/isode/stroke/tls/PlatformTLSFactories.java
new file mode 100644
index 0000000..0959d07
--- /dev/null
+++ b/src/com/isode/stroke/tls/PlatformTLSFactories.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2011 Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010 Remko Tron¨on.
+ * All rights reserved.
+ */
+package com.isode.stroke.tls;
+
+public class PlatformTLSFactories {
+ public TLSContextFactory getTLSContextFactory() {
+ /*FIXME: Implement*/
+ return null;
+ }
+
+ public CertificateFactory getCertificateFactory() {
+ /*FIXME: Implement*/
+ return null;
+ }
+}
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;
+}
diff --git a/src/com/isode/stroke/tls/TLSContext.java b/src/com/isode/stroke/tls/TLSContext.java
new file mode 100644
index 0000000..16f2ae3
--- /dev/null
+++ b/src/com/isode/stroke/tls/TLSContext.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.tls;
+
+import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.signals.Signal;
+import com.isode.stroke.signals.Signal1;
+
+public abstract class TLSContext {
+ //See SSLEngine for real implementation when the time comes
+ public abstract void connect();
+
+ public abstract boolean setClientCertificate(PKCS12Certificate cert);
+
+ public abstract void handleDataFromNetwork(ByteArray data);
+ public abstract void handleDataFromApplication(ByteArray data);
+
+ public abstract Certificate getPeerCertificate();
+ public abstract CertificateVerificationError getPeerCertificateVerificationError();
+
+ public abstract ByteArray getFinishMessage();
+
+ public Signal1<ByteArray> onDataForNetwork = new Signal1<ByteArray>();
+ public Signal1<ByteArray> onDataForApplication = new Signal1<ByteArray>();
+ public Signal onError = new Signal();
+ public Signal onConnected = new Signal();
+}
diff --git a/src/com/isode/stroke/tls/TLSContextFactory.java b/src/com/isode/stroke/tls/TLSContextFactory.java
new file mode 100644
index 0000000..1b84a42
--- /dev/null
+++ b/src/com/isode/stroke/tls/TLSContextFactory.java
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2011, Isode Limited, London, England.
+ * All rights reserved.
+ */
+/*
+ * Copyright (c) 2010, Remko Tron¨on.
+ * All rights reserved.
+ */
+
+package com.isode.stroke.tls;
+
+public interface TLSContextFactory {
+ boolean canCreate();
+ TLSContext createTLSContext();
+}