diff options
author | Kevin Smith <git@kismith.co.uk> | 2011-07-01 09:19:49 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2011-07-01 09:19:49 (GMT) |
commit | 2da71a8a85486a494343f1662d64fb5ae5a2a44e (patch) | |
tree | 23992f9f2a00bac23b345e5c2cc9c1194efc25be /src/com/isode/stroke/tls | |
download | stroke-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.java | 47 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/CertificateFactory.java | 16 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/CertificateTrustChecker.java | 23 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/CertificateVerificationError.java | 39 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/PKCS12Certificate.java | 40 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/PlatformTLSFactories.java | 21 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/ServerIdentityVerifier.java | 88 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/TLSContext.java | 34 | ||||
-rw-r--r-- | src/com/isode/stroke/tls/TLSContextFactory.java | 15 |
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(); +} |