enable SASL EXTERNAL (certificate login
This commit is contained in:
parent
7be331bbb2
commit
b519411d34
|
@ -0,0 +1,29 @@
|
|||
package eu.siacs.conversations.crypto.sasl;
|
||||
|
||||
import android.util.Base64;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.xml.TagWriter;
|
||||
|
||||
public class External extends SaslMechanism {
|
||||
|
||||
public External(TagWriter tagWriter, Account account, SecureRandom rng) {
|
||||
super(tagWriter, account, rng);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMechanism() {
|
||||
return "EXTERNAL";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientFirstMessage() {
|
||||
return Base64.encodeToString(account.getJid().toBareJid().toString().getBytes(),Base64.NO_WRAP);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ import android.os.Parcelable;
|
|||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.SystemClock;
|
||||
import android.security.KeyChain;
|
||||
import android.security.KeyChainException;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
@ -33,7 +35,12 @@ import java.net.UnknownHostException;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -45,14 +52,17 @@ import java.util.List;
|
|||
import java.util.Map.Entry;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509KeyManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import de.duenndns.ssl.MemorizingTrustManager;
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.crypto.sasl.DigestMd5;
|
||||
import eu.siacs.conversations.crypto.sasl.External;
|
||||
import eu.siacs.conversations.crypto.sasl.Plain;
|
||||
import eu.siacs.conversations.crypto.sasl.SaslMechanism;
|
||||
import eu.siacs.conversations.crypto.sasl.ScramSha1;
|
||||
|
@ -126,6 +136,46 @@ public class XmppConnection implements Runnable {
|
|||
|
||||
private SaslMechanism saslMechanism;
|
||||
|
||||
private X509KeyManager mKeyManager = new X509KeyManager() {
|
||||
@Override
|
||||
public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
|
||||
return account.getPrivateKeyAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getCertificateChain(String alias) {
|
||||
try {
|
||||
return KeyChain.getCertificateChain(mXmppConnectionService, alias);
|
||||
} catch (Exception e) {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getClientAliases(String s, Principal[] principals) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getServerAliases(String s, Principal[] principals) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey(String alias) {
|
||||
try {
|
||||
return KeyChain.getPrivateKey(mXmppConnectionService, alias);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private OnIqPacketReceived createPacketReceiveHandler() {
|
||||
OnIqPacketReceived receiver = new OnIqPacketReceived() {
|
||||
@Override
|
||||
|
@ -551,7 +601,13 @@ public class XmppConnection implements Runnable {
|
|||
try {
|
||||
final SSLContext sc = SSLContext.getInstance("TLS");
|
||||
MemorizingTrustManager trustManager = this.mXmppConnectionService.getMemorizingTrustManager();
|
||||
sc.init(null,new X509TrustManager[]{mInteractive ? trustManager : trustManager.getNonInteractive()},mXmppConnectionService.getRNG());
|
||||
KeyManager[] keyManager;
|
||||
if (account.getPrivateKeyAlias() != null && account.getPassword().isEmpty()) {
|
||||
keyManager = new KeyManager[]{ mKeyManager };
|
||||
} else {
|
||||
keyManager = null;
|
||||
}
|
||||
sc.init(keyManager,new X509TrustManager[]{mInteractive ? trustManager : trustManager.getNonInteractive()},mXmppConnectionService.getRNG());
|
||||
final SSLSocketFactory factory = sc.getSocketFactory();
|
||||
final HostnameVerifier verifier;
|
||||
if (mInteractive) {
|
||||
|
@ -622,7 +678,9 @@ public class XmppConnection implements Runnable {
|
|||
.findChild("mechanisms"));
|
||||
final Element auth = new Element("auth");
|
||||
auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
|
||||
if (mechanisms.contains("SCRAM-SHA-1")) {
|
||||
if (mechanisms.contains("EXTERNAL")) {
|
||||
saslMechanism = new External(tagWriter, account, mXmppConnectionService.getRNG());
|
||||
} else if (mechanisms.contains("SCRAM-SHA-1")) {
|
||||
saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG());
|
||||
} else if (mechanisms.contains("PLAIN")) {
|
||||
saslMechanism = new Plain(tagWriter, account);
|
||||
|
|
Loading…
Reference in New Issue