From af3bb03053b9d83f4d38b31d66b292792206a327 Mon Sep 17 00:00:00 2001 From: Tarun Gupta Date: Thu, 23 Jul 2015 03:51:20 +0530 Subject: 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 diff --git a/src/com/isode/stroke/client/Client.java b/src/com/isode/stroke/client/Client.java index 6938225..1d137c5 100644 --- a/src/com/isode/stroke/client/Client.java +++ b/src/com/isode/stroke/client/Client.java @@ -28,6 +28,7 @@ import com.isode.stroke.roster.XMPPRosterController; import com.isode.stroke.roster.XMPPRosterImpl; import com.isode.stroke.signals.Signal1; import com.isode.stroke.vcards.VCardManager; +import com.isode.stroke.base.SafeByteArray; /** * Provides the core functionality for writing XMPP client software. @@ -76,7 +77,7 @@ public class Client extends CoreClient { * @param networkFactories An implementation of network interaction, must * not be null. */ - public Client(final JID jid, final String password, final NetworkFactories networkFactories, Storages storages) { + public Client(final JID jid, final SafeByteArray password, final NetworkFactories networkFactories, Storages storages) { super(jid, password, networkFactories); this.storages = storages; @@ -111,7 +112,7 @@ public class Client extends CoreClient { pubSubManager = new PubSubManagerImpl(getStanzaChannel(), getIQRouter()); } - public Client(final JID jid, final String password, final NetworkFactories networkFactories) { + public Client(final JID jid, final SafeByteArray password, final NetworkFactories networkFactories) { this(jid, password, networkFactories, null); } diff --git a/src/com/isode/stroke/client/ClientSession.java b/src/com/isode/stroke/client/ClientSession.java index 7654630..fe9481d 100644 --- a/src/com/isode/stroke/client/ClientSession.java +++ b/src/com/isode/stroke/client/ClientSession.java @@ -50,6 +50,10 @@ import com.isode.stroke.tls.Certificate; import com.isode.stroke.tls.CertificateTrustChecker; import com.isode.stroke.tls.CertificateVerificationError; import com.isode.stroke.tls.ServerIdentityVerifier; +import com.isode.stroke.idn.IDNConverter; +import com.isode.stroke.idn.ICUConverter; +import com.isode.stroke.crypto.CryptoProvider; +import com.isode.stroke.crypto.JavaCryptoProvider; import java.util.List; import java.util.UUID; @@ -84,6 +88,8 @@ public class ClientSession { private StanzaAckResponder stanzaAckResponder_; private com.isode.stroke.base.Error error_; private CertificateTrustChecker certificateTrustChecker; + private IDNConverter idnConverter = new ICUConverter(); //TOPORT: Accomodated later in Constructor. + private CryptoProvider crypto = new JavaCryptoProvider(); //TOPORT: Accomodated later in Constructor. public enum State { @@ -354,7 +360,7 @@ public class ClientSession { stream.writeElement(new AuthRequest("EXTERNAL",new SafeByteArray())); } else if (streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1") || streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")) { - final SCRAMSHA1ClientAuthenticator scramAuthenticator = new SCRAMSHA1ClientAuthenticator(UUID.randomUUID().toString(), streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1-PLUS")); + final SCRAMSHA1ClientAuthenticator scramAuthenticator = new SCRAMSHA1ClientAuthenticator(UUID.randomUUID().toString(), streamFeatures.hasAuthenticationMechanism("SCRAM-SHA-1-PLUS"), idnConverter, crypto); if (stream.isTLSEncrypted()) { scramAuthenticator.setTLSChannelBindingData(stream.getTLSFinishMessage()); } @@ -508,7 +514,7 @@ public class ClientSession { return true; } - public void sendCredentials(final String password) { + public void sendCredentials(final SafeByteArray password) { if (!checkState(State.WaitingForCredentials)) { throw new IllegalStateException("Asking for credentials when we shouldn't be asked."); } diff --git a/src/com/isode/stroke/client/CoreClient.java b/src/com/isode/stroke/client/CoreClient.java index efefa1c..39229a3 100644 --- a/src/com/isode/stroke/client/CoreClient.java +++ b/src/com/isode/stroke/client/CoreClient.java @@ -80,7 +80,7 @@ public class CoreClient { */ public final Signal1 onStanzaAcked = new Signal1(); private JID jid_; - private String password_; + private SafeByteArray password_; private ClientSessionStanzaChannel stanzaChannel_; private IQRouter iqRouter_; private Connector connector_; @@ -117,7 +117,7 @@ public class CoreClient { * @param networkFactories An implementation of network interaction, must * not be null. */ - public CoreClient(final JID jid, final String password, final NetworkFactories networkFactories) { + public CoreClient(final JID jid, final SafeByteArray password, final NetworkFactories networkFactories) { jid_ = jid; password_ = password; disconnectRequested_ = false; diff --git a/src/com/isode/stroke/examples/ConnectDisconnect.java b/src/com/isode/stroke/examples/ConnectDisconnect.java index 6b4cbc4..12b3c27 100644 --- a/src/com/isode/stroke/examples/ConnectDisconnect.java +++ b/src/com/isode/stroke/examples/ConnectDisconnect.java @@ -13,6 +13,7 @@ import com.isode.stroke.jid.JID; import com.isode.stroke.network.JavaNetworkFactories; import com.isode.stroke.signals.Slot; import com.isode.stroke.signals.Slot1; +import com.isode.stroke.base.SafeByteArray; /** * Simple example. @@ -66,7 +67,7 @@ public class ConnectDisconnect { public void go(String args[]) { jid = new JID(args[0]); - String password = args[1]; + SafeByteArray password = new SafeByteArray(args[1]); DummyEventLoop eventLoop = new DummyEventLoop(); JavaNetworkFactories factories = new JavaNetworkFactories(eventLoop); diff --git a/src/com/isode/stroke/examples/gui/StrokeGUI.java b/src/com/isode/stroke/examples/gui/StrokeGUI.java index 6fc07de..5d0c1ca 100644 --- a/src/com/isode/stroke/examples/gui/StrokeGUI.java +++ b/src/com/isode/stroke/examples/gui/StrokeGUI.java @@ -158,7 +158,7 @@ public class StrokeGUI extends javax.swing.JFrame { } }; - client_ = new CoreClient(JID.fromString(loginJID_.getText()), loginPassword_.getText(), new JavaNetworkFactories(eventLoop)); + client_ = new CoreClient(JID.fromString(loginJID_.getText()), new SafeByteArray(loginPassword_.getText()), new JavaNetworkFactories(eventLoop)); System.out.println("Connecting"); try { client_.connect(new ClientOptions()); diff --git a/src/com/isode/stroke/sasl/ClientAuthenticator.java b/src/com/isode/stroke/sasl/ClientAuthenticator.java index 2dc3756..450ef1b 100644 --- a/src/com/isode/stroke/sasl/ClientAuthenticator.java +++ b/src/com/isode/stroke/sasl/ClientAuthenticator.java @@ -21,11 +21,11 @@ public abstract class ClientAuthenticator { return name; } - public void setCredentials(String authcid, String password) { + public void setCredentials(String authcid, SafeByteArray password) { setCredentials(authcid, password, ""); } - public void setCredentials(String authcid, String password, String authzid) { + public void setCredentials(String authcid, SafeByteArray password, String authzid) { this.authcid = authcid; this.password = password; this.authzid = authzid; @@ -43,11 +43,11 @@ public abstract class ClientAuthenticator { return authzid; } - public String getPassword() { + public SafeByteArray getPassword() { return password; } private String name; private String authcid; - private String password; + private SafeByteArray password; private String authzid; } 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 diff --git a/src/com/isode/stroke/sasl/DIGESTMD5Properties.java b/src/com/isode/stroke/sasl/DIGESTMD5Properties.java new file mode 100644 index 0000000..0bc6a8d --- /dev/null +++ b/src/com/isode/stroke/sasl/DIGESTMD5Properties.java @@ -0,0 +1,146 @@ +/* + * 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.base.SafeByteArray; +import com.isode.stroke.base.ByteArray; +import java.util.TreeMap; +import java.util.Map; +import java.util.Vector; + +public class DIGESTMD5Properties { + + // Swiften uses std::multimap, but this is not required, so a TreeMap is used here. + private TreeMap properties = new TreeMap(); + + static boolean insideQuotes(final ByteArray v) { + if (v.isEmpty()) { + return false; + } + else if (v.getSize() == 1) { + return v.getData()[0] == '"'; + } + else if (v.getData()[0] == '"') { + return v.getData()[v.getSize() - 1] != '"'; + } + else { + return false; + } + } + + static ByteArray stripQuotes(final ByteArray v) { + String s = new String(v.getData()); // possibly with a charset + int size = v.getSize(); + int i = 0; + if(s.charAt(0) == '"') { + i++; + size--; + } + if(s.charAt(v.getSize() - 1) == '"') { + size--; + } + String data = s.substring(i, size+1); + return new ByteArray(data); + } + + public DIGESTMD5Properties() { + + } + + public String getValue(final String key) { + if (properties.containsKey(key)) { + return properties.get(key).toString(); + } + else { + return null; + } + } + + public void setValue(final String key, final String value) { + if(!(properties.containsKey(key))) { + properties.put(key, new ByteArray(value)); + } + } + + public ByteArray serialize() { + ByteArray result = new ByteArray(); + for(Map.Entry entry : properties.entrySet()) { + if(entry.getKey() != properties.firstKey()) { + result.append((byte)(',')); + } + result.append(new ByteArray(entry.getKey())); + result.append((byte)('=')); + if (isQuoted(entry.getKey())) { + result.append(new ByteArray("\"")); + result.append(entry.getValue()); //It does not iterate over all values possible for this key. So no need for MultiMap. Also serialize test also indicates the same. + result.append(new ByteArray("\"")); + } + else { + result.append(entry.getValue()); + } + } + return result; + } + + public static DIGESTMD5Properties parse(final ByteArray data) { + DIGESTMD5Properties result = new DIGESTMD5Properties(); + boolean inKey = true; + ByteArray currentKey = new ByteArray(); + ByteArray currentValue = new ByteArray(); + byte[] byteArrayData = data.getData(); + for (int i = 0; i < data.getSize(); ++i) { + char c = (char)(byteArrayData[i]); + if (inKey) { + if (c == '=') { + inKey = false; + } + else { + currentKey.append((byte)(c)); + } + } + else { + if (c == ',' && !insideQuotes(currentValue)) { + String key = currentKey.toString(); + if (isQuoted(key)) { + result.setValue(key, stripQuotes(currentValue).toString()); + } + else { + result.setValue(key, currentValue.toString()); + } + inKey = true; + currentKey = new ByteArray(); + currentValue = new ByteArray(); + } + else { + currentValue.append((byte)(c)); + } + } + } + + if (!currentKey.isEmpty()) { + String key = currentKey.toString(); + if (isQuoted(key)) { + result.setValue(key, stripQuotes(currentValue).toString()); + } + else { + result.setValue(key, currentValue.toString()); + } + } + + return result; + } + + private static boolean isQuoted(final String p) { + return p.equals("authzid") || p.equals("cnonce") || p.equals("digest-uri") || p.equals("nonce") || p.equals("realm") || p.equals("username"); + } +} diff --git a/src/com/isode/stroke/sasl/EXTERNALClientAuthenticator.java b/src/com/isode/stroke/sasl/EXTERNALClientAuthenticator.java new file mode 100644 index 0000000..9cd78d7 --- /dev/null +++ b/src/com/isode/stroke/sasl/EXTERNALClientAuthenticator.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012-2015 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.base.SafeByteArray; +import com.isode.stroke.base.ByteArray; + +public class EXTERNALClientAuthenticator extends ClientAuthenticator { + + private boolean finished; + + public EXTERNALClientAuthenticator() { + super("EXTERNAL"); + this.finished = false; + } + + public SafeByteArray getResponse() { + return null; + } + + public boolean setChallenge(final ByteArray byteArray) { + if (finished) { + return false; + } + finished = true; + return true; + } +} \ No newline at end of file diff --git a/src/com/isode/stroke/sasl/PLAINMessage.java b/src/com/isode/stroke/sasl/PLAINMessage.java new file mode 100644 index 0000000..5c1fe8b --- /dev/null +++ b/src/com/isode/stroke/sasl/PLAINMessage.java @@ -0,0 +1,75 @@ +/* + * 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.base.SafeByteArray; +import com.isode.stroke.base.ByteArray; + +public class PLAINMessage { + + private String authcid = ""; + private String authzid = ""; + private SafeByteArray password = new SafeByteArray(); + + public PLAINMessage(final String authcid, final SafeByteArray password) { + this(authcid, password, ""); + } + + public PLAINMessage(final String authcid, final SafeByteArray password, final String authzid) { + this.authcid = authcid; + this.password = password; + this.authzid = authzid; + } + + public PLAINMessage(final SafeByteArray value) { + int i = 0; + byte[] byteArrayValue = value.getData(); + while (i < value.getSize() && byteArrayValue[i] != ((byte)0)) { + authzid += (char)(byteArrayValue[i]); + ++i; + } + if (i == value.getSize()) { + return; + } + ++i; + while (i < value.getSize() && byteArrayValue[i] != ((byte)0)) { + authcid += (char)(byteArrayValue[i]); + ++i; + } + if (i == value.getSize()) { + authcid = ""; + return; + } + ++i; + while (i < value.getSize()) { + password.append(byteArrayValue[i]); + ++i; + } + } + + public SafeByteArray getValue() { + return new SafeByteArray().append(authzid).append((byte)0).append(authcid).append((byte)0).append(password); + } + + public String getAuthenticationID() { + return authcid; + } + + public SafeByteArray getPassword() { + return password; + } + + public String getAuthorizationID() { + return authzid; + } +} \ No newline at end of file diff --git a/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java b/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java index 29a37aa..9797e24 100644 --- a/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java +++ b/src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java @@ -10,10 +10,13 @@ package com.isode.stroke.sasl; import com.isode.stroke.base.ByteArray; import com.isode.stroke.base.SafeByteArray; +import com.ibm.icu.text.StringPrepParseException; import com.isode.stroke.stringcodecs.Base64; import com.isode.stroke.stringcodecs.HMACSHA1; import com.isode.stroke.stringcodecs.PBKDF2; import com.isode.stroke.stringcodecs.SHA1; +import com.isode.stroke.idn.IDNConverter; +import com.isode.stroke.crypto.CryptoProvider; import java.text.Normalizer; import java.text.Normalizer.Form; import java.util.HashMap; @@ -35,14 +38,13 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { return result; } - public SCRAMSHA1ClientAuthenticator(String nonce) { - this(nonce, false); - } - public SCRAMSHA1ClientAuthenticator(String nonce, boolean useChannelBinding) { + public SCRAMSHA1ClientAuthenticator(String nonce, boolean useChannelBinding, IDNConverter idnConverter, CryptoProvider crypto) { super(useChannelBinding ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1"); step = Step.Initial; clientnonce = nonce; this.useChannelBinding = useChannelBinding; + this.idnConverter = idnConverter; + this.crypto = crypto; } public void setTLSChannelBindingData(ByteArray channelBindingData) { @@ -53,9 +55,9 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { if (step.equals(Step.Initial)) { return new SafeByteArray(getGS2Header().append(getInitialBareClientMessage())); } else if (step.equals(Step.Proof)) { - ByteArray clientKey = HMACSHA1.getResult(saltedPassword, new ByteArray("Client Key")); - ByteArray storedKey = SHA1.getHash(clientKey); - ByteArray clientSignature = HMACSHA1.getResult(storedKey, authMessage); + ByteArray clientKey = crypto.getHMACSHA1(saltedPassword, new ByteArray("Client Key")); + ByteArray storedKey = crypto.getSHA1Hash(clientKey); + ByteArray clientSignature = crypto.getHMACSHA1(new SafeByteArray(storedKey), authMessage); ByteArray clientProof = clientKey; byte[] clientProofData = clientProof.getData(); for (int i = 0; i < clientProofData.length; ++i) { @@ -104,16 +106,21 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { return false; } + //Not Sure, why this here. ByteArray channelBindData = new ByteArray(); if (useChannelBinding && tlsChannelBindingData != null) { channelBindData = tlsChannelBindingData; } // Compute all the values needed for the server signature - saltedPassword = PBKDF2.encode(new ByteArray(SASLPrep(getPassword())), salt, iterations); + try { + saltedPassword = PBKDF2.encode(idnConverter.getStringPrepared(getPassword(), IDNConverter.StringPrepProfile.SASLPrep), salt, iterations, crypto); + } catch (StringPrepParseException e) { + + } authMessage = getInitialBareClientMessage().append(",").append(initialServerMessage).append(",").append(getFinalMessageWithoutProof()); - ByteArray serverKey = HMACSHA1.getResult(saltedPassword, new ByteArray("Server Key")); - serverSignature = HMACSHA1.getResult(serverKey, authMessage); + ByteArray serverKey = crypto.getHMACSHA1(saltedPassword, new ByteArray("Server Key")); + serverSignature = crypto.getHMACSHA1(serverKey, authMessage); step = Step.Proof; return true; @@ -126,10 +133,6 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { } } - private String SASLPrep(String source) { - return Normalizer.normalize(source, Form.NFKC); /* FIXME: Implement real SASLPrep */ - } - private Map parseMap(String s) { HashMap result = new HashMap(); if (s.length() > 0) { @@ -157,7 +160,12 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { } private ByteArray getInitialBareClientMessage() { - String authenticationID = SASLPrep(getAuthenticationID()); + String authenticationID = ""; + try { + authenticationID = idnConverter.getStringPrepared(getAuthenticationID(), IDNConverter.StringPrepProfile.SASLPrep); + } catch (StringPrepParseException e) { + + } return new ByteArray("n=" + escape(authenticationID) + ",r=" + clientnonce); } @@ -198,4 +206,6 @@ public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator { private ByteArray serverSignature = new ByteArray(); private boolean useChannelBinding; private ByteArray tlsChannelBindingData; + private IDNConverter idnConverter; + private CryptoProvider crypto; } diff --git a/src/com/isode/stroke/stringcodecs/PBKDF2.java b/src/com/isode/stroke/stringcodecs/PBKDF2.java index 1392d2f..6147ee4 100644 --- a/src/com/isode/stroke/stringcodecs/PBKDF2.java +++ b/src/com/isode/stroke/stringcodecs/PBKDF2.java @@ -9,16 +9,18 @@ package com.isode.stroke.stringcodecs; import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; +import com.isode.stroke.crypto.CryptoProvider; public class PBKDF2 { - public static ByteArray encode(ByteArray password, ByteArray salt, int iterations) { - ByteArray u = HMACSHA1.getResult(password, ByteArray.plus(salt, new ByteArray("\0\0\0\1"))); + public static ByteArray encode(SafeByteArray password, ByteArray salt, int iterations, CryptoProvider crypto) { + ByteArray u = crypto.getHMACSHA1(password, ByteArray.plus(salt, new ByteArray("\0\0\0\1"))); ByteArray result = new ByteArray(u); byte[] resultData = result.getData(); int i = 1; while (i < iterations) { - u = HMACSHA1.getResult(password, u); + u = crypto.getHMACSHA1(password, u); for (int j = 0; j < u.getSize(); ++j) { resultData[j] ^= u.getData()[j]; } diff --git a/test/com/isode/stroke/pubsub/Client.java b/test/com/isode/stroke/pubsub/Client.java index c68ba96..5a0059d 100644 --- a/test/com/isode/stroke/pubsub/Client.java +++ b/test/com/isode/stroke/pubsub/Client.java @@ -22,7 +22,7 @@ public class Client { static boolean debugInfo = false; static boolean debugInfoXml = false; - public Client(String name, JID jid, String password, JavaNetworkFactories networkFactories, final Slot connectCallback) { + public Client(String name, JID jid, SafeByteArray password, JavaNetworkFactories networkFactories, final Slot connectCallback) { name_ = name; connecting_ = true; connected_ = false; diff --git a/test/com/isode/stroke/pubsub/TestMain.java b/test/com/isode/stroke/pubsub/TestMain.java index 2088898..40b46e0 100644 --- a/test/com/isode/stroke/pubsub/TestMain.java +++ b/test/com/isode/stroke/pubsub/TestMain.java @@ -40,15 +40,16 @@ import com.isode.stroke.jid.JID; import com.isode.stroke.network.JavaNetworkFactories; import com.isode.stroke.signals.Slot; import com.isode.stroke.signals.Slot2; +import com.isode.stroke.base.SafeByteArray; public class TestMain { /* begin test parameters */ static String _server = "stan.isode.net"; static String _pubJID = "test1@stan.isode.net"; - static String _pubPass = "password"; + static SafeByteArray _pubPass = new SafeByteArray("password"); static String _subJID = "test2@stan.isode.net"; - static String _subPass = "password"; + static SafeByteArray _subPass = new SafeByteArray("password"); static String _pubSubDomain = "pubsub.stan.isode.net"; static String _pubSubNode = "testnode"; /* end test parameters */ diff --git a/test/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticatorTest.java b/test/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticatorTest.java new file mode 100644 index 0000000..92c8b7c --- /dev/null +++ b/test/com/isode/stroke/sasl/DIGESTMD5ClientAuthenticatorTest.java @@ -0,0 +1,72 @@ +/* + * 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.Before; +import com.isode.stroke.sasl.DIGESTMD5ClientAuthenticator; +import com.isode.stroke.base.ByteArray; +import com.isode.stroke.base.SafeByteArray; +import com.isode.stroke.crypto.CryptoProvider; +import com.isode.stroke.crypto.JavaCryptoProvider; + +public class DIGESTMD5ClientAuthenticatorTest { + + private CryptoProvider crypto; + + @Before + public void setUp() { + crypto = new JavaCryptoProvider(); + } + + @Test + public void testGetInitialResponse() { + DIGESTMD5ClientAuthenticator testling = new DIGESTMD5ClientAuthenticator("xmpp.example.com", "abcdefgh", crypto); + + assertNull(testling.getResponse()); + } + + @Test + public void testGetResponse() { + DIGESTMD5ClientAuthenticator testling = new DIGESTMD5ClientAuthenticator("xmpp.example.com", "abcdefgh", crypto); + + testling.setCredentials("user", new SafeByteArray("pass"), ""); + testling.setChallenge(new ByteArray( + "realm=\"example.com\"," + + "nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\"," + + "qop=auth,charset=utf-8,algorithm=md5-sess")); + + SafeByteArray response = testling.getResponse(); + + assertEquals(new SafeByteArray("charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=088891c800ecff1b842159ad6459104a,username=\"user\""), response); + } + + @Test + public void testGetResponse_WithAuthorizationID() { + DIGESTMD5ClientAuthenticator testling = new DIGESTMD5ClientAuthenticator("xmpp.example.com", "abcdefgh", crypto); + + testling.setCredentials("user", new SafeByteArray("pass"), "myauthzid"); + testling.setChallenge(new ByteArray( + "realm=\"example.com\"," + + "nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\"," + + "qop=auth,charset=utf-8,algorithm=md5-sess")); + + SafeByteArray response = testling.getResponse(); + + assertEquals(new SafeByteArray("authzid=\"myauthzid\",charset=utf-8,cnonce=\"abcdefgh\",digest-uri=\"xmpp/xmpp.example.com\",nc=00000001,nonce=\"O6skKPuaCZEny3hteI19qXMBXSadoWs840MchORo\",qop=auth,realm=\"example.com\",response=4293834432b6e7889a2dee7e8fe7dd06,username=\"user\""), response); + } +} diff --git a/test/com/isode/stroke/sasl/DIGESTMD5PropertiesTest.java b/test/com/isode/stroke/sasl/DIGESTMD5PropertiesTest.java new file mode 100644 index 0000000..1288b2f --- /dev/null +++ b/test/com/isode/stroke/sasl/DIGESTMD5PropertiesTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.Before; +import com.isode.stroke.sasl.DIGESTMD5Properties; +import com.isode.stroke.base.ByteArray; + +public class DIGESTMD5PropertiesTest { + + @Test + public void testParse() { + DIGESTMD5Properties properties = DIGESTMD5Properties.parse(new ByteArray( + "realm=\"myrealm1\",realm=\"myrealm2\",nonce=\"mynonce\"," + + "algorithm=md5-sess,charset=utf-8")); + + assertNotNull(properties.getValue("realm")); + assertEquals(("myrealm1"), properties.getValue("realm")); + assertNotNull(properties.getValue("nonce")); + assertEquals(("mynonce"), properties.getValue("nonce")); + assertNotNull(properties.getValue("algorithm")); + assertEquals(("md5-sess"), properties.getValue("algorithm")); + assertNotNull(properties.getValue("charset")); + assertEquals(("utf-8"), properties.getValue("charset")); + } + + @Test + public void testSerialize() { + DIGESTMD5Properties properties = new DIGESTMD5Properties(); + properties.setValue("authzid", "myauthzid"); + properties.setValue("charset", "utf-8"); + properties.setValue("cnonce", "mycnonce"); + properties.setValue("digest-uri", "mydigesturi"); + properties.setValue("nc", "1"); + properties.setValue("nonce", "mynonce"); + properties.setValue("qop", "auth"); + properties.setValue("realm", "myrealm"); + properties.setValue("response", "myresponse"); + properties.setValue("username", "myuser"); + + ByteArray result = properties.serialize(); + ByteArray expected = new ByteArray("authzid=\"myauthzid\",charset=utf-8,cnonce=\"mycnonce\",digest-uri=\"mydigesturi\",nc=1,nonce=\"mynonce\",qop=auth,realm=\"myrealm\",response=myresponse,username=\"myuser\""); + assertEquals(expected.toString(), result.toString()); + } +} \ No newline at end of file diff --git a/test/com/isode/stroke/sasl/PLAINClientAuthenticatorTest.java b/test/com/isode/stroke/sasl/PLAINClientAuthenticatorTest.java new file mode 100644 index 0000000..2f9170b --- /dev/null +++ b/test/com/isode/stroke/sasl/PLAINClientAuthenticatorTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.Before; +import com.isode.stroke.sasl.PLAINClientAuthenticator; +import com.isode.stroke.base.SafeByteArray; + +public class PLAINClientAuthenticatorTest { + + @Test + public void testGetResponse_WithoutAuthzID() { + PLAINClientAuthenticator testling = new PLAINClientAuthenticator(); + + testling.setCredentials("user", new SafeByteArray("pass")); + + assertEquals(testling.getResponse(), new SafeByteArray("\0user\0pass")); + } + + @Test + public void testGetResponse_WithAuthzID() { + PLAINClientAuthenticator testling = new PLAINClientAuthenticator(); + + testling.setCredentials("user", new SafeByteArray("pass"), "authz"); + + assertEquals(testling.getResponse(), new SafeByteArray("authz\0user\0pass")); + } +} \ No newline at end of file diff --git a/test/com/isode/stroke/sasl/PLAINMessageTest.java b/test/com/isode/stroke/sasl/PLAINMessageTest.java new file mode 100644 index 0000000..de7f5ee --- /dev/null +++ b/test/com/isode/stroke/sasl/PLAINMessageTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010 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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.Before; +import com.isode.stroke.sasl.PLAINMessage; +import com.isode.stroke.base.SafeByteArray; + +public class PLAINMessageTest { + + @Test + public void testGetValue_WithoutAuthzID() { + PLAINMessage message = new PLAINMessage("user", new SafeByteArray("pass")); + assertEquals(message.getValue(), new SafeByteArray("\0user\0pass")); + } + + @Test + public void testGetValue_WithAuthzID() { + PLAINMessage message = new PLAINMessage("user", new SafeByteArray("pass"), "authz"); + assertEquals(message.getValue(), new SafeByteArray("authz\0user\0pass")); + } + + @Test + public void testConstructor_WithoutAuthzID() { + PLAINMessage message = new PLAINMessage(new SafeByteArray("\0user\0pass")); + + assertEquals((""), message.getAuthorizationID()); + assertEquals(("user"), message.getAuthenticationID()); + assertEquals(new SafeByteArray("pass"), message.getPassword()); + } + + @Test + public void testConstructor_WithAuthzID() { + PLAINMessage message = new PLAINMessage(new SafeByteArray("authz\0user\0pass")); + + assertEquals(("authz"), message.getAuthorizationID()); + assertEquals(("user"), message.getAuthenticationID()); + assertEquals(new SafeByteArray("pass"), message.getPassword()); + } + + @Test + public void testConstructor_NoAuthcid() { + PLAINMessage message = new PLAINMessage(new SafeByteArray("authzid")); + + assertEquals((""), message.getAuthenticationID()); + } + + @Test + public void testConstructor_NoPassword() { + PLAINMessage message = new PLAINMessage(new SafeByteArray("authzid\0authcid")); + + assertEquals((""), message.getAuthenticationID()); + } +} diff --git a/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java b/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java index 7217d8d..9969ebd 100644 --- a/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java +++ b/test/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticatorTest.java @@ -14,6 +14,10 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; +import com.isode.stroke.idn.IDNConverter; +import com.isode.stroke.idn.ICUConverter; +import com.isode.stroke.crypto.CryptoProvider; +import com.isode.stroke.crypto.JavaCryptoProvider; /** * @@ -21,107 +25,116 @@ import static org.junit.Assert.*; */ public class SCRAMSHA1ClientAuthenticatorTest { + private IDNConverter idnConverter; + private CryptoProvider crypto; + + @Before + public void setUp() { + idnConverter = new ICUConverter(); + crypto = new JavaCryptoProvider(); + } + @Test public void testGetInitialResponse() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("n,,n=user,r=abcdefghABCDEFGH"), response); + assertEquals(new SafeByteArray("n,,n=user,r=abcdefghABCDEFGH"), response); } @Test public void testGetInitialResponse_UsernameHasSpecialChars() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); - testling.setCredentials(",us=,er=", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", false, idnConverter, crypto); + testling.setCredentials(",us=,er=", new SafeByteArray("pass"), ""); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), response); + assertEquals(new SafeByteArray("n,,n==2Cus=3D=2Cer=3D,r=abcdefghABCDEFGH"), response); } @Test public void testGetInitialResponse_WithAuthorizationID() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); - testling.setCredentials("user", "pass", "auth"); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), "auth"); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("n,a=auth,n=user,r=abcdefghABCDEFGH"), response); + assertEquals(new SafeByteArray("n,a=auth,n=user,r=abcdefghABCDEFGH"), response); } @Test public void testGetInitialResponse_WithAuthorizationIDWithSpecialChars() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH"); - testling.setCredentials("user", "pass", "a=u,th"); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), "a=u,th"); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), response); + assertEquals(new SafeByteArray("n,a=a=3Du=2Cth,n=user,r=abcdefghABCDEFGH"), response); } @Test public void testGetInitialResponse_WithoutChannelBindingWithTLSChannelBindingData() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", false); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", false, idnConverter, crypto); testling.setTLSChannelBindingData(new ByteArray("xyza")); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", new SafeByteArray("pass"), ""); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("y,,n=user,r=abcdefghABCDEFGH"), response); + assertEquals(new SafeByteArray("y,,n=user,r=abcdefghABCDEFGH"), response); } @Test public void testGetInitialResponse_WithChannelBindingWithTLSChannelBindingData() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", true); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefghABCDEFGH", true, idnConverter, crypto); testling.setTLSChannelBindingData(new ByteArray("xyza")); - testling.setCredentials("user", "pass", ""); + testling.setCredentials("user", new SafeByteArray("pass"), ""); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), response); + assertEquals(new SafeByteArray("p=tls-unique,,n=user,r=abcdefghABCDEFGH"), response); } @Test public void testGetFinalResponse() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); assertTrue(testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096"))); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), response); + assertEquals(new SafeByteArray("c=biws,r=abcdefghABCDEFGH,p=CZbjGDpIteIJwQNBgO0P8pKkMGY="), response); } @Test public void testGetFinalResponse_WithoutChannelBindingWithTLSChannelBindingData() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); testling.setTLSChannelBindingData(new ByteArray("xyza")); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), response); + assertEquals(new SafeByteArray("c=eSws,r=abcdefghABCDEFGH,p=JNpsiFEcxZvNZ1+FFBBqrYvYxMk="), response); } @Test public void testGetFinalResponse_WithChannelBindingWithTLSChannelBindingData() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", true); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", true, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); testling.setTLSChannelBindingData(new ByteArray("xyza")); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); SafeByteArray response = testling.getResponse(); - assertEquals(new ByteArray("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), response); + assertEquals(new SafeByteArray("c=cD10bHMtdW5pcXVlLCx4eXph,r=abcdefghABCDEFGH,p=i6Rghite81P1ype8XxaVAa5l7v0="), response); } @Test public void testSetFinalChallenge() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); boolean result = testling.setChallenge(new ByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); @@ -131,8 +144,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -141,8 +154,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge_InvalidClientNonce() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefgiABCDEFGH,s=MTIzNDU2NzgK,i=4096")); @@ -151,8 +164,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge_OnlyClientNonce() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefgh,s=MTIzNDU2NzgK,i=4096")); @@ -161,8 +174,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge_InvalidIterations() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=bla")); @@ -171,8 +184,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge_MissingIterations() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK")); @@ -181,8 +194,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge_ZeroIterations() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=0")); @@ -191,8 +204,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetChallenge_NegativeIterations() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); boolean result = testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=-1")); @@ -201,8 +214,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testSetFinalChallenge_InvalidChallenge() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); boolean result = testling.setChallenge(new ByteArray("v=e26kI69ICb6zosapLLxrER/631A=")); @@ -211,8 +224,8 @@ public class SCRAMSHA1ClientAuthenticatorTest { @Test public void testGetResponseAfterFinalChallenge() { - SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh"); - testling.setCredentials("user", "pass", ""); + SCRAMSHA1ClientAuthenticator testling = new SCRAMSHA1ClientAuthenticator("abcdefgh", false, idnConverter, crypto); + testling.setCredentials("user", new SafeByteArray("pass"), ""); testling.setChallenge(new ByteArray("r=abcdefghABCDEFGH,s=MTIzNDU2NzgK,i=4096")); testling.setChallenge(new ByteArray("v=Dd+Q20knZs9jeeK0pi1Mx1Se+yo=")); -- cgit v0.10.2-6-g49f6