treat omemo keys >= 32 bytes as containing auth tag. add config flag to put auth tag in key
This commit is contained in:
		
							parent
							
								
									a1cb855739
								
							
						
					
					
						commit
						f0c3b31a42
					
				| @ -83,6 +83,7 @@ public final class Config { | |||||||
| 	public static final long OMEMO_AUTO_EXPIRY = 7 * MILLISECONDS_IN_DAY; | 	public static final long OMEMO_AUTO_EXPIRY = 7 * MILLISECONDS_IN_DAY; | ||||||
| 	public static final boolean REMOVE_BROKEN_DEVICES = false; | 	public static final boolean REMOVE_BROKEN_DEVICES = false; | ||||||
| 	public static final boolean OMEMO_PADDING = false; | 	public static final boolean OMEMO_PADDING = false; | ||||||
|  | 	public static boolean PUT_AUTH_TAG_INTO_KEY = false; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb | 	public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb | ||||||
|  | |||||||
| @ -1007,14 +1007,11 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	private XmppAxolotlMessage buildHeader(Conversation conversation) { | 	private boolean buildHeader(XmppAxolotlMessage axolotlMessage, Conversation conversation) { | ||||||
| 		final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage( |  | ||||||
| 				account.getJid().toBareJid(), getOwnDeviceId()); |  | ||||||
| 
 |  | ||||||
| 		Set<XmppAxolotlSession> remoteSessions = findSessionsForConversation(conversation); | 		Set<XmppAxolotlSession> remoteSessions = findSessionsForConversation(conversation); | ||||||
| 		Collection<XmppAxolotlSession> ownSessions = findOwnSessions(); | 		Collection<XmppAxolotlSession> ownSessions = findOwnSessions(); | ||||||
| 		if (remoteSessions.isEmpty()) { | 		if (remoteSessions.isEmpty()) { | ||||||
| 			return null; | 			return false; | ||||||
| 		} | 		} | ||||||
| 		for (XmppAxolotlSession session : remoteSessions) { | 		for (XmppAxolotlSession session : remoteSessions) { | ||||||
| 			axolotlMessage.addDevice(session); | 			axolotlMessage.addDevice(session); | ||||||
| @ -1023,14 +1020,12 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 			axolotlMessage.addDevice(session); | 			axolotlMessage.addDevice(session); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return axolotlMessage; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	public XmppAxolotlMessage encrypt(Message message) { | 	public XmppAxolotlMessage encrypt(Message message) { | ||||||
| 		XmppAxolotlMessage axolotlMessage = buildHeader(message.getConversation()); | 		final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().toBareJid(), getOwnDeviceId()); | ||||||
| 
 |  | ||||||
| 		if (axolotlMessage != null) { |  | ||||||
| 		final String content; | 		final String content; | ||||||
| 		if (message.hasFileOnRemoteHost()) { | 		if (message.hasFileOnRemoteHost()) { | ||||||
| 			content = message.getFileParams().url.toString(); | 			content = message.getFileParams().url.toString(); | ||||||
| @ -1043,6 +1038,8 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 			Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage()); | 			Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage()); | ||||||
| 			return null; | 			return null; | ||||||
| 		} | 		} | ||||||
|  | 		if (!buildHeader(axolotlMessage,message.getConversation())) { | ||||||
|  | 			return null; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return axolotlMessage; | 		return axolotlMessage; | ||||||
| @ -1069,8 +1066,12 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { | |||||||
| 		executor.execute(new Runnable() { | 		executor.execute(new Runnable() { | ||||||
| 			@Override | 			@Override | ||||||
| 			public void run() { | 			public void run() { | ||||||
| 				XmppAxolotlMessage axolotlMessage = buildHeader(conversation); | 				final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().toBareJid(), getOwnDeviceId()); | ||||||
|  | 				if (buildHeader(axolotlMessage,conversation)) { | ||||||
| 					onMessageCreatedCallback.run(axolotlMessage); | 					onMessageCreatedCallback.run(axolotlMessage); | ||||||
|  | 				} else { | ||||||
|  | 					onMessageCreatedCallback.run(null); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ package eu.siacs.conversations.crypto.axolotl; | |||||||
| import android.util.Base64; | import android.util.Base64; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
| 
 | 
 | ||||||
| import org.whispersystems.libaxolotl.protocol.CiphertextMessage; |  | ||||||
| 
 | 
 | ||||||
| import java.security.InvalidAlgorithmParameterException; | import java.security.InvalidAlgorithmParameterException; | ||||||
| import java.security.InvalidKeyException; | import java.security.InvalidKeyException; | ||||||
| @ -24,6 +23,7 @@ import javax.crypto.spec.IvParameterSpec; | |||||||
| import javax.crypto.spec.SecretKeySpec; | import javax.crypto.spec.SecretKeySpec; | ||||||
| 
 | 
 | ||||||
| import eu.siacs.conversations.Config; | import eu.siacs.conversations.Config; | ||||||
|  | import eu.siacs.conversations.utils.CryptoHelper; | ||||||
| import eu.siacs.conversations.xml.Element; | import eu.siacs.conversations.xml.Element; | ||||||
| import eu.siacs.conversations.xmpp.jid.Jid; | import eu.siacs.conversations.xmpp.jid.Jid; | ||||||
| 
 | 
 | ||||||
| @ -42,6 +42,7 @@ public class XmppAxolotlMessage { | |||||||
| 
 | 
 | ||||||
| 	private byte[] innerKey; | 	private byte[] innerKey; | ||||||
| 	private byte[] ciphertext = null; | 	private byte[] ciphertext = null; | ||||||
|  | 	private byte[] authtagPlusInnerKey = null; | ||||||
| 	private byte[] iv = null; | 	private byte[] iv = null; | ||||||
| 	private final Map<Integer, XmppAxolotlSession.AxolotlKey> keys; | 	private final Map<Integer, XmppAxolotlSession.AxolotlKey> keys; | ||||||
| 	private final Jid from; | 	private final Jid from; | ||||||
| @ -166,6 +167,14 @@ public class XmppAxolotlMessage { | |||||||
| 			Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER); | 			Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER); | ||||||
| 			cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); | 			cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); | ||||||
| 			this.ciphertext = cipher.doFinal(Config.OMEMO_PADDING ? getPaddedBytes(plaintext) : plaintext.getBytes()); | 			this.ciphertext = cipher.doFinal(Config.OMEMO_PADDING ? getPaddedBytes(plaintext) : plaintext.getBytes()); | ||||||
|  | 			if (Config.PUT_AUTH_TAG_INTO_KEY && this.ciphertext != null) { | ||||||
|  | 				this.authtagPlusInnerKey = new byte[16+16]; | ||||||
|  | 				byte[] ciphertext = new byte[this.ciphertext.length - 16]; | ||||||
|  | 				System.arraycopy(this.ciphertext,0,ciphertext,0,ciphertext.length); | ||||||
|  | 				System.arraycopy(this.ciphertext,ciphertext.length,authtagPlusInnerKey,16,16); | ||||||
|  | 				System.arraycopy(this.innerKey,0,authtagPlusInnerKey,0,this.innerKey.length); | ||||||
|  | 				this.ciphertext = ciphertext; | ||||||
|  | 			} | ||||||
| 		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | 		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | ||||||
| 				| IllegalBlockSizeException | BadPaddingException | NoSuchProviderException | 				| IllegalBlockSizeException | BadPaddingException | NoSuchProviderException | ||||||
| 				| InvalidAlgorithmParameterException e) { | 				| InvalidAlgorithmParameterException e) { | ||||||
| @ -202,7 +211,12 @@ public class XmppAxolotlMessage { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void addDevice(XmppAxolotlSession session) { | 	public void addDevice(XmppAxolotlSession session) { | ||||||
| 		XmppAxolotlSession.AxolotlKey key = session.processSending(innerKey); | 		XmppAxolotlSession.AxolotlKey key; | ||||||
|  | 		if (authtagPlusInnerKey != null) { | ||||||
|  | 			key = session.processSending(authtagPlusInnerKey); | ||||||
|  | 		} else { | ||||||
|  | 			key = session.processSending(innerKey); | ||||||
|  | 		} | ||||||
| 		if (key != null) { | 		if (key != null) { | ||||||
| 			keys.put(session.getRemoteAddress().getDeviceId(), key); | 			keys.put(session.getRemoteAddress().getDeviceId(), key); | ||||||
| 		} | 		} | ||||||
| @ -254,6 +268,19 @@ public class XmppAxolotlMessage { | |||||||
| 		byte[] key = unpackKey(session, sourceDeviceId); | 		byte[] key = unpackKey(session, sourceDeviceId); | ||||||
| 		if (key != null) { | 		if (key != null) { | ||||||
| 			try { | 			try { | ||||||
|  | 
 | ||||||
|  | 				if (key.length >= 32) { | ||||||
|  | 					int authtaglength = key.length - 16; | ||||||
|  | 					Log.d(Config.LOGTAG,"found auth tag as part of omemo key"); | ||||||
|  | 					byte[] newCipherText = new byte[key.length - 16  + ciphertext.length]; | ||||||
|  | 					byte[] newKey = new byte[16]; | ||||||
|  | 					System.arraycopy(ciphertext, 0, newCipherText, 0, ciphertext.length); | ||||||
|  | 					System.arraycopy(key, 16, newCipherText, ciphertext.length, authtaglength); | ||||||
|  | 					System.arraycopy(key,0,newKey,0,newKey.length); | ||||||
|  | 					ciphertext = newCipherText; | ||||||
|  | 					key = newKey; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER); | 				Cipher cipher = Cipher.getInstance(CIPHERMODE, PROVIDER); | ||||||
| 				SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE); | 				SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE); | ||||||
| 				IvParameterSpec ivSpec = new IvParameterSpec(iv); | 				IvParameterSpec ivSpec = new IvParameterSpec(iv); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch