adding prekey='true' to omemo messages if applicable
This commit is contained in:
		
							parent
							
								
									ef4ed90811
								
							
						
					
					
						commit
						a1cb855739
					
				| @ -3,6 +3,8 @@ 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; | ||||||
| import java.security.NoSuchAlgorithmException; | import java.security.NoSuchAlgorithmException; | ||||||
| @ -41,7 +43,7 @@ public class XmppAxolotlMessage { | |||||||
| 	private byte[] innerKey; | 	private byte[] innerKey; | ||||||
| 	private byte[] ciphertext = null; | 	private byte[] ciphertext = null; | ||||||
| 	private byte[] iv = null; | 	private byte[] iv = null; | ||||||
| 	private final Map<Integer, byte[]> keys; | 	private final Map<Integer, XmppAxolotlSession.AxolotlKey> keys; | ||||||
| 	private final Jid from; | 	private final Jid from; | ||||||
| 	private final int sourceDeviceId; | 	private final int sourceDeviceId; | ||||||
| 
 | 
 | ||||||
| @ -104,7 +106,8 @@ public class XmppAxolotlMessage { | |||||||
| 					try { | 					try { | ||||||
| 						Integer recipientId = Integer.parseInt(keyElement.getAttribute(REMOTEID)); | 						Integer recipientId = Integer.parseInt(keyElement.getAttribute(REMOTEID)); | ||||||
| 						byte[] key = Base64.decode(keyElement.getContent().trim(), Base64.DEFAULT); | 						byte[] key = Base64.decode(keyElement.getContent().trim(), Base64.DEFAULT); | ||||||
| 						this.keys.put(recipientId, key); | 						boolean isPreKey =keyElement.getAttributeAsBoolean("prekey"); | ||||||
|  | 						this.keys.put(recipientId, new XmppAxolotlSession.AxolotlKey(key,isPreKey)); | ||||||
| 					} catch (NumberFormatException e) { | 					} catch (NumberFormatException e) { | ||||||
| 						throw new IllegalArgumentException("invalid remote id"); | 						throw new IllegalArgumentException("invalid remote id"); | ||||||
| 					} | 					} | ||||||
| @ -199,7 +202,7 @@ public class XmppAxolotlMessage { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void addDevice(XmppAxolotlSession session) { | 	public void addDevice(XmppAxolotlSession session) { | ||||||
| 		byte[] key = session.processSending(innerKey); | 		XmppAxolotlSession.AxolotlKey key = session.processSending(innerKey); | ||||||
| 		if (key != null) { | 		if (key != null) { | ||||||
| 			keys.put(session.getRemoteAddress().getDeviceId(), key); | 			keys.put(session.getRemoteAddress().getDeviceId(), key); | ||||||
| 		} | 		} | ||||||
| @ -217,10 +220,13 @@ public class XmppAxolotlMessage { | |||||||
| 		Element encryptionElement = new Element(CONTAINERTAG, AxolotlService.PEP_PREFIX); | 		Element encryptionElement = new Element(CONTAINERTAG, AxolotlService.PEP_PREFIX); | ||||||
| 		Element headerElement = encryptionElement.addChild(HEADER); | 		Element headerElement = encryptionElement.addChild(HEADER); | ||||||
| 		headerElement.setAttribute(SOURCEID, sourceDeviceId); | 		headerElement.setAttribute(SOURCEID, sourceDeviceId); | ||||||
| 		for (Map.Entry<Integer, byte[]> keyEntry : keys.entrySet()) { | 		for (Map.Entry<Integer, XmppAxolotlSession.AxolotlKey> keyEntry : keys.entrySet()) { | ||||||
| 			Element keyElement = new Element(KEYTAG); | 			Element keyElement = new Element(KEYTAG); | ||||||
| 			keyElement.setAttribute(REMOTEID, keyEntry.getKey()); | 			keyElement.setAttribute(REMOTEID, keyEntry.getKey()); | ||||||
| 			keyElement.setContent(Base64.encodeToString(keyEntry.getValue(), Base64.NO_WRAP)); | 			if (keyEntry.getValue().prekey) { | ||||||
|  | 				keyElement.setAttribute("prekey","true"); | ||||||
|  | 			} | ||||||
|  | 			keyElement.setContent(Base64.encodeToString(keyEntry.getValue().key, Base64.NO_WRAP)); | ||||||
| 			headerElement.addChild(keyElement); | 			headerElement.addChild(keyElement); | ||||||
| 		} | 		} | ||||||
| 		headerElement.addChild(IVTAG).setContent(Base64.encodeToString(iv, Base64.NO_WRAP)); | 		headerElement.addChild(IVTAG).setContent(Base64.encodeToString(iv, Base64.NO_WRAP)); | ||||||
| @ -232,7 +238,7 @@ public class XmppAxolotlMessage { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private byte[] unpackKey(XmppAxolotlSession session, Integer sourceDeviceId) { | 	private byte[] unpackKey(XmppAxolotlSession session, Integer sourceDeviceId) { | ||||||
| 		byte[] encryptedKey = keys.get(sourceDeviceId); | 		XmppAxolotlSession.AxolotlKey encryptedKey = keys.get(sourceDeviceId); | ||||||
| 		return (encryptedKey != null) ? session.processReceiving(encryptedKey) : null; | 		return (encryptedKey != null) ? session.processReceiving(encryptedKey) : null; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -82,13 +82,13 @@ public class XmppAxolotlSession implements Comparable<XmppAxolotlSession> { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	public byte[] processReceiving(byte[] encryptedKey) { | 	public byte[] processReceiving(AxolotlKey encryptedKey) { | ||||||
| 		byte[] plaintext = null; | 		byte[] plaintext = null; | ||||||
| 		FingerprintStatus status = getTrust(); | 		FingerprintStatus status = getTrust(); | ||||||
| 		if (!status.isCompromised()) { | 		if (!status.isCompromised()) { | ||||||
| 			try { | 			try { | ||||||
| 				try { | 				try { | ||||||
| 					PreKeyWhisperMessage message = new PreKeyWhisperMessage(encryptedKey); | 					PreKeyWhisperMessage message = new PreKeyWhisperMessage(encryptedKey.key); | ||||||
| 					if (!message.getPreKeyId().isPresent()) { | 					if (!message.getPreKeyId().isPresent()) { | ||||||
| 						Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "PreKeyWhisperMessage did not contain a PreKeyId"); | 						Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "PreKeyWhisperMessage did not contain a PreKeyId"); | ||||||
| 						return null; | 						return null; | ||||||
| @ -104,7 +104,7 @@ public class XmppAxolotlSession implements Comparable<XmppAxolotlSession> { | |||||||
| 					} | 					} | ||||||
| 				} catch (InvalidMessageException | InvalidVersionException e) { | 				} catch (InvalidMessageException | InvalidVersionException e) { | ||||||
| 					Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "WhisperMessage received"); | 					Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "WhisperMessage received"); | ||||||
| 					WhisperMessage message = new WhisperMessage(encryptedKey); | 					WhisperMessage message = new WhisperMessage(encryptedKey.key); | ||||||
| 					plaintext = cipher.decrypt(message); | 					plaintext = cipher.decrypt(message); | ||||||
| 				} catch (InvalidKeyException | InvalidKeyIdException | UntrustedIdentityException e) { | 				} catch (InvalidKeyException | InvalidKeyIdException | UntrustedIdentityException e) { | ||||||
| 					Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error decrypting axolotl header, " + e.getClass().getName() + ": " + e.getMessage()); | 					Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error decrypting axolotl header, " + e.getClass().getName() + ": " + e.getMessage()); | ||||||
| @ -123,11 +123,11 @@ public class XmppAxolotlSession implements Comparable<XmppAxolotlSession> { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	public byte[] processSending(@NonNull byte[] outgoingMessage) { | 	public AxolotlKey processSending(@NonNull byte[] outgoingMessage) { | ||||||
| 		FingerprintStatus status = getTrust(); | 		FingerprintStatus status = getTrust(); | ||||||
| 		if (status.isTrustedAndActive()) { | 		if (status.isTrustedAndActive()) { | ||||||
| 			CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); | 			CiphertextMessage ciphertextMessage = cipher.encrypt(outgoingMessage); | ||||||
| 			return ciphertextMessage.serialize(); | 			return new AxolotlKey(ciphertextMessage.serialize(),ciphertextMessage.getType() == CiphertextMessage.PREKEY_TYPE); | ||||||
| 		} else { | 		} else { | ||||||
| 			return null; | 			return null; | ||||||
| 		} | 		} | ||||||
| @ -141,4 +141,16 @@ public class XmppAxolotlSession implements Comparable<XmppAxolotlSession> { | |||||||
| 	public int compareTo(XmppAxolotlSession o) { | 	public int compareTo(XmppAxolotlSession o) { | ||||||
| 		return getTrust().compareTo(o.getTrust()); | 		return getTrust().compareTo(o.getTrust()); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	public static class AxolotlKey { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		public final byte[] key; | ||||||
|  | 		public final boolean prekey; | ||||||
|  | 
 | ||||||
|  | 		public AxolotlKey(byte[] key, boolean prekey) { | ||||||
|  | 			this.key = key; | ||||||
|  | 			this.prekey = prekey; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch