aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java3
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java6
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java24
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java40
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java14
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java23
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java4
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml2
-rw-r--r--libraries/spongycastle/pg/src/main/j2me/org/spongycastle/openpgp/PGPSecretKey.java11
-rw-r--r--libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPSecretKey.java11
13 files changed, 130 insertions, 32 deletions
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 8f6b7a758..47e897d6c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java
@@ -42,6 +42,7 @@ public class KeychainContract {
String CAN_ENCRYPT = "can_encrypt";
String CAN_CERTIFY = "can_certify";
String IS_REVOKED = "is_revoked";
+ String HAS_SECRET = "has_secret";
String CREATION = "creation";
String EXPIRY = "expiry";
@@ -106,7 +107,7 @@ public class KeychainContract {
public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID;
public static final String IS_REVOKED = KeysColumns.IS_REVOKED;
public static final String VERIFIED = CertsColumns.VERIFIED;
- public static final String HAS_SECRET = "has_secret";
+ public static final String HAS_ANY_SECRET = "has_any_secret";
public static final String HAS_ENCRYPT = "has_encrypt";
public static final String HAS_SIGN = "has_encrypt";
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 614b166d6..2cd0427b1 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java
@@ -84,6 +84,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ KeysColumns.CAN_SIGN + " BOOLEAN, "
+ KeysColumns.CAN_ENCRYPT + " BOOLEAN, "
+ KeysColumns.IS_REVOKED + " BOOLEAN, "
+ + KeysColumns.HAS_SECRET + " BOOLEAN, "
+ KeysColumns.CREATION + " INTEGER, "
+ KeysColumns.EXPIRY + " INTEGER, "
@@ -187,6 +188,11 @@ public class KeychainDatabase extends SQLiteOpenHelper {
if (!db.isReadOnly()) {
// Enable foreign key constraints
db.execSQL("PRAGMA foreign_keys=ON;");
+ // TODO this is a dev hack, remove for release!
+ try {
+ db.execSQL("ALTER TABLE keys ADD COLUMN has_secret BOOLEAN");
+ } catch(Exception e) {
+ }
}
}
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 1ad42b13a..a201db342 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java
@@ -254,16 +254,18 @@ public class KeychainProvider extends ContentProvider {
projectionMap.put(KeyRings.FINGERPRINT, Keys.FINGERPRINT);
projectionMap.put(KeyRings.USER_ID, UserIds.USER_ID);
projectionMap.put(KeyRings.VERIFIED, KeyRings.VERIFIED);
- projectionMap.put(KeyRings.HAS_SECRET,
+ projectionMap.put(KeyRings.HAS_SECRET, KeyRings.HAS_SECRET);
+ projectionMap.put(KeyRings.HAS_ANY_SECRET,
"(EXISTS (SELECT * FROM " + Tables.KEY_RINGS_SECRET
+ " WHERE " + Tables.KEY_RINGS_SECRET + "." + KeyRingData.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
- + ")) AS " + KeyRings.HAS_SECRET);
+ + ")) AS " + KeyRings.HAS_ANY_SECRET);
projectionMap.put(KeyRings.HAS_ENCRYPT,
"(EXISTS (SELECT COUNT(*) FROM " + Tables.KEYS + " AS k"
+" WHERE k." + Keys.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " AND k." + Keys.IS_REVOKED + " = 0"
+ + " AND k." + Keys.HAS_SECRET + " = 1"
+ " AND k." + Keys.CAN_ENCRYPT + " = 1"
+ " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY
+ " >= '" + new Date().getTime() / 1000 + "' )"
@@ -273,6 +275,7 @@ public class KeychainProvider extends ContentProvider {
+" WHERE k." + Keys.MASTER_KEY_ID
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
+ " AND k." + Keys.IS_REVOKED + " = 0"
+ + " AND k." + Keys.HAS_SECRET + " = 1"
+ " AND k." + Keys.CAN_SIGN + " = 1"
+ " AND ( k." + Keys.EXPIRY + " IS NULL OR k." + Keys.EXPIRY
+ " >= '" + new Date().getTime() / 1000 + "' )"
@@ -373,6 +376,7 @@ public class KeychainProvider extends ContentProvider {
projectionMap.put(Keys.CAN_CERTIFY, Keys.CAN_CERTIFY);
projectionMap.put(Keys.CAN_ENCRYPT, Keys.CAN_ENCRYPT);
projectionMap.put(Keys.CAN_SIGN, Keys.CAN_SIGN);
+ projectionMap.put(Keys.HAS_SECRET, Keys.HAS_SECRET);
projectionMap.put(Keys.CREATION, Keys.CREATION);
projectionMap.put(Keys.EXPIRY, Keys.EXPIRY);
projectionMap.put(Keys.ALGORITHM, Keys.ALGORITHM);
@@ -699,6 +703,20 @@ public class KeychainProvider extends ContentProvider {
try {
final int match = mUriMatcher.match(uri);
switch (match) {
+ case KEY_RING_KEYS: {
+ if (values.size() != 1 || !values.containsKey(Keys.HAS_SECRET)) {
+ throw new UnsupportedOperationException(
+ "Only has_secret column may be updated!");
+ }
+ // make sure we get a long value here
+ Long mkid = Long.parseLong(uri.getPathSegments().get(1));
+ String actualSelection = Keys.MASTER_KEY_ID + " = " + Long.toString(mkid);
+ if (!TextUtils.isEmpty(selection)) {
+ actualSelection += " AND (" + selection + ")";
+ }
+ count = db.update(Tables.KEYS, values, actualSelection, selectionArgs);
+ break;
+ }
case API_APPS_BY_PACKAGE_NAME:
count = db.update(Tables.API_APPS, values,
buildDefaultApiAppsSelection(uri, selection), selectionArgs);
@@ -715,7 +733,7 @@ public class KeychainProvider extends ContentProvider {
getContext().getContentResolver().notifyChange(uri, null);
} catch (SQLiteConstraintException e) {
- Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?");
+ Log.e(Constants.TAG, "Constraint exception on update! Entry already existing?", e);
}
return count;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 1da4ffe55..01e95343d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -28,12 +28,15 @@ import android.net.Uri;
import android.os.RemoteException;
import org.spongycastle.bcpg.ArmoredOutputStream;
+import org.spongycastle.bcpg.S2K;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
+import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.spongycastle.openpgp.PGPSignature;
+import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
@@ -387,13 +390,38 @@ public class ProviderHelper {
public void saveKeyRing(PGPSecretKeyRing keyRing) throws IOException {
long masterKeyId = keyRing.getPublicKey().getKeyID();
+ {
+ Uri uri = Keys.buildKeysUri(Long.toString(masterKeyId));
+
+ // first, mark all keys as not available
+ ContentValues values = new ContentValues();
+ values.put(Keys.HAS_SECRET, 0);
+ mContentResolver.update(uri, values, null, null);
+
+ values.put(Keys.HAS_SECRET, 1);
+ // then, mark exactly the keys we have available
+ for (PGPSecretKey sub : new IterableIterator<PGPSecretKey>(keyRing.getSecretKeys())) {
+ // Set to 1, except if the encryption type is GNU_DUMMY_S2K
+ if(sub.getS2K().getType() != S2K.GNU_DUMMY_S2K) {
+ mContentResolver.update(uri, values, Keys.KEY_ID + " = ?", new String[]{
+ Long.toString(sub.getKeyID())
+ });
+ }
+ }
+ // this implicitly leaves all keys which were not in the secret key ring
+ // with has_secret = 0
+ }
+
// save secret keyring
- ContentValues values = new ContentValues();
- values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
- values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
- // insert new version of this keyRing
- Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
- mContentResolver.insert(uri, values);
+ {
+ ContentValues values = new ContentValues();
+ values.put(KeyRingData.MASTER_KEY_ID, masterKeyId);
+ values.put(KeyRingData.KEY_RING_DATA, keyRing.getEncoded());
+ // insert new version of this keyRing
+ Uri uri = KeyRingData.buildSecretKeyRingUri(Long.toString(masterKeyId));
+ mContentResolver.insert(uri, values);
+ }
+
}
/**
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index bb54a9fe0..c883dee0e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -685,7 +685,7 @@ public class KeychainIntentService extends IntentService
}
Cursor cursor = getContentResolver().query(KeyRings.buildUnifiedKeyRingsUri(),
- new String[]{KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET},
+ new String[]{KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET},
selection, null, null);
try {
cursor.moveToFirst();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index c60acf9a2..2cc3396ec 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -256,7 +256,7 @@ public class KeyListFragment extends Fragment
KeyRings.IS_REVOKED,
KeyRings.EXPIRY,
KeyRings.VERIFIED,
- KeyRings.HAS_SECRET
+ KeyRings.HAS_ANY_SECRET
};
static final int INDEX_MASTER_KEY_ID = 1;
@@ -264,10 +264,10 @@ public class KeyListFragment extends Fragment
static final int INDEX_IS_REVOKED = 3;
static final int INDEX_EXPIRY = 4;
static final int INDEX_VERIFIED = 5;
- static final int INDEX_HAS_SECRET = 6;
+ static final int INDEX_HAS_ANY_SECRET = 6;
static final String ORDER = // IN THE COURT
- KeyRings.HAS_SECRET + " DESC, " + KeyRings.USER_ID + " ASC";
+ KeyRings.HAS_ANY_SECRET + " DESC, " + KeyRings.USER_ID + " ASC";
@Override
@@ -518,7 +518,7 @@ public class KeyListFragment extends Fragment
{ // set edit button and revoked info, specific by key type
- if (cursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
+ if (cursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {
// this is a secret key - show the edit mButton
h.mStatusDivider.setVisibility(View.VISIBLE);
h.mStatusLayout.setVisibility(View.VISIBLE);
@@ -564,7 +564,7 @@ public class KeyListFragment extends Fragment
throw new IllegalStateException("couldn't move cursor to position " + id);
}
- return mCursor.getInt(INDEX_HAS_SECRET) != 0;
+ return mCursor.getInt(INDEX_HAS_ANY_SECRET) != 0;
}
public long getMasterKeyId(int id) {
if (!mCursor.moveToPosition(id)) {
@@ -604,7 +604,7 @@ public class KeyListFragment extends Fragment
throw new IllegalStateException("couldn't move cursor to position " + position);
}
- if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
+ if (mCursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {
{ // set contact count
int num = mCursor.getCount();
String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num);
@@ -643,7 +643,7 @@ public class KeyListFragment extends Fragment
}
// early breakout: all secret keys are assigned id 0
- if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) {
+ if (mCursor.getInt(KeyListFragment.INDEX_HAS_ANY_SECRET) != 0) {
return 1L;
}
// otherwise, return the first character of the name as ID
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
index 47f4f52d7..118449b9b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyFragment.java
@@ -117,10 +117,11 @@ public class SelectSecretKeyFragment extends ListFragment implements
KeyRings.IS_REVOKED,
KeyRings.CAN_CERTIFY,
KeyRings.HAS_SIGN,
- KeyRings.HAS_SECRET
+ KeyRings.HAS_SECRET,
+ KeyRings.HAS_ANY_SECRET
};
- String where = KeyRings.HAS_SECRET + " = 1";
+ String where = KeyRings.HAS_ANY_SECRET + " = 1";
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
@@ -151,7 +152,7 @@ public class SelectSecretKeyFragment extends ListFragment implements
private class SelectSecretKeyCursorAdapter extends SelectKeyCursorAdapter {
- private int mIndexHasSign, mIndexCanCertify;
+ private int mIndexHasSecret, mIndexHasSign, mIndexCanCertify;
public SelectSecretKeyCursorAdapter(Context context, Cursor c, int flags, ListView listView) {
super(context, c, flags, listView);
@@ -161,6 +162,7 @@ public class SelectSecretKeyFragment extends ListFragment implements
protected void initIndex(Cursor cursor) {
super.initIndex(cursor);
if (cursor != null) {
+ mIndexHasSecret = cursor.getColumnIndexOrThrow(KeyRings.HAS_SECRET);
mIndexCanCertify = cursor.getColumnIndexOrThrow(KeyRings.CAN_CERTIFY);
mIndexHasSign = cursor.getColumnIndexOrThrow(KeyRings.HAS_SIGN);
}
@@ -177,8 +179,10 @@ public class SelectSecretKeyFragment extends ListFragment implements
// Special from superclass: Te
boolean enabled = false;
if((Boolean) h.status.getTag()) {
+ if (cursor.getInt(mIndexHasSecret) == 0) {
+ h.status.setText(R.string.no_subkey);
// Check if key is viable for our purposes (certify or sign)
- if(mFilterCertify) {
+ } else if(mFilterCertify) {
if (cursor.getInt(mIndexCanCertify) == 0) {
h.status.setText(R.string.can_certify_not);
} else {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
index 89f6a467b..39eceda81 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -158,13 +158,13 @@ public class ViewKeyMainFragment extends Fragment implements
}
static final String[] UNIFIED_PROJECTION = new String[] {
- KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_SECRET,
+ KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
KeyRings.USER_ID, KeyRings.FINGERPRINT,
KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.EXPIRY,
};
static final int INDEX_UNIFIED_MKI = 1;
- static final int INDEX_UNIFIED_HAS_SECRET = 2;
+ static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2;
static final int INDEX_UNIFIED_UID = 3;
static final int INDEX_UNIFIED_FINGERPRINT = 4;
static final int INDEX_UNIFIED_ALGORITHM = 5;
@@ -174,11 +174,11 @@ public class ViewKeyMainFragment extends Fragment implements
static final String[] KEYS_PROJECTION = new String[] {
Keys._ID,
- Keys.KEY_ID, Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE,
+ Keys.KEY_ID, Keys.RANK, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.HAS_SECRET,
Keys.CAN_CERTIFY, Keys.CAN_ENCRYPT, Keys.CAN_SIGN, Keys.IS_REVOKED,
Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT
};
- static final int KEYS_INDEX_CAN_ENCRYPT = 6;
+ static final int KEYS_INDEX_CAN_ENCRYPT = 7;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
@@ -225,7 +225,7 @@ public class ViewKeyMainFragment extends Fragment implements
mEmail.setText(mainUserId[1]);
mComment.setText(mainUserId[2]);
- if (data.getInt(INDEX_UNIFIED_HAS_SECRET) != 0) {
+ if (data.getInt(INDEX_UNIFIED_HAS_ANY_SECRET) != 0) {
mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
mSecretKey.setText(R.string.secret_key_yes);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
index 534fbfb02..27ba19233 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
@@ -45,9 +45,12 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
private int mIndexCanCertify;
private int mIndexCanEncrypt;
private int mIndexCanSign;
+ private int mIndexHasSecret;
private int mIndexRevokedKey;
private int mIndexExpiry;
+ private boolean hasAnySecret;
+
private ColorStateList mDefaultTextColor;
public ViewKeyKeysAdapter(Context context, Cursor c, int flags) {
@@ -62,6 +65,17 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
public Cursor swapCursor(Cursor newCursor) {
initIndex(newCursor);
+ hasAnySecret = false;
+ if (newCursor != null) {
+ newCursor.moveToFirst();
+ do {
+ if (newCursor.getInt(mIndexHasSecret) != 0) {
+ hasAnySecret = true;
+ break;
+ }
+ } while(newCursor.moveToNext());
+ }
+
return super.swapCursor(newCursor);
}
@@ -80,6 +94,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY);
mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT);
mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN);
+ mIndexHasSecret = cursor.getColumnIndexOrThrow(Keys.HAS_SECRET);
mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED);
mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY);
}
@@ -101,7 +116,13 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
cursor.getInt(mIndexKeySize));
keyId.setText(keyIdStr);
- keyDetails.setText("(" + algorithmStr + ")");
+ // may be set with additional "stripped" later on
+ if (hasAnySecret && cursor.getInt(mIndexHasSecret) == 0) {
+ keyDetails.setText("(" + algorithmStr + ", " +
+ context.getString(R.string.key_stripped) + ")");
+ } else {
+ keyDetails.setText("(" + algorithmStr + ")");
+ }
if (cursor.getInt(mIndexRank) == 0) {
masterKeyIcon.setVisibility(View.INVISIBLE);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index 7b4a7be83..14f7b6810 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -91,10 +91,10 @@ public class DeleteKeyDialogFragment extends DialogFragment {
HashMap<String, Object> data = new ProviderHelper(activity).getUnifiedData(masterKeyId, new String[]{
KeyRings.USER_ID,
- KeyRings.HAS_SECRET
+ KeyRings.HAS_ANY_SECRET
}, new int[]{ProviderHelper.FIELD_TYPE_STRING, ProviderHelper.FIELD_TYPE_INTEGER});
String userId = (String) data.get(KeyRings.USER_ID);
- boolean hasSecret = ((Long) data.get(KeyRings.HAS_SECRET)) == 1;
+ boolean hasSecret = ((Long) data.get(KeyRings.HAS_ANY_SECRET)) == 1;
// Set message depending on which key it is.
mMainMessage.setText(getString(
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index 1cb4da986..0a855ae70 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -535,5 +535,7 @@
<string name="can_certify_not">cannot certify</string>
<string name="error_key_not_found">Key not found!</string>
<string name="error_key_processing">Error processing key!</string>
+ <string name="no_subkey">subkey unavailable</string>
+ <string name="key_stripped">stripped</string>
</resources>
diff --git a/libraries/spongycastle/pg/src/main/j2me/org/spongycastle/openpgp/PGPSecretKey.java b/libraries/spongycastle/pg/src/main/j2me/org/spongycastle/openpgp/PGPSecretKey.java
index 2554be8f1..8552f6fca 100644
--- a/libraries/spongycastle/pg/src/main/j2me/org/spongycastle/openpgp/PGPSecretKey.java
+++ b/libraries/spongycastle/pg/src/main/j2me/org/spongycastle/openpgp/PGPSecretKey.java
@@ -278,7 +278,16 @@ public class PGPSecretKey
{
return pub.getUserIDs();
}
-
+
+ /**
+ * Return the S2K object used to encrypt this secret key.
+ *
+ * @return this secret key's s2k object'
+ */
+ public S2K getS2K() {
+ return secret.getS2K();
+ }
+
/**
* Return any user attribute vectors associated with the key.
*
diff --git a/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPSecretKey.java b/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPSecretKey.java
index c0f7dfa3b..f7e3a50c7 100644
--- a/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPSecretKey.java
+++ b/libraries/spongycastle/pg/src/main/java/org/spongycastle/openpgp/PGPSecretKey.java
@@ -431,7 +431,16 @@ public class PGPSecretKey
{
return pub.getUserIDs();
}
-
+
+ /**
+ * Return the S2K this secret key is encrypted with.
+ *
+ * @return the S2K for this key.
+ */
+ public S2K getS2K() {
+ return secret.getS2K();
+ }
+
/**
* Return any user attribute vectors associated with the key.
*