From ca8835420dabe82d4b320ee723196773bbe421fc Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 20 Jan 2018 22:08:51 +0100 Subject: [PATCH] Remember "origin" of gossip keys --- .../AutocryptPeerDataAccessObject.java | 15 ++++++++++- .../keychain/provider/KeychainContract.java | 5 ++++ .../keychain/provider/KeychainDatabase.java | 25 ++++++++++++------- .../keychain/provider/KeychainProvider.java | 1 + .../keychain/remote/AutocryptInteractor.java | 2 +- .../keychain/remote/OpenPgpService.java | 13 +++++----- .../ui/dialog/RemoteDeduplicatePresenter.java | 2 +- .../remote/KeychainExternalProviderTest.java | 4 +-- 8 files changed, 46 insertions(+), 21 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/AutocryptPeerDataAccessObject.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/AutocryptPeerDataAccessObject.java index dd6f3d05e..62afe2bec 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/AutocryptPeerDataAccessObject.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/AutocryptPeerDataAccessObject.java @@ -187,10 +187,23 @@ public class AutocryptPeerDataAccessObject { .update(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId), cv, null, null); } - public void updateKeyGossip(String autocryptId, Date effectiveDate, long masterKeyId) { + public void updateKeyGossipFromAutocrypt(String autocryptId, Date effectiveDate, long masterKeyId) { + updateKeyGossip(autocryptId, effectiveDate, masterKeyId, ApiAutocryptPeer.GOSSIP_ORIGIN_AUTOCRYPT); + } + + public void updateKeyGossipFromSignature(String autocryptId, Date effectiveDate, long masterKeyId) { + updateKeyGossip(autocryptId, effectiveDate, masterKeyId, ApiAutocryptPeer.GOSSIP_ORIGIN_SIGNATURE); + } + + public void updateKeyGossipFromDedup(String autocryptId, Date effectiveDate, long masterKeyId) { + updateKeyGossip(autocryptId, effectiveDate, masterKeyId, ApiAutocryptPeer.GOSSIP_ORIGIN_DEDUP); + } + + private void updateKeyGossip(String autocryptId, Date effectiveDate, long masterKeyId, int origin) { ContentValues cv = new ContentValues(); cv.put(ApiAutocryptPeer.GOSSIP_MASTER_KEY_ID, masterKeyId); cv.put(ApiAutocryptPeer.GOSSIP_LAST_SEEN_KEY, effectiveDate.getTime()); + cv.put(ApiAutocryptPeer.GOSSIP_ORIGIN, origin); queryInterface .update(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId), cv, null, null); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 65fc34cfd..b97bb44cc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -110,6 +110,7 @@ public class KeychainContract { String GOSSIP_MASTER_KEY_ID = "gossip_master_key_id"; String GOSSIP_LAST_SEEN_KEY = "gossip_last_seen_key"; + String GOSSIP_ORIGIN = "gossip_origin"; } public static final String CONTENT_AUTHORITY = Constants.PROVIDER_AUTHORITY; @@ -382,6 +383,10 @@ public class KeychainContract { public static final String GOSSIP_KEY_IS_EXPIRED = "gossip_key_is_expired"; public static final String GOSSIP_KEY_IS_VERIFIED = "gossip_key_is_verified"; + public static final int GOSSIP_ORIGIN_AUTOCRYPT = 0; + public static final int GOSSIP_ORIGIN_SIGNATURE = 10; + public static final int GOSSIP_ORIGIN_DEDUP = 20; + public static Uri buildByKeyUri(Uri uri) { return CONTENT_URI.buildUpon().appendPath(PATH_BY_KEY_ID).appendPath(uri.getPathSegments().get(1)).build(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index c53183901..b1ed2ae82 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -179,6 +179,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { + ApiAutocryptPeerColumns.MASTER_KEY_ID + " INTEGER NULL, " + ApiAutocryptPeerColumns.GOSSIP_MASTER_KEY_ID + " INTEGER NULL, " + ApiAutocryptPeerColumns.GOSSIP_LAST_SEEN_KEY + " INTEGER NULL, " + + ApiAutocryptPeerColumns.GOSSIP_ORIGIN + " INTEGER NULL, " + "PRIMARY KEY(" + ApiAutocryptPeerColumns.PACKAGE_NAME + ", " + ApiAutocryptPeerColumns.IDENTIFIER + "), " + "FOREIGN KEY(" + ApiAutocryptPeerColumns.PACKAGE_NAME + ") REFERENCES " @@ -418,26 +419,32 @@ public class KeychainDatabase extends SQLiteOpenHelper { + "package_name TEXT NOT NULL, " + "identifier TEXT NOT NULL, " + "last_seen INTEGER, " - + "last_seen_key INTEGER NULL, " - + "is_mutual INTEGER NULL, " - + "master_key_id INTEGER NULL, " - + "gossip_master_key_id INTEGER NULL, " - + "gossip_last_seen_key INTEGER NULL, " + + "last_seen_key INTEGER, " + + "is_mutual INTEGER, " + + "master_key_id INTEGER, " + + "gossip_master_key_id INTEGER, " + + "gossip_last_seen_key INTEGER, " + + "gossip_origin INTEGER, " + "PRIMARY KEY(package_name, identifier), " + "FOREIGN KEY(package_name) REFERENCES api_apps (package_name) ON DELETE CASCADE" + ")"); + // Note: Keys from Autocrypt 0.X with state == "reset" (0) are dropped db.execSQL("INSERT INTO api_autocrypt_peers " + - "(package_name, identifier, last_seen, gossip_last_seen_key, gossip_master_key_id, is_mutual) " + + "(package_name, identifier, last_seen, gossip_last_seen_key, gossip_master_key_id, gossip_origin) " + "SELECT package_name, identifier, last_updated, last_seen_key, master_key_id, 0 " + - "FROM tmp WHERE state IN (1,2)"); + "FROM tmp WHERE state = 1"); // Autocrypt 0.X, "gossip" -> now origin=autocrypt + db.execSQL("INSERT INTO api_autocrypt_peers " + + "(package_name, identifier, last_seen, gossip_last_seen_key, gossip_master_key_id, gossip_origin) " + + "SELECT package_name, identifier, last_updated, last_seen_key, master_key_id, 20 " + + "FROM tmp WHERE state = 2"); // "selected" keys -> now origin=dedup db.execSQL("INSERT INTO api_autocrypt_peers " + "(package_name, identifier, last_seen, last_seen_key, master_key_id, is_mutual) " + "SELECT package_name, identifier, last_updated, last_seen_key, master_key_id, 0 " + - "FROM tmp WHERE state = 3"); + "FROM tmp WHERE state = 3"); // Autocrypt 0.X, state = "available" db.execSQL("INSERT INTO api_autocrypt_peers " + "(package_name, identifier, last_seen, last_seen_key, master_key_id, is_mutual) " + "SELECT package_name, identifier, last_updated, last_seen_key, master_key_id, 1 " + - "FROM tmp WHERE state = 4"); + "FROM tmp WHERE state = 4"); // from Autocrypt 0.X, state = "mutual" db.execSQL("DROP TABLE tmp"); db.setTransactionSuccessful(); db.endTransaction(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index d7f7f2efe..bd5881eda 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -729,6 +729,7 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(ApiAutocryptPeer.LAST_SEEN_KEY, ApiAutocryptPeer.LAST_SEEN_KEY); projectionMap.put(ApiAutocryptPeer.GOSSIP_MASTER_KEY_ID, ApiAutocryptPeer.GOSSIP_MASTER_KEY_ID); projectionMap.put(ApiAutocryptPeer.GOSSIP_LAST_SEEN_KEY, ApiAutocryptPeer.GOSSIP_LAST_SEEN_KEY); + projectionMap.put(ApiAutocryptPeer.GOSSIP_ORIGIN, ApiAutocryptPeer.GOSSIP_ORIGIN); projectionMap.put(ApiAutocryptPeer.KEY_IS_REVOKED, "ac_key." + Keys.IS_REVOKED + " AS " + ApiAutocryptPeer.KEY_IS_REVOKED); projectionMap.put(ApiAutocryptPeer.KEY_IS_EXPIRED, "(CASE" + " WHEN ac_key." + Keys.EXPIRY + " IS NULL THEN 0" + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/AutocryptInteractor.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/AutocryptInteractor.java index 0d56522f3..3026aaaba 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/AutocryptInteractor.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/AutocryptInteractor.java @@ -94,7 +94,7 @@ class AutocryptInteractor { // 4. Set peers[gossip-addr].gossip_key to the value of the keydata attribute. Long newMasterKeyId = saveKeyringResult.savedMasterKeyId; - autocryptPeerDao.updateKeyGossip(autocryptPeerId, effectiveDate, newMasterKeyId); + autocryptPeerDao.updateKeyGossipFromAutocrypt(autocryptPeerId, effectiveDate, newMasterKeyId); } @Nullable diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 9550f161b..1fcba550f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -577,13 +577,12 @@ public class OpenPgpService extends Service { long masterKeyId = signatureResult.getKeyId(); if (autocryptPeerMasterKeyId == null) { - // TODO -// Date now = new Date(); -// Date effectiveTime = signatureResult.getSignatureTimestamp(); -// if (effectiveTime.after(now)) { -// effectiveTime = now; -// } -// autocryptPeerentityDao.updateKeyGossip(autocryptPeerId, effectiveTime, masterKeyId); + Date now = new Date(); + Date effectiveTime = signatureResult.getSignatureTimestamp(); + if (effectiveTime.after(now)) { + effectiveTime = now; + } + autocryptPeerentityDao.updateKeyGossipFromSignature(autocryptPeerId, effectiveTime, masterKeyId); return signatureResult.withAutocryptPeerResult(AutocryptPeerResult.NEW); } else if (masterKeyId == autocryptPeerMasterKeyId) { return signatureResult.withAutocryptPeerResult(AutocryptPeerResult.OK); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java index 354053686..4717f7da5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/dialog/RemoteDeduplicatePresenter.java @@ -122,7 +122,7 @@ class RemoteDeduplicatePresenter implements LoaderCallbacks> { } long masterKeyId = keyInfoData.get(selectedItem).getMasterKeyId(); - autocryptPeerDao.updateKeyGossip(duplicateAddress, new Date(), masterKeyId); + autocryptPeerDao.updateKeyGossipFromDedup(duplicateAddress, new Date(), masterKeyId); view.finish(); } diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java index 950d3f275..e27a97ac9 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/remote/KeychainExternalProviderTest.java @@ -305,7 +305,7 @@ public class KeychainExternalProviderTest { insertSecretKeyringFrom("/test-keys/testring.sec"); insertPublicKeyringFrom("/test-keys/testring.pub"); - autocryptPeerDao.updateKeyGossip("tid", new Date(), KEY_ID_PUBLIC); + autocryptPeerDao.updateKeyGossipFromAutocrypt("tid", new Date(), KEY_ID_PUBLIC); autocryptPeerDao.delete("tid"); Cursor cursor = contentResolver.query( @@ -330,7 +330,7 @@ public class KeychainExternalProviderTest { insertSecretKeyringFrom("/test-keys/testring.sec"); insertPublicKeyringFrom("/test-keys/testring.pub"); - autocryptPeerDao.updateKeyGossip(AUTOCRYPT_PEER, new Date(), KEY_ID_PUBLIC); + autocryptPeerDao.updateKeyGossipFromAutocrypt(AUTOCRYPT_PEER, new Date(), KEY_ID_PUBLIC); certifyKey(KEY_ID_SECRET, KEY_ID_PUBLIC, USER_ID_1); Cursor cursor = contentResolver.query(