mirror of
https://github.com/etesync/android
synced 2024-12-23 15:18:14 +00:00
Journal: use journal keys if available.
If a journal has a key set to it (usually used for shared journals), use it instead of the symmetric key. The key of the journal is asymmetrically encrypted using our keypair.
This commit is contained in:
parent
43803b6d3e
commit
beccb33904
@ -123,8 +123,21 @@ public class Crypto {
|
||||
private SecureRandom _random = null;
|
||||
@Getter
|
||||
private final byte version;
|
||||
private final byte[] cipherKey;
|
||||
private final byte[] hmacKey;
|
||||
private byte[] cipherKey;
|
||||
private byte[] hmacKey;
|
||||
|
||||
private void setDerivedKey(byte[] derivedKey) {
|
||||
cipherKey = hmac256("aes".getBytes(Charsets.UTF_8), derivedKey);
|
||||
hmacKey = hmac256("hmac".getBytes(Charsets.UTF_8), derivedKey);
|
||||
}
|
||||
|
||||
public CryptoManager(int version, AsymmetricKeyPair keyPair, byte[] encryptedKey) {
|
||||
Crypto.AsymmetricCryptoManager cryptoManager = new Crypto.AsymmetricCryptoManager(keyPair);
|
||||
byte[] derivedKey = cryptoManager.decrypt(encryptedKey);
|
||||
|
||||
this.version = (byte) version;
|
||||
setDerivedKey(derivedKey);
|
||||
}
|
||||
|
||||
public CryptoManager(int version, @NonNull String keyBase64, @NonNull String salt) throws Exceptions.IntegrityException, Exceptions.VersionTooNewException {
|
||||
byte[] derivedKey;
|
||||
@ -139,8 +152,7 @@ public class Crypto {
|
||||
}
|
||||
|
||||
this.version = (byte) version;
|
||||
cipherKey = hmac256("aes".getBytes(Charsets.UTF_8), derivedKey);
|
||||
hmacKey = hmac256("hmac".getBytes(Charsets.UTF_8), derivedKey);
|
||||
setDerivedKey(derivedKey);
|
||||
}
|
||||
|
||||
private static final int blockSize = 16; // AES's block size in bytes
|
||||
|
@ -40,7 +40,7 @@ public class JournalManager extends BaseManager {
|
||||
this.client = httpClient;
|
||||
}
|
||||
|
||||
public List<Journal> getJournals(String keyBase64) throws Exceptions.HttpException, Exceptions.IntegrityException, Exceptions.GenericCryptoException {
|
||||
public List<Journal> getJournals() throws Exceptions.HttpException {
|
||||
Request request = new Request.Builder()
|
||||
.get()
|
||||
.url(remote)
|
||||
@ -51,9 +51,7 @@ public class JournalManager extends BaseManager {
|
||||
List<Journal> ret = GsonHelper.gson.fromJson(body.charStream(), journalType);
|
||||
|
||||
for (Journal journal : ret) {
|
||||
Crypto.CryptoManager crypto = new Crypto.CryptoManager(journal.getVersion(), keyBase64, journal.getUid());
|
||||
journal.processFromJson();
|
||||
journal.verify(crypto);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -157,7 +155,7 @@ public class JournalManager extends BaseManager {
|
||||
setContent(Arrays.copyOfRange(getContent(), HMAC_SIZE, getContent().length));
|
||||
}
|
||||
|
||||
void verify(Crypto.CryptoManager crypto) throws Exceptions.IntegrityException {
|
||||
public void verify(Crypto.CryptoManager crypto) throws Exceptions.IntegrityException {
|
||||
if (hmac == null) {
|
||||
throw new Exceptions.IntegrityException("HMAC is null!");
|
||||
}
|
||||
|
@ -158,8 +158,16 @@ public abstract class SyncAdapterService extends Service {
|
||||
|
||||
List<Pair<JournalManager.Journal, CollectionInfo>> journals = new LinkedList<>();
|
||||
|
||||
for (JournalManager.Journal journal : journalsManager.getJournals(settings.password())) {
|
||||
Crypto.CryptoManager crypto = new Crypto.CryptoManager(journal.getVersion(), settings.password(), journal.getUid());
|
||||
for (JournalManager.Journal journal : journalsManager.getJournals()) {
|
||||
Crypto.CryptoManager crypto;
|
||||
if (journal.getKey() != null) {
|
||||
crypto = new Crypto.CryptoManager(journal.getVersion(), settings.getKeyPair(), journal.getKey());
|
||||
} else {
|
||||
crypto = new Crypto.CryptoManager(journal.getVersion(), settings.password(), journal.getUid());
|
||||
}
|
||||
|
||||
journal.verify(crypto);
|
||||
|
||||
CollectionInfo info = CollectionInfo.fromJson(journal.getContent(crypto));
|
||||
info.updateFromJournal(journal);
|
||||
|
||||
|
@ -33,6 +33,7 @@ import com.etesync.syncadapter.model.SyncEntry;
|
||||
import com.etesync.syncadapter.resource.LocalCollection;
|
||||
import com.etesync.syncadapter.resource.LocalResource;
|
||||
import com.etesync.syncadapter.ui.DebugInfoActivity;
|
||||
import com.etesync.syncadapter.utils.Base64;
|
||||
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
|
||||
@ -118,7 +119,12 @@ abstract public class SyncManager {
|
||||
notificationManager.cancel();
|
||||
|
||||
App.log.info(String.format(Locale.getDefault(), "Syncing collection %s (version: %d)", journalUid, info.version));
|
||||
crypto = new Crypto.CryptoManager(info.version, settings.password(), journalUid);
|
||||
|
||||
if (getJournalEntity().getEncryptedKey() != null) {
|
||||
crypto = new Crypto.CryptoManager(info.version, settings.getKeyPair(), getJournalEntity().getEncryptedKey());
|
||||
} else {
|
||||
crypto = new Crypto.CryptoManager(info.version, settings.password(), info.uid);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int notificationId();
|
||||
@ -235,7 +241,7 @@ abstract public class SyncManager {
|
||||
|
||||
private JournalEntity getJournalEntity() {
|
||||
if (_journalEntity == null)
|
||||
_journalEntity = JournalModel.Journal.fetch(data, info.getServiceEntity(data), journal.getUid());
|
||||
_journalEntity = JournalModel.Journal.fetch(data, info.getServiceEntity(data), info.uid);
|
||||
return _journalEntity;
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class ServiceTest {
|
||||
}
|
||||
assertNotNull(caught);
|
||||
|
||||
List<JournalManager.Journal> journals = journalManager.getJournals(Helpers.keyBase64);
|
||||
List<JournalManager.Journal> journals = journalManager.getJournals();
|
||||
assertEquals(journals.size(), 1);
|
||||
CollectionInfo info2 = CollectionInfo.fromJson(journals.get(0).getContent(crypto));
|
||||
assertEquals(info2.displayName, info.displayName);
|
||||
@ -103,7 +103,7 @@ public class ServiceTest {
|
||||
journal = new JournalManager.Journal(crypto, info.toJson(), info.uid);
|
||||
journalManager.updateJournal(journal);
|
||||
|
||||
journals = journalManager.getJournals(Helpers.keyBase64);
|
||||
journals = journalManager.getJournals();
|
||||
assertEquals(journals.size(), 1);
|
||||
info2 = CollectionInfo.fromJson(journals.get(0).getContent(crypto));
|
||||
assertEquals(info2.displayName, info.displayName);
|
||||
@ -111,7 +111,7 @@ public class ServiceTest {
|
||||
// Delete journal
|
||||
journalManager.deleteJournal(journal);
|
||||
|
||||
journals = journalManager.getJournals(Helpers.keyBase64);
|
||||
journals = journalManager.getJournals();
|
||||
assertEquals(journals.size(), 0);
|
||||
|
||||
// Bad HMAC
|
||||
@ -124,7 +124,10 @@ public class ServiceTest {
|
||||
|
||||
try {
|
||||
caught = null;
|
||||
journalManager.getJournals(Helpers.keyBase64);
|
||||
for (JournalManager.Journal journal1 : journalManager.getJournals()) {
|
||||
Crypto.CryptoManager crypto1 = new Crypto.CryptoManager(info.version, Helpers.keyBase64, journal1.getUid());
|
||||
journal1.verify(crypto1);
|
||||
}
|
||||
} catch (Exceptions.IntegrityException e) {
|
||||
caught = e;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user