Merge pull request #2580 from moparisthebest/master
Read support for 12-byte IVs in addition to 16-byte IVs
This commit is contained in:
		
						commit
						1b5979dc50
					
				|  | @ -49,11 +49,18 @@ public class DownloadableFile extends File { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void setKeyAndIv(byte[] keyIvCombo) { | 	public void setKeyAndIv(byte[] keyIvCombo) { | ||||||
|  | 		// originally, we used a 16 byte IV, then found for aes-gcm a 12 byte IV is ideal | ||||||
|  | 		// this code supports reading either length, with sending 12 byte IV to be done in future | ||||||
| 		if (keyIvCombo.length == 48) { | 		if (keyIvCombo.length == 48) { | ||||||
| 			this.aeskey = new byte[32]; | 			this.aeskey = new byte[32]; | ||||||
| 			this.iv = new byte[16]; | 			this.iv = new byte[16]; | ||||||
| 			System.arraycopy(keyIvCombo, 0, this.iv, 0, 16); | 			System.arraycopy(keyIvCombo, 0, this.iv, 0, 16); | ||||||
| 			System.arraycopy(keyIvCombo, 16, this.aeskey, 0, 32); | 			System.arraycopy(keyIvCombo, 16, this.aeskey, 0, 32); | ||||||
|  | 		} else if (keyIvCombo.length == 44) { | ||||||
|  | 			this.aeskey = new byte[32]; | ||||||
|  | 			this.iv = new byte[12]; | ||||||
|  | 			System.arraycopy(keyIvCombo, 0, this.iv, 0, 12); | ||||||
|  | 			System.arraycopy(keyIvCombo, 12, this.aeskey, 0, 32); | ||||||
| 		} else if (keyIvCombo.length >= 32) { | 		} else if (keyIvCombo.length >= 32) { | ||||||
| 			this.aeskey = new byte[32]; | 			this.aeskey = new byte[32]; | ||||||
| 			System.arraycopy(keyIvCombo, 0, aeskey, 0, 32); | 			System.arraycopy(keyIvCombo, 0, aeskey, 0, 32); | ||||||
|  |  | ||||||
|  | @ -670,7 +670,7 @@ public class Message extends AbstractEntity { | ||||||
| 				final URL url = new URL(body); | 				final URL url = new URL(body); | ||||||
| 				final String ref = url.getRef(); | 				final String ref = url.getRef(); | ||||||
| 				final String protocol = url.getProtocol(); | 				final String protocol = url.getProtocol(); | ||||||
| 				final boolean encrypted = ref != null && ref.matches("([A-Fa-f0-9]{2}){48}"); | 				final boolean encrypted = ref != null && AesGcmURLStreamHandler.IV_KEY.matcher(ref).matches(); | ||||||
| 				treatAsDownloadable = (AesGcmURLStreamHandler.PROTOCOL_NAME.equalsIgnoreCase(protocol) && encrypted) | 				treatAsDownloadable = (AesGcmURLStreamHandler.PROTOCOL_NAME.equalsIgnoreCase(protocol) && encrypted) | ||||||
| 						|| (("http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol)) && (oob || encrypted)); | 						|| (("http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol)) && (oob || encrypted)); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,10 +4,16 @@ import java.io.IOException; | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| import java.net.URLConnection; | import java.net.URLConnection; | ||||||
| import java.net.URLStreamHandler; | import java.net.URLStreamHandler; | ||||||
|  | import java.util.regex.Pattern; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| public class AesGcmURLStreamHandler extends URLStreamHandler { | public class AesGcmURLStreamHandler extends URLStreamHandler { | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * This matches a 48 or 44 byte IV + KEY hex combo, like used in http/aesgcm upload anchors | ||||||
|  |      */ | ||||||
|  |     public static final Pattern IV_KEY = Pattern.compile("([A-Fa-f0-9]{2}){48}|([A-Fa-f0-9]{2}){44}"); | ||||||
|  | 
 | ||||||
|     public static final String PROTOCOL_NAME = "aesgcm"; |     public static final String PROTOCOL_NAME = "aesgcm"; | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  |  | ||||||
|  | @ -92,7 +92,7 @@ public class HttpDownloadConnection implements Transferable { | ||||||
| 			message.setRelativeFilePath(message.getUuid() + "." + extension); | 			message.setRelativeFilePath(message.getUuid() + "." + extension); | ||||||
| 			this.file = mXmppConnectionService.getFileBackend().getFile(message, false); | 			this.file = mXmppConnectionService.getFileBackend().getFile(message, false); | ||||||
| 			final String reference = mUrl.getRef(); | 			final String reference = mUrl.getRef(); | ||||||
| 			if (reference != null && reference.matches("([A-Fa-f0-9]{2}){48}")) { | 			if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { | ||||||
| 				this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference)); | 				this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference)); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -373,7 +373,7 @@ public class HttpDownloadConnection implements Transferable { | ||||||
| 			message.setType(Message.TYPE_FILE); | 			message.setType(Message.TYPE_FILE); | ||||||
| 			final URL url; | 			final URL url; | ||||||
| 			final String ref = mUrl.getRef(); | 			final String ref = mUrl.getRef(); | ||||||
| 			if (ref != null && ref.matches("([A-Fa-f0-9]{2}){48}")) { | 			if (ref != null && AesGcmURLStreamHandler.IV_KEY.matcher(ref).matches()) { | ||||||
| 				url = CryptoHelper.toAesGcmUrl(mUrl); | 				url = CryptoHelper.toAesGcmUrl(mUrl); | ||||||
| 			} else { | 			} else { | ||||||
| 				url = mUrl; | 				url = mUrl; | ||||||
|  |  | ||||||
|  | @ -105,7 +105,7 @@ public class HttpUploadConnection implements Transferable { | ||||||
| 		if (Config.ENCRYPT_ON_HTTP_UPLOADED | 		if (Config.ENCRYPT_ON_HTTP_UPLOADED | ||||||
| 				|| message.getEncryption() == Message.ENCRYPTION_AXOLOTL | 				|| message.getEncryption() == Message.ENCRYPTION_AXOLOTL | ||||||
| 				|| message.getEncryption() == Message.ENCRYPTION_OTR) { | 				|| message.getEncryption() == Message.ENCRYPTION_OTR) { | ||||||
| 			this.key = new byte[48]; | 			this.key = new byte[48]; // todo: change this to 44 for 12-byte IV instead of 16-byte at some point in future | ||||||
| 			mXmppConnectionService.getRNG().nextBytes(this.key); | 			mXmppConnectionService.getRNG().nextBytes(this.key); | ||||||
| 			this.file.setKeyAndIv(this.key); | 			this.file.setKeyAndIv(this.key); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Daniel Gultsch
						Daniel Gultsch