summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarun Gupta <tarun1995gupta@gmail.com>2015-07-22 22:21:20 (GMT)
committerNick Hudson <nick.hudson@isode.com>2015-08-03 14:06:04 (GMT)
commitaf3bb03053b9d83f4d38b31d66b292792206a327 (patch)
tree0e5826f6b1fbb638d899ee6aadca902a7c2fdb18 /src/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticator.java
parent32ef37b9059e21de19209a9a1ab4ef2564051918 (diff)
downloadstroke-af3bb03053b9d83f4d38b31d66b292792206a327.zip
stroke-af3bb03053b9d83f4d38b31d66b292792206a327.tar.bz2
Make SASL equivalent with Swiften.
Adds DIGESTMD5ClientAuthenticator, DIGESTMD5Properties, ExternalClientAuthenticator, PLAINMessage. Updates Client, ClientSession, CoreClient, ConnectDisconnect, StrokeGUI to reflect changes made in SASL. Updates ClientAuthenticator, SCRAMSHA1ClientAuthenticator, PBKDF2. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details. Test-Information: Added tests for DIGESTMD5ClientAuthenticator, DIGESTMD5Properties, PLAINClientAuthenticator, PLAINMessage. Update test for SCRAMSHA1ClientAuthenticatorTest. All tests pass. Change-Id: I4fd38f922cab7e4c4548d9706f6ad3b9e1506e81
Diffstat (limited to 'src/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticator.java')
-rw-r--r--src/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticator.java115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticator.java b/src/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticator.java
new file mode 100644
index 0000000..639c353
--- /dev/null
+++ b/src/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticator.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010-2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+/*
+ * Copyright (c) 2015 Tarun Gupta.
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+package com.isode.stroke.sasl;
+
+import com.isode.stroke.sasl.ClientAuthenticator;
+import com.isode.stroke.sasl.DIGESTMD5Properties;
+import com.isode.stroke.crypto.CryptoProvider;
+import com.isode.stroke.base.SafeByteArray;
+import com.isode.stroke.base.ByteArray;
+import com.isode.stroke.stringcodecs.Hexify;
+
+public class DIGESTMD5ClientAuthenticator extends ClientAuthenticator {
+
+ private enum Step {
+ Initial,
+ Response,
+ Final
+ };
+ private Step step;
+ private String host = "";
+ private String cnonce = "";
+ private CryptoProvider crypto;
+ private DIGESTMD5Properties challenge = new DIGESTMD5Properties();
+
+ public DIGESTMD5ClientAuthenticator(final String host, final String nonce, CryptoProvider crypto) {
+ super("DIGEST-MD5");
+ this.step = Step.Initial;
+ this.host = host;
+ this.cnonce = nonce;
+ this.crypto = crypto;
+ }
+
+ public SafeByteArray getResponse() {
+ if (Step.Initial.equals(step)) {
+ return null;
+ }
+ else if (Step.Response.equals(step)) {
+ String realm = "";
+ if (challenge.getValue("realm") != null) {
+ realm = challenge.getValue("realm");
+ }
+ String qop = "auth";
+ String digestURI = "xmpp/" + host;
+ String nc = "00000001";
+
+ ByteArray A11 = crypto.getMD5Hash(new SafeByteArray().append(getAuthenticationID()).append(":").append(realm).append(":").append(getPassword()));
+ ByteArray A12 = new ByteArray().append(":").append(challenge.getValue("nonce")).append(":").append(cnonce);
+ // Compute the response value
+ ByteArray A1 = A11.append(A12);
+ if (!getAuthorizationID().isEmpty()) {
+ A1.append(new ByteArray(":" + getAuthenticationID()));
+ }
+ ByteArray A2 = new ByteArray("AUTHENTICATE:" + digestURI);
+
+ String responseValue = Hexify.hexify(crypto.getMD5Hash(new ByteArray(
+ Hexify.hexify(crypto.getMD5Hash(A1)) + ":"
+ + challenge.getValue("nonce") + ":" + nc + ":" + cnonce + ":" + qop + ":"
+ + Hexify.hexify(crypto.getMD5Hash(A2)))));
+
+
+ DIGESTMD5Properties response = new DIGESTMD5Properties();
+ response.setValue("username", getAuthenticationID());
+ if (!realm.isEmpty()) {
+ response.setValue("realm", realm);
+ }
+ response.setValue("nonce", challenge.getValue("nonce"));
+ response.setValue("cnonce", cnonce);
+ response.setValue("nc", "00000001");
+ response.setValue("qop", qop);
+ response.setValue("digest-uri", digestURI);
+ response.setValue("charset", "utf-8");
+ response.setValue("response", responseValue);
+ if (!getAuthorizationID().isEmpty()) {
+ response.setValue("authzid", getAuthorizationID());
+ }
+ return new SafeByteArray(response.serialize());
+ }
+ else {
+ return null;
+ }
+ }
+
+ public boolean setChallenge(final ByteArray challengeData) {
+ if (Step.Initial.equals(step)) {
+ if (challengeData == null) {
+ return false;
+ }
+ challenge = DIGESTMD5Properties.parse(challengeData);
+
+ // Sanity checks
+ if (challenge.getValue("nonce") == null) {
+ return false;
+ }
+ if (challenge.getValue("charset") ==null || !(challenge.getValue("charset").equals("utf-8"))) {
+ return false;
+ }
+ step = Step.Response;
+ return true;
+ }
+ else {
+ step = Step.Final;
+ // TODO: Check RSPAuth
+ return true;
+ }
+ }
+} \ No newline at end of file