full-on autocrypt!

This commit is contained in:
Vincent Breitmoser
2017-06-16 18:29:01 +02:00
parent 1e620e01aa
commit 019e63f681
11 changed files with 297 additions and 125 deletions

View File

@@ -85,13 +85,30 @@ public class AutocryptPeerDataAccessObject {
return null;
}
public Date getLastUpdateForAutocryptPeer(String autocryptId) {
public Date getLastSeen(String autocryptId) {
Cursor cursor = mQueryInterface.query(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId),
null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
long lastUpdated = cursor.getColumnIndex(ApiAutocryptPeer.LAST_UPDATED);
long lastUpdated = cursor.getColumnIndex(ApiAutocryptPeer.LAST_SEEN);
return new Date(lastUpdated);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
public Date getLastSeenKey(String autocryptId) {
Cursor cursor = mQueryInterface.query(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId),
null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
long lastUpdated = cursor.getColumnIndex(ApiAutocryptPeer.LAST_SEEN_KEY);
return new Date(lastUpdated);
}
} finally {
@@ -103,14 +120,36 @@ public class AutocryptPeerDataAccessObject {
}
public void setMasterKeyIdForAutocryptPeer(String autocryptId, long masterKeyId, Date date) {
Date lastUpdated = getLastUpdateForAutocryptPeer(autocryptId);
Date lastUpdated = getLastSeen(autocryptId);
if (lastUpdated != null && lastUpdated.after(date)) {
throw new IllegalArgumentException("Database entry was newer than the one to be inserted! Cannot backdate");
}
ContentValues cv = new ContentValues();
cv.put(ApiAutocryptPeer.MASTER_KEY_ID, masterKeyId);
cv.put(ApiAutocryptPeer.LAST_UPDATED, date.getTime());
cv.put(ApiAutocryptPeer.LAST_SEEN_KEY, date.getTime());
mQueryInterface.update(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId), cv, null, null);
}
public void updateToResetState(String autocryptId, Date effectiveDate) {
updateAutocryptState(autocryptId, effectiveDate, ApiAutocryptPeer.RESET);
}
public void updateToMutualState(String autocryptId, Date effectiveDate, long masterKeyId) {
setMasterKeyIdForAutocryptPeer(autocryptId, masterKeyId, effectiveDate);
updateAutocryptState(autocryptId, effectiveDate, ApiAutocryptPeer.MUTUAL);
}
public void updateToAvailableState(String autocryptId, Date effectiveDate, long masterKeyId) {
setMasterKeyIdForAutocryptPeer(autocryptId, masterKeyId, effectiveDate);
updateAutocryptState(autocryptId, effectiveDate, ApiAutocryptPeer.AVAILABLE);
}
private void updateAutocryptState(String autocryptId, Date date, int status) {
ContentValues cv = new ContentValues();
cv.put(ApiAutocryptPeer.MASTER_KEY_ID, (Integer) null);
cv.put(ApiAutocryptPeer.LAST_SEEN, date.getTime());
cv.put(ApiAutocryptPeer.STATUS, status);
mQueryInterface.update(ApiAutocryptPeer.buildByPackageNameAndAutocryptId(packageName, autocryptId), cv, null, null);
}
}

View File

@@ -98,7 +98,9 @@ public class KeychainContract {
interface ApiAutocryptPeerColumns {
String PACKAGE_NAME = "package_name";
String IDENTIFIER = "identifier";
String LAST_UPDATED = "last_updated";
String LAST_SEEN = "last_updated";
String LAST_SEEN_KEY = "last_seen_key";
String STATUS = "status";
String MASTER_KEY_ID = "master_key_id";
}
@@ -349,6 +351,11 @@ public class KeychainContract {
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
.appendPath(BASE_AUTOCRYPT_PEERS).build();
public static final int RESET = 0;
public static final int GOSSIP = 1;
public static final int AVAILABLE = 2;
public static final int MUTUAL = 3;
public static Uri buildByKeyUri(Uri uri) {
return CONTENT_URI.buildUpon().appendPath(PATH_BY_KEY_ID).appendPath(uri.getPathSegments().get(1)).build();
}

View File

@@ -162,8 +162,10 @@ public class KeychainDatabase extends SQLiteOpenHelper {
"CREATE TABLE IF NOT EXISTS " + Tables.API_AUTOCRYPT_PEERS + " ("
+ ApiAutocryptPeerColumns.PACKAGE_NAME + " TEXT NOT NULL, "
+ ApiAutocryptPeerColumns.IDENTIFIER + " TEXT NOT NULL, "
+ ApiAutocryptPeerColumns.LAST_UPDATED + " INTEGER NOT NULL, "
+ ApiAutocryptPeerColumns.MASTER_KEY_ID + " INTEGER NOT NULL, "
+ ApiAutocryptPeerColumns.LAST_SEEN + " INTEGER NOT NULL, "
+ ApiAutocryptPeerColumns.LAST_SEEN_KEY + " INTEGER NOT NULL, "
+ ApiAutocryptPeerColumns.STATUS + " INTEGER NOT NULL, "
+ ApiAutocryptPeerColumns.MASTER_KEY_ID + " INTEGER NULL, "
+ "PRIMARY KEY(" + ApiAutocryptPeerColumns.PACKAGE_NAME + ", "
+ ApiAutocryptPeerColumns.IDENTIFIER + "), "
+ "FOREIGN KEY(" + ApiAutocryptPeerColumns.PACKAGE_NAME + ") REFERENCES "

View File

@@ -26,6 +26,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAutocryptPee
public class KeychainExternalContract {
public static final int KEY_STATUS_UNAVAILABLE = 0;
public static final int KEY_STATUS_UNVERIFIED = 1;
public static final int KEY_STATUS_VERIFIED = 2;
@@ -35,6 +36,7 @@ public class KeychainExternalContract {
private static final Uri BASE_CONTENT_URI_EXTERNAL = Uri
.parse("content://" + CONTENT_AUTHORITY_EXTERNAL);
public static final String BASE_EMAIL_STATUS = "email_status";
public static final String BASE_AUTOCRYPT_PEER_STATUS = "autocrypt_status";
public static final String BASE_AUTOCRYPT_PEERS = "autocrypt_peers";
@@ -43,8 +45,6 @@ public class KeychainExternalContract {
public static final String USER_ID = "user_id";
public static final String USER_ID_STATUS = "email_status";
public static final String MASTER_KEY_ID = "master_key_id";
public static final String AUTOCRYPT_PEER_LAST_SEEN = "autocrypt_peer_last_seen";
public static final String AUTOCRYPT_PEER_STATE = "autocrypt_peer_state";
public static final Uri CONTENT_URI = BASE_CONTENT_URI_EXTERNAL.buildUpon()
.appendPath(BASE_EMAIL_STATUS).build();
@@ -53,6 +53,19 @@ public class KeychainExternalContract {
"vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.email_status";
}
public static class AutocryptPeerStatus implements BaseColumns {
public static final String EMAIL_ADDRESS = "email_address";
public static final String MASTER_KEY_ID = "master_key_id";
public static final String AUTOCRYPT_PEER_LAST_SEEN = "autocrypt_peer_last_seen";
public static final String AUTOCRYPT_PEER_STATUS = "autocrypt_peer_state";
public static final Uri CONTENT_URI = BASE_CONTENT_URI_EXTERNAL.buildUpon()
.appendPath(BASE_EMAIL_STATUS).build();
public static final String CONTENT_TYPE =
"vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.autocrypt_status";
}
public static class ApiAutocryptPeer implements ApiAutocryptPeerColumns, BaseColumns {
public static final Uri CONTENT_URI = BASE_CONTENT_URI_EXTERNAL.buildUpon()
.appendPath(BASE_AUTOCRYPT_PEERS).build();

View File

@@ -676,7 +676,7 @@ public class KeychainProvider extends ContentProvider {
projectionMap.put(ApiAutocryptPeer.PACKAGE_NAME, ApiAutocryptPeer.PACKAGE_NAME);
projectionMap.put(ApiAutocryptPeer.IDENTIFIER, ApiAutocryptPeer.IDENTIFIER);
projectionMap.put(ApiAutocryptPeer.MASTER_KEY_ID, ApiAutocryptPeer.MASTER_KEY_ID);
projectionMap.put(ApiAutocryptPeer.LAST_UPDATED, ApiAutocryptPeer.LAST_UPDATED);
projectionMap.put(ApiAutocryptPeer.LAST_SEEN, ApiAutocryptPeer.LAST_SEEN);
qb.setProjectionMap(projectionMap);
qb.setTables(Tables.API_AUTOCRYPT_PEERS);
@@ -999,7 +999,7 @@ public class KeychainProvider extends ContentProvider {
}
case TRUST_IDS_BY_PACKAGE_NAME_AND_TRUST_ID: {
Long masterKeyId = values.getAsLong(ApiAutocryptPeer.MASTER_KEY_ID);
long updateTime = values.getAsLong(ApiAutocryptPeer.LAST_UPDATED);
long updateTime = values.getAsLong(ApiAutocryptPeer.LAST_SEEN);
if (masterKeyId == null) {
throw new IllegalArgumentException("master_key_id must be a non-null value!");
}
@@ -1009,7 +1009,7 @@ public class KeychainProvider extends ContentProvider {
actualValues.put(ApiAutocryptPeer.PACKAGE_NAME, packageName);
actualValues.put(ApiAutocryptPeer.IDENTIFIER, uri.getLastPathSegment());
actualValues.put(ApiAutocryptPeer.MASTER_KEY_ID, masterKeyId);
actualValues.put(ApiAutocryptPeer.LAST_UPDATED, updateTime);
actualValues.put(ApiAutocryptPeer.LAST_SEEN, updateTime);
try {
db.replace(Tables.API_AUTOCRYPT_PEERS, null, actualValues);