fixed #30 - added support for digest-md5 - only works with Icewarp 11???git add src/?
This commit is contained in:
		
							parent
							
								
									aed5b01434
								
							
						
					
					
						commit
						601e5ca33e
					
				| 
						 | 
				
			
			@ -1,15 +1,23 @@
 | 
			
		|||
package eu.siacs.conversations.utils;
 | 
			
		||||
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
import java.security.MessageDigest;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.SecureRandom;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
import eu.siacs.conversations.entities.Account;
 | 
			
		||||
 | 
			
		||||
import android.util.Base64;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
public class CryptoHelper {
 | 
			
		||||
	final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
 | 
			
		||||
	final protected static char[] vowels = "aeiou".toCharArray();
 | 
			
		||||
	final protected static char[] consonants ="bcdfghjklmnpqrstvwxyz".toCharArray();
 | 
			
		||||
	final protected static char[] consonants = "bcdfghjklmnpqrstvwxyz"
 | 
			
		||||
			.toCharArray();
 | 
			
		||||
 | 
			
		||||
	public static String bytesToHex(byte[] bytes) {
 | 
			
		||||
		char[] hexChars = new char[bytes.length * 2];
 | 
			
		||||
		for (int j = 0; j < bytes.length; j++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -17,11 +25,71 @@ public class CryptoHelper {
 | 
			
		|||
			hexChars[j * 2] = hexArray[v >>> 4];
 | 
			
		||||
			hexChars[j * 2 + 1] = hexArray[v & 0x0F];
 | 
			
		||||
		}
 | 
			
		||||
	    return new String(hexChars);
 | 
			
		||||
		return new String(hexChars).toLowerCase();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static String saslPlain(String username, String password) {
 | 
			
		||||
		String sasl = '\u0000' + username + '\u0000' + password;
 | 
			
		||||
		return Base64.encodeToString(sasl.getBytes(Charset.defaultCharset()),Base64.NO_WRAP);
 | 
			
		||||
		return Base64.encodeToString(sasl.getBytes(Charset.defaultCharset()),
 | 
			
		||||
				Base64.NO_WRAP);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static byte[] concatenateByteArrays(byte[] a, byte[] b) {
 | 
			
		||||
	    byte[] result = new byte[a.length + b.length]; 
 | 
			
		||||
	    System.arraycopy(a, 0, result, 0, a.length); 
 | 
			
		||||
	    System.arraycopy(b, 0, result, a.length, b.length); 
 | 
			
		||||
	    return result;
 | 
			
		||||
	} 
 | 
			
		||||
	
 | 
			
		||||
	public static String saslDigestMd5(Account account, String challenge) {
 | 
			
		||||
		try {
 | 
			
		||||
			Random random = new SecureRandom();
 | 
			
		||||
			Log.d("xmppService",
 | 
			
		||||
					"challenge="
 | 
			
		||||
							+ new String(Base64.decode(challenge,
 | 
			
		||||
									Base64.DEFAULT)));
 | 
			
		||||
			String[] challengeParts = new String(Base64.decode(challenge,
 | 
			
		||||
					Base64.DEFAULT)).split(",");
 | 
			
		||||
			String nonce = "";
 | 
			
		||||
			for (int i = 0; i < challengeParts.length; ++i) {
 | 
			
		||||
				String[] parts = challengeParts[i].split("=");
 | 
			
		||||
				if (parts[0].equals("nonce")) {
 | 
			
		||||
					nonce = parts[1].replace("\"", "");
 | 
			
		||||
				} else if (parts[0].equals("rspauth")) {
 | 
			
		||||
					return null;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			String digestUri = "xmpp/"+account.getServer();
 | 
			
		||||
			String nonceCount = "00000001";
 | 
			
		||||
			String x = account.getUsername() + ":" + account.getServer() + ":"
 | 
			
		||||
					+ account.getPassword();
 | 
			
		||||
			MessageDigest md = MessageDigest.getInstance("MD5");
 | 
			
		||||
			byte[] y = md
 | 
			
		||||
					.digest(x.getBytes(Charset.defaultCharset()));
 | 
			
		||||
			String cNonce = new BigInteger(100, random).toString(32);
 | 
			
		||||
			Log.d("xmppService", "conce=" + cNonce);
 | 
			
		||||
			byte[] a1 = concatenateByteArrays(y,(":"+nonce+":"+cNonce).getBytes(Charset.defaultCharset()));
 | 
			
		||||
			String a2 = "AUTHENTICATE:"+digestUri;
 | 
			
		||||
			String ha1 = bytesToHex(md.digest(a1));
 | 
			
		||||
			String ha2 = bytesToHex(md.digest(a2.getBytes(Charset
 | 
			
		||||
					.defaultCharset())));
 | 
			
		||||
			String kd = ha1 + ":" + nonce + ":"+nonceCount+":" + cNonce + ":auth:"
 | 
			
		||||
					+ ha2;
 | 
			
		||||
			Log.d("xmppService", "kd=" + kd);
 | 
			
		||||
			String response = bytesToHex(md.digest(kd.getBytes(Charset
 | 
			
		||||
					.defaultCharset())));
 | 
			
		||||
			String saslString = "username=\"" + account.getUsername()
 | 
			
		||||
					+ "\",realm=\"" + account.getServer() + "\",nonce=\""
 | 
			
		||||
					+ nonce + "\",cnonce=\"" + cNonce
 | 
			
		||||
					+ "\",nc="+nonceCount+",qop=auth,digest-uri=\""+digestUri+"\",response=" + response
 | 
			
		||||
					+ ",charset=utf-8,authzid=\"" + account.getJid() + "\"";
 | 
			
		||||
			Log.d("xmppService", "saslString=" + saslString);
 | 
			
		||||
			return Base64.encodeToString(
 | 
			
		||||
					saslString.getBytes(Charset.defaultCharset()),
 | 
			
		||||
					Base64.NO_WRAP);
 | 
			
		||||
		} catch (NoSuchAlgorithmException e) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static String randomMucName() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -210,11 +210,16 @@ public class XmppConnection implements Runnable {
 | 
			
		|||
				processStream(tagReader.readTag());
 | 
			
		||||
				break;
 | 
			
		||||
			} else if (nextTag.isStart("failure")) {
 | 
			
		||||
				tagReader.readElement(nextTag);
 | 
			
		||||
				Element failure = tagReader.readElement(nextTag);
 | 
			
		||||
				Log.d(LOGTAG,"login failure"+failure);
 | 
			
		||||
				changeStatus(Account.STATUS_UNAUTHORIZED);
 | 
			
		||||
			} else if (nextTag.isStart("challenge")) {
 | 
			
		||||
				String challange = tagReader.readElement(nextTag).getContent();
 | 
			
		||||
				Log.d(LOGTAG,"a challange arrived! "+challange);
 | 
			
		||||
				Element response = new Element("response");
 | 
			
		||||
				response.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl");
 | 
			
		||||
				response.setContent(CryptoHelper.saslDigestMd5(account, challange));
 | 
			
		||||
				Log.d(LOGTAG,response.toString());
 | 
			
		||||
				tagWriter.writeElement(response);
 | 
			
		||||
			} else if (nextTag.isStart("enabled")) {
 | 
			
		||||
				this.stanzasSent = 0;
 | 
			
		||||
				Element enabled = tagReader.readElement(nextTag);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue