Fixes for passphrase cache implementation

This commit is contained in:
Dominik 2012-09-12 11:50:30 +02:00
parent 4b8400685a
commit 979aad6589
4 changed files with 23 additions and 95 deletions

View File

@ -21,7 +21,6 @@ import java.security.Security;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.thialfihar.android.apg.helper.PGPMain;
import org.thialfihar.android.apg.service.PassphraseCacheService;
import android.app.Application;
import android.os.Environment;
@ -37,10 +36,6 @@ public class ApgApplication extends Application {
public void onCreate() {
super.onCreate();
/* Start passphrase cache service */
// TODO: not needed anymore!
// PassphraseCacheService.startCacheService(this);
// TODO: Do it better than this!
// this initializes the database to be used in PGPMain
PGPMain.initialize(this);

View File

@ -1,70 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thialfihar.android.apg.service;
public class CachedPassphrase {
private final long timestamp;
private final String passphrase;
public CachedPassphrase(long timestamp, String passPhrase) {
super();
this.timestamp = timestamp;
this.passphrase = passPhrase;
}
public long getTimestamp() {
return timestamp;
}
public String getPassphrase() {
return passphrase;
}
@Override
public int hashCode() {
int hc1 = (int) (this.timestamp & 0xffffffff);
int hc2 = (this.passphrase == null ? 0 : this.passphrase.hashCode());
return (hc1 + hc2) * hc2 + hc1;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof CachedPassphrase)) {
return false;
}
CachedPassphrase o = (CachedPassphrase) other;
if (timestamp != o.timestamp) {
return false;
}
if (passphrase != o.passphrase) {
if (passphrase == null || o.passphrase == null) {
return false;
}
if (!passphrase.equals(o.passphrase)) {
return false;
}
}
return true;
}
@Override
public String toString() {
return "(" + timestamp + ", *******)";
}
}

View File

@ -16,6 +16,7 @@
package org.thialfihar.android.apg.service;
import java.util.Date;
import java.util.HashMap;
import org.spongycastle.openpgp.PGPSecretKey;
@ -35,10 +36,11 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
public class PassphraseCacheService extends Service {
public static final String TAG = Constants.TAG + ": PassphraseCacheService";
public static final String BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE = Constants.INTENT_PREFIX
+ "PASSPHRASE_CACHE_SERVICE";
@ -53,7 +55,7 @@ public class PassphraseCacheService extends Service {
// TODO: This is static to be easily retrieved by getCachedPassphrase()
// To avoid static we would need a messenger from the service back to the activity?
private static HashMap<Long, CachedPassphrase> mPassphraseCache = new HashMap<Long, CachedPassphrase>();
private static HashMap<Long, String> mPassphraseCache = new HashMap<Long, String>();
/**
* This caches a new passphrase by sending a new command to the service. An android service is
@ -65,7 +67,7 @@ public class PassphraseCacheService extends Service {
* @param passphrase
*/
public static void addCachedPassphrase(Context context, long keyId, String passphrase) {
Log.d(Constants.TAG, "cacheNewPassphrase() for " + keyId);
Log.d(TAG, "cacheNewPassphrase() for " + keyId);
Intent intent = new Intent(context, PassphraseCacheService.class);
intent.putExtra(EXTRA_TTL, Preferences.getPreferences(context).getPassPhraseCacheTtl());
@ -98,14 +100,15 @@ public class PassphraseCacheService extends Service {
}
// get cached passphrase
CachedPassphrase cpp = mPassphraseCache.get(realId);
if (cpp == null) {
String cachedPassphrase = mPassphraseCache.get(realId);
if (cachedPassphrase == null) {
return null;
}
// set it again to reset the cache life cycle
addCachedPassphrase(context, realId, cpp.getPassphrase());
Log.d(TAG, "Cache passphrase again when getting it!");
addCachedPassphrase(context, realId, cachedPassphrase);
return cpp.getPassphrase();
return cachedPassphrase;
}
/**
@ -120,6 +123,8 @@ public class PassphraseCacheService extends Service {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "Received broadcast...");
if (action.equals(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
timeout(context, keyId);
@ -129,7 +134,7 @@ public class PassphraseCacheService extends Service {
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE);
LocalBroadcastManager.getInstance(this).registerReceiver(mIntentReceiver, filter);
registerReceiver(mIntentReceiver, filter);
}
}
@ -151,7 +156,7 @@ public class PassphraseCacheService extends Service {
@Override
public void onCreate() {
Log.d(Constants.TAG, "PassphraseCacheService created!");
Log.d(TAG, "onCreate()");
}
/**
@ -159,7 +164,7 @@ public class PassphraseCacheService extends Service {
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(Constants.TAG, "PassphraseCacheService started");
Log.d(TAG, "onStartCommand()");
// register broadcastreceiver
registerReceiver();
@ -169,14 +174,13 @@ public class PassphraseCacheService extends Service {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
String passphrase = intent.getStringExtra(EXTRA_PASSPHRASE);
Log.d(Constants.TAG, "received intent with keyId: " + keyId + ", ttl: " + ttl);
Log.d(TAG, "Received intent in onStartCommand() with keyId: " + keyId + ", ttl: " + ttl);
// add keyId and passphrase to memory
mPassphraseCache.put(keyId,
new CachedPassphrase(System.currentTimeMillis(), passphrase));
mPassphraseCache.put(keyId, passphrase);
// register new alarm with keyId for this passphrase
long triggerTime = System.currentTimeMillis() + ttl;
long triggerTime = new Date().getTime() + (ttl * 1000);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, keyId));
}
@ -191,23 +195,23 @@ public class PassphraseCacheService extends Service {
* @param keyId
*/
private void timeout(Context context, long keyId) {
Log.d(Constants.TAG, "Timeout of " + keyId);
// remove passphrase corresponding to keyId from memory
mPassphraseCache.remove(keyId);
Log.d(TAG, "Timeout of " + keyId + ", removed from memory!");
// stop whole service if no cached passphrases remaining
if (mPassphraseCache.isEmpty()) {
Log.d(Constants.TAG, "No passphrases remaining in memory, stopping service!");
Log.d(TAG, "No passphrases remaining in memory, stopping service!");
stopSelf();
}
}
@Override
public void onDestroy() {
Log.d(Constants.TAG, "PassphraseCacheService destroyed!");
Log.d(TAG, "onDestroy()");
LocalBroadcastManager.getInstance(this).unregisterReceiver(mIntentReceiver);
unregisterReceiver(mIntentReceiver);
}
public class PassphraseCacheBinder extends Binder {

View File

@ -21,7 +21,6 @@ import org.spongycastle.openpgp.PGPEncryptedData;
import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.helper.Preferences;
import org.thialfihar.android.apg.service.PassphraseCacheService;
import org.thialfihar.android.apg.ui.widget.IntegerListPreference;
import org.thialfihar.android.apg.R;