diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-04-16 19:40:36 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-04-16 19:40:36 +0200 |
commit | b0c65729a98dfbd61063491a5facff2f782f56af (patch) | |
tree | a5f6756144051f9d8f804d549276bddde98106c0 /OpenKeychain/src | |
parent | 676262b052b12f1d72162acb9bf435a8630644a0 (diff) | |
parent | 8b4700d5218ce19ca5b51daecda55f2ab4489e17 (diff) | |
download | open-keychain-b0c65729a98dfbd61063491a5facff2f782f56af.tar.gz open-keychain-b0c65729a98dfbd61063491a5facff2f782f56af.tar.bz2 open-keychain-b0c65729a98dfbd61063491a5facff2f782f56af.zip |
Merge pull request #576 from Valodim/stripped-secretkeys
Support stripped secretkeys
Diffstat (limited to 'OpenKeychain/src')
11 files changed, 110 insertions, 30 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> |