diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java index a1b2289f4..7e0613b7f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/CloudSearch.java @@ -47,10 +47,10 @@ public class CloudSearch { servers.add(cloudPrefs.keyserver); } if (cloudPrefs.searchKeybase) { - servers.add(new KeybaseKeyserver()); + servers.add(KeybaseKeyserver.getInstance()); } if (cloudPrefs.searchFacebook) { - servers.add(new FacebookKeyserver()); + servers.add(FacebookKeyserver.getInstance()); } int numberOfServers = servers.size(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java index 347b018f8..a29aec9d5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java @@ -46,15 +46,19 @@ import okhttp3.Request; import okhttp3.Response; public class FacebookKeyserver extends Keyserver { - private static final String FB_KEY_URL_FORMAT = "https://www.facebook.com/%s/publickey/download"; private static final String FB_HOST = "facebook.com"; private static final String FB_HOST_WWW = "www." + FB_HOST; - public FacebookKeyserver() { + + public static FacebookKeyserver getInstance() { + return new FacebookKeyserver(); } + private FacebookKeyserver() { } + + @Override public List search(String fbUsername, ParcelableProxy proxy) throws QueryFailedException, QueryNeedsRepairException { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java index 30141c07c..4173e3ff4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/KeybaseKeyserver.java @@ -33,9 +33,12 @@ import java.util.List; public class KeybaseKeyserver extends Keyserver { - public KeybaseKeyserver() { + public static KeybaseKeyserver getInstance() { + return new KeybaseKeyserver(); } + private KeybaseKeyserver() { } + @Override public ArrayList search(String query, ParcelableProxy proxy) throws QueryFailedException, QueryNeedsRepairException { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java index 2a2137baf..3f466b821 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportOperation.java @@ -19,8 +19,21 @@ package org.sufficientlysecure.keychain.operations; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + import android.content.Context; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -29,6 +42,7 @@ import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver; import org.sufficientlysecure.keychain.keyimport.Keyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableHkpKeyserver; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; +import org.sufficientlysecure.keychain.network.orbot.OrbotHelper; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; @@ -50,20 +64,6 @@ import org.sufficientlysecure.keychain.util.ParcelableFileCache; import org.sufficientlysecure.keychain.util.ParcelableProxy; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.ProgressScaler; -import org.sufficientlysecure.keychain.network.orbot.OrbotHelper; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorCompletionService; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; /** * An operation class which implements high level import @@ -85,9 +85,10 @@ public class ImportOperation extends BaseReadWriteOperation private static final int MAX_THREADS = 10; public static final String CACHE_FILE_NAME = "key_import.pcl"; + private FacebookKeyserver facebookServer; + private KeybaseKeyserver keybaseServer; - public ImportOperation(Context context, KeyWritableRepository databaseInteractor, Progressable - progressable) { + public ImportOperation(Context context, KeyWritableRepository databaseInteractor, Progressable progressable) { super(context, databaseInteractor, progressable); } @@ -158,10 +159,6 @@ public class ImportOperation extends BaseReadWriteOperation boolean cancelled = false; int keyImportsFinished = 0; - KeybaseKeyserver keybaseServer = null; - FacebookKeyserver facebookServer = null; - ParcelableHkpKeyserver keyServer = null; - // iterate over all entries while (entries.hasNext()) { ParcelableKeyRing entry = entries.next(); @@ -179,121 +176,13 @@ public class ImportOperation extends BaseReadWriteOperation // If there is already byte data, use that if (entry.mBytes != null) { key = UncachedKeyRing.decodeFromData(entry.mBytes); - } - // Otherwise, we need to fetch the data from a server first - else { + } else { + key = fetchKeyFromInternet(hkpKeyserver, proxy, log, entry, key); - // We fetch from keyservers first, because we tend to get more certificates - // from there, so the number of certificates which are merged in later is - // smaller. - - // If we have a keyServerUri and a fingerprint or at least a keyId, - // download from HKP - if (hkpKeyserver != null - && (entry.mKeyIdHex != null || entry.mExpectedFingerprint != null)) { - // Make sure we have the keyserver instance cached - if (keyServer == null) { - log.add(LogType.MSG_IMPORT_KEYSERVER, 1, hkpKeyserver); - keyServer = hkpKeyserver; - } - - try { - byte[] data; - // Download by fingerprint, or keyId - whichever is available - if (entry.mExpectedFingerprint != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + - entry.mExpectedFingerprint.substring(24)); - data = keyServer.get("0x" + entry.mExpectedFingerprint, proxy).getBytes(); - } else { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex); - data = keyServer.get(entry.mKeyIdHex, proxy).getBytes(); - } - key = UncachedKeyRing.decodeFromData(data); - if (key != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); - } else { - log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); - } - } catch (Keyserver.QueryFailedException e) { - Log.d(Constants.TAG, "query failed", e); - log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage()); - } - } - - // If we have a keybase name, try to fetch from there - if (entry.mKeybaseName != null) { - // Make sure we have this cached - if (keybaseServer == null) { - keybaseServer = new KeybaseKeyserver(); - } - - try { - log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName); - byte[] data = keybaseServer.get(entry.mKeybaseName, proxy).getBytes(); - UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data); - - if (keybaseKey != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); - } else { - log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); - } - - // If there already is a key, merge the two - if (key != null && keybaseKey != null) { - log.add(LogType.MSG_IMPORT_MERGE, 3); - keybaseKey = key.merge(keybaseKey, log, 4); - // If the merge didn't fail, use the new merged key - if (keybaseKey != null) { - key = keybaseKey; - } else { - log.add(LogType.MSG_IMPORT_MERGE_ERROR, 4); - } - } else if (keybaseKey != null) { - key = keybaseKey; - } - } catch (Keyserver.QueryFailedException e) { - // download failed, too bad. just proceed - Log.e(Constants.TAG, "query failed", e); - log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage()); - } - } - - // if the key is from Facebook, fetch from there - if (entry.mFbUsername != null) { - // Make sure we have this cached - if (facebookServer == null) { - facebookServer = new FacebookKeyserver(); - } - - try { - log.add(LogType.MSG_IMPORT_FETCH_FACEBOOK, 2, entry.mFbUsername); - byte[] data = facebookServer.get(entry.mFbUsername, proxy).getBytes(); - UncachedKeyRing facebookKey = UncachedKeyRing.decodeFromData(data); - - if (facebookKey != null) { - log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); - } else { - log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); - } - - // If there already is a key, merge the two - if (key != null && facebookKey != null) { - log.add(LogType.MSG_IMPORT_MERGE, 3); - facebookKey = key.merge(facebookKey, log, 4); - // If the merge didn't fail, use the new merged key - if (facebookKey != null) { - key = facebookKey; - } else { - log.add(LogType.MSG_IMPORT_MERGE_ERROR, 4); - } - } else if (facebookKey != null) { - key = facebookKey; - } - } catch (Keyserver.QueryFailedException e) { - // download failed, too bad. just proceed - Log.e(Constants.TAG, "query failed", e); - log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage()); - } + if (key.isSecret()) { + log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER_SECRET, 2); + badKeys += 1; + continue; } } @@ -303,13 +192,6 @@ public class ImportOperation extends BaseReadWriteOperation continue; } - // never import secret keys from keyserver! - if (entry.mBytes == null && key.isSecret()) { - log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER_SECRET, 2); - badKeys += 1; - continue; - } - SaveKeyringResult result; // synchronizing prevents https://github.com/open-keychain/open-keychain/issues/1221 // and https://github.com/open-keychain/open-keychain/issues/1480 @@ -334,13 +216,9 @@ public class ImportOperation extends BaseReadWriteOperation } importedMasterKeyIds.add(key.getMasterKeyId()); } - if (!skipSave && (entry.mBytes == null)) { - // synonymous to isDownloadFromKeyserver. - // If no byte data was supplied, import from keyserver took place - // this prevents file imports being noted as keyserver imports - mKeyWritableRepository.renewKeyLastUpdatedTime(key.getMasterKeyId(), - GregorianCalendar.getInstance().getTimeInMillis(), - TimeUnit.MILLISECONDS); + + if (!skipSave) { + mKeyWritableRepository.renewKeyLastUpdatedTime(key.getMasterKeyId()); } } @@ -424,6 +302,136 @@ public class ImportOperation extends BaseReadWriteOperation return result; } + private UncachedKeyRing fetchKeyFromInternet(ParcelableHkpKeyserver hkpKeyserver, @NonNull ParcelableProxy proxy, + OperationLog log, ParcelableKeyRing entry, UncachedKeyRing key) throws PgpGeneralException, IOException { + boolean canFetchFromKeyservers = + hkpKeyserver != null && (entry.mKeyIdHex != null || entry.mExpectedFingerprint != null); + if (canFetchFromKeyservers) { + UncachedKeyRing keyserverKey = fetchKeyFromKeyserver(hkpKeyserver, proxy, log, entry); + if (keyserverKey != null) { + key = keyserverKey; + } + } + + boolean hasKeybaseName = entry.mKeybaseName != null; + if (hasKeybaseName) { + UncachedKeyRing keybaseKey = fetchKeyFromKeybase(proxy, log, entry); + if (keybaseKey != null) { + key = mergeKeysOrUseEither(log, 3, key, keybaseKey); + } + } + + boolean hasFacebookName = entry.mFbUsername != null; + if (hasFacebookName) { + UncachedKeyRing facebookKey = fetchKeyFromFacebook(proxy, log, entry); + if (facebookKey != null) { + key = mergeKeysOrUseEither(log, 3, key, facebookKey); + } + } + return key; + } + + @Nullable + private UncachedKeyRing fetchKeyFromKeyserver(ParcelableHkpKeyserver hkpKeyserver, @NonNull ParcelableProxy proxy, + OperationLog log, ParcelableKeyRing entry) throws PgpGeneralException, IOException { + try { + byte[] data; + log.add(LogType.MSG_IMPORT_KEYSERVER, 1, hkpKeyserver); + + // Download by fingerprint, or keyId - whichever is available + if (entry.mExpectedFingerprint != null) { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, "0x" + + entry.mExpectedFingerprint.substring(24)); + data = hkpKeyserver.get("0x" + entry.mExpectedFingerprint, proxy).getBytes(); + } else { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER, 2, entry.mKeyIdHex); + data = hkpKeyserver.get(entry.mKeyIdHex, proxy).getBytes(); + } + UncachedKeyRing keyserverKey = UncachedKeyRing.decodeFromData(data); + if (keyserverKey != null) { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); + } else { + log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); + } + + return keyserverKey; + } catch (Keyserver.QueryFailedException e) { + Log.d(Constants.TAG, "query failed", e); + log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage()); + return null; + } + } + + private UncachedKeyRing fetchKeyFromKeybase(@NonNull ParcelableProxy proxy, OperationLog log, ParcelableKeyRing entry) + throws PgpGeneralException, IOException { + if (keybaseServer == null) { + keybaseServer = KeybaseKeyserver.getInstance(); + } + + try { + log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName); + byte[] data = keybaseServer.get(entry.mKeybaseName, proxy).getBytes(); + UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data); + + if (keybaseKey != null) { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); + } else { + log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); + } + + return keybaseKey; + } catch (Keyserver.QueryFailedException e) { + // download failed, too bad. just proceed + Log.e(Constants.TAG, "query failed", e); + log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage()); + return null; + } + } + + private UncachedKeyRing fetchKeyFromFacebook(@NonNull ParcelableProxy proxy, OperationLog log, ParcelableKeyRing entry) + throws PgpGeneralException, IOException { + if (facebookServer == null) { + facebookServer = FacebookKeyserver.getInstance(); + } + + try { + log.add(LogType.MSG_IMPORT_FETCH_FACEBOOK, 2, entry.mFbUsername); + byte[] data = facebookServer.get(entry.mFbUsername, proxy).getBytes(); + UncachedKeyRing facebookKey = UncachedKeyRing.decodeFromData(data); + + if (facebookKey != null) { + log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_OK, 3); + } else { + log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3); + } + + return facebookKey; + } catch (Keyserver.QueryFailedException e) { + // download failed, too bad. just proceed + Log.e(Constants.TAG, "query failed", e); + log.add(LogType.MSG_IMPORT_FETCH_ERROR_KEYSERVER, 3, e.getMessage()); + return null; + } + } + + @Nullable + private UncachedKeyRing mergeKeysOrUseEither(OperationLog log, int indent, + UncachedKeyRing firstKey, UncachedKeyRing otherKey) { + if (firstKey == null) { + return otherKey; + } + + log.add(LogType.MSG_IMPORT_MERGE, indent); + UncachedKeyRing mergedKey = firstKey.merge(otherKey, log, indent +1); + + if (mergedKey != null) { + return mergedKey; + } else { + log.add(LogType.MSG_IMPORT_MERGE_ERROR, indent +1); + return firstKey; + } + } + @NonNull @Override public ImportKeyResult execute(ImportKeyringParcel importInput, CryptoInputParcel cryptoInput) { @@ -534,7 +542,7 @@ public class ImportOperation extends BaseReadWriteOperation private int mResultType = 0; private boolean mHasCancelledResult; - public ArrayList mCanonicalizedKeyRings; + ArrayList mCanonicalizedKeyRings; /** * Accumulates keyring imports and updates the progressable whenever a new key is imported. @@ -631,7 +639,7 @@ public class ImportOperation extends BaseReadWriteOperation return result; } - public boolean isImportFinished() { + boolean isImportFinished() { return mTotalKeys == mImportedKeys; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyRepository.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyRepository.java index 117caee63..a21db2cce 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyRepository.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyRepository.java @@ -10,6 +10,7 @@ import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; +import android.support.annotation.Nullable; import android.util.Log; import org.sufficientlysecure.keychain.Constants; @@ -23,6 +24,7 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; @@ -253,6 +255,31 @@ public class KeyRepository { return mContentResolver; } + @Nullable + Long getLastUpdateTime(long masterKeyId) { + Cursor lastUpdatedCursor = mContentResolver.query( + UpdatedKeys.CONTENT_URI, + new String[] { UpdatedKeys.LAST_UPDATED }, + UpdatedKeys.MASTER_KEY_ID + " = ?", + new String[] { "" + masterKeyId }, + null + ); + if (lastUpdatedCursor == null) { + return null; + } + + Long lastUpdateTime; + try { + if (!lastUpdatedCursor.moveToNext()) { + return null; + } + lastUpdateTime = lastUpdatedCursor.getLong(0); + } finally { + lastUpdatedCursor.close(); + } + return lastUpdateTime; + } + public final byte[] loadPublicKeyRingData(long masterKeyId) throws NotFoundException { byte[] data = (byte[]) getGenericDataOrNull(KeyRingData.buildPublicKeyRingUri(masterKeyId), KeyRingData.KEY_RING_DATA, FIELD_TYPE_BLOB); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyWritableRepository.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyWritableRepository.java index fec374fdf..64ffe652a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyWritableRepository.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeyWritableRepository.java @@ -24,9 +24,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; -import java.util.concurrent.TimeUnit; import android.content.ContentProviderOperation; import android.content.ContentValues; @@ -517,35 +517,10 @@ public class KeyWritableRepository extends KeyRepository { mIndent -= 1; } - // before deleting key, retrieve it's last updated time - final int INDEX_MASTER_KEY_ID = 0; - final int INDEX_LAST_UPDATED = 1; - Cursor lastUpdatedCursor = mContentResolver.query( - UpdatedKeys.CONTENT_URI, - new String[]{ - UpdatedKeys.MASTER_KEY_ID, - UpdatedKeys.LAST_UPDATED - }, - UpdatedKeys.MASTER_KEY_ID + " = ?", - new String[]{"" + masterKeyId}, - null - ); - if (lastUpdatedCursor.moveToNext()) { - // there was an entry to re-insert - // this operation must happen after the new key is inserted - ContentValues lastUpdatedEntry = new ContentValues(2); - lastUpdatedEntry.put(UpdatedKeys.MASTER_KEY_ID, - lastUpdatedCursor.getLong(INDEX_MASTER_KEY_ID)); - lastUpdatedEntry.put(UpdatedKeys.LAST_UPDATED, - lastUpdatedCursor.getLong(INDEX_LAST_UPDATED)); - operations.add( - ContentProviderOperation - .newInsert(UpdatedKeys.CONTENT_URI) - .withValues(lastUpdatedEntry) - .build() - ); + ContentProviderOperation lastUpdateReinsertOp = getLastUpdatedReinsertOperationByMasterKeyId(masterKeyId); + if (lastUpdateReinsertOp != null) { + operations.add(lastUpdateReinsertOp); } - lastUpdatedCursor.close(); try { // delete old version of this keyRing (from database only!), which also deletes all keys and userIds on cascade @@ -576,6 +551,21 @@ public class KeyWritableRepository extends KeyRepository { } + private ContentProviderOperation getLastUpdatedReinsertOperationByMasterKeyId(long masterKeyId) { + Long lastUpdateTime = getLastUpdateTime(masterKeyId); + if (lastUpdateTime == null) { + return null; + } + + ContentValues lastUpdatedEntry = new ContentValues(2); + lastUpdatedEntry.put(UpdatedKeys.MASTER_KEY_ID, masterKeyId); + lastUpdatedEntry.put(UpdatedKeys.LAST_UPDATED, lastUpdateTime); + return ContentProviderOperation + .newInsert(UpdatedKeys.CONTENT_URI) + .withValues(lastUpdatedEntry) + .build(); + } + private void writePublicKeyRing(CanonicalizedPublicKeyRing keyRing, long masterKeyId, ArrayList operations) throws IOException { byte[] encodedKey = keyRing.getEncoded(); @@ -1363,10 +1353,10 @@ public class KeyWritableRepository extends KeyRepository { return ContentProviderOperation.newInsert(uri).withValues(values).build(); } - public Uri renewKeyLastUpdatedTime(long masterKeyId, long time, TimeUnit timeUnit) { + public Uri renewKeyLastUpdatedTime(long masterKeyId) { ContentValues values = new ContentValues(); values.put(UpdatedKeys.MASTER_KEY_ID, masterKeyId); - values.put(UpdatedKeys.LAST_UPDATED, timeUnit.toSeconds(time)); + values.put(UpdatedKeys.LAST_UPDATED, GregorianCalendar.getInstance().getTimeInMillis() / 1000); return mContentResolver.insert(UpdatedKeys.CONTENT_URI, values); }