From b1a978d573763aa2b867eadf4e3ee8597bd8f0a0 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 5 Feb 2016 19:24:22 +0100 Subject: split off ApiDataAccessObject from ProviderHelper --- .../keychain/provider/ApiDataAccessObject.java | 243 +++++++++++++++++++++ .../keychain/provider/ProviderHelper.java | 230 ++----------------- .../provider/SimpleContentResolverInterface.java | 22 ++ .../keychain/remote/ApiPermissionHelper.java | 17 +- .../keychain/remote/OpenPgpService.java | 11 +- .../remote/ui/AccountSettingsActivity.java | 6 +- .../keychain/remote/ui/AppSettingsActivity.java | 4 +- .../ui/AppSettingsAllowedKeysListFragment.java | 10 +- .../remote/ui/RemoteCreateAccountActivity.java | 11 +- .../keychain/remote/ui/RemoteRegisterActivity.java | 8 +- .../remote/ui/SelectSignKeyIdListFragment.java | 9 +- 11 files changed, 324 insertions(+), 247 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java new file mode 100644 index 000000000..0d3d4dcbd --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java @@ -0,0 +1,243 @@ +package org.sufficientlysecure.keychain.provider; + + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.OperationApplicationException; +import android.database.Cursor; +import android.net.Uri; +import android.os.RemoteException; + +import org.bouncycastle.bcpg.CompressionAlgorithmTags; +import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.remote.AppSettings; + + +public class ApiDataAccessObject { + + private final SimpleContentResolverInterface mQueryInterface; + + public ApiDataAccessObject(Context context) { + final ContentResolver contentResolver = context.getContentResolver(); + mQueryInterface = new SimpleContentResolverInterface() { + @Override + public Cursor query(Uri contentUri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + return contentResolver.query(contentUri, projection, selection, selectionArgs, sortOrder); + } + + @Override + public Uri insert(Uri contentUri, ContentValues values) { + return contentResolver.insert(contentUri, values); + } + + @Override + public int update(Uri contentUri, ContentValues values, String where, String[] selectionArgs) { + return contentResolver.update(contentUri, values, where, selectionArgs); + } + + @Override + public int delete(Uri contentUri, String where, String[] selectionArgs) { + return contentResolver.delete(contentUri, where, selectionArgs); + } + }; + } + + public ApiDataAccessObject(SimpleContentResolverInterface queryInterface) { + mQueryInterface = queryInterface; + } + + public ArrayList getRegisteredApiApps() { + Cursor cursor = mQueryInterface.query(ApiApps.CONTENT_URI, null, null, null, null); + + ArrayList packageNames = new ArrayList<>(); + try { + if (cursor != null) { + int packageNameCol = cursor.getColumnIndex(ApiApps.PACKAGE_NAME); + if (cursor.moveToFirst()) { + do { + packageNames.add(cursor.getString(packageNameCol)); + } while (cursor.moveToNext()); + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return packageNames; + } + + private ContentValues contentValueForApiApps(AppSettings appSettings) { + ContentValues values = new ContentValues(); + values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); + values.put(ApiApps.PACKAGE_CERTIFICATE, appSettings.getPackageCertificate()); + return values; + } + + private ContentValues contentValueForApiAccounts(AccountSettings accSettings) { + ContentValues values = new ContentValues(); + values.put(KeychainContract.ApiAccounts.ACCOUNT_NAME, accSettings.getAccountName()); + values.put(KeychainContract.ApiAccounts.KEY_ID, accSettings.getKeyId()); + + // DEPRECATED and thus hardcoded + values.put(KeychainContract.ApiAccounts.COMPRESSION, CompressionAlgorithmTags.ZLIB); + values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, + PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT); + values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, + PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT); + return values; + } + + public void insertApiApp(AppSettings appSettings) { + mQueryInterface.insert(ApiApps.CONTENT_URI, + contentValueForApiApps(appSettings)); + } + + public void insertApiAccount(Uri uri, AccountSettings accSettings) { + mQueryInterface.insert(uri, contentValueForApiAccounts(accSettings)); + } + + public void updateApiAccount(Uri uri, AccountSettings accSettings) { + if (mQueryInterface.update(uri, contentValueForApiAccounts(accSettings), null, + null) <= 0) { + throw new RuntimeException(); + } + } + + /** + * Must be an uri pointing to an account + */ + public AppSettings getApiAppSettings(Uri uri) { + AppSettings settings = null; + + Cursor cursor = mQueryInterface.query(uri, null, null, null, null); + try { + if (cursor != null && cursor.moveToFirst()) { + settings = new AppSettings(); + settings.setPackageName(cursor.getString( + cursor.getColumnIndex(ApiApps.PACKAGE_NAME))); + settings.setPackageCertificate(cursor.getBlob( + cursor.getColumnIndex(ApiApps.PACKAGE_CERTIFICATE))); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return settings; + } + + public AccountSettings getApiAccountSettings(Uri accountUri) { + AccountSettings settings = null; + + Cursor cursor = mQueryInterface.query(accountUri, null, null, null, null); + try { + if (cursor != null && cursor.moveToFirst()) { + settings = new AccountSettings(); + + settings.setAccountName(cursor.getString( + cursor.getColumnIndex(KeychainContract.ApiAccounts.ACCOUNT_NAME))); + settings.setKeyId(cursor.getLong( + cursor.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID))); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return settings; + } + + public Set getAllKeyIdsForApp(Uri uri) { + Set keyIds = new HashSet<>(); + + Cursor cursor = mQueryInterface.query(uri, null, null, null, null); + try { + if (cursor != null) { + int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID); + while (cursor.moveToNext()) { + keyIds.add(cursor.getLong(keyIdColumn)); + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return keyIds; + } + + public HashSet getAllowedKeyIdsForApp(Uri uri) { + HashSet keyIds = new HashSet<>(); + + Cursor cursor = mQueryInterface.query(uri, null, null, null, null); + try { + if (cursor != null) { + int keyIdColumn = cursor.getColumnIndex(ApiAllowedKeys.KEY_ID); + while (cursor.moveToNext()) { + keyIds.add(cursor.getLong(keyIdColumn)); + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return keyIds; + } + + public void saveAllowedKeyIdsForApp(Uri uri, Set allowedKeyIds) + throws RemoteException, OperationApplicationException { + // wipe whole table of allowed keys for this account + mQueryInterface.delete(uri, null, null); + + // re-insert allowed key ids + for (Long keyId : allowedKeyIds) { + ContentValues values = new ContentValues(); + values.put(ApiAllowedKeys.KEY_ID, keyId); + mQueryInterface.insert(uri, values); + } + } + + public void addAllowedKeyIdForApp(Uri uri, long allowedKeyId) { + ContentValues values = new ContentValues(); + values.put(ApiAllowedKeys.KEY_ID, allowedKeyId); + mQueryInterface.insert(uri, values); + } + + public byte[] getApiAppCertificate(String packageName) { + Uri queryUri = ApiApps.buildByPackageNameUri(packageName); + + String[] projection = new String[]{ApiApps.PACKAGE_CERTIFICATE}; + + Cursor cursor = mQueryInterface.query(queryUri, projection, null, null, null); + try { + byte[] signature = null; + if (cursor != null && cursor.moveToFirst()) { + int signatureCol = 0; + + signature = cursor.getBlob(signatureCol); + } + return signature; + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + +} 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 83e2baf9a..72a3e2ff5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -18,6 +18,18 @@ package org.sufficientlysecure.keychain.provider; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; + import android.content.ContentProviderOperation; import android.content.ContentResolver; import android.content.ContentValues; @@ -29,19 +41,12 @@ import android.os.RemoteException; import android.support.annotation.NonNull; import android.support.v4.util.LongSparseArray; -import org.bouncycastle.bcpg.CompressionAlgorithmTags; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; -import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; -import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.ImportOperation; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult; @@ -51,41 +56,29 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing; -import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants; import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedPublicKey; import org.sufficientlysecure.keychain.pgp.WrappedSignature; +import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys; -import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; +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.Keys; import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys; -import org.sufficientlysecure.keychain.remote.AccountSettings; -import org.sufficientlysecure.keychain.remote.AppSettings; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ParcelableFileCache; +import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; +import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.ProgressFixedScaler; import org.sufficientlysecure.keychain.util.ProgressScaler; import org.sufficientlysecure.keychain.util.Utf8Util; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; - /** * This class contains high level methods for database access. Despite its * name, it is not only a helper but actually the main interface for all @@ -1481,191 +1474,6 @@ public class ProviderHelper { return mContentResolver.insert(UpdatedKeys.CONTENT_URI, values); } - public ArrayList getRegisteredApiApps() { - Cursor cursor = mContentResolver.query(ApiApps.CONTENT_URI, null, null, null, null); - - ArrayList packageNames = new ArrayList<>(); - try { - if (cursor != null) { - int packageNameCol = cursor.getColumnIndex(ApiApps.PACKAGE_NAME); - if (cursor.moveToFirst()) { - do { - packageNames.add(cursor.getString(packageNameCol)); - } while (cursor.moveToNext()); - } - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return packageNames; - } - - private ContentValues contentValueForApiApps(AppSettings appSettings) { - ContentValues values = new ContentValues(); - values.put(ApiApps.PACKAGE_NAME, appSettings.getPackageName()); - values.put(ApiApps.PACKAGE_CERTIFICATE, appSettings.getPackageCertificate()); - return values; - } - - private ContentValues contentValueForApiAccounts(AccountSettings accSettings) { - ContentValues values = new ContentValues(); - values.put(KeychainContract.ApiAccounts.ACCOUNT_NAME, accSettings.getAccountName()); - values.put(KeychainContract.ApiAccounts.KEY_ID, accSettings.getKeyId()); - - // DEPRECATED and thus hardcoded - values.put(KeychainContract.ApiAccounts.COMPRESSION, CompressionAlgorithmTags.ZLIB); - values.put(KeychainContract.ApiAccounts.ENCRYPTION_ALGORITHM, - PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT); - values.put(KeychainContract.ApiAccounts.HASH_ALORITHM, - PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT); - return values; - } - - public void insertApiApp(AppSettings appSettings) { - mContentResolver.insert(KeychainContract.ApiApps.CONTENT_URI, - contentValueForApiApps(appSettings)); - } - - public void insertApiAccount(Uri uri, AccountSettings accSettings) { - mContentResolver.insert(uri, contentValueForApiAccounts(accSettings)); - } - - public void updateApiAccount(Uri uri, AccountSettings accSettings) { - if (mContentResolver.update(uri, contentValueForApiAccounts(accSettings), null, - null) <= 0) { - throw new RuntimeException(); - } - } - - /** - * Must be an uri pointing to an account - */ - public AppSettings getApiAppSettings(Uri uri) { - AppSettings settings = null; - - Cursor cursor = mContentResolver.query(uri, null, null, null, null); - try { - if (cursor != null && cursor.moveToFirst()) { - settings = new AppSettings(); - settings.setPackageName(cursor.getString( - cursor.getColumnIndex(KeychainContract.ApiApps.PACKAGE_NAME))); - settings.setPackageCertificate(cursor.getBlob( - cursor.getColumnIndex(KeychainContract.ApiApps.PACKAGE_CERTIFICATE))); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return settings; - } - - public AccountSettings getApiAccountSettings(Uri accountUri) { - AccountSettings settings = null; - - Cursor cursor = mContentResolver.query(accountUri, null, null, null, null); - try { - if (cursor != null && cursor.moveToFirst()) { - settings = new AccountSettings(); - - settings.setAccountName(cursor.getString( - cursor.getColumnIndex(KeychainContract.ApiAccounts.ACCOUNT_NAME))); - settings.setKeyId(cursor.getLong( - cursor.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID))); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return settings; - } - - public Set getAllKeyIdsForApp(Uri uri) { - Set keyIds = new HashSet<>(); - - Cursor cursor = mContentResolver.query(uri, null, null, null, null); - try { - if (cursor != null) { - int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAccounts.KEY_ID); - while (cursor.moveToNext()) { - keyIds.add(cursor.getLong(keyIdColumn)); - } - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return keyIds; - } - - public HashSet getAllowedKeyIdsForApp(Uri uri) { - HashSet keyIds = new HashSet<>(); - - Cursor cursor = mContentResolver.query(uri, null, null, null, null); - try { - if (cursor != null) { - int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAllowedKeys.KEY_ID); - while (cursor.moveToNext()) { - keyIds.add(cursor.getLong(keyIdColumn)); - } - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - return keyIds; - } - - public void saveAllowedKeyIdsForApp(Uri uri, Set allowedKeyIds) - throws RemoteException, OperationApplicationException { - // wipe whole table of allowed keys for this account - mContentResolver.delete(uri, null, null); - - // re-insert allowed key ids - for (Long keyId : allowedKeyIds) { - ContentValues values = new ContentValues(); - values.put(ApiAllowedKeys.KEY_ID, keyId); - mContentResolver.insert(uri, values); - } - } - - public void addAllowedKeyIdForApp(Uri uri, long allowedKeyId) { - ContentValues values = new ContentValues(); - values.put(ApiAllowedKeys.KEY_ID, allowedKeyId); - mContentResolver.insert(uri, values); - } - - public byte[] getApiAppCertificate(String packageName) { - Uri queryUri = ApiApps.buildByPackageNameUri(packageName); - - String[] projection = new String[]{ApiApps.PACKAGE_CERTIFICATE}; - - Cursor cursor = mContentResolver.query(queryUri, projection, null, null, null); - try { - byte[] signature = null; - if (cursor != null && cursor.moveToFirst()) { - int signatureCol = 0; - - signature = cursor.getBlob(signatureCol); - } - return signature; - } finally { - if (cursor != null) { - cursor.close(); - } - } - } - public ContentResolver getContentResolver() { return mContentResolver; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java new file mode 100644 index 000000000..c47d210a3 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java @@ -0,0 +1,22 @@ +package org.sufficientlysecure.keychain.provider; + + +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +/** This interface contains the principal methods for database access + * from {#android.content.ContentResolver}. It is used to allow substitution + * of a ContentResolver in DAOs. + * + * @see ApiDataAccessObject + */ +public interface SimpleContentResolverInterface { + Cursor query(Uri contentUri, String[] projection, String selection, String[] selectionArgs, String sortOrder); + + Uri insert(Uri contentUri, ContentValues values); + + int update(Uri contentUri, ContentValues values, String where, String[] selectionArgs); + + int delete(Uri contentUri, String where, String[] selectionArgs); +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java index 7edd8b2b0..1a6638bd9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java @@ -33,8 +33,8 @@ import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; import java.io.ByteArrayOutputStream; @@ -49,13 +49,13 @@ import java.util.Arrays; public class ApiPermissionHelper { private final Context mContext; - private final ProviderHelper mProviderHelper; + private final ApiDataAccessObject mApiDao; private PackageManager mPackageManager; - public ApiPermissionHelper(Context context) { + public ApiPermissionHelper(Context context, ApiDataAccessObject apiDao) { mContext = context; mPackageManager = context.getPackageManager(); - mProviderHelper = new ProviderHelper(context); + mApiDao = apiDao; } public static class WrongPackageCertificateException extends Exception { @@ -71,9 +71,8 @@ public class ApiPermissionHelper { * * @return null if caller is allowed, or a Bundle with a PendingIntent */ - protected Intent isAllowed(Intent data) { + protected Intent isAllowedOrReturnIntent(Intent data) { ApiPendingIntentFactory piFactory = new ApiPendingIntentFactory(mContext); - try { if (isCallerAllowed()) { return null; @@ -168,7 +167,7 @@ public class ApiPermissionHelper { Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(currentPkg, accountName); - return mProviderHelper.getApiAccountSettings(uri); // can be null! + return mApiDao.getApiAccountSettings(uri); // can be null! } @Deprecated @@ -224,7 +223,7 @@ public class ApiPermissionHelper { private boolean isPackageAllowed(String packageName) throws WrongPackageCertificateException { Log.d(Constants.TAG, "isPackageAllowed packageName: " + packageName); - ArrayList allowedPkgs = mProviderHelper.getRegisteredApiApps(); + ArrayList allowedPkgs = mApiDao.getRegisteredApiApps(); Log.d(Constants.TAG, "allowed: " + allowedPkgs); // check if package is allowed to use our service @@ -239,7 +238,7 @@ public class ApiPermissionHelper { throw new WrongPackageCertificateException(e.getMessage()); } - byte[] storedCert = mProviderHelper.getApiAppCertificate(packageName); + byte[] storedCert = mApiDao.getApiAppCertificate(packageName); if (Arrays.equals(currentCert, storedCert)) { Log.d(Constants.TAG, "Package certificate is correct! (equals certificate from database)"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 2e14099de..2bf14f876 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -47,6 +47,7 @@ import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants; import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel; import org.sufficientlysecure.keychain.pgp.PgpSignEncryptOperation; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; @@ -82,12 +83,14 @@ public class OpenPgpService extends Service { private ApiPermissionHelper mApiPermissionHelper; private ProviderHelper mProviderHelper; + private ApiDataAccessObject mApiDao; @Override public void onCreate() { super.onCreate(); - mApiPermissionHelper = new ApiPermissionHelper(this); + mApiPermissionHelper = new ApiPermissionHelper(this, new ApiDataAccessObject(this)); mProviderHelper = new ProviderHelper(this); + mApiDao = new ApiDataAccessObject(this); } /** @@ -402,11 +405,11 @@ public class OpenPgpService extends Service { } String currentPkg = mApiPermissionHelper.getCurrentCallingPackage(); - HashSet allowedKeyIds = mProviderHelper.getAllowedKeyIdsForApp( + HashSet allowedKeyIds = mApiDao.getAllowedKeyIdsForApp( KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg)); if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) { - allowedKeyIds.addAll(mProviderHelper.getAllKeyIdsForApp( + allowedKeyIds.addAll(mApiDao.getAllKeyIdsForApp( ApiAccounts.buildBaseUri(currentPkg))); } @@ -732,7 +735,7 @@ public class OpenPgpService extends Service { } // check if caller is allowed to access OpenKeychain - Intent result = mApiPermissionHelper.isAllowed(data); + Intent result = mApiPermissionHelper.isAllowedOrReturnIntent(data); if (result != null) { return result; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java index e19757d65..27700b5e6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java @@ -29,7 +29,7 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.SingletonResult; -import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.util.Log; @@ -98,7 +98,7 @@ public class AccountSettingsActivity extends BaseActivity { } private void loadData(Uri accountUri) { - AccountSettings settings = new ProviderHelper(this).getApiAccountSettings(accountUri); + AccountSettings settings = new ApiDataAccessObject(this).getApiAccountSettings(accountUri); mAccountSettingsFragment.setAccSettings(settings); } @@ -110,7 +110,7 @@ public class AccountSettingsActivity extends BaseActivity { } private void save() { - new ProviderHelper(this).updateApiAccount(mAccountUri, mAccountSettingsFragment.getAccSettings()); + new ApiDataAccessObject(this).updateApiAccount(mAccountUri, mAccountSettingsFragment.getAccSettings()); SingletonResult result = new SingletonResult( SingletonResult.RESULT_OK, LogType.MSG_ACC_SAVED); Intent intent = new Intent(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java index 3b5fdfd8a..249c0c208 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsActivity.java @@ -37,8 +37,8 @@ import org.bouncycastle.util.encoders.Hex; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.dialog.AdvancedAppSettingsDialogFragment; @@ -182,7 +182,7 @@ public class AppSettingsActivity extends BaseActivity { } private void loadData(Bundle savedInstanceState, Uri appUri) { - mAppSettings = new ProviderHelper(this).getApiAppSettings(appUri); + mAppSettings = new ApiDataAccessObject(this).getApiAppSettings(appUri); // get application name and icon from package manager String appName; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java index caa173f03..22a03a7c5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AppSettingsAllowedKeysListFragment.java @@ -36,8 +36,8 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ListFragmentWorkaround; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter; import org.sufficientlysecure.keychain.ui.adapter.KeySelectableAdapter; import org.sufficientlysecure.keychain.ui.widget.FixedListView; @@ -47,7 +47,7 @@ public class AppSettingsAllowedKeysListFragment extends ListFragmentWorkaround i private static final String ARG_DATA_URI = "uri"; private KeySelectableAdapter mAdapter; - private ProviderHelper mProviderHelper; + private ApiDataAccessObject mApiDao; private Uri mDataUri; @@ -69,7 +69,7 @@ public class AppSettingsAllowedKeysListFragment extends ListFragmentWorkaround i public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mProviderHelper = new ProviderHelper(getActivity()); + mApiDao = new ApiDataAccessObject(getActivity()); } @Override @@ -107,7 +107,7 @@ public class AppSettingsAllowedKeysListFragment extends ListFragmentWorkaround i // application this would come from a resource. setEmptyText(getString(R.string.list_empty)); - Set checked = mProviderHelper.getAllKeyIdsForApp(mDataUri); + Set checked = mApiDao.getAllKeyIdsForApp(mDataUri); mAdapter = new KeySelectableAdapter(getActivity(), null, 0, checked); setListAdapter(mAdapter); getListView().setOnItemClickListener(mAdapter); @@ -141,7 +141,7 @@ public class AppSettingsAllowedKeysListFragment extends ListFragmentWorkaround i public void saveAllowedKeys() { try { - mProviderHelper.saveAllowedKeyIdsForApp(mDataUri, getSelectedMasterKeyIds()); + mApiDao.saveAllowedKeyIdsForApp(mDataUri, getSelectedMasterKeyIds()); } catch (RemoteException | OperationApplicationException e) { Log.e(Constants.TAG, "Problem saving allowed key ids!", e); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteCreateAccountActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteCreateAccountActivity.java index adc1f5abf..a4a0b242c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteCreateAccountActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteCreateAccountActivity.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.remote.ui; + import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -25,8 +26,8 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.AccountSettings; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.util.Notify; @@ -56,7 +57,7 @@ public class RemoteCreateAccountActivity extends BaseActivity { final String packageName = extras.getString(EXTRA_PACKAGE_NAME); final String accName = extras.getString(EXTRA_ACC_NAME); - final ProviderHelper providerHelper = new ProviderHelper(this); + final ApiDataAccessObject apiDao = new ApiDataAccessObject(this); mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById( R.id.api_account_settings_fragment); @@ -65,7 +66,7 @@ public class RemoteCreateAccountActivity extends BaseActivity { // update existing? Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(packageName, accName); - AccountSettings settings = providerHelper.getApiAccountSettings(uri); + AccountSettings settings = apiDao.getApiAccountSettings(uri); if (settings == null) { // create new account settings = new AccountSettings(accName); @@ -94,11 +95,11 @@ public class RemoteCreateAccountActivity extends BaseActivity { if (mUpdateExistingAccount) { Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(packageName); Uri accountUri = baseUri.buildUpon().appendEncodedPath(accName).build(); - providerHelper.updateApiAccount( + apiDao.updateApiAccount( accountUri, mAccSettingsFragment.getAccSettings()); } else { - providerHelper.insertApiAccount( + apiDao.insertApiAccount( KeychainContract.ApiAccounts.buildBaseUri(packageName), mAccSettingsFragment.getAccSettings()); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteRegisterActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteRegisterActivity.java index d31f9e35a..0ce9e66c9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteRegisterActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteRegisterActivity.java @@ -17,13 +17,14 @@ package org.sufficientlysecure.keychain.remote.ui; + import android.content.Intent; import android.os.Bundle; import android.view.View; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.remote.AppSettings; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.util.Log; @@ -52,7 +53,7 @@ public class RemoteRegisterActivity extends BaseActivity { final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName); - final ProviderHelper providerHelper = new ProviderHelper(this); + final ApiDataAccessObject apiDao = new ApiDataAccessObject(this); mAppSettingsHeaderFragment = (AppSettingsHeaderFragment) getSupportFragmentManager().findFragmentById( R.id.api_app_settings_fragment); @@ -67,8 +68,7 @@ public class RemoteRegisterActivity extends BaseActivity { @Override public void onClick(View v) { // Allow - - providerHelper.insertApiApp(mAppSettingsHeaderFragment.getAppSettings()); + apiDao.insertApiApp(mAppSettingsHeaderFragment.getAppSettings()); // give data through for new service call Intent resultData = extras.getParcelable(EXTRA_DATA); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java index 852e8bb81..73ce5fe47 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/SelectSignKeyIdListFragment.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.remote.ui; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -36,9 +37,9 @@ import org.openintents.openpgp.util.OpenPgpApi; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ListFragmentWorkaround; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter; import org.sufficientlysecure.keychain.ui.widget.FixedListView; import org.sufficientlysecure.keychain.util.Log; @@ -49,7 +50,7 @@ public class SelectSignKeyIdListFragment extends ListFragmentWorkaround implemen public static final String ARG_DATA = "data"; private SelectKeyCursorAdapter mAdapter; - private ProviderHelper mProviderHelper; + private ApiDataAccessObject mApiDao; private Uri mDataUri; @@ -72,7 +73,7 @@ public class SelectSignKeyIdListFragment extends ListFragmentWorkaround implemen public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mProviderHelper = new ProviderHelper(getActivity()); + mApiDao = new ApiDataAccessObject(getActivity()); } @Override @@ -116,7 +117,7 @@ public class SelectSignKeyIdListFragment extends ListFragmentWorkaround implemen Uri allowedKeysUri = mDataUri.buildUpon().appendPath(KeychainContract.PATH_ALLOWED_KEYS).build(); Log.d(Constants.TAG, "allowedKeysUri: " + allowedKeysUri); - mProviderHelper.addAllowedKeyIdForApp(allowedKeysUri, masterKeyId); + mApiDao.addAllowedKeyIdForApp(allowedKeysUri, masterKeyId); resultData.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, masterKeyId); -- cgit v1.2.3 From da3167476b7e30ba653fc706a4a023ad1e07ea38 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 2 Dec 2015 02:18:14 +0100 Subject: external-provider: add (experimental) external provider --- OpenKeychain/src/main/AndroidManifest.xml | 7 +- .../provider/KeychainExternalContract.java | 35 ++++ .../keychain/remote/KeychainExternalProvider.java | 231 +++++++++++++++++++++ 3 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainExternalContract.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index bbd4b9e63..ee21c19ba 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -806,7 +806,12 @@ android:exported="false" android:label="@string/keyserver_sync_settings_title" /> - + + + + * Copyright (C) 2010-2014 Thialfihar + * Copyright (C) 2014 Vincent Breitmoser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.remote; + + +import java.util.Arrays; +import java.util.HashMap; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.DatabaseUtils; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteQueryBuilder; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.text.TextUtils; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; +import org.sufficientlysecure.keychain.provider.KeychainDatabase; +import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; +import org.sufficientlysecure.keychain.provider.KeychainExternalContract; +import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus; +import org.sufficientlysecure.keychain.util.Log; + + +public class KeychainExternalProvider extends ContentProvider { + private static final int EMAIL_STATUS = 101; + + + protected UriMatcher mUriMatcher; + + + /** + * Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by + * this {@link ContentProvider}. + */ + protected UriMatcher buildUriMatcher() { + final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); + + String authority = KeychainExternalContract.CONTENT_AUTHORITY_EXTERNAL; + + /** + * list email_status + * + *
+         * email_status/
+         * 
+ */ + matcher.addURI(authority, KeychainExternalContract.BASE_EMAIL_STATUS, EMAIL_STATUS); + + return matcher; + } + + private KeychainDatabase mKeychainDatabase; + + /** {@inheritDoc} */ + @Override + public boolean onCreate() { + mUriMatcher = buildUriMatcher(); + return true; + } + + public KeychainDatabase getDb() { + if(mKeychainDatabase == null) + mKeychainDatabase = new KeychainDatabase(getContext()); + return mKeychainDatabase; + } + + /** + * {@inheritDoc} + */ + @Override + public String getType(@NonNull Uri uri) { + final int match = mUriMatcher.match(uri); + switch (match) { + case EMAIL_STATUS: + return EmailStatus.CONTENT_TYPE; + + default: + throw new UnsupportedOperationException("Unknown uri: " + uri); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + Log.v(Constants.TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")"); + + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + + int match = mUriMatcher.match(uri); + + String groupBy; + + switch (match) { + case EMAIL_STATUS: { + HashMap projectionMap = new HashMap<>(); + projectionMap.put(EmailStatus._ID, "email AS _id"); + projectionMap.put(EmailStatus.EMAIL_ADDRESS, + Tables.USER_PACKETS + "." + UserPackets.USER_ID + " AS " + EmailStatus.EMAIL_ADDRESS); + // we take the minimum (>0) here, where "1" is "verified by known secret key", "2" is "self-certified" + projectionMap.put(EmailStatus.EMAIL_STATUS, "CASE ( MIN (" + Certs.VERIFIED + " ) ) " + // remap to keep this provider contract independent from our internal representation + + " WHEN " + Certs.VERIFIED_SELF + " THEN 1" + + " WHEN " + Certs.VERIFIED_SECRET + " THEN 2" + + " END AS " + EmailStatus.EMAIL_STATUS); + qb.setProjectionMap(projectionMap); + + if (projection == null) { + throw new IllegalArgumentException("Please provide a projection!"); + } + + qb.setTables( + Tables.USER_PACKETS + + " INNER JOIN " + Tables.CERTS + " ON (" + + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = " + + Tables.CERTS + "." + Certs.MASTER_KEY_ID + + " AND " + Tables.USER_PACKETS + "." + UserPackets.RANK + " = " + + Tables.CERTS + "." + Certs.RANK + // verified == 0 has no self-cert, which is basically an error case. never return that! + + " AND " + Tables.CERTS + "." + Certs.VERIFIED + " > 0" + + ")" + ); + qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.USER_ID + " IS NOT NULL"); + // in case there are multiple verifying certificates + groupBy = Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + ", " + + Tables.USER_PACKETS + "." + UserPackets.USER_ID; + + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = EmailStatus.EMAIL_ADDRESS + " ASC, " + EmailStatus.EMAIL_STATUS + " DESC"; + } + + // uri to watch is all /key_rings/ + uri = KeyRings.CONTENT_URI; + + boolean gotCondition = false; + String emailWhere = ""; + // JAVA ♥ + for (int i = 0; i < selectionArgs.length; ++i) { + if (selectionArgs[i].length() == 0) { + continue; + } + if (i != 0) { + emailWhere += " OR "; + } + emailWhere += UserPackets.USER_ID + " LIKE "; + // match '*', so it has to be at the *end* of the user id + emailWhere += DatabaseUtils.sqlEscapeString("%<" + selectionArgs[i] + ">"); + gotCondition = true; + } + + if (gotCondition) { + qb.appendWhere(" AND (" + emailWhere + ")"); + } else { + // TODO better way to do this? + Log.e(Constants.TAG, "Malformed find by email query!"); + qb.appendWhere(" AND 0"); + } + + break; + } + + default: { + throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")"); + } + + } + + // If no sort order is specified use the default + String orderBy; + if (TextUtils.isEmpty(sortOrder)) { + orderBy = null; + } else { + orderBy = sortOrder; + } + + SQLiteDatabase db = getDb().getReadableDatabase(); + + Cursor cursor = qb.query(db, projection, selection, null, groupBy, null, orderBy); + if (cursor != null) { + // Tell the cursor what uri to watch, so it knows when its source data changes + cursor.setNotificationUri(getContext().getContentResolver(), uri); + } + + Log.d(Constants.TAG, + "Query: " + qb.buildQuery(projection, selection, null, null, orderBy, null)); + + return cursor; + } + + @Override + public Uri insert(@NonNull Uri uri, ContentValues values) { + throw new UnsupportedOperationException(); + } + + @Override + public int delete(@NonNull Uri uri, String additionalSelection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + + @Override + public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + +} -- cgit v1.2.3 From 1c256e9e50547f92f7e468fadd442157155d57c8 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 5 Feb 2016 19:24:30 +0100 Subject: external-provider: add permission check for status query --- .../keychain/provider/KeychainProvider.java | 2 +- .../keychain/remote/ApiPermissionHelper.java | 11 +++++ .../keychain/remote/KeychainExternalProvider.java | 47 +++++++++++++++++++--- .../keychain/remote/OpenPgpService.java | 1 + 4 files changed, 54 insertions(+), 7 deletions(-) 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 87b8a3b65..0cb8e4675 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2010-2014 Thialfihar - * Copyright (C) 2014 Vincent Breitmoser + * Copyright (C) 2014-2016 Vincent Breitmoser * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java index 1a6638bd9..3af8e70dd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ApiPermissionHelper.java @@ -66,6 +66,17 @@ public class ApiPermissionHelper { } } + /** Returns true iff the caller is allowed, or false on any type of problem. + * This method should only be used in cases where error handling is dealt with separately. + */ + protected boolean isAllowedIgnoreErrors() { + try { + return isCallerAllowed(); + } catch (WrongPackageCertificateException e) { + return false; + } + } + /** * Checks if caller is allowed to access the API * diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java index 9ab4be08a..7eb5d558f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/KeychainExternalProvider.java @@ -1,7 +1,5 @@ /* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010-2014 Thialfihar - * Copyright (C) 2014 Vincent Breitmoser + * Copyright (C) 2016 Vincent Breitmoser * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +18,7 @@ package org.sufficientlysecure.keychain.remote; +import java.security.AccessControlException; import java.util.Arrays; import java.util.HashMap; @@ -35,6 +34,9 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; @@ -42,14 +44,18 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables; import org.sufficientlysecure.keychain.provider.KeychainExternalContract; import org.sufficientlysecure.keychain.provider.KeychainExternalContract.EmailStatus; +import org.sufficientlysecure.keychain.provider.SimpleContentResolverInterface; import org.sufficientlysecure.keychain.util.Log; -public class KeychainExternalProvider extends ContentProvider { +public class KeychainExternalProvider extends ContentProvider implements SimpleContentResolverInterface { private static final int EMAIL_STATUS = 101; + private static final int API_APPS = 301; + private static final int API_APPS_BY_PACKAGE_NAME = 302; - protected UriMatcher mUriMatcher; + private UriMatcher mUriMatcher; + private ApiPermissionHelper mApiPermissionHelper; /** @@ -70,6 +76,9 @@ public class KeychainExternalProvider extends ContentProvider { */ matcher.addURI(authority, KeychainExternalContract.BASE_EMAIL_STATUS, EMAIL_STATUS); + matcher.addURI(KeychainContract.CONTENT_AUTHORITY, KeychainContract.BASE_API_APPS, API_APPS); + matcher.addURI(KeychainContract.CONTENT_AUTHORITY, KeychainContract.BASE_API_APPS + "/*", API_APPS_BY_PACKAGE_NAME); + return matcher; } @@ -79,6 +88,7 @@ public class KeychainExternalProvider extends ContentProvider { @Override public boolean onCreate() { mUriMatcher = buildUriMatcher(); + mApiPermissionHelper = new ApiPermissionHelper(getContext(), new ApiDataAccessObject(this)); return true; } @@ -98,6 +108,12 @@ public class KeychainExternalProvider extends ContentProvider { case EMAIL_STATUS: return EmailStatus.CONTENT_TYPE; + case API_APPS: + return ApiApps.CONTENT_TYPE; + + case API_APPS_BY_PACKAGE_NAME: + return ApiApps.CONTENT_ITEM_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -115,10 +131,15 @@ public class KeychainExternalProvider extends ContentProvider { int match = mUriMatcher.match(uri); - String groupBy; + String groupBy = null; switch (match) { case EMAIL_STATUS: { + boolean callerIsAllowed = mApiPermissionHelper.isAllowedIgnoreErrors(); + if (!callerIsAllowed) { + throw new AccessControlException("An application must register before use of KeychainExternalProvider!"); + } + HashMap projectionMap = new HashMap<>(); projectionMap.put(EmailStatus._ID, "email AS _id"); projectionMap.put(EmailStatus.EMAIL_ADDRESS, @@ -185,6 +206,20 @@ public class KeychainExternalProvider extends ContentProvider { break; } + case API_APPS: { + qb.setTables(Tables.API_APPS); + + break; + } + + case API_APPS_BY_PACKAGE_NAME: { + qb.setTables(Tables.API_APPS); + qb.appendWhere(ApiApps.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; + } + default: { throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")"); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 2bf14f876..d92393e64 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -1,5 +1,6 @@ /* * Copyright (C) 2013-2015 Dominik Schürmann + * Copyright (C) 2016 Vincent Breitmoser * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3 From 31b27e59ee8f578be35df1e4ece3c4381c5dfae5 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 Feb 2016 16:29:41 +0100 Subject: add ACTION_CHECK_PERMISSION for a simple permission check --- .../sufficientlysecure/keychain/remote/OpenPgpService.java | 13 +++++++++++++ extern/openpgp-api-lib | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index d92393e64..91d3cda7c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -674,6 +674,16 @@ public class OpenPgpService extends Service { } } + private Intent checkPermissionImpl(@NonNull Intent data) { + Intent permissionIntent = mApiPermissionHelper.isAllowedOrReturnIntent(data); + if (permissionIntent != null) { + return permissionIntent; + } + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + return result; + } + private Intent getSignKeyMasterId(Intent data) { // NOTE: Accounts are deprecated on API version >= 7 if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) { @@ -803,6 +813,9 @@ public class OpenPgpService extends Service { String action = data.getAction(); switch (action) { + case OpenPgpApi.ACTION_CHECK_PERMISSION: { + return checkPermissionImpl(data); + } case OpenPgpApi.ACTION_CLEARTEXT_SIGN: { return signImpl(data, inputStream, outputStream, true); } diff --git a/extern/openpgp-api-lib b/extern/openpgp-api-lib index 075616c46..e177b56ab 160000 --- a/extern/openpgp-api-lib +++ b/extern/openpgp-api-lib @@ -1 +1 @@ -Subproject commit 075616c461f5ce2bd76a4078c31a51a6ee6b8605 +Subproject commit e177b56ab36056f6e79fc0ae4dc4875c9a2941f6 -- cgit v1.2.3 From 6a853f4c84e66aee70e3e1cd784ddbb8c1deac00 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 23 Feb 2016 17:08:17 +0100 Subject: wip --- .../keychain/remote/OpenPgpService.java | 130 ++++++++++++++------- 1 file changed, 88 insertions(+), 42 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 91d3cda7c..10b137b4f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -18,6 +18,17 @@ package org.sufficientlysecure.keychain.remote; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; + import android.app.PendingIntent; import android.app.Service; import android.content.Intent; @@ -42,6 +53,8 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel; import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; +import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.KeyRing.UserId; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation; import org.sufficientlysecure.keychain.pgp.PgpSecurityConstants; @@ -60,18 +73,9 @@ import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; - public class OpenPgpService extends Service { - static final String[] EMAIL_SEARCH_PROJECTION = new String[]{ + static final String[] KEY_SEARCH_PROJECTION = new String[]{ KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.IS_EXPIRED, @@ -79,7 +83,7 @@ public class OpenPgpService extends Service { }; // do not pre-select revoked or expired keys - static final String EMAIL_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED + static final String KEY_SEARCH_WHERE = Tables.KEYS + "." + KeychainContract.KeyRings.IS_REVOKED + " = 0 AND " + KeychainContract.KeyRings.IS_EXPIRED + " = 0"; private ApiPermissionHelper mApiPermissionHelper; @@ -94,22 +98,35 @@ public class OpenPgpService extends Service { mApiDao = new ApiDataAccessObject(this); } - /** - * Search database for key ids based on emails. - */ - private Intent returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds) { + private static class KeyIdResult { + final Intent mRequiredUserInteraction; + final HashSet mKeyIds; + + KeyIdResult(Intent requiredUserInteraction) { + mRequiredUserInteraction = requiredUserInteraction; + mKeyIds = null; + } + KeyIdResult(HashSet keyIds) { + mRequiredUserInteraction = null; + mKeyIds = keyIds; + } + } + + private KeyIdResult returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds) { boolean noUserIdsCheck = (encryptionUserIds == null || encryptionUserIds.length == 0); boolean missingUserIdsCheck = false; boolean duplicateUserIdsCheck = false; - ArrayList keyIds = new ArrayList<>(); + HashSet keyIds = new HashSet<>(); ArrayList missingEmails = new ArrayList<>(); ArrayList duplicateEmails = new ArrayList<>(); if (!noUserIdsCheck) { - for (String email : encryptionUserIds) { + for (String rawUserId : encryptionUserIds) { + UserId userId = KeyRing.splitUserId(rawUserId); + String email = userId.email != null ? userId.email : rawUserId; // try to find the key for this specific email Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email); - Cursor cursor = getContentResolver().query(uri, EMAIL_SEARCH_PROJECTION, EMAIL_SEARCH_WHERE, null, null); + Cursor cursor = getContentResolver().query(uri, KEY_SEARCH_PROJECTION, KEY_SEARCH_WHERE, null, null); try { // result should be one entry containing the key id if (cursor != null && cursor.moveToFirst()) { @@ -138,15 +155,11 @@ public class OpenPgpService extends Service { } } - // convert ArrayList to long[] - long[] keyIdsArray = new long[keyIds.size()]; - for (int i = 0; i < keyIdsArray.length; i++) { - keyIdsArray[i] = keyIds.get(i); - } - if (noUserIdsCheck || missingUserIdsCheck || duplicateUserIdsCheck) { // allow the user to verify pub key selection + // convert ArrayList to long[] + long[] keyIdsArray = getUnboxedLongArray(keyIds); ApiPendingIntentFactory piFactory = new ApiPendingIntentFactory(getBaseContext()); PendingIntent pi = piFactory.createSelectPublicKeyPendingIntent(data, keyIdsArray, missingEmails, duplicateEmails, noUserIdsCheck); @@ -155,18 +168,15 @@ public class OpenPgpService extends Service { Intent result = new Intent(); result.putExtra(OpenPgpApi.RESULT_INTENT, pi); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); - return result; + return new KeyIdResult(result); } else { // everything was easy, we have exactly one key for every email - if (keyIdsArray.length == 0) { + if (keyIds.isEmpty()) { Log.e(Constants.TAG, "keyIdsArray.length == 0, should never happen!"); } - Intent result = new Intent(); - result.putExtra(OpenPgpApi.RESULT_KEY_IDS, keyIdsArray); - result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); - return result; + return new KeyIdResult(keyIds); } } @@ -281,20 +291,31 @@ public class OpenPgpService extends Service { compressionId = PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.UNCOMPRESSED; } - // first try to get key ids from non-ambiguous key id extra - long[] keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS); - if (keyIds == null) { + long[] keyIds; + { + HashSet encryptKeyIds = new HashSet<>(); + // get key ids based on given user ids - String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); - // give params through to activity... - Intent result = returnKeyIdsFromEmails(data, userIds); + if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) { + String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); + data.removeExtra(OpenPgpApi.EXTRA_USER_IDS); + // give params through to activity... + KeyIdResult result = returnKeyIdsFromEmails(data, userIds); + + if (result.mRequiredUserInteraction != null) { + return result.mRequiredUserInteraction; + } + encryptKeyIds.addAll(result.mKeyIds); + } - if (result.getIntExtra(OpenPgpApi.RESULT_CODE, 0) == OpenPgpApi.RESULT_CODE_SUCCESS) { - keyIds = result.getLongArrayExtra(OpenPgpApi.RESULT_KEY_IDS); - } else { - // if not success -> result contains a PendingIntent for user interaction - return result; + // add key ids from non-ambiguous key id extra + if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) { + for (long keyId : data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS)) { + encryptKeyIds.add(keyId); + } } + + keyIds = getUnboxedLongArray(encryptKeyIds); } // TODO this is not correct! @@ -670,8 +691,33 @@ public class OpenPgpService extends Service { } else { // get key ids based on given user ids String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); - return returnKeyIdsFromEmails(data, userIds); + data.removeExtra(OpenPgpApi.EXTRA_USER_IDS); + KeyIdResult keyResult = returnKeyIdsFromEmails(data, userIds); + if (keyResult.mRequiredUserInteraction != null) { + return keyResult.mRequiredUserInteraction; + } + + if (keyResult.mKeyIds == null) { + throw new AssertionError("one of requiredUserInteraction and keyIds must be non-null, this is a bug!"); + } + + long[] keyIds = getUnboxedLongArray(keyResult.mKeyIds); + + Intent resultIntent = new Intent(); + resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS); + resultIntent.putExtra(OpenPgpApi.RESULT_KEY_IDS, keyIds); + return resultIntent; + } + } + + @NonNull + private static long[] getUnboxedLongArray(@NonNull Collection arrayList) { + long[] result = new long[arrayList.size()]; + int i = 0; + for (Long e : arrayList) { + result[i++] = e; } + return result; } private Intent checkPermissionImpl(@NonNull Intent data) { -- cgit v1.2.3 From 5989b7b4b82c4d645fab1793de32c051fa68428d Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 24 Feb 2016 19:08:20 +0100 Subject: add some license headers --- .../keychain/provider/ApiDataAccessObject.java | 18 ++++++++++++++++++ .../keychain/provider/KeychainExternalContract.java | 17 +++++++++++++++++ .../provider/SimpleContentResolverInterface.java | 17 +++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java index 0d3d4dcbd..7c8295ad5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ApiDataAccessObject.java @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2014-2016 Vincent Breitmoser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package org.sufficientlysecure.keychain.provider; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainExternalContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainExternalContract.java index 07a28d710..a4d35f168 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainExternalContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainExternalContract.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2016 Vincent Breitmoser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package org.sufficientlysecure.keychain.provider; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java index c47d210a3..0e4d76aa4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/SimpleContentResolverInterface.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2016 Vincent Breitmoser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package org.sufficientlysecure.keychain.provider; -- cgit v1.2.3 From 05accb49066a2693cfc1c92e29ad10112f957495 Mon Sep 17 00:00:00 2001 From: "tdjogi010@gmail.com" Date: Wed, 2 Mar 2016 02:51:25 +0530 Subject: Alert for Stripping Subkeys. --- .../keychain/ui/dialog/EditSubkeyDialogFragment.java | 17 ++++++++++++++++- OpenKeychain/src/main/res/values/strings.xml | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java index b51648740..c34312e79 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java @@ -75,7 +75,22 @@ public class EditSubkeyDialogFragment extends DialogFragment { sendMessageToHandler(MESSAGE_REVOKE, null); break; case 2: - sendMessageToHandler(MESSAGE_STRIP, null); + CustomAlertDialogBuilder stripAlertDialog = new CustomAlertDialogBuilder(getActivity()); + stripAlertDialog.setTitle(getResources().getString(R.string.title_alert_strip)). + setMessage(R.string.alert_strip).setCancelable(true); + stripAlertDialog.setPositiveButton(R.string.strip, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + sendMessageToHandler(MESSAGE_STRIP, null); + } + }); + stripAlertDialog.setNegativeButton(R.string.btn_do_not_save, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + dismiss(); + } + }); + stripAlertDialog.show(); break; case 3: sendMessageToHandler(MESSAGE_MOVE_KEY_TO_CARD, null); diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 9920d8057..f4c51e8c5 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -40,6 +40,7 @@ "Advanced" "Delete YOUR key '%s'?" "Manage my keys" + "Strip this Subkey" "Identities" @@ -291,6 +292,7 @@ "Error: %s" "Dark" "Light" + "Strip it" "Certify" @@ -331,6 +333,7 @@ "Delete key '%s'?" "Also export secret keys" "You encountered a known bug with Android. Please reinstall OpenKeychain if you want to link your contacts with keys." + "Stripping this Subkey will render it useless." "Successfully exported 1 key." "Successfully exported %d keys." -- cgit v1.2.3 From ece848dee87c4e068189d511a51e28a7f2525f38 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Wed, 2 Mar 2016 00:07:34 +0100 Subject: Fix backup code comparison --- .../sufficientlysecure/keychain/ui/BackupCodeFragment.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java index a9dfaa2c5..47552bf13 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java @@ -351,27 +351,28 @@ public class BackupCodeFragment extends CryptoOperationFragment Date: Tue, 1 Mar 2016 17:41:04 +0100 Subject: some changelog for v3.9 --- OpenKeychain/src/main/res/raw/help_changelog.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OpenKeychain/src/main/res/raw/help_changelog.md b/OpenKeychain/src/main/res/raw/help_changelog.md index ec6a732c1..5babf658a 100644 --- a/OpenKeychain/src/main/res/raw/help_changelog.md +++ b/OpenKeychain/src/main/res/raw/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing -- cgit v1.2.3 From 8e00465c320647a7a602861f05b25705bc79b3a4 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 2 Mar 2016 14:42:44 +0100 Subject: nfc: disable broadcomWorkaround for TagDispatcher to reduce delay (see #1734) --- .../keychain/ui/base/BaseSecurityTokenNfcActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java index ae1944ced..c3352363a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseSecurityTokenNfcActivity.java @@ -199,7 +199,7 @@ public abstract class BaseSecurityTokenNfcActivity extends BaseActivity implemen protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mTagDispatcher = TagDispatcher.get(this, this, false, false); + mTagDispatcher = TagDispatcher.get(this, this, false, false, true, false); // Check whether we're recreating a previously destroyed instance if (savedInstanceState != null) { -- cgit v1.2.3 From 2e69952326a034bb9f1bdba4573adc9af9be3c2b Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 2 Mar 2016 15:08:57 +0100 Subject: small nullpointer fix --- .../sufficientlysecure/keychain/keyimport/FacebookKeyserver.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 d87a82a24..faa2a1848 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java @@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.keyimport; import android.net.Uri; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; @@ -37,7 +38,6 @@ import org.sufficientlysecure.keychain.util.Log; import java.io.IOException; import java.net.Proxy; -import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -190,8 +190,11 @@ public class FacebookKeyserver extends Keyserver { return uri.getPathSegments().get(0); } - public static boolean isFacebookHost(Uri uri) { + public static boolean isFacebookHost(@Nullable Uri uri) { + if (uri == null) { + return false; + } String host = uri.getHost(); - return host.equalsIgnoreCase(FB_HOST) || host.equalsIgnoreCase(FB_HOST_WWW); + return FB_HOST.equalsIgnoreCase(host) || FB_HOST_WWW.equalsIgnoreCase(host); } } -- cgit v1.2.3 From c7761d09cbd5a148d16760afeddefb89ee469364 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 2 Mar 2016 15:12:14 +0100 Subject: handle openpgp4fpr intent filter as import rather than certify (see #1661) --- OpenKeychain/src/main/AndroidManifest.xml | 32 ++++++++++++---------- .../keychain/ui/ImportKeysActivity.java | 5 +++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index ee21c19ba..771f1b2e9 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -503,21 +503,6 @@ android:theme="@style/Theme.Keychain.Transparent" android:windowSoftInputMode="stateHidden"> - - - - - - - - - - - - - - @@ -730,6 +715,23 @@ + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index f67c6a724..72e42eec3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -131,8 +131,11 @@ public class ImportKeysActivity extends BaseActivity if (Intent.ACTION_VIEW.equals(action)) { if (FacebookKeyserver.isFacebookHost(dataUri)) { action = ACTION_IMPORT_KEY_FROM_FACEBOOK; - } else if ("http".equals(scheme) || "https".equals(scheme)) { + } else if ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)) { action = ACTION_SEARCH_KEYSERVER_FROM_URL; + } else if ("openpgp4fpr".equalsIgnoreCase(scheme)) { + action = ACTION_IMPORT_KEY_FROM_KEYSERVER; + extras.putString(EXTRA_FINGERPRINT, dataUri.getSchemeSpecificPart()); } else { // Android's Action when opening file associated to Keychain (see AndroidManifest.xml) // delegate action to ACTION_IMPORT_KEY -- cgit v1.2.3 From 1d78f9c93300a9934acbd47471e7208d7d0a0fa9 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 2 Mar 2016 15:29:50 +0100 Subject: update openpgp-api-lib to v11 (closes #1735) --- extern/openpgp-api-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/openpgp-api-lib b/extern/openpgp-api-lib index e177b56ab..3b6681ecf 160000 --- a/extern/openpgp-api-lib +++ b/extern/openpgp-api-lib @@ -1 +1 @@ -Subproject commit e177b56ab36056f6e79fc0ae4dc4875c9a2941f6 +Subproject commit 3b6681ecf669c4662d4a7cf4d276840e8bd40e7d -- cgit v1.2.3 From 4b3d584d1e3328565b918e437e073700ca797202 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 2 Mar 2016 16:05:52 +0100 Subject: add v11 to supported api versions --- .../org/sufficientlysecure/keychain/remote/OpenPgpService.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 10b137b4f..2d70f3681 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -25,6 +25,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -75,6 +76,9 @@ import org.sufficientlysecure.keychain.util.Passphrase; public class OpenPgpService extends Service { + public static final List SUPPORTED_VERSIONS = + Collections.unmodifiableList(Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10, 11)); + static final String[] KEY_SEARCH_PROJECTION = new String[]{ KeyRings._ID, KeyRings.MASTER_KEY_ID, @@ -779,13 +783,12 @@ public class OpenPgpService extends Service { // version code is required and needs to correspond to version code of service! // History of versions in openpgp-api's CHANGELOG.md - List supportedVersions = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10); - if (!supportedVersions.contains(data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1))) { + if (!SUPPORTED_VERSIONS.contains(data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1))) { Intent result = new Intent(); OpenPgpError error = new OpenPgpError (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!\n" + "used API version: " + data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) + "\n" - + "supported API versions: " + supportedVersions); + + "supported API versions: " + SUPPORTED_VERSIONS); result.putExtra(OpenPgpApi.RESULT_ERROR, error); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); return result; -- cgit v1.2.3 From 81ba0ff108310d70dfbec30261276c75d2286121 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Wed, 2 Mar 2016 17:09:12 +0100 Subject: Always check read permission --- .../sufficientlysecure/keychain/ui/ImportKeysListFragment.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index b399af950..18063ed1a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -330,9 +330,16 @@ public class ImportKeysListFragment extends ListFragment implements } public void loadNew(LoaderState loaderState) { - mLoaderState = loaderState; + if (mLoaderState instanceof BytesLoaderState) { + BytesLoaderState ls = (BytesLoaderState) mLoaderState; + + if ( ! checkAndRequestReadPermission(ls.mDataUri)) { + return; + } + } + restartLoaders(); } -- cgit v1.2.3 From e422b3af045768e64c555e33ea333e3712adc378 Mon Sep 17 00:00:00 2001 From: Advaita Date: Thu, 3 Mar 2016 01:52:21 +0530 Subject: Update ContactSyncAdapterService.java --- .../keychain/service/ContactSyncAdapterService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java index cdfe2f1ce..15f8a47db 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ContactSyncAdapterService.java @@ -143,6 +143,13 @@ public class ContactSyncAdapterService extends Service { } public static void requestContactsSync() { + // if user has disabled automatic sync, do nothing + if (!ContentResolver.getSyncAutomatically( + new Account(Constants.ACCOUNT_NAME, Constants.ACCOUNT_TYPE), + ContactsContract.AUTHORITY)) { + return; + } + Bundle extras = new Bundle(); // no need to wait, do it immediately extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); -- cgit v1.2.3 From a3a87fad8750d72de6c1505f784812f1fb5371a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Mar 2016 13:12:51 +0100 Subject: Update openpgp-api submodule --- extern/openpgp-api-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/openpgp-api-lib b/extern/openpgp-api-lib index 3b6681ecf..8ca0f578b 160000 --- a/extern/openpgp-api-lib +++ b/extern/openpgp-api-lib @@ -1 +1 @@ -Subproject commit 3b6681ecf669c4662d4a7cf4d276840e8bd40e7d +Subproject commit 8ca0f578bb843db7744dbd5724b32f6664b5c3db -- cgit v1.2.3 From 7d3b903690708f22e853b2fccc64f192bc8535b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Mar 2016 13:31:46 +0100 Subject: Transifex: pt_BR --- .tx/config | 2 +- OpenKeychain/src/main/res/raw-cs/help_about.md | 2 +- OpenKeychain/src/main/res/raw-cs/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-de/help_about.md | 2 +- OpenKeychain/src/main/res/raw-de/help_changelog.md | 9 +- OpenKeychain/src/main/res/raw-es-rMX/help_about.md | 2 +- .../src/main/res/raw-es-rMX/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-es/help_about.md | 2 +- OpenKeychain/src/main/res/raw-es/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-eu/advanced.md | 14 +- OpenKeychain/src/main/res/raw-eu/help_about.md | 2 +- OpenKeychain/src/main/res/raw-eu/help_changelog.md | 13 +- OpenKeychain/src/main/res/raw-fa/help_about.md | 2 +- OpenKeychain/src/main/res/raw-fa/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-fi/help_about.md | 2 +- OpenKeychain/src/main/res/raw-fi/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-fr/help_about.md | 2 +- OpenKeychain/src/main/res/raw-fr/help_changelog.md | 9 +- OpenKeychain/src/main/res/raw-hi/help_about.md | 2 +- OpenKeychain/src/main/res/raw-hi/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-hu/help_about.md | 2 +- OpenKeychain/src/main/res/raw-hu/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-id/advanced.md | 12 +- OpenKeychain/src/main/res/raw-id/help_about.md | 2 +- OpenKeychain/src/main/res/raw-id/help_changelog.md | 77 ++--- OpenKeychain/src/main/res/raw-it/help_about.md | 2 +- OpenKeychain/src/main/res/raw-it/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-ja/help_about.md | 2 +- OpenKeychain/src/main/res/raw-ja/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-kn/advanced.md | 9 + OpenKeychain/src/main/res/raw-kn/help_about.md | 72 +++++ .../src/main/res/raw-kn/help_certification.md | 28 ++ OpenKeychain/src/main/res/raw-kn/help_changelog.md | 326 +++++++++++++++++++++ OpenKeychain/src/main/res/raw-kn/help_start.md | 16 + OpenKeychain/src/main/res/raw-ko/help_about.md | 2 +- OpenKeychain/src/main/res/raw-ko/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-nb/advanced.md | 9 + OpenKeychain/src/main/res/raw-nb/help_about.md | 72 +++++ .../src/main/res/raw-nb/help_certification.md | 28 ++ OpenKeychain/src/main/res/raw-nb/help_changelog.md | 326 +++++++++++++++++++++ OpenKeychain/src/main/res/raw-nb/help_start.md | 16 + OpenKeychain/src/main/res/raw-nl/help_about.md | 2 +- OpenKeychain/src/main/res/raw-nl/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-pl/help_about.md | 2 +- OpenKeychain/src/main/res/raw-pl/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-pt-rBR/advanced.md | 9 + OpenKeychain/src/main/res/raw-pt-rBR/help_about.md | 72 +++++ .../src/main/res/raw-pt-rBR/help_certification.md | 28 ++ .../src/main/res/raw-pt-rBR/help_changelog.md | 326 +++++++++++++++++++++ OpenKeychain/src/main/res/raw-pt-rBR/help_start.md | 16 + OpenKeychain/src/main/res/raw-ru/help_about.md | 2 +- .../src/main/res/raw-ru/help_certification.md | 2 +- OpenKeychain/src/main/res/raw-ru/help_changelog.md | 17 +- OpenKeychain/src/main/res/raw-ru/help_start.md | 2 +- OpenKeychain/src/main/res/raw-sl/help_about.md | 2 +- OpenKeychain/src/main/res/raw-sl/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-sr/help_about.md | 2 +- OpenKeychain/src/main/res/raw-sr/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-sv/advanced.md | 2 +- OpenKeychain/src/main/res/raw-sv/help_about.md | 4 +- OpenKeychain/src/main/res/raw-sv/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-tr/help_about.md | 2 +- OpenKeychain/src/main/res/raw-tr/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-uk/help_about.md | 2 +- OpenKeychain/src/main/res/raw-uk/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-vi/help_about.md | 2 +- OpenKeychain/src/main/res/raw-vi/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-zh-rTW/help_about.md | 2 +- .../src/main/res/raw-zh-rTW/help_changelog.md | 7 + OpenKeychain/src/main/res/raw-zh/advanced.md | 14 +- OpenKeychain/src/main/res/raw-zh/help_about.md | 8 +- .../src/main/res/raw-zh/help_certification.md | 32 +- OpenKeychain/src/main/res/raw-zh/help_changelog.md | 15 +- OpenKeychain/src/main/res/raw-zh/help_start.md | 18 +- OpenKeychain/src/main/res/values-cs/strings.xml | 324 +++++++++++++++++++- OpenKeychain/src/main/res/values-de/strings.xml | 61 ++-- .../src/main/res/values-es-rMX/strings.xml | 1 - OpenKeychain/src/main/res/values-es/strings.xml | 13 - OpenKeychain/src/main/res/values-eu/strings.xml | 100 ++++++- OpenKeychain/src/main/res/values-fa/strings.xml | 1 - OpenKeychain/src/main/res/values-fr/strings.xml | 43 ++- OpenKeychain/src/main/res/values-hi/strings.xml | 18 ++ OpenKeychain/src/main/res/values-it/strings.xml | 6 - OpenKeychain/src/main/res/values-ja/strings.xml | 36 ++- OpenKeychain/src/main/res/values-kn/strings.xml | 88 ++++++ OpenKeychain/src/main/res/values-ko/strings.xml | 1 - OpenKeychain/src/main/res/values-nb/strings.xml | 88 ++++++ OpenKeychain/src/main/res/values-nl/strings.xml | 11 - OpenKeychain/src/main/res/values-pl/strings.xml | 6 - .../src/main/res/values-pt-rBR/strings.xml | 88 ++++++ OpenKeychain/src/main/res/values-ru/strings.xml | 323 +++++++++++++++++++- OpenKeychain/src/main/res/values-sl/strings.xml | 6 - OpenKeychain/src/main/res/values-sr/strings.xml | 35 ++- OpenKeychain/src/main/res/values-sv/strings.xml | 7 - OpenKeychain/src/main/res/values-tr/strings.xml | 1 - OpenKeychain/src/main/res/values-uk/strings.xml | 5 - .../src/main/res/values-zh-rTW/strings.xml | 3 - OpenKeychain/src/main/res/values-zh/strings.xml | 139 +++++++-- 98 files changed, 2894 insertions(+), 292 deletions(-) create mode 100644 OpenKeychain/src/main/res/raw-kn/advanced.md create mode 100644 OpenKeychain/src/main/res/raw-kn/help_about.md create mode 100644 OpenKeychain/src/main/res/raw-kn/help_certification.md create mode 100644 OpenKeychain/src/main/res/raw-kn/help_changelog.md create mode 100644 OpenKeychain/src/main/res/raw-kn/help_start.md create mode 100644 OpenKeychain/src/main/res/raw-nb/advanced.md create mode 100644 OpenKeychain/src/main/res/raw-nb/help_about.md create mode 100644 OpenKeychain/src/main/res/raw-nb/help_certification.md create mode 100644 OpenKeychain/src/main/res/raw-nb/help_changelog.md create mode 100644 OpenKeychain/src/main/res/raw-nb/help_start.md create mode 100644 OpenKeychain/src/main/res/raw-pt-rBR/advanced.md create mode 100644 OpenKeychain/src/main/res/raw-pt-rBR/help_about.md create mode 100644 OpenKeychain/src/main/res/raw-pt-rBR/help_certification.md create mode 100644 OpenKeychain/src/main/res/raw-pt-rBR/help_changelog.md create mode 100644 OpenKeychain/src/main/res/raw-pt-rBR/help_start.md create mode 100644 OpenKeychain/src/main/res/values-kn/strings.xml create mode 100644 OpenKeychain/src/main/res/values-nb/strings.xml create mode 100644 OpenKeychain/src/main/res/values-pt-rBR/strings.xml diff --git a/.tx/config b/.tx/config index 4ea2ec29f..de1ec1ed0 100644 --- a/.tx/config +++ b/.tx/config @@ -1,6 +1,6 @@ [main] host = https://www.transifex.com -lang_map = he: iw, zh_TW: zh-rTW, es_MX: es-rMX +lang_map = he: iw, zh_TW: zh-rTW, es_MX: es-rMX, pt_BR: pt-rBR [open-keychain.strings] file_filter = OpenKeychain/src/main/res/values-/strings.xml diff --git a/OpenKeychain/src/main/res/raw-cs/help_about.md b/OpenKeychain/src/main/res/raw-cs/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_about.md +++ b/OpenKeychain/src/main/res/raw-cs/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-cs/help_changelog.md b/OpenKeychain/src/main/res/raw-cs/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-cs/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-cs/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-de/help_about.md b/OpenKeychain/src/main/res/raw-de/help_about.md index fa75bed0e..ffd97656e 100644 --- a/OpenKeychain/src/main/res/raw-de/help_about.md +++ b/OpenKeychain/src/main/res/raw-de/help_about.md @@ -65,7 +65,7 @@ Lizenz: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache-Lizenz v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT-Lizenz) * [Snackbar](https://github.com/nispok/snackbar) (MIT-Lizenz) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT-X11-Lizenz) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 Lizenz) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache-Lizenz v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache-Lizenz v2) * [ZXing](https://github.com/zxing/zxing) (Apache-Lizenz v2) diff --git a/OpenKeychain/src/main/res/raw-de/help_changelog.md b/OpenKeychain/src/main/res/raw-de/help_changelog.md index bb84548ee..8b170fb76 100644 --- a/OpenKeychain/src/main/res/raw-de/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-de/help_changelog.md @@ -1,10 +1,17 @@ [//]: # (Beachte: Bitte schreibe jeden Satz in eine eigene Zeile, Transifex wird jede Zeile in ein eigenes Übesetzungsfeld setzen!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Bearbeiten von Schlüsseln überarbeitet * Wähle die Zeit wie lange dein Passwort erinnert wird beim jedem Eingeben - * Facebook key import + Facebook Schlüsselimport ## 3.7 diff --git a/OpenKeychain/src/main/res/raw-es-rMX/help_about.md b/OpenKeychain/src/main/res/raw-es-rMX/help_about.md index 463d3315c..f72cb8cb4 100644 --- a/OpenKeychain/src/main/res/raw-es-rMX/help_about.md +++ b/OpenKeychain/src/main/res/raw-es-rMX/help_about.md @@ -65,7 +65,7 @@ Licencia: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Licencia Apache v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (Licencia MIT) * [Snackbar](https://github.com/nispok/snackbar) (Licencia MIT) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (Licencia MIT X11) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Licencia Apache v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Licencia Apache v2) * [ZXing](https://github.com/zxing/zxing) (Licencia Apache v2) diff --git a/OpenKeychain/src/main/res/raw-es-rMX/help_changelog.md b/OpenKeychain/src/main/res/raw-es-rMX/help_changelog.md index 99a093c89..5148c17a8 100644 --- a/OpenKeychain/src/main/res/raw-es-rMX/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-es-rMX/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (Observe: ¡Por favor ingrese cada enunciado en su propia línea, Transifex coloca cada línea en su propio campo de traducción!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-es/help_about.md b/OpenKeychain/src/main/res/raw-es/help_about.md index 9c82cae5a..44a544694 100644 --- a/OpenKeychain/src/main/res/raw-es/help_about.md +++ b/OpenKeychain/src/main/res/raw-es/help_about.md @@ -65,7 +65,7 @@ Licencia: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Licencia Apache v2) * [Librería SafeSlinger Exchange](https://github.com/SafeSlingerProject/exchange-android) (Licencia MIT) * [Snackbar](https://github.com/nispok/snackbar) (Licencia MIT) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Licencia Apache v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Licencia Apache v2) * [ZXing](https://github.com/zxing/zxing) (Licencia Apache v2) diff --git a/OpenKeychain/src/main/res/raw-es/help_changelog.md b/OpenKeychain/src/main/res/raw-es/help_changelog.md index ca3c09563..8198ec9a2 100644 --- a/OpenKeychain/src/main/res/raw-es/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-es/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTA: ¡Por favor ponga cada frase en su propia línea, Transifex pone cada línea en su propio campo de traducción!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-eu/advanced.md b/OpenKeychain/src/main/res/raw-eu/advanced.md index 54a694084..3f2a00127 100644 --- a/OpenKeychain/src/main/res/raw-eu/advanced.md +++ b/OpenKeychain/src/main/res/raw-eu/advanced.md @@ -1,9 +1,9 @@ -[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +[//]: # (OHARRA: Mesedez jarri esaldi bakoitza bere lerroan, Transifex-ek lerroak bere itzulpen eremuan jartzen ditu!) -Advanced screen allows you to -* share key in non-recommended ways -* edit identities -* edit subkeys -* examine certificates in detail +Ikusleiho aurreratuak ahalbidetzen dizu +* giltza elkarbanatzea bide ez-gomendatuan +* nortasunak editatzea +* azpigiltzak editatzea +* egiaztagiriak xehetasunez aztartzea -Only proceed if you know what you are doing! \ No newline at end of file +Zer egiten ari zaren badakizu besterik ez jarraitu! \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-eu/help_about.md b/OpenKeychain/src/main/res/raw-eu/help_about.md index 13925d9ea..bd373f1e3 100644 --- a/OpenKeychain/src/main/res/raw-eu/help_about.md +++ b/OpenKeychain/src/main/res/raw-eu/help_about.md @@ -65,7 +65,7 @@ Baimena: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Diseinua) (Apache Baimena 2 bertsioa) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT Baimena) * [Snackbar](https://github.com/nispok/snackbar) (MIT Baimena) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 Baimena) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 Baimena) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache Baimena v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache Baimena v2) * [ZXing](https://github.com/zxing/zxing) (Apache Baimena v2) diff --git a/OpenKeychain/src/main/res/raw-eu/help_changelog.md b/OpenKeychain/src/main/res/raw-eu/help_changelog.md index 2d52f8953..08be3f6ce 100644 --- a/OpenKeychain/src/main/res/raw-eu/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-eu/help_changelog.md @@ -1,10 +1,17 @@ [//]: # (OHARRA: Meseez jarri esaldi bakoitza bere lerroan, Transifex-ek lerroak bere itzulpen eremuan jartzen ditu!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 - * Redesigned key editing - * Choose remember time individually when entering passwords - * Facebook key import + * Giltza edizio berdiseinatua + * Hautatu ordua banaka sarhitzak idazterakoan + * Facebook giltza inportazioa ## 3.7 diff --git a/OpenKeychain/src/main/res/raw-fa/help_about.md b/OpenKeychain/src/main/res/raw-fa/help_about.md index 833295cbb..1543a4dcb 100644 --- a/OpenKeychain/src/main/res/raw-fa/help_about.md +++ b/OpenKeychain/src/main/res/raw-fa/help_about.md @@ -65,7 +65,7 @@ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-fa/help_changelog.md b/OpenKeychain/src/main/res/raw-fa/help_changelog.md index 464bdc61b..87544a346 100644 --- a/OpenKeychain/src/main/res/raw-fa/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-fa/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (تذکر: هر جمله در همان خط!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-fi/help_about.md b/OpenKeychain/src/main/res/raw-fi/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-fi/help_about.md +++ b/OpenKeychain/src/main/res/raw-fi/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-fi/help_changelog.md b/OpenKeychain/src/main/res/raw-fi/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-fi/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-fi/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-fr/help_about.md b/OpenKeychain/src/main/res/raw-fr/help_about.md index 4522af54b..553ab16b6 100644 --- a/OpenKeychain/src/main/res/raw-fr/help_about.md +++ b/OpenKeychain/src/main/res/raw-fr/help_about.md @@ -65,7 +65,7 @@ Licence : GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Conception matérielle) (Licence Apache v2) * [Bibliothèque d'échange SafeSlinger](https://github.com/SafeSlingerProject/exchange-android) (Licence MIT) * [Snackbar](https://github.com/nispok/snackbar) (Licence MIT) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (Licence MIT X11) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (Licence MIT X11) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Licence Apache v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Licence Apache v2) * [ZXing](https://github.com/zxing/zxing) (Licence Apache v2) diff --git a/OpenKeychain/src/main/res/raw-fr/help_changelog.md b/OpenKeychain/src/main/res/raw-fr/help_changelog.md index ff0c610b7..096fda99d 100644 --- a/OpenKeychain/src/main/res/raw-fr/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-fr/help_changelog.md @@ -1,10 +1,17 @@ [//] : # (NOTE : veuillez mettre chaque phrase sur sa propre ligne. Transifex met chaque ligne dans son propre champ de traduction !) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Nouvelle conception de la modification des clefs * Choisir les délais de mémorisation individuellement lors de la saisie des mots de passe - * Facebook key import + * Importation de clef Facebook ## 3.7 diff --git a/OpenKeychain/src/main/res/raw-hi/help_about.md b/OpenKeychain/src/main/res/raw-hi/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-hi/help_about.md +++ b/OpenKeychain/src/main/res/raw-hi/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-hi/help_changelog.md b/OpenKeychain/src/main/res/raw-hi/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-hi/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-hi/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-hu/help_about.md b/OpenKeychain/src/main/res/raw-hu/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-hu/help_about.md +++ b/OpenKeychain/src/main/res/raw-hu/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-hu/help_changelog.md b/OpenKeychain/src/main/res/raw-hu/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-hu/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-hu/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-id/advanced.md b/OpenKeychain/src/main/res/raw-id/advanced.md index 54a694084..bf3daf41e 100644 --- a/OpenKeychain/src/main/res/raw-id/advanced.md +++ b/OpenKeychain/src/main/res/raw-id/advanced.md @@ -1,9 +1,9 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) -Advanced screen allows you to -* share key in non-recommended ways -* edit identities -* edit subkeys -* examine certificates in detail +Layar Advanced memungkinkan Anda untuk +* membagikan kunci dengan cara yang tidak disarankan +* mengedit identitas +* mengedit kunci tambahan +* memeriksa sertifikat dengan lebih detail -Only proceed if you know what you are doing! \ No newline at end of file +Lanjutkan hanya jika Anda mengetahui apa yang Anda lakukan! \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-id/help_about.md b/OpenKeychain/src/main/res/raw-id/help_about.md index 7c8b894c2..2ec7f239e 100644 --- a/OpenKeychain/src/main/res/raw-id/help_about.md +++ b/OpenKeychain/src/main/res/raw-id/help_about.md @@ -65,7 +65,7 @@ Lisensi: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-id/help_changelog.md b/OpenKeychain/src/main/res/raw-id/help_changelog.md index d18fbb1a0..114f1e493 100644 --- a/OpenKeychain/src/main/res/raw-id/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-id/help_changelog.md @@ -1,10 +1,17 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 - * Redesigned key editing - * Choose remember time individually when entering passwords - * Facebook key import + * Perubahan design pengeditan kunci + * Pilih waktu mengingat kata sandi secara individu + * Import kunci Facebook ## 3.7 @@ -17,68 +24,68 @@ * Backup yang terenkripsi * Perbaikan keamanan berdasarkan audit keamanan eksternal - * YubiKey NEO key creation wizard + * Pengaturan pembuatan kunci YubiKey NEO * Dukungan basic internal MIME - * Automatic key synchronization - * Experimental feature: link keys to Github, Twitter accounts - * Experimental feature: key confirmation via phrases - * Experimental feature: dark theme - * API: Version 9 + * Sinkronisasi kunci otomatis + * Fitur eksperimental: hubungkan kunci ke akun Github dan Twitter + * Fitur experimental: konfirmasi kunci menggunakan frasa + * Fitur eksperimental: tema gelap + * API: Versi 9 ## 3.5 - * Key revocation on key deletion - * Improved checks for insecure cryptography - * Fix: Don't close OpenKeychain after first time wizard succeeds - * API: Version 8 + * Pencabutan kunci saat penghapusan + * Pembaharuan pengecekan untuk kriptografi yang tidak aman + * Perbaikan: Jangan tutup OpenKeychain setelah pengaturan pertama selesai + * API: Versi 8 ## 3.4 - * Anonymous key download over Tor - * Proxy support - * Better YubiKey error handling + * Unduh kunci secara anonim melalui Tor + * Dukungan proxy + * Penanganan error YubiKey yang lebih baik ## 3.3 - * New decryption screen - * Decryption of multiple files at once - * Better handling of YubiKey errors + * Layar dekripsi yang baru + * Dekripsi banyak file dalam satu kali + * Penanganan error YubiKey yang lebih baik ## 3.2 - * First version with full YubiKey support available from the user interface: Edit keys, bind YubiKey to keys,... + * Versi pertama dengan dukungan penuh YubiKey dari antarmuka pengguna: Edit kunci, hubungkan YubiKey dengan kunci,... * Material design - * Integration of QR Code Scanning (New permissions required) - * Improved key creation wizard - * Fix missing contacts after sync - * Requires Android 4 - * Redesigned key screen - * Simplify crypto preferences, better selection of secure ciphers - * API: Detached signatures, free selection of signing key,... - * Fix: Some valid keys were shown revoked or expired - * Don't accept signatures by expired or revoked subkeys - * Keybase.io support in advanced view - * Method to update all keys at once + * Intregrasi pemindai kode QR (Izin baru dibutuhkan) + * Pengaturan pembuatan kunci yang lebih baik + * Perbaikan kehilangan kontak setelah sinkronasi + * Membutuhkan Android 4 + * Design baru layar kunci + * Meringkas preferensi kripto, pilihan sandi aman yang lebih baik + * API: Tandatangan terpisah, pilihan bebas kunci tandatangan,... + * Perbaikan: Beberapa kunci valid ditunjukan sebagai expired atau dicabut + * Tidak menerima tandatangan dari kunci tambahan yang expired atau dicabut + * Dukungan Keybase.io di pilihan lanjutan + * Cara untuk memperbaharui semua kunci sekaligus ## 3.1.2 - * Fix key export to files (now for real) + * Perbaikan export kunci ke file (beres) ## 3.1.1 - * Fix key export to files (they were written partially) - * Fix crash on Android 2.3 + * Perbaikan export kunci ke file (sebagian) + * Perbaikan crash di Android 2.3 ## 3.1 - * Fix crash on Android 5 + * Perbaikan crash di Android 5 * New certify screen * Secure Exchange directly from key list (SafeSlinger library) * New QR Code program flow diff --git a/OpenKeychain/src/main/res/raw-it/help_about.md b/OpenKeychain/src/main/res/raw-it/help_about.md index 8cd939be2..a5957475c 100644 --- a/OpenKeychain/src/main/res/raw-it/help_about.md +++ b/OpenKeychain/src/main/res/raw-it/help_about.md @@ -65,7 +65,7 @@ Licenza: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Design materiale) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-it/help_changelog.md b/OpenKeychain/src/main/res/raw-it/help_changelog.md index 777ac503f..55c62bbcd 100644 --- a/OpenKeychain/src/main/res/raw-it/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-it/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTA: Si prega di mettere ogni frase in una propria linea, Transifex mette ogni riga nel proprio campo di traduzione!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-ja/help_about.md b/OpenKeychain/src/main/res/raw-ja/help_about.md index c8de63ce5..44c1a23c5 100644 --- a/OpenKeychain/src/main/res/raw-ja/help_about.md +++ b/OpenKeychain/src/main/res/raw-ja/help_about.md @@ -65,7 +65,7 @@ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 ライセンス) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-ja/help_changelog.md b/OpenKeychain/src/main/res/raw-ja/help_changelog.md index 7491bfb4a..1c5d077f5 100644 --- a/OpenKeychain/src/main/res/raw-ja/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-ja/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * 鍵編集の再デザイン diff --git a/OpenKeychain/src/main/res/raw-kn/advanced.md b/OpenKeychain/src/main/res/raw-kn/advanced.md new file mode 100644 index 000000000..54a694084 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-kn/advanced.md @@ -0,0 +1,9 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +Advanced screen allows you to +* share key in non-recommended ways +* edit identities +* edit subkeys +* examine certificates in detail + +Only proceed if you know what you are doing! \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-kn/help_about.md b/OpenKeychain/src/main/res/raw-kn/help_about.md new file mode 100644 index 000000000..fad35b356 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-kn/help_about.md @@ -0,0 +1,72 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +[https://www.openkeychain.org](https://www.openkeychain.org) + +[OpenKeychain](https://www.openkeychain.org) is an OpenPGP implementation for Android. + +License: GPLv3+ + +[//]: # (NOTE: Alphabetic ordering) + +## Main Developers + * Dominik Schürmann (Maintainer) + * Vincent Breitmoser + +## Top Contributors + * Adithya Abraham Philip + * Ash Hughes + * 'mar-v-in' + * 'Thialfihar' (APG developer) + * Tim Bray + +## Occasional Contributors + * Art O Cathain + * Brian C. Barnes + * Bahtiar 'kalkin' Gadimov + * Daniel Albert + * Daniel Hammann + * Daniel Haß + * Daniel Nelz + * Daniel Ramos + * Greg Witczak + * 'iseki' + * Ishan Khanna + * 'jellysheep' + * 'Jesperbk' + * 'jkolo' + * Joey Castillo + * Kai Jiang + * Kartik Arora + * 'Kent' + * 'ligi' + * Lukas Zorich + * Manoj Khanna + * Markus Doits + * Miroojin Bakshi + * Morgan Gangwere + * Nikhil Peter Raj + * Paul Sarbinowski + * 'Senecaso' + * Signe Rüsch + * Sreeram Boyapati + * 'steelman' + +[//]: # (NOTE: Alphabetic ordering) + +## Libraries + * [Android Support Libraries](http://developer.android.com/tools/support-library/index.html) (Apache License v2) + * [FloatingActionButton](https://github.com/futuresimple/android-floating-action-button) (Apache License v2) + * [HtmlTextView](https://github.com/sufficientlysecure/html-textview) (Apache License v2) + * [KeybaseLib](https://github.com/timbray/KeybaseLib) (Apache License v2) + * [Markdown4J](https://github.com/jdcasey/markdown4j) (Apache License v2) + * [MaterialDrawer](https://github.com/mikepenz/MaterialDrawer) (Apache License v2) + * [MiniDNS](https://github.com/rtreffer/minidns) (Apache License v2) + * [OkHttp](https://square.github.io/okhttp/) (Apache License v2) + * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) + * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) + * [Snackbar](https://github.com/nispok/snackbar) (MIT License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) + * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) + * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) + * [ZXing](https://github.com/zxing/zxing) (Apache License v2) + * [ZXing Android Minimal](https://github.com/journeyapps/zxing-android-embedded) (Apache License v2) \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-kn/help_certification.md b/OpenKeychain/src/main/res/raw-kn/help_certification.md new file mode 100644 index 000000000..3518adf73 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-kn/help_certification.md @@ -0,0 +1,28 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## Key Confirmation +Without confirmation, you cannot be sure if a key really corresponds to a specific person. +The simplest way to confirm a key is by scanning the QR Code or exchanging it via NFC. +To confirm keys between more than two persons, we suggest to use the key exchange method available for your keys. + +## Key Status + + +Confirmed: You have already confirmed this key, e.g., by scanning the QR Code. + +Unconfirmed: This key has not been confirmed yet. You cannot be sure if the key really corresponds to a specific person. + +Expired: This key is no longer valid. Only the owner can extend its validity. + +Revoked: This key is no longer valid. It has been revoked by its owner. + +## Advanced Information +A "key confirmation" in OpenKeychain is implemented by creating a certification according to the OpenPGP standard. +This certification is a ["generic certification (0x10)"](http://tools.ietf.org/html/rfc4880#section-5.2.1) described in the standard by: +"The issuer of this certification does not make any particular assertion as to how well the certifier has checked that the owner of the key is in fact the person described by the User ID." + +Traditionally, certifications (also with higher certification levels, such as "positive certifications" (0x13)) are organized in OpenPGP's Web of Trust. +Our model of key confirmation is a much simpler concept to avoid common usability problems related to this Web of Trust. +We assume that keys are verified only to a certain degree that is still usable enough to be executed "on the go". +We also do not implement (potentially transitive) trust signatures or an ownertrust database like in GnuPG. +Furthermore, keys which contain at least one user ID certified by a trusted key will be marked as "confirmed" in the key listings. \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-kn/help_changelog.md b/OpenKeychain/src/main/res/raw-kn/help_changelog.md new file mode 100644 index 000000000..629931b2c --- /dev/null +++ b/OpenKeychain/src/main/res/raw-kn/help_changelog.md @@ -0,0 +1,326 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + +## 3.8 + + * Redesigned key editing + * Choose remember time individually when entering passwords + * Facebook key import + + +## 3.7 + + * Improved Android 6 support (permissions, integration into text selection) + * API: Version 10 + + +## 3.6 + + * Encrypted backups + * Security fixes based on external security audit + * YubiKey NEO key creation wizard + * Basic internal MIME support + * Automatic key synchronization + * Experimental feature: link keys to Github, Twitter accounts + * Experimental feature: key confirmation via phrases + * Experimental feature: dark theme + * API: Version 9 + + +## 3.5 + + * Key revocation on key deletion + * Improved checks for insecure cryptography + * Fix: Don't close OpenKeychain after first time wizard succeeds + * API: Version 8 + + +## 3.4 + + * Anonymous key download over Tor + * Proxy support + * Better YubiKey error handling + + +## 3.3 + + * New decryption screen + * Decryption of multiple files at once + * Better handling of YubiKey errors + + +## 3.2 + + * First version with full YubiKey support available from the user interface: Edit keys, bind YubiKey to keys,... + * Material design + * Integration of QR Code Scanning (New permissions required) + * Improved key creation wizard + * Fix missing contacts after sync + * Requires Android 4 + * Redesigned key screen + * Simplify crypto preferences, better selection of secure ciphers + * API: Detached signatures, free selection of signing key,... + * Fix: Some valid keys were shown revoked or expired + * Don't accept signatures by expired or revoked subkeys + * Keybase.io support in advanced view + * Method to update all keys at once + + +## 3.1.2 + + * Fix key export to files (now for real) + + +## 3.1.1 + + * Fix key export to files (they were written partially) + * Fix crash on Android 2.3 + + +## 3.1 + + * Fix crash on Android 5 + * New certify screen + * Secure Exchange directly from key list (SafeSlinger library) + * New QR Code program flow + * Redesigned decrypt screen + * New icon usage and colors + * Fix import of secret keys from Symantec Encryption Desktop + * Experimental YubiKey support: Subkey IDs are now checked correctly + + +## 3.0.1 + + * Better handling of large key imports + * Improved subkey selection + + +## 3.0 + + * Propose installable compatible apps in apps list + * New design for decryption screens + * Many fixes for key import, also fixes stripped keys + * Honor and display key authenticate flags + * User interface to generate custom keys + * Fixing user id revocation certificates + * New cloud search (searches over traditional keyservers and keybase.io) + * Support for stripping keys inside OpenKeychain + * Experimental YubiKey support: Support for signature generation and decryption + + +## 2.9.2 + + * Fix keys broken in 2.9.1 + * Experimental YubiKey support: Decryption now working via API + + +## 2.9.1 + + * Split encrypt screen into two + * Fix key flags handling (now supporting Mailvelope 0.7 keys) + * Improved passphrase handling + * Key sharing via SafeSlinger + * Experimental YubiKey support: Preference to allow other PINs, currently only signing via the OpenPGP API works, not inside of OpenKeychain + * Fix usage of stripped keys + * SHA256 as default for compatibility + * Intent API has changed, see https://github.com/open-keychain/open-keychain/wiki/Intent-API + * OpenPGP API now handles revoked/expired keys and returns all user ids + + +## 2.9 + + * Fixing crashes introduced in v2.8 + * Experimental ECC support + * Experimental YubiKey support: Only signing with imported keys + + +## 2.8 + + * So many bugs have been fixed in this release that we focus on the main new features + * Key edit: awesome new design, key revocation + * Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records + * New first time screen + * New key creation screen: autocompletion of name and email based on your personal Android accounts + * File encryption: awesome new design, support for encrypting multiple files + * New icons to show status of key (by Brennan Novak) + * Important bug fix: Importing of large key collections from a file is now possible + * Notification showing cached passphrases + * Keys are connected to Android's contacts + +This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar + +## 2.7 + + * Purple! (Dominik, Vincent) + * New key view design (Dominik, Vincent) + * New flat Android buttons (Dominik, Vincent) + * API fixes (Dominik) + * Keybase.io import (Tim Bray) + + +## 2.6.1 + + * Some fixes for regression bugs + + +## 2.6 + + * Key certifications (thanks to Vincent Breitmoser) + * Support for GnuPG partial secret keys (thanks to Vincent Breitmoser) + * New design for signature verification + * Custom key length (thanks to Greg Witczak) + * Fix share-functionality from other apps + + +## 2.5 + + * Fix decryption of symmetric OpenPGP messages/files + * Refactored key edit screen (thanks to Ash Hughes) + * New modern design for encrypt/decrypt screens + * OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup) + + +## 2.4 +Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free! +Besides several small patches, a notable number of patches are made by the following people (in alphabetical order): +Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser. + + * New unified key list + * Colorized key fingerprint + * Support for keyserver ports + * Deactivate possibility to generate weak keys + * Much more internal work on the API + * Certify user ids + * Keyserver query based on machine-readable output + * Lock navigation drawer on tablets + * Suggestions for emails on creation of keys + * Search in public key lists + * And much more improvements and fixes… + + +## 2.3.1 + + * Hotfix for crash when upgrading from old versions + + +## 2.3 + + * Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes) + * Fix setting expiry dates on keys (thanks to Ash Hughes) + * More internal fixes when editing keys (thanks to Ash Hughes) + * Querying keyservers directly from the import screen + * Fix layout and dialog style on Android 2.2-3.0 + * Fix crash on keys with empty user ids + * Fix crash and empty lists when coming back from signing screen + * Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source + * Fix upload of key from signing screen + + +## 2.2 + + * New design with navigation drawer + * New public key list design + * New public key view + * Bug fixes for importing of keys + * Key cross-certification (thanks to Ash Hughes) + * Handle UTF-8 passwords properly (thanks to Ash Hughes) + * First version with new languages (thanks to the contributors on Transifex) + * Sharing of keys via QR Codes fixed and improved + * Package signature verification for API + + +## 2.1.1 + + * API Updates, preparation for K-9 Mail integration + + +## 2.1 + + * Lots of bug fixes + * New API for developers + * PRNG bug fix by Google + + +## 2.0 + + * Complete redesign + * Share public keys via QR codes, NFC beam + * Sign keys + * Upload keys to server + * Fixes import issues + * New AIDL API + + +## 1.0.8 + + * Basic keyserver support + * App2sd + * More choices for passphrase cache: 1, 2, 4, 8, hours + * Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick) + * Bugfixes + * Optimizations + + +## 1.0.7 + + * Fixed problem with signature verification of texts with trailing newline + * More options for passphrase cache time to live (20, 40, 60 mins) + + +## 1.0.6 + + * Account adding crash on Froyo fixed + * Secure file deletion + * Option to delete key file after import + * Stream encryption/decryption (gallery, etc.) + * New options (language, force v3 signatures) + * Interface changes + * Bugfixes + + +## 1.0.5 + + * German and Italian translation + * Much smaller package, due to reduced BC sources + * New preferences GUI + * Layout adjustment for localization + * Signature bugfix + + +## 1.0.4 + + * Fixed another crash caused by some SDK bug with query builder + + +## 1.0.3 + + * Fixed crashes during encryption/signing and possibly key export + + +## 1.0.2 + + * Filterable key lists + * Smarter pre-selection of encryption keys + * New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers + * Fixes and additional features (key preselection) for K-9 Mail, new beta build available + + +## 1.0.1 + + * GMail account listing was broken in 1.0.0, fixed again + + +## 1.0.0 + + * K-9 Mail integration, APG supporting beta build of K-9 Mail + * Support of more file managers (including ASTRO) + * Slovenian translation + * New database, much faster, less memory usage + * Defined Intents and content provider for other apps + * Bugfixes \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-kn/help_start.md b/OpenKeychain/src/main/res/raw-kn/help_start.md new file mode 100644 index 000000000..4cc331942 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-kn/help_start.md @@ -0,0 +1,16 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## How do I activate OpenKeychain in K-9 Mail? +To use OpenKeychain with K-9 Mail, you want to follow these steps: + 1. Open K-9 Mail and long-tap on the account you want to use OpenKeychain with. + 2. Select "Account settings", scroll to the very bottom and click "Cryptography". + 3. Click on "OpenPGP Provider" and select OpenKeychain from the list. + +## I found a bug in OpenKeychain! +Please report the bug using the [issue tracker of OpenKeychain](https://github.com/openpgp-keychain/openpgp-keychain/issues). + +## Contribute +If you want to help us developing OpenKeychain by contributing code [follow our small guide on Github](https://github.com/openpgp-keychain/openpgp-keychain#contribute-code). + +## Translations +Help translating OpenKeychain! Everybody can participate at [OpenKeychain on Transifex](https://www.transifex.com/projects/p/open-keychain/). \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-ko/help_about.md b/OpenKeychain/src/main/res/raw-ko/help_about.md index f60a918da..dddbc60a3 100644 --- a/OpenKeychain/src/main/res/raw-ko/help_about.md +++ b/OpenKeychain/src/main/res/raw-ko/help_about.md @@ -65,7 +65,7 @@ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-ko/help_changelog.md b/OpenKeychain/src/main/res/raw-ko/help_changelog.md index 929933144..95cf8fba4 100644 --- a/OpenKeychain/src/main/res/raw-ko/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-ko/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-nb/advanced.md b/OpenKeychain/src/main/res/raw-nb/advanced.md new file mode 100644 index 000000000..54a694084 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-nb/advanced.md @@ -0,0 +1,9 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +Advanced screen allows you to +* share key in non-recommended ways +* edit identities +* edit subkeys +* examine certificates in detail + +Only proceed if you know what you are doing! \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-nb/help_about.md b/OpenKeychain/src/main/res/raw-nb/help_about.md new file mode 100644 index 000000000..fad35b356 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-nb/help_about.md @@ -0,0 +1,72 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +[https://www.openkeychain.org](https://www.openkeychain.org) + +[OpenKeychain](https://www.openkeychain.org) is an OpenPGP implementation for Android. + +License: GPLv3+ + +[//]: # (NOTE: Alphabetic ordering) + +## Main Developers + * Dominik Schürmann (Maintainer) + * Vincent Breitmoser + +## Top Contributors + * Adithya Abraham Philip + * Ash Hughes + * 'mar-v-in' + * 'Thialfihar' (APG developer) + * Tim Bray + +## Occasional Contributors + * Art O Cathain + * Brian C. Barnes + * Bahtiar 'kalkin' Gadimov + * Daniel Albert + * Daniel Hammann + * Daniel Haß + * Daniel Nelz + * Daniel Ramos + * Greg Witczak + * 'iseki' + * Ishan Khanna + * 'jellysheep' + * 'Jesperbk' + * 'jkolo' + * Joey Castillo + * Kai Jiang + * Kartik Arora + * 'Kent' + * 'ligi' + * Lukas Zorich + * Manoj Khanna + * Markus Doits + * Miroojin Bakshi + * Morgan Gangwere + * Nikhil Peter Raj + * Paul Sarbinowski + * 'Senecaso' + * Signe Rüsch + * Sreeram Boyapati + * 'steelman' + +[//]: # (NOTE: Alphabetic ordering) + +## Libraries + * [Android Support Libraries](http://developer.android.com/tools/support-library/index.html) (Apache License v2) + * [FloatingActionButton](https://github.com/futuresimple/android-floating-action-button) (Apache License v2) + * [HtmlTextView](https://github.com/sufficientlysecure/html-textview) (Apache License v2) + * [KeybaseLib](https://github.com/timbray/KeybaseLib) (Apache License v2) + * [Markdown4J](https://github.com/jdcasey/markdown4j) (Apache License v2) + * [MaterialDrawer](https://github.com/mikepenz/MaterialDrawer) (Apache License v2) + * [MiniDNS](https://github.com/rtreffer/minidns) (Apache License v2) + * [OkHttp](https://square.github.io/okhttp/) (Apache License v2) + * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) + * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) + * [Snackbar](https://github.com/nispok/snackbar) (MIT License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) + * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) + * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) + * [ZXing](https://github.com/zxing/zxing) (Apache License v2) + * [ZXing Android Minimal](https://github.com/journeyapps/zxing-android-embedded) (Apache License v2) \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-nb/help_certification.md b/OpenKeychain/src/main/res/raw-nb/help_certification.md new file mode 100644 index 000000000..3518adf73 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-nb/help_certification.md @@ -0,0 +1,28 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## Key Confirmation +Without confirmation, you cannot be sure if a key really corresponds to a specific person. +The simplest way to confirm a key is by scanning the QR Code or exchanging it via NFC. +To confirm keys between more than two persons, we suggest to use the key exchange method available for your keys. + +## Key Status + + +Confirmed: You have already confirmed this key, e.g., by scanning the QR Code. + +Unconfirmed: This key has not been confirmed yet. You cannot be sure if the key really corresponds to a specific person. + +Expired: This key is no longer valid. Only the owner can extend its validity. + +Revoked: This key is no longer valid. It has been revoked by its owner. + +## Advanced Information +A "key confirmation" in OpenKeychain is implemented by creating a certification according to the OpenPGP standard. +This certification is a ["generic certification (0x10)"](http://tools.ietf.org/html/rfc4880#section-5.2.1) described in the standard by: +"The issuer of this certification does not make any particular assertion as to how well the certifier has checked that the owner of the key is in fact the person described by the User ID." + +Traditionally, certifications (also with higher certification levels, such as "positive certifications" (0x13)) are organized in OpenPGP's Web of Trust. +Our model of key confirmation is a much simpler concept to avoid common usability problems related to this Web of Trust. +We assume that keys are verified only to a certain degree that is still usable enough to be executed "on the go". +We also do not implement (potentially transitive) trust signatures or an ownertrust database like in GnuPG. +Furthermore, keys which contain at least one user ID certified by a trusted key will be marked as "confirmed" in the key listings. \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-nb/help_changelog.md b/OpenKeychain/src/main/res/raw-nb/help_changelog.md new file mode 100644 index 000000000..629931b2c --- /dev/null +++ b/OpenKeychain/src/main/res/raw-nb/help_changelog.md @@ -0,0 +1,326 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + +## 3.8 + + * Redesigned key editing + * Choose remember time individually when entering passwords + * Facebook key import + + +## 3.7 + + * Improved Android 6 support (permissions, integration into text selection) + * API: Version 10 + + +## 3.6 + + * Encrypted backups + * Security fixes based on external security audit + * YubiKey NEO key creation wizard + * Basic internal MIME support + * Automatic key synchronization + * Experimental feature: link keys to Github, Twitter accounts + * Experimental feature: key confirmation via phrases + * Experimental feature: dark theme + * API: Version 9 + + +## 3.5 + + * Key revocation on key deletion + * Improved checks for insecure cryptography + * Fix: Don't close OpenKeychain after first time wizard succeeds + * API: Version 8 + + +## 3.4 + + * Anonymous key download over Tor + * Proxy support + * Better YubiKey error handling + + +## 3.3 + + * New decryption screen + * Decryption of multiple files at once + * Better handling of YubiKey errors + + +## 3.2 + + * First version with full YubiKey support available from the user interface: Edit keys, bind YubiKey to keys,... + * Material design + * Integration of QR Code Scanning (New permissions required) + * Improved key creation wizard + * Fix missing contacts after sync + * Requires Android 4 + * Redesigned key screen + * Simplify crypto preferences, better selection of secure ciphers + * API: Detached signatures, free selection of signing key,... + * Fix: Some valid keys were shown revoked or expired + * Don't accept signatures by expired or revoked subkeys + * Keybase.io support in advanced view + * Method to update all keys at once + + +## 3.1.2 + + * Fix key export to files (now for real) + + +## 3.1.1 + + * Fix key export to files (they were written partially) + * Fix crash on Android 2.3 + + +## 3.1 + + * Fix crash on Android 5 + * New certify screen + * Secure Exchange directly from key list (SafeSlinger library) + * New QR Code program flow + * Redesigned decrypt screen + * New icon usage and colors + * Fix import of secret keys from Symantec Encryption Desktop + * Experimental YubiKey support: Subkey IDs are now checked correctly + + +## 3.0.1 + + * Better handling of large key imports + * Improved subkey selection + + +## 3.0 + + * Propose installable compatible apps in apps list + * New design for decryption screens + * Many fixes for key import, also fixes stripped keys + * Honor and display key authenticate flags + * User interface to generate custom keys + * Fixing user id revocation certificates + * New cloud search (searches over traditional keyservers and keybase.io) + * Support for stripping keys inside OpenKeychain + * Experimental YubiKey support: Support for signature generation and decryption + + +## 2.9.2 + + * Fix keys broken in 2.9.1 + * Experimental YubiKey support: Decryption now working via API + + +## 2.9.1 + + * Split encrypt screen into two + * Fix key flags handling (now supporting Mailvelope 0.7 keys) + * Improved passphrase handling + * Key sharing via SafeSlinger + * Experimental YubiKey support: Preference to allow other PINs, currently only signing via the OpenPGP API works, not inside of OpenKeychain + * Fix usage of stripped keys + * SHA256 as default for compatibility + * Intent API has changed, see https://github.com/open-keychain/open-keychain/wiki/Intent-API + * OpenPGP API now handles revoked/expired keys and returns all user ids + + +## 2.9 + + * Fixing crashes introduced in v2.8 + * Experimental ECC support + * Experimental YubiKey support: Only signing with imported keys + + +## 2.8 + + * So many bugs have been fixed in this release that we focus on the main new features + * Key edit: awesome new design, key revocation + * Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records + * New first time screen + * New key creation screen: autocompletion of name and email based on your personal Android accounts + * File encryption: awesome new design, support for encrypting multiple files + * New icons to show status of key (by Brennan Novak) + * Important bug fix: Importing of large key collections from a file is now possible + * Notification showing cached passphrases + * Keys are connected to Android's contacts + +This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar + +## 2.7 + + * Purple! (Dominik, Vincent) + * New key view design (Dominik, Vincent) + * New flat Android buttons (Dominik, Vincent) + * API fixes (Dominik) + * Keybase.io import (Tim Bray) + + +## 2.6.1 + + * Some fixes for regression bugs + + +## 2.6 + + * Key certifications (thanks to Vincent Breitmoser) + * Support for GnuPG partial secret keys (thanks to Vincent Breitmoser) + * New design for signature verification + * Custom key length (thanks to Greg Witczak) + * Fix share-functionality from other apps + + +## 2.5 + + * Fix decryption of symmetric OpenPGP messages/files + * Refactored key edit screen (thanks to Ash Hughes) + * New modern design for encrypt/decrypt screens + * OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup) + + +## 2.4 +Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free! +Besides several small patches, a notable number of patches are made by the following people (in alphabetical order): +Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser. + + * New unified key list + * Colorized key fingerprint + * Support for keyserver ports + * Deactivate possibility to generate weak keys + * Much more internal work on the API + * Certify user ids + * Keyserver query based on machine-readable output + * Lock navigation drawer on tablets + * Suggestions for emails on creation of keys + * Search in public key lists + * And much more improvements and fixes… + + +## 2.3.1 + + * Hotfix for crash when upgrading from old versions + + +## 2.3 + + * Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes) + * Fix setting expiry dates on keys (thanks to Ash Hughes) + * More internal fixes when editing keys (thanks to Ash Hughes) + * Querying keyservers directly from the import screen + * Fix layout and dialog style on Android 2.2-3.0 + * Fix crash on keys with empty user ids + * Fix crash and empty lists when coming back from signing screen + * Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source + * Fix upload of key from signing screen + + +## 2.2 + + * New design with navigation drawer + * New public key list design + * New public key view + * Bug fixes for importing of keys + * Key cross-certification (thanks to Ash Hughes) + * Handle UTF-8 passwords properly (thanks to Ash Hughes) + * First version with new languages (thanks to the contributors on Transifex) + * Sharing of keys via QR Codes fixed and improved + * Package signature verification for API + + +## 2.1.1 + + * API Updates, preparation for K-9 Mail integration + + +## 2.1 + + * Lots of bug fixes + * New API for developers + * PRNG bug fix by Google + + +## 2.0 + + * Complete redesign + * Share public keys via QR codes, NFC beam + * Sign keys + * Upload keys to server + * Fixes import issues + * New AIDL API + + +## 1.0.8 + + * Basic keyserver support + * App2sd + * More choices for passphrase cache: 1, 2, 4, 8, hours + * Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick) + * Bugfixes + * Optimizations + + +## 1.0.7 + + * Fixed problem with signature verification of texts with trailing newline + * More options for passphrase cache time to live (20, 40, 60 mins) + + +## 1.0.6 + + * Account adding crash on Froyo fixed + * Secure file deletion + * Option to delete key file after import + * Stream encryption/decryption (gallery, etc.) + * New options (language, force v3 signatures) + * Interface changes + * Bugfixes + + +## 1.0.5 + + * German and Italian translation + * Much smaller package, due to reduced BC sources + * New preferences GUI + * Layout adjustment for localization + * Signature bugfix + + +## 1.0.4 + + * Fixed another crash caused by some SDK bug with query builder + + +## 1.0.3 + + * Fixed crashes during encryption/signing and possibly key export + + +## 1.0.2 + + * Filterable key lists + * Smarter pre-selection of encryption keys + * New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers + * Fixes and additional features (key preselection) for K-9 Mail, new beta build available + + +## 1.0.1 + + * GMail account listing was broken in 1.0.0, fixed again + + +## 1.0.0 + + * K-9 Mail integration, APG supporting beta build of K-9 Mail + * Support of more file managers (including ASTRO) + * Slovenian translation + * New database, much faster, less memory usage + * Defined Intents and content provider for other apps + * Bugfixes \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-nb/help_start.md b/OpenKeychain/src/main/res/raw-nb/help_start.md new file mode 100644 index 000000000..4cc331942 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-nb/help_start.md @@ -0,0 +1,16 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## How do I activate OpenKeychain in K-9 Mail? +To use OpenKeychain with K-9 Mail, you want to follow these steps: + 1. Open K-9 Mail and long-tap on the account you want to use OpenKeychain with. + 2. Select "Account settings", scroll to the very bottom and click "Cryptography". + 3. Click on "OpenPGP Provider" and select OpenKeychain from the list. + +## I found a bug in OpenKeychain! +Please report the bug using the [issue tracker of OpenKeychain](https://github.com/openpgp-keychain/openpgp-keychain/issues). + +## Contribute +If you want to help us developing OpenKeychain by contributing code [follow our small guide on Github](https://github.com/openpgp-keychain/openpgp-keychain#contribute-code). + +## Translations +Help translating OpenKeychain! Everybody can participate at [OpenKeychain on Transifex](https://www.transifex.com/projects/p/open-keychain/). \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-nl/help_about.md b/OpenKeychain/src/main/res/raw-nl/help_about.md index a6f22d371..7bb7d2cf9 100644 --- a/OpenKeychain/src/main/res/raw-nl/help_about.md +++ b/OpenKeychain/src/main/res/raw-nl/help_about.md @@ -65,7 +65,7 @@ Licentie: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache licentie v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT licentie) * [Snackbar](https://github.com/nispok/snackbar) (MIT licentie) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache licentie v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache licentie v2) * [ZXing](https://github.com/zxing/zxing) (Apache licentie v2) diff --git a/OpenKeychain/src/main/res/raw-nl/help_changelog.md b/OpenKeychain/src/main/res/raw-nl/help_changelog.md index bc03b2662..c581c968b 100644 --- a/OpenKeychain/src/main/res/raw-nl/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-nl/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-pl/help_about.md b/OpenKeychain/src/main/res/raw-pl/help_about.md index 13fcbc185..d9930f0d7 100644 --- a/OpenKeychain/src/main/res/raw-pl/help_about.md +++ b/OpenKeychain/src/main/res/raw-pl/help_about.md @@ -65,7 +65,7 @@ Licencja: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-pl/help_changelog.md b/OpenKeychain/src/main/res/raw-pl/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-pl/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-pl/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-pt-rBR/advanced.md b/OpenKeychain/src/main/res/raw-pt-rBR/advanced.md new file mode 100644 index 000000000..54a694084 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt-rBR/advanced.md @@ -0,0 +1,9 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +Advanced screen allows you to +* share key in non-recommended ways +* edit identities +* edit subkeys +* examine certificates in detail + +Only proceed if you know what you are doing! \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-pt-rBR/help_about.md b/OpenKeychain/src/main/res/raw-pt-rBR/help_about.md new file mode 100644 index 000000000..fad35b356 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt-rBR/help_about.md @@ -0,0 +1,72 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +[https://www.openkeychain.org](https://www.openkeychain.org) + +[OpenKeychain](https://www.openkeychain.org) is an OpenPGP implementation for Android. + +License: GPLv3+ + +[//]: # (NOTE: Alphabetic ordering) + +## Main Developers + * Dominik Schürmann (Maintainer) + * Vincent Breitmoser + +## Top Contributors + * Adithya Abraham Philip + * Ash Hughes + * 'mar-v-in' + * 'Thialfihar' (APG developer) + * Tim Bray + +## Occasional Contributors + * Art O Cathain + * Brian C. Barnes + * Bahtiar 'kalkin' Gadimov + * Daniel Albert + * Daniel Hammann + * Daniel Haß + * Daniel Nelz + * Daniel Ramos + * Greg Witczak + * 'iseki' + * Ishan Khanna + * 'jellysheep' + * 'Jesperbk' + * 'jkolo' + * Joey Castillo + * Kai Jiang + * Kartik Arora + * 'Kent' + * 'ligi' + * Lukas Zorich + * Manoj Khanna + * Markus Doits + * Miroojin Bakshi + * Morgan Gangwere + * Nikhil Peter Raj + * Paul Sarbinowski + * 'Senecaso' + * Signe Rüsch + * Sreeram Boyapati + * 'steelman' + +[//]: # (NOTE: Alphabetic ordering) + +## Libraries + * [Android Support Libraries](http://developer.android.com/tools/support-library/index.html) (Apache License v2) + * [FloatingActionButton](https://github.com/futuresimple/android-floating-action-button) (Apache License v2) + * [HtmlTextView](https://github.com/sufficientlysecure/html-textview) (Apache License v2) + * [KeybaseLib](https://github.com/timbray/KeybaseLib) (Apache License v2) + * [Markdown4J](https://github.com/jdcasey/markdown4j) (Apache License v2) + * [MaterialDrawer](https://github.com/mikepenz/MaterialDrawer) (Apache License v2) + * [MiniDNS](https://github.com/rtreffer/minidns) (Apache License v2) + * [OkHttp](https://square.github.io/okhttp/) (Apache License v2) + * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) + * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) + * [Snackbar](https://github.com/nispok/snackbar) (MIT License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) + * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) + * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) + * [ZXing](https://github.com/zxing/zxing) (Apache License v2) + * [ZXing Android Minimal](https://github.com/journeyapps/zxing-android-embedded) (Apache License v2) \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-pt-rBR/help_certification.md b/OpenKeychain/src/main/res/raw-pt-rBR/help_certification.md new file mode 100644 index 000000000..3518adf73 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt-rBR/help_certification.md @@ -0,0 +1,28 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## Key Confirmation +Without confirmation, you cannot be sure if a key really corresponds to a specific person. +The simplest way to confirm a key is by scanning the QR Code or exchanging it via NFC. +To confirm keys between more than two persons, we suggest to use the key exchange method available for your keys. + +## Key Status + + +Confirmed: You have already confirmed this key, e.g., by scanning the QR Code. + +Unconfirmed: This key has not been confirmed yet. You cannot be sure if the key really corresponds to a specific person. + +Expired: This key is no longer valid. Only the owner can extend its validity. + +Revoked: This key is no longer valid. It has been revoked by its owner. + +## Advanced Information +A "key confirmation" in OpenKeychain is implemented by creating a certification according to the OpenPGP standard. +This certification is a ["generic certification (0x10)"](http://tools.ietf.org/html/rfc4880#section-5.2.1) described in the standard by: +"The issuer of this certification does not make any particular assertion as to how well the certifier has checked that the owner of the key is in fact the person described by the User ID." + +Traditionally, certifications (also with higher certification levels, such as "positive certifications" (0x13)) are organized in OpenPGP's Web of Trust. +Our model of key confirmation is a much simpler concept to avoid common usability problems related to this Web of Trust. +We assume that keys are verified only to a certain degree that is still usable enough to be executed "on the go". +We also do not implement (potentially transitive) trust signatures or an ownertrust database like in GnuPG. +Furthermore, keys which contain at least one user ID certified by a trusted key will be marked as "confirmed" in the key listings. \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-pt-rBR/help_changelog.md b/OpenKeychain/src/main/res/raw-pt-rBR/help_changelog.md new file mode 100644 index 000000000..629931b2c --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt-rBR/help_changelog.md @@ -0,0 +1,326 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + +## 3.8 + + * Redesigned key editing + * Choose remember time individually when entering passwords + * Facebook key import + + +## 3.7 + + * Improved Android 6 support (permissions, integration into text selection) + * API: Version 10 + + +## 3.6 + + * Encrypted backups + * Security fixes based on external security audit + * YubiKey NEO key creation wizard + * Basic internal MIME support + * Automatic key synchronization + * Experimental feature: link keys to Github, Twitter accounts + * Experimental feature: key confirmation via phrases + * Experimental feature: dark theme + * API: Version 9 + + +## 3.5 + + * Key revocation on key deletion + * Improved checks for insecure cryptography + * Fix: Don't close OpenKeychain after first time wizard succeeds + * API: Version 8 + + +## 3.4 + + * Anonymous key download over Tor + * Proxy support + * Better YubiKey error handling + + +## 3.3 + + * New decryption screen + * Decryption of multiple files at once + * Better handling of YubiKey errors + + +## 3.2 + + * First version with full YubiKey support available from the user interface: Edit keys, bind YubiKey to keys,... + * Material design + * Integration of QR Code Scanning (New permissions required) + * Improved key creation wizard + * Fix missing contacts after sync + * Requires Android 4 + * Redesigned key screen + * Simplify crypto preferences, better selection of secure ciphers + * API: Detached signatures, free selection of signing key,... + * Fix: Some valid keys were shown revoked or expired + * Don't accept signatures by expired or revoked subkeys + * Keybase.io support in advanced view + * Method to update all keys at once + + +## 3.1.2 + + * Fix key export to files (now for real) + + +## 3.1.1 + + * Fix key export to files (they were written partially) + * Fix crash on Android 2.3 + + +## 3.1 + + * Fix crash on Android 5 + * New certify screen + * Secure Exchange directly from key list (SafeSlinger library) + * New QR Code program flow + * Redesigned decrypt screen + * New icon usage and colors + * Fix import of secret keys from Symantec Encryption Desktop + * Experimental YubiKey support: Subkey IDs are now checked correctly + + +## 3.0.1 + + * Better handling of large key imports + * Improved subkey selection + + +## 3.0 + + * Propose installable compatible apps in apps list + * New design for decryption screens + * Many fixes for key import, also fixes stripped keys + * Honor and display key authenticate flags + * User interface to generate custom keys + * Fixing user id revocation certificates + * New cloud search (searches over traditional keyservers and keybase.io) + * Support for stripping keys inside OpenKeychain + * Experimental YubiKey support: Support for signature generation and decryption + + +## 2.9.2 + + * Fix keys broken in 2.9.1 + * Experimental YubiKey support: Decryption now working via API + + +## 2.9.1 + + * Split encrypt screen into two + * Fix key flags handling (now supporting Mailvelope 0.7 keys) + * Improved passphrase handling + * Key sharing via SafeSlinger + * Experimental YubiKey support: Preference to allow other PINs, currently only signing via the OpenPGP API works, not inside of OpenKeychain + * Fix usage of stripped keys + * SHA256 as default for compatibility + * Intent API has changed, see https://github.com/open-keychain/open-keychain/wiki/Intent-API + * OpenPGP API now handles revoked/expired keys and returns all user ids + + +## 2.9 + + * Fixing crashes introduced in v2.8 + * Experimental ECC support + * Experimental YubiKey support: Only signing with imported keys + + +## 2.8 + + * So many bugs have been fixed in this release that we focus on the main new features + * Key edit: awesome new design, key revocation + * Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records + * New first time screen + * New key creation screen: autocompletion of name and email based on your personal Android accounts + * File encryption: awesome new design, support for encrypting multiple files + * New icons to show status of key (by Brennan Novak) + * Important bug fix: Importing of large key collections from a file is now possible + * Notification showing cached passphrases + * Keys are connected to Android's contacts + +This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar + +## 2.7 + + * Purple! (Dominik, Vincent) + * New key view design (Dominik, Vincent) + * New flat Android buttons (Dominik, Vincent) + * API fixes (Dominik) + * Keybase.io import (Tim Bray) + + +## 2.6.1 + + * Some fixes for regression bugs + + +## 2.6 + + * Key certifications (thanks to Vincent Breitmoser) + * Support for GnuPG partial secret keys (thanks to Vincent Breitmoser) + * New design for signature verification + * Custom key length (thanks to Greg Witczak) + * Fix share-functionality from other apps + + +## 2.5 + + * Fix decryption of symmetric OpenPGP messages/files + * Refactored key edit screen (thanks to Ash Hughes) + * New modern design for encrypt/decrypt screens + * OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup) + + +## 2.4 +Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free! +Besides several small patches, a notable number of patches are made by the following people (in alphabetical order): +Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser. + + * New unified key list + * Colorized key fingerprint + * Support for keyserver ports + * Deactivate possibility to generate weak keys + * Much more internal work on the API + * Certify user ids + * Keyserver query based on machine-readable output + * Lock navigation drawer on tablets + * Suggestions for emails on creation of keys + * Search in public key lists + * And much more improvements and fixes… + + +## 2.3.1 + + * Hotfix for crash when upgrading from old versions + + +## 2.3 + + * Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes) + * Fix setting expiry dates on keys (thanks to Ash Hughes) + * More internal fixes when editing keys (thanks to Ash Hughes) + * Querying keyservers directly from the import screen + * Fix layout and dialog style on Android 2.2-3.0 + * Fix crash on keys with empty user ids + * Fix crash and empty lists when coming back from signing screen + * Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source + * Fix upload of key from signing screen + + +## 2.2 + + * New design with navigation drawer + * New public key list design + * New public key view + * Bug fixes for importing of keys + * Key cross-certification (thanks to Ash Hughes) + * Handle UTF-8 passwords properly (thanks to Ash Hughes) + * First version with new languages (thanks to the contributors on Transifex) + * Sharing of keys via QR Codes fixed and improved + * Package signature verification for API + + +## 2.1.1 + + * API Updates, preparation for K-9 Mail integration + + +## 2.1 + + * Lots of bug fixes + * New API for developers + * PRNG bug fix by Google + + +## 2.0 + + * Complete redesign + * Share public keys via QR codes, NFC beam + * Sign keys + * Upload keys to server + * Fixes import issues + * New AIDL API + + +## 1.0.8 + + * Basic keyserver support + * App2sd + * More choices for passphrase cache: 1, 2, 4, 8, hours + * Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick) + * Bugfixes + * Optimizations + + +## 1.0.7 + + * Fixed problem with signature verification of texts with trailing newline + * More options for passphrase cache time to live (20, 40, 60 mins) + + +## 1.0.6 + + * Account adding crash on Froyo fixed + * Secure file deletion + * Option to delete key file after import + * Stream encryption/decryption (gallery, etc.) + * New options (language, force v3 signatures) + * Interface changes + * Bugfixes + + +## 1.0.5 + + * German and Italian translation + * Much smaller package, due to reduced BC sources + * New preferences GUI + * Layout adjustment for localization + * Signature bugfix + + +## 1.0.4 + + * Fixed another crash caused by some SDK bug with query builder + + +## 1.0.3 + + * Fixed crashes during encryption/signing and possibly key export + + +## 1.0.2 + + * Filterable key lists + * Smarter pre-selection of encryption keys + * New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers + * Fixes and additional features (key preselection) for K-9 Mail, new beta build available + + +## 1.0.1 + + * GMail account listing was broken in 1.0.0, fixed again + + +## 1.0.0 + + * K-9 Mail integration, APG supporting beta build of K-9 Mail + * Support of more file managers (including ASTRO) + * Slovenian translation + * New database, much faster, less memory usage + * Defined Intents and content provider for other apps + * Bugfixes \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-pt-rBR/help_start.md b/OpenKeychain/src/main/res/raw-pt-rBR/help_start.md new file mode 100644 index 000000000..4cc331942 --- /dev/null +++ b/OpenKeychain/src/main/res/raw-pt-rBR/help_start.md @@ -0,0 +1,16 @@ +[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) + +## How do I activate OpenKeychain in K-9 Mail? +To use OpenKeychain with K-9 Mail, you want to follow these steps: + 1. Open K-9 Mail and long-tap on the account you want to use OpenKeychain with. + 2. Select "Account settings", scroll to the very bottom and click "Cryptography". + 3. Click on "OpenPGP Provider" and select OpenKeychain from the list. + +## I found a bug in OpenKeychain! +Please report the bug using the [issue tracker of OpenKeychain](https://github.com/openpgp-keychain/openpgp-keychain/issues). + +## Contribute +If you want to help us developing OpenKeychain by contributing code [follow our small guide on Github](https://github.com/openpgp-keychain/openpgp-keychain#contribute-code). + +## Translations +Help translating OpenKeychain! Everybody can participate at [OpenKeychain on Transifex](https://www.transifex.com/projects/p/open-keychain/). \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-ru/help_about.md b/OpenKeychain/src/main/res/raw-ru/help_about.md index 7d6e99951..b6ab6ac17 100644 --- a/OpenKeychain/src/main/res/raw-ru/help_about.md +++ b/OpenKeychain/src/main/res/raw-ru/help_about.md @@ -65,7 +65,7 @@ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-ru/help_certification.md b/OpenKeychain/src/main/res/raw-ru/help_certification.md index 787588b05..f4811892d 100644 --- a/OpenKeychain/src/main/res/raw-ru/help_certification.md +++ b/OpenKeychain/src/main/res/raw-ru/help_certification.md @@ -1,7 +1,7 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) ## Подтверждение ключей -Без подтверждения Вы не можете быть уверены, что ключ принадлежит определенному человеку. +Без подтверждения вы не можете быть уверены, что ключ принадлежит определённому человеку. Простейший способ подтвердить ключ — отсканировать QR-код или получить его через NFC. Для подтверждения ключей более чем двух человек, мы рекомендуем использовать один из доступных методов обмена ключами. diff --git a/OpenKeychain/src/main/res/raw-ru/help_changelog.md b/OpenKeychain/src/main/res/raw-ru/help_changelog.md index b3aab989e..b76586fe2 100644 --- a/OpenKeychain/src/main/res/raw-ru/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-ru/help_changelog.md @@ -1,10 +1,17 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing * Choose remember time individually when entering passwords - * Facebook key import + * Импорт ключа с Facebook ## 3.7 @@ -15,21 +22,21 @@ ## 3.6 - * Encrypted backups + * Зашифрованные резервные копии * Security fixes based on external security audit * YubiKey NEO key creation wizard * Basic internal MIME support - * Automatic key synchronization + * Автоматическая синхронизация ключа * Experimental feature: link keys to Github, Twitter accounts * Experimental feature: key confirmation via phrases - * Experimental feature: dark theme + * Экспериментальная функция: тёмная тема * API: Version 9 ## 3.5 * Key revocation on key deletion - * Improved checks for insecure cryptography + * Улучшенная проверка небезопасной криптографии * Fix: Don't close OpenKeychain after first time wizard succeeds * API: Version 8 diff --git a/OpenKeychain/src/main/res/raw-ru/help_start.md b/OpenKeychain/src/main/res/raw-ru/help_start.md index 0f12fde29..dd345c2d5 100644 --- a/OpenKeychain/src/main/res/raw-ru/help_start.md +++ b/OpenKeychain/src/main/res/raw-ru/help_start.md @@ -1,6 +1,6 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) -## Как мне активировать OpenKeychain в K-9 Mail? +Как мне активировать OpenKeychain в K-9 Mail? Для использования OpenKeychain с K-9 Mail, необходимо выполнить следующие шаги: 1. Откройте K-9 Mail и долгим нажатием выберите учетную запись, с которой будет использоваться OpenKeychain. 2. Выберите "Настройки учетной записи" и опуститесь в самый конец меню до пункта "Шифрование". diff --git a/OpenKeychain/src/main/res/raw-sl/help_about.md b/OpenKeychain/src/main/res/raw-sl/help_about.md index d7ce930cc..bee93f210 100644 --- a/OpenKeychain/src/main/res/raw-sl/help_about.md +++ b/OpenKeychain/src/main/res/raw-sl/help_about.md @@ -65,7 +65,7 @@ Licenca: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (Licenca MIT) * [Snackbar](https://github.com/nispok/snackbar) (Licenca MIT) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Licenca Apache v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Licenca Apache v2) * [ZXing](https://github.com/zxing/zxing) (Licenca Apache v2) diff --git a/OpenKeychain/src/main/res/raw-sl/help_changelog.md b/OpenKeychain/src/main/res/raw-sl/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-sl/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-sl/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-sr/help_about.md b/OpenKeychain/src/main/res/raw-sr/help_about.md index ad9cdc231..f6eecb622 100644 --- a/OpenKeychain/src/main/res/raw-sr/help_about.md +++ b/OpenKeychain/src/main/res/raw-sr/help_about.md @@ -65,7 +65,7 @@ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Материјал дизајн) (Апачи лиценца в2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (МИТ лиценца) * [Snackbar](https://github.com/nispok/snackbar) (МИТ лиценца) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (МИТ Икс11 лиценца) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (МИТ Икс11 лиценца) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Апачи лиценца в2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Апачи лиценца в2) * [ZXing](https://github.com/zxing/zxing) (Апачи лиценца в2) diff --git a/OpenKeychain/src/main/res/raw-sr/help_changelog.md b/OpenKeychain/src/main/res/raw-sr/help_changelog.md index f17e4f74b..0fd4c11e4 100644 --- a/OpenKeychain/src/main/res/raw-sr/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-sr/help_changelog.md @@ -1,5 +1,12 @@ [//]: # +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Редизајн уређивања кључа diff --git a/OpenKeychain/src/main/res/raw-sv/advanced.md b/OpenKeychain/src/main/res/raw-sv/advanced.md index 54a694084..8cf50c854 100644 --- a/OpenKeychain/src/main/res/raw-sv/advanced.md +++ b/OpenKeychain/src/main/res/raw-sv/advanced.md @@ -1,4 +1,4 @@ -[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +[//]: # (NOTERING: Var vänlig och sätt varje mening på sin egen rad, Transifex sätter varje rad i sitt eget fält för översättningar!) Advanced screen allows you to * share key in non-recommended ways diff --git a/OpenKeychain/src/main/res/raw-sv/help_about.md b/OpenKeychain/src/main/res/raw-sv/help_about.md index 161decace..f7d05e363 100644 --- a/OpenKeychain/src/main/res/raw-sv/help_about.md +++ b/OpenKeychain/src/main/res/raw-sv/help_about.md @@ -2,7 +2,7 @@ [https://www.openkeychain.org](https://www.openkeychain.org) -[OpenKeychain](https://www.openkeychain.org) is an OpenPGP implementation for Android. +[OpenKeychain](https://www.openkeychain.org) är en OpenPGP-implementation till Android. Licens: GPLv3+ @@ -65,7 +65,7 @@ Licens: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger's bibliotek för utbyte](https://github.com/SafeSlingerProject/exchange-android) (MIT-licens) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-sv/help_changelog.md b/OpenKeychain/src/main/res/raw-sv/help_changelog.md index 9edf4979a..f8fa439c6 100644 --- a/OpenKeychain/src/main/res/raw-sv/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-sv/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTERING: Var vänlig och sätt varje mening på sin egen rad, Transifex sätter varje rad i sitt eget fält för översättningar!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-tr/help_about.md b/OpenKeychain/src/main/res/raw-tr/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-tr/help_about.md +++ b/OpenKeychain/src/main/res/raw-tr/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-tr/help_changelog.md b/OpenKeychain/src/main/res/raw-tr/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-tr/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-tr/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-uk/help_about.md b/OpenKeychain/src/main/res/raw-uk/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-uk/help_about.md +++ b/OpenKeychain/src/main/res/raw-uk/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-uk/help_changelog.md b/OpenKeychain/src/main/res/raw-uk/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-uk/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-uk/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-vi/help_about.md b/OpenKeychain/src/main/res/raw-vi/help_about.md index 4e8f0270b..fad35b356 100644 --- a/OpenKeychain/src/main/res/raw-vi/help_about.md +++ b/OpenKeychain/src/main/res/raw-vi/help_about.md @@ -65,7 +65,7 @@ License: GPLv3+ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-vi/help_changelog.md b/OpenKeychain/src/main/res/raw-vi/help_changelog.md index b3aab989e..629931b2c 100644 --- a/OpenKeychain/src/main/res/raw-vi/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-vi/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-zh-rTW/help_about.md b/OpenKeychain/src/main/res/raw-zh-rTW/help_about.md index 1d133a37c..1170365ae 100644 --- a/OpenKeychain/src/main/res/raw-zh-rTW/help_about.md +++ b/OpenKeychain/src/main/res/raw-zh-rTW/help_about.md @@ -65,7 +65,7 @@ * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT License) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 License) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache License v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache License v2) * [ZXing](https://github.com/zxing/zxing) (Apache License v2) diff --git a/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.md b/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.md index 14a81bdf1..a62c581bc 100644 --- a/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-zh-rTW/help_changelog.md @@ -1,5 +1,12 @@ [//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + + ## 3.8 * Redesigned key editing diff --git a/OpenKeychain/src/main/res/raw-zh/advanced.md b/OpenKeychain/src/main/res/raw-zh/advanced.md index 54a694084..0f9563fc7 100644 --- a/OpenKeychain/src/main/res/raw-zh/advanced.md +++ b/OpenKeychain/src/main/res/raw-zh/advanced.md @@ -1,9 +1,9 @@ -[//]: # (NOTE: Please put every sentence in its own line, Transifex puts every line in its own translation field!) +[//]: # (注意:请把每个句子放在单独一行中, Transifex 将把每一行放置在独立的翻译表单内!) -Advanced screen allows you to -* share key in non-recommended ways -* edit identities -* edit subkeys -* examine certificates in detail +您可以在高级选项界面进行以下操作 +以其他方式分享密钥(不推荐) +编辑身份 +编辑子密钥 +查看证书详情 -Only proceed if you know what you are doing! \ No newline at end of file +在进行这些操作前,请确认您了解具体操作可能带来的危险后果! \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-zh/help_about.md b/OpenKeychain/src/main/res/raw-zh/help_about.md index 6f3f841a0..17672c57f 100644 --- a/OpenKeychain/src/main/res/raw-zh/help_about.md +++ b/OpenKeychain/src/main/res/raw-zh/help_about.md @@ -1,4 +1,4 @@ -[//]: # (注意: 请把每个句子放在其本行中, Transifex把每一行放在它自己的位置!) +[//]: # (注意:请把每个句子放在单独一行中, Transifex 将把每一行放置在独立的翻译表单内!) [https://www.openkeychain.org](https://www.openkeychain.org) @@ -61,11 +61,11 @@ * [Markdown4J](https://github.com/jdcasey/markdown4j) (Apache 许可证 v2) * [MaterialDrawer](https://github.com/mikepenz/MaterialDrawer) (Apache 许可证 v2) * [MiniDNS](https://github.com/rtreffer/minidns) (Apache 许可证 v2) - * [OkHttp](https://square.github.io/okhttp/) (Apache License v2) - * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache 许可证 v2) + * [OkHttp](https://square.github.io/okhttp/) (Apache 许可证 v2) + * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache 许可证 v2) * [SafeSlinger Exchange library](https://github.com/SafeSlingerProject/exchange-android) (MIT 许可证) * [Snackbar](https://github.com/nispok/snackbar) (MIT 许可证) - * [SpongyCastle](https://rtyley.github.io/bouncycastle/) (MIT X11 License) + * [BouncyCastle](https://github.com/open-keychain/bouncycastle) (MIT X11 许可证) * [StickyListHeaders](https://github.com/emilsjolander/StickyListHeaders) (Apache 许可证 v2) * [TokenAutoComplete](https://github.com/splitwise/TokenAutoComplete) (Apache 许可证 v2) * [ZXing](https://github.com/zxing/zxing) (Apache 许可证 v2) diff --git a/OpenKeychain/src/main/res/raw-zh/help_certification.md b/OpenKeychain/src/main/res/raw-zh/help_certification.md index efac9322b..ac3a20c27 100644 --- a/OpenKeychain/src/main/res/raw-zh/help_certification.md +++ b/OpenKeychain/src/main/res/raw-zh/help_certification.md @@ -1,28 +1,28 @@ -[//]: # (注意: 请把每个句子放在其本行中, Transifex把每一行放在它自己的位置!) +[//]: # (注意:请把每个句子放在单独一行中, Transifex 将把每一行放置在独立的翻译表单内!) ## 密钥确认 -在没有进行确认之前,你无法确保一个密钥与特定的人的密钥是相符的 -确认密钥相符的最简单方式是扫描二维码或者通过NFC交换 -为了确认多于2个人的密钥是相符的, 我们建议使用密钥交换的方法进行确认. +在进行确认之前,您无法可靠地将一个密钥与特定人物关联起来。 +确认密钥的最简单方式是扫描二维码或者通过NFC进行交换。 +在2人以上的团体内进行密钥确认时,我们建议使用密钥交换的方法。 ## 密钥状态 -已确认: 你已经通过例如二维码扫描这种方式确认了这个密钥 +已确认:您已经通过某种方式(例如扫描二维码)确认了这个密钥。 -未确认: 这个密钥尚未被确认. 你无法确保这个密钥与指定的人的密钥是相同的. +未确认:这个密钥尚未被确认。您无法确保这个密钥与特定人物的关联是可靠的。 -已过期: 这个密钥不再有效. 只有它的拥有者能扩展它的正确性. +已过期:这个密钥不再有效。只有它的拥有者能扩展它的有效期。 -已作废:这个密钥不再有效。它已经被所有者作废. +已作废:这个密钥不再有效。它已经被所有者声明为已作废。 -##进一步说明 -在OpenKeychain中“确认密钥”是根据OpenPGP标准创建一个认证所实现。 -这个认证是一个 ["一般认证(0x10)"]http://tools.ietf.org/html/rfc4880#section-5.2.1) 标准中的描述是: -认证的发行者不对妥善检查密钥所有者与密钥所示使用者身份是否相符的情况做出任何表态。 +## 进一步说明 +OpenKeychain 中的“密钥确认”行为,是根据 OpenPGP 标准规定,通过创建认证实现的。 +这个认证是一个 [“一般认证(0x10)”](http://tools.ietf.org/html/rfc4880#section-5.2.1) ,标准中的描述是: +“对于密钥持有者与密钥所示身份之间的关联,认证签发者不对其可靠性做出任何表态。” -习惯上,认证(更高级的认证,例如“主动认证”(0x13))是有组织的存储在OpenPGP的信任网络中。 -我们的确认密钥模型采用一套相对简单的概念,为了避开上述提到的信任网络中普遍的可用性问题。 -我们假设密钥只被验证到足以随时使用的程度。 -我们也不进行像GnuPG那样的信任签名或导入主观信任数据库。 +习惯上,这些认证(也包括较高的信任等级,例如“正向认证” (0x13) )是以 OpenPGP 的信任网络的形式存在的。 +为了消除信任网络的可用性问题,我们的密钥确认模型采用一套相对简单的概念。 +我们相信密钥的确认过程应该在不妨碍日常使用的情况下尽量可靠。 +我们也不实现像 GnuPG 那样的(可传递)信任签名或信任数据库。 此外,当某密钥含有至少一个被信任密钥所认证过的使用者身份时,它将在密钥列表中被标记为“已确认”。 \ No newline at end of file diff --git a/OpenKeychain/src/main/res/raw-zh/help_changelog.md b/OpenKeychain/src/main/res/raw-zh/help_changelog.md index 047ef4858..9f91ebe5b 100644 --- a/OpenKeychain/src/main/res/raw-zh/help_changelog.md +++ b/OpenKeychain/src/main/res/raw-zh/help_changelog.md @@ -1,10 +1,17 @@ -[//]: # (备注: 请把每个句子保持在它自己的一行里,Transifex会把每一行放到他应该的位置!) +[//]: # (注意:请把每个句子放在单独一行中, Transifex 将把每一行放置在独立的翻译表单内!) + +## 3.9 + + * Detection and handling of text data + * Performance improvements + * UI improvements for Security Token handling + ## 3.8 - * Redesigned key editing - * Choose remember time individually when entering passwords - * Facebook key import + * 重新设计了密钥编辑操作 + * 键入密码时单独选择记忆时间 + * 导入 Facebook 密钥 ## 3.7 diff --git a/OpenKeychain/src/main/res/raw-zh/help_start.md b/OpenKeychain/src/main/res/raw-zh/help_start.md index 183c63150..0aed388a3 100644 --- a/OpenKeychain/src/main/res/raw-zh/help_start.md +++ b/OpenKeychain/src/main/res/raw-zh/help_start.md @@ -1,16 +1,16 @@ -[//]: # (注意: 请把每个句子放在其本行中, Transifex把每一行放在它自己的位置!) +[//]: # (注意:请把每个句子放在单独一行中, Transifex 将把每一行放置在独立的翻译表单内!) ## 我怎样才能在 K-9 Mail 中激活 OpenKeychain? -在K-9 Mail中使用OpenKeychain,请遵循以下步骤: - 1.打开K-9 Mail并长按你想要使用OpenKeychain的账户。 - 2.选择“账户设置”,滑到最下方,点击“加密”。 - 3.点击“OpenPGP提供者”并在列表中选择OpenKeychain。 +在 K-9 Mail 中使用 OpenKeychain ,请遵循以下步骤: + 1. 打开 K-9 Mail 并长按你想要使用 OpenKeychain 的账户。 + 2. 选择“账户设置”,滑到最下方,点击“加密”。 + 3. 点击“ OpenPGP 提供者”并在列表中选择 OpenKeychain. -## 我发现了OpenKeychain的问题! -请使用 [OpenKeychain问题跟踪系统](https://github.com/openpgp-keychain/openpgp-keychain/issues)提交问题。 +## 我发现了OpenKeychain 的问题! +请使用 [OpenKeychain 问题跟踪系统](https://github.com/openpgp-keychain/openpgp-keychain/issues) 提交问题。 ## 贡献 -如果你想要通过贡献代码来帮助开发OpenKeychain [请按照我们在Github上的一个小指引](https://github.com/openpgp-keychain/openpgp-keychain#contribute-code). +如果你想要通过贡献代码来帮助开发 OpenKeychain [请按照我们在 Github 上的一个小指引](https://github.com/openpgp-keychain/openpgp-keychain#contribute-code). ## 翻译 -帮助翻译OpenKeychain!每个人都可以参与。[OpenKeychain on Transifex](https://www.transifex.com/projects/p/open-keychain/). \ No newline at end of file +帮助翻译 OpenKeychain !每个人都可以参与。 [OpenKeychain on Transifex](https://www.transifex.com/projects/p/open-keychain/). \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values-cs/strings.xml b/OpenKeychain/src/main/res/values-cs/strings.xml index bcfb71d0b..9ba8e1e36 100644 --- a/OpenKeychain/src/main/res/values-cs/strings.xml +++ b/OpenKeychain/src/main/res/values-cs/strings.xml @@ -9,6 +9,7 @@ Rozšifrovat Přidat podklíč Editovat klíč + Vyrořit propojenou identitu Nastavení Aplikace OpenPGP keyservery @@ -20,33 +21,54 @@ Zašifrovat do souboru Rozšifrovat do souboru Importovat klíče + Zálohovat klíč + Zálohovat klíče Klíč nebyl nalezen Nahrát na keyserver + Zálohovat klíč Potvrdit klíč Detaily klíče Nápověda Log Vyměnit klíče + Pokročilé Smazat Váš klíč \'%s\'? Spravovat klíče Identity + Bezpečnostní token Propojený kontakt v systému + Keybase.io Proofs Důvěřujete tomuto klíči? Doložit ověření Podklíče + Vyhledávání klíče + Keyserver, keybase.io + Hesla a PINy + Přenášení, uživatelské rozhraní, čas po který si pamatovat + Anonimita na síti + Tor, Nastavení proxy + Rozhraní + Synchronizace + Automatická aktualizace klíče, propojení s kontaktem + Experimentální funkce Potvrdit Akce Klíč Keyserver Otisk + Fráze Zašifrovat + Dešifrovat / Ověřit Současná expirace Nová expirace Dešifrovat, ověřit a uložit soubor Zašifrovat a sdílet soubor Zašifrovat a uložit soubor + Uložit soubor + Uložit + Zobrazit log Zrušit Smazat Žádná expirace @@ -56,10 +78,17 @@ Zpět Ne Otisky souhlasí + Fráze odpovídá + Zašifrovat/podepsat a sdílet text + Zašifrovat/podepsat a kopírovat text + Zašifrovat/podepsat a vložit text Zobrazit klíč certifikátu Vytvořit klíč Přidat soubor(y) - Kopírovat dešifrovaný text + Sdílet + Otevřít pomocí... + Načíst ze schránky + Vybrat vstupní soubor Zašifrovat soubory Zašifrovat text Přidat další emailové adresy @@ -67,10 +96,16 @@ Přidat Uložit jako výchozí Uloženo! + Neodpovídá + Zašifrovat soubory + Vyměnit klíče + Zašifrovat text + Sdílet přes NFC Nastavení Nápověda + Zálohovat klíč Smazat klíč Spravovat klíče Hledat @@ -80,6 +115,12 @@ Vybrat vše Exportovat všechny klíče Aktualizovat všechny klíče + Pokročilé + Ověřit pomocí otisku prstu + Ověřit pomocí frází + Sdílet log + Změnit heslo + Přidat Text Soubor @@ -87,6 +128,7 @@ Soubor: Žádné heslo Heslo + PIN Odemykám... Zopakovat heslo Zobrazit heslo @@ -95,11 +137,15 @@ Povolit ASCII armor Dát ostatním vědět, že používáte OpenKeychain Zapisovat \'OpenKeychain v2.7\' do OpenPGP podpisů, šifrovaného textu a exportovaných klíčů + Použít numerickou klávesnici pro PIN bezpečnostního tokenu + Podepsat pomocí: + Zašifrovat do Smazat soubory po zašifrování Smazat po rozšifrování Šifrovací algoritmus Hashovací algoritmus Zašifrovat heslem + Zapamatovat hesla pomocí subklíče Komprimovat text Komprimovat soubor Vyberte OpenPGP keyservery @@ -114,22 +160,73 @@ Jméno Komentář Email + Synchronizovat s Internetem Otisk Nastavit datum expirace + Keyservery + Pro změnu řazení přetáhněte, pro editaci/smazání klepněte + Vyberte keyserver upřednostněno Zapnout kompresi Zašifrovat jména souborů Skrýt příjemce + Otestovat připojení + Pouze důvěryhodný keyserver + URL + Smazat keyserver + Téma vzhledu OpenPGP keyserver Vyhledat klíče na vybraném OpenPGP keyserveru (protokol HKP) keybase.io Hledat klíče na keybase.io + Facebook + Vyhledat klíče na Facebooku pomocí uživatelského jména + Automaticky aktualizovat klíč + Klíče jsou aktualizovány z preferovaného keyserveru každé tři dny + Klíče nejsou automaticky aktualizovány + Propojit klíče s kontakty + Protojit klíče s kontakty na základě jmen a emailových adres. Odehrává se to kompletně offline na vašem zařízení. + Nové klíče nebudou propoeny ke kontaktům + Automaticky aktualizovat klíč + Varovnání + Tyto funkce nejsou ještě dokončené nebo neprošli uživatelským testováním/bezpečnostním auditem. Prosím nepoužívejte je v situacích kdy na nich závisí vaše zabezpečení a nehlašte problémy s nimi spojené, pokud na ně narazíte. + Ověření pomocí frází + Ověřit klíč pomocí frází namísto hexadecimálního fingerprintu + Propojené identity + Propojit klíče s Twitterem, GitHubem, webem nebo DNS (podobně jako keybase.io ale decentralizované) + Keybase.io Proofs + Kontaktovat keybase.io pro proofs klíče a ukázat je pokaždé když je klíč zobrazen + (Ikony a mnoho obrazovek ještě nejsou uzpůsobené pro temné téma vzhledu) + Zapnout Tor + Vyžaduje instalovaný Orbot + Zapnout jinou proxy + Proxy server + Proxy server nemůže zůstat prázdný + Proxy port + Vložen neplatné číslo portu + Typ proxy + HTTP + SOCKS + Nepoužívat Tor + Nainstalovat Orbot abyste mohli použít Tor? + Instalovat + Musíte mít nainstalovaný a aktivovaný Orbot abyste mohli vést provoz skrz něj. Chcete ho nainstalovat? + Zrušit + Nepoužívat Tor + Spustit Orbot? + Nezdá se že by Orbot běžel. Chcete ho spustit a připojit se do Toru? + Spustit Orbot + Spustit Orbot + Zrušit + Nepoužívat Tor + ]]> + ]]> 1 klíč %d klíče @@ -155,6 +252,7 @@ 4 hodiny 8 hodin navždy + Vybrat klíč DSA ElGamal RSA @@ -163,6 +261,8 @@ Otevřít... Chyba Chyba: %s + Temný + Světlý Certifikovat Podepsat @@ -173,17 +273,31 @@ Není nainstalován žádný compatibilní správce souborů. Hesla se neschodují. Zadejte heslo. + Zadejte heslo + Zadejte záložní kód Zadejte heslo pro \'%s\' Zadejte PIN pro \'%s\' + Zadejte PIN pro přístup k bezpečnostnímu tokenu pro \'%s\' + Podržte bezpečnostní token u NFC značky na zadní straně vašeho přístroje. + Podržte bezpečnostní token u zadní strany! + Nyní odeberte bezpečnostní token. + Nyní odeberte bezpečnostní token a zmáčkněte ZKUSIT ZNOVU. Smazat původní soubory? Následjící soubory budou vymazány:%s %1$d z %2$d souborů bylo vymazáno.%3$s + Nebyl vybrán žádný soubor. Úspěšně podepsáno a/nebo zašifrováno. Úspěšně podepsání a/nebo zašifrováno do schránky. Vyberte alespoň jeden šifrovací klíč. + Vyberte alespoň jeden šifrovací nebo podpisový klíč. Prosím specifikujte do kterého souboru zašifrovat.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán. Prosím specifikujte do kterého souboru rozšifrovat.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán. + Bude provedena záloha vyjma vašich klíčů, prosím specifikujte cílový sobor.\nVAROVÁNÍ: Soubor bude přepsán pokud existuje! + Tento klíč bude sdílen, prosím specifikujte cílový soubor.\nVAROVÁNÍ: Pokud soubor existuje, bude přepsán! + Úplná záloha vašeho klíče bude provedena, prosím specifikujte cílový soubor.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán. + Bude provedena úplná záloha všech vašich klíčů, prosím specifikujte cílový soubor.\nVAROVÁNÍ: Pokud soubor již existuje, bude přepsán. Opravdu chcete smazat všechny vybrané soubory? + Po smazání nebudete moci dešifrovat zprávy/soubory zašifrované tímto klíčem a příjdete o všechna potvrzení k nimž jste tento klíč použili. Smazat klíč \'%s\'? Zárověň exportovat tajný klíč Narazili jste na známou chybu v Androidu. Přeinstalujte prosím OpenKeychain pokud chcete své propojit kontakty s klíči. @@ -198,6 +312,7 @@ Fingerprint byl zkopírován do schránky! Prosím vyberte klíč, který bude použit k potvrzení! Text byl zkopírován do schránky! + Jak toto importovat na PC? @@ -318,6 +433,7 @@ Verze: Keyserver + Vyhledávání klíče Soubor/schránka QR kód/NFC Importovat vybrané klíče @@ -334,18 +450,60 @@ Nic k importu Import zrušen. + + Úspěšně smazán jeden klíč + Úspěšně smazáno %1$d klíče + Úspěšně smazáno %1$d klíčů + + + , ale selhalo smazání jednoho klíče%2$s. + , ale selhalo smazání %1$d klíčů%2$s. + , ale selhalo smazání %1$d klíčů%2$s. + + + Úspěšně smazáno klíče%2$s. + Úspěšně smazáno %1$d klíčů%2$s. + Úspěšně smazáno %1$d klíčů%2$s. + + + Chyba mazání jednoho klíče%2$s. + Chyba smazání %1$d klíčů. + Chyba smazání %1$d klíčů. + Nic ke smazání. Operace smazání zrušena. + Klíč úspěšně zneplatněn. + Chyba zneplatnění klíče! + Nic k zneplatnění + Operace zneplatnění zrušena. + + Úspěšně potvrzen klíč%2$s. + Úspěšně potvrzeny %1$d klíče%2$s. + Úspěšně potvrzeno %1$d klíčů%2$s. + + + Certifikace selhala! + Certifikace selhala pro %d klíče! + Certifikace selhala pro %d klíčů! + + + Certifikace selhala! + Certifikace pro %d klíče selhala! + Certifikace pro %d klíčů selhala! + Dešifrovat soubor pomocí OpenKeychain Importovat kíč pomocí OpenKeychain Zašifrovat pomocí OpenKeychain Dešifrovat pomocí OpenKeychain + Zobrazit pokročilé informace + Schovat pokročilá informace Žádný klíč nebyl vybrán Vybrat klíč + Vytvořit nový klíč Uložit Účet byl uložen Zrušit @@ -353,12 +511,21 @@ Spustit aplikaci Smazat účet Jméno balíčku + SHA-256 z certifikátu balíčku + Účty (staré API) + Pokročilé + Povolené klíče Nastavení Klíč účtu: Žádné účty nejsou specifikovány pro tuto appku. + Pro tento účet není nastaven žádný klíč. Vyberte prosím jeden z existujících klíčů nebo vytvořte nový.\nAplikace mohou rošifrovat/podepisovat pouze klíči, které jsou zde vybrány! + Klíč uložen pro tento účet byl smazán. Vyberte prosím jiný!\nAplikace mohou rošifrovat/podepisovat pouze klíči, které jsou zde vybrány! + Zobrazená appka chce zašifrovat/rozšifrovat zprávu a podepsat jí vaším jménem.\nPovolit přístup?\n\nVAROVÁNÍ: Pokud nevíte proč se tato zpráva oběvila, nepovolujte přístup! Zneplatnint přístup můžete také pomocí obrazovky \'Aplikace\'. Povolit přístup Zamítnout přístup Prosím vyberte klíč! + Pro tyto emailové adresy nebyl nalezen žádný klíč: + Pro tyto emailové adresy existuje více jak jeden klíč: Zkontrolujte prosím seznam příjemců! Vyberte prosím příjemce! Selhala kontrola podpisu! Instalovali jste tuto aplikaci z jiného zdroje? Pokud jste si jistí, že toto není útok, zneplatněte registraci této aplikace v OpenKeychain a poté ji znovu zaregistrujte. @@ -368,8 +535,18 @@ Sdílet pomocí QR kódu Sdílet pomocí NFC + Nahrávání selhalo + Nahrávání selhalo. Chcete to zkušit znovu? + Zkusit znovu + Zrušit operaci + Pokud nechcete nadáe používat tento klíč, měl by být zevokován a nahrán. Vyberte \'POUZE SMAZAT\' pokud si přejete smazat klíč z OpenKeychain ale chcete ho i nadále používat někde jinde. + Zneplatnit/Smazat klíč \'%s\' + Zneplatnit a nahrát + Pouze smazat + Pouze smazat + Zneplatnit a Nahrát 1 kíč vybrán @@ -378,7 +555,12 @@ Žádný klíč nenalezen! Zobrazit všechny klíče + Zobrazit pouze potvrzené klíče + Naskenovat QR kód + Vyhledávání klíče + Importovat ze souboru + Editovat Zašifrovat text soubory Potvrdit klíč @@ -387,22 +569,51 @@ Sdílet přes NFC Nahrát na keyserver Hlavní info + Začít Sdílet Podklíče Certifikáty Keybase.io Zneplatněno Tato identity byla zneplatněna vlastníkem klíče. Klíč již není platný. + Potvrzeno + Tato identita byla potvrzena vámi. + Nepotvrzeno + Tato identita zatím nebyla potvrzena. Nemůžete si být jisti zda je identita odpovídá určité osobě. Neplatná S touto identitou je něco v nepořádku! + Žádný důkaz o důvěryhodnosti klíče z internetu. Vyhledat Keybase.io nabízí “důkazy” které tvrdí, že vlastníkem tohoto klíče je: + Postuje na Twitter jako %s + Je znám na GitHubu jako %s + Spravuje doménové jmén(o/a) %s + Postuje na webovou stránku(y) %s + Postuje na Reddit jako %s + Je znám na Coinbase jako %s + Postuje na Hacker News jako %s + Neznámý typ důkazu %s + Naneštěstí tento důkaz nemůže být ověřen. + Nerozpoznatelný problém s ověřováním důkazu + Problém s důkazem + Otisk klíče nesouhlasí s tím v důkazu + Stažení záznamu DNS TXT selhalo + Nenalezen zůsob ověření pro + Rošifrovaný záznam důkazu nesouhlasí s očekávanou hodnotou + Stahuji důkaz + Tento důkaz byl ověřen! Příspěvek + stažen z + pro doménu + obsahuje zprávu, která mohla být vytvořena pouze vlastníkem tohoto klíče. tweet + Záznam DNS TXT textový soubor + Gist soubor JSON + Reddit připisuje Ověřit Změnit heslo @@ -418,11 +629,21 @@ Tato identity byla zneplatněna. Toto není možné vzít zpět. Vyberte akci! + + Změnit expiraci + Zneplatnit podklíč + Svléknout podklíč + Přesunout podklíč do bezpečnostního tokenu + nový podklíč Prosím vyberte alespoň jeden příznak! Přidejte alespoň jednu identitu! Přidejte alespoň jeden podklíč! + Algoritmus nepodporován bezpečnostním tokenem! + Dékla klíče není bezpečnostním tokenem podporována! + Nemohu přesunout klíč do bezpečnostního tokenu (buď je holý nebo označen jako \'divert-to-card\')! + Synchronizovat s Internetem Toto pole je vyžadováno Hesla se neschodují. Zadali jste následující identitu: @@ -437,6 +658,7 @@ Další emailové adresy jsou přiřazeny k tomuto klíči a mohou být požity k zabezpečené komunikaci. Emailová adresa již byla přidána. Formát emailové adresy není platný. + PIN Zneplatněn: Klíč nesmí být dále použit! Vypršel: Kontakt musí rozšířit platnost klíče! @@ -447,8 +669,14 @@ <žádný> Přidat keyserver + Editovat keyserver + Spojení ověřeno! Keyserver přidán bez verifikace. Neplatná URL! + Keyserver není jedním z důvěryhodných (žádný pinned certifikát k dispozici)! + Selhalo spojení s keyserverem. Ověřte prosím URL a vaše připojení na Internet. + %s smazán + Není možné smazat poslední keyserver. Alespoň jeden je vyžadován! Klíče Zašifrovat/Dešifrovat @@ -456,6 +684,7 @@ Otevřít navigační panel Zavří navigační panel Moje Klíče + Záloha/Obnova Napsat text @@ -505,6 +734,7 @@ Hlavní příznaky: přihlášení Hlavní příznaky: žádné Slučuji importovaná data do existující veřejné klíčenky + Zařazuji importovaná data do existující zabezpečené klíčenky Zpracovávám podklíč %s Podklíč vypršel %s Podklíč vypršel %s @@ -535,6 +765,17 @@ Certifikát je novější, nahrazuji předchozí. Nalezen platný certifikát od %1$s Nalezena platné zneplatnění certifikátu od %1$s + + Ignoruji certifikát vydaný neznámým veřejným klíčem. + Ignoruji %s certifikátů vydaných neznámým veřejnými klíči. + Ignoruji %s certifikátů vydaných neznámým veřejnými klíči. + + Klasifikuji uživatelská ID (žádné důvěryhodné klíče k dispozici) + + Klasifikuji uživatelské ID (používám jeden důvěryhodný klíč) + Klasifikuji uživatelská ID (používám %s důvěryhodné klíče) + Klasifikuji uživatelská ID (používám %s důvěryhodných klíčů) + Přeskládávám uživatelské jména Zpracovávám uživatelské jméno %s Uživatelské jméno zneplatněno @@ -547,6 +788,12 @@ Certifikát je novější, nahrazuji předchozí. Nalezen platný certifikát od %1$s Nalezena platné zneplatnění certifikátu od %1$s + + Ignoruji jeden certifikát vydaný neznámým veřejným klíčem + Ignoruji %s certifikáty vydané neznámými veřejnými klíči + Ignoruji %s certifikáty vydané neznámými veřejnými klíči + + Třídím uživatelské atributy Atribut uživatele je zneplatněn Pokus o import veřejné klíčenky jako tajné. Toto je bug, prosím nahlašte ho! Pokus o importování klíčenky bez kanonizace. Toto je bug, prosím vyplňte hlášení! @@ -556,14 +803,20 @@ Zpracovávám tajné podklíče Chyba kódování klíčenky Slučuji importovaná data do existující veřejné klíčenky + Slučuji importovaná data do existující zabezpečené klíčenky + Slučuji data vlastních certifikátů z veřejné klíčenky Vytvářím veřejnou klíčenku z tajné Podklíč %s není k dispozici v tajném klíči Označen tajný podklíč %s jako že je k dispozici Označen tajný podklíč %s jako k dispozici s prázným heslem Označen tajný podklíč %s jako že je k dispozici s PINem + Tajný podklíč %s označen jako holý + Tajný podklíč %s označen jako \'divert-to-card\' Klíčenka neobsahuje žádná nová data, není co provést Úspěšně importován tajný klíč + Kanonizuji veřejnou klíčenku %s + Kanonizuji tajnou klíčenku %s Toto je klíč OpenPGP verze 3, který již naní podporován! Klíčenka neobsahuje žádná platná uživatelská jména! Hlavní klíč používá neznámý (%s) algoritmus! @@ -577,18 +830,66 @@ Odebírám špatný hlavní klíč certifikátu Odebírám hlavní klíč certifikátu s příznakem \'lokální\' Odebírám redundantní zneplatňovací certifikát klíčenky + Odebírám nadbytečný certifikát + Odebírám prázdný natation certifikát + Zpracovávám podklíč %s + Odebírám neplatné napojení podklíče certifikátu + Odebírám spatné napojení podklíče certifikátu + Odebírám napojení podklíče certifikátu s příznakem \'lokální\' + Napojení podklíče na id vydavatele nesouhlasí + Odebírám napojení podklíče s časovou značkou v budoucnu + Napojení podklíče certifikátu má dřívější čas než jeho klíč! + Neznámý typ certifikátu podklíče: %s + Odebírám nadbitečné napojení podklíče certifikátu + Odebírám napojení podklíče certifikátu kůli neplatnému napojení hlavního certifikátu + Odebírám napojení podklíče certifikátu kůli čpatnému napojení hlavního certifikátu + Odebírám napojení podklíče certifikátu kůli chybějícímu napojení hlavního certifikátu + Pro %s nebyl nalezen žádný platný certifikát, odebírám z klíčenky + Odebírám špatný zneplatňovací podklíč certifikátu + Odebírám špatný zneplatňovací podklíč certifikátu + Odebírám redundantní zneplatňovací podklíč certifikátu + Podklíč používá neznámý algoritmus, neimportuji... + Podklíč má příznak použitelnosti k šifrování, ale algoritmus není k šifrování vhodný. + Podklíč má příznak použitelnosti k podepisování, ale algoritmus není k podepisování vhodný. + Kanonizace klíčenky úspšná, žádné změny + + Kanonizace klíčenky úspšná, odebrán jeden chybný certifikát + Kanonizace klíčenky úspšná, odebráno %d chybné certifikáty + Kanonizace klíčenky úspšná, odebráno %d chybných certifikátů + + Kanonizace klíčenky úspšná, odebráno %1$s chybných a %2$s nadbytečných certifikátů + + Kanonizace klíčenky úspšná, odebrán jeden nadbytečný certifikát + Kanonizace klíčenky úspšná, odebrány %d nadbytečné certifikáty + Kanonizace klíčenky úspšná, odebráno %d nadbytečných certifikátů + + Odebírám chybný vlastní certifikát pro uživatele \'%s\' + Odebírám uživatelské ID certifikátu s příznakem \'lokální\' + Odebírám uživatelské ID s časovou značkou v budoucnu + Odebírám uživatelské ID certifikátu neznámého typu (%s) + Odebírám chybný vlastní certifikát pro uživatele \'%s\' + Odebrírám zastaralý vlastní certifikát pro uživatelské ID \'%s\' + Odebírám cizí uživatelské ID certifikátu od \'%s\' + Odebírám nadbytečný zneplatňovací certifikát pro uživatelské ID \'%s\' + Odebírám zastaralý zneplatňovací certifikát pro uživatelské ID \'%s\' + Nenalezen žádný platný vlastní certifikát pro uživatelské ID \'%s\', odebírám z klíčenky + Odebírám neplatnou uživatelskou identitu \'%s\' + Uživatelské ID neověřeno jako UTF-8! + Uživatelské ID neověřeno jako UTF-8! Generuji nový hlavní klíč Nebyla specifikována eliptická křivka! Toto je chyba v programování a je třeba ji nahlásit! Upravuji klíčenku %s + Modifikace holého podklíče %s se nezdařila! Uživatelské ID nesmí být prázdné! Chyba otevírání databáze! + Nemohu editovat klíčenku s holým hlavním klíčem! Klíč nenalezen! @@ -597,9 +898,13 @@ Účet uložen + Otisk klíče nesouhlasí s tím v důkazu + Stažení záznamu DNS TXT selhalo + Rošifrovaný záznam důkazu nesouhlasí s očekávanou hodnotou + Spustit Orbot Převezměte opět kontrolu nad svým soukromím s OpenKeychain! Přeskočit nastavení @@ -611,6 +916,7 @@ Typ Klíč nenalezen! Chyba zpracování klíče! + holý nedostupný Vaše vlastní klíče lze mazat pouze jednotlivě! Zobrazit detaily certifikátu @@ -619,10 +925,26 @@ Není dostupný šifrovací podklíč! Zobrazit klíč (%s) Potáhnout dolů pro aktualizaci z keyserveru + ]]> + Zadejte heslo + Propojené identity + Sdílet + Zrušit + Uložit + Zapamatovat + Žádná PGP aplikace nenalezena na bezpečnostním tokenu + Instalovat PGP? + Na vašem Fidesmo zařízení nebyla nalezena žádná PGP aplikace. + Instalovat + Zrušit + Nainstalovat Fidesmo? + K instalaci PGP potřebujete Fidesmo Android aplikaci. + Instalovat + Zrušit diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index 6eada434b..18bc957ce 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -13,7 +13,7 @@ Einstellungen Apps OpenPGP-Schlüsselserver - Merkdauer von Passwörtern + Zwischenspeicherdauer für Passwörter Passwort ändern Teile Fingerabdruck über… Teile Schlüssel über... @@ -88,7 +88,7 @@ Datei(en) hinzufügen Teilen Öffnen mit… - Entschlüsselten Text kopieren + In die Zwischenablage kopieren Aus Zwischenablage lesen Datei auswählen Dateien verschlüsseln @@ -147,7 +147,7 @@ Verschlüsselungsalgorithmus Hash-Algorithmus Mit Passwort verschlüsseln - Merkdauer von Passwörtern + Zwischenspeicherdauer für Passwörter Passwort pro Unterschlüssel merken Textkomprimierung Dateikomprimierung @@ -451,6 +451,7 @@ Changelog Über Version: + Spende Schlüsselserver Schlüsselsuche @@ -981,6 +982,7 @@ Signaturfehler! Gekürzter Unterschlüssel %s kann nicht verändert werden! Versuch mit fehlendem Unterschlüssel %s zu arbeiten! + Kann Schlüssel nicht auf Smartcard verschieben wenn im gleichen Vorgang die Kartensignatur erstellt wird. Smartcard unterstützt nur einen Slot pro Schlüsseltyp. Ungeeignete Schlüsselattribute für Schlüssel auf Smartcard. Hauptbeglaubigungen werden verändert @@ -1292,6 +1294,10 @@ Dateiname: \'%s\' Versuche MIME-Typ aus Dateiendung zu ermitteln Content-Länge: %s + Zeichensatz ist \'%s\' + Zeichensatz ist \'%s\', aber Decodieren ist fehlgeschlagen. + Zeichensatz scheint \'%s\' zu sein + Zeichensatz unbekannt, oder Daten sind kein Text. Verarbeite MIME Daten Struktur Parsen beendet Keine MIME-Struktur gefunden @@ -1301,15 +1307,11 @@ Überspringe MIME-Parsing Benutzerkonto gespeichert Erfolgreich heruntergeladen! - Keine gültigen Schlüssel in der Datei/Zwischenablage gefunden! - NOCH ZU MACHEN: Plurale! - - ein Teil der geladenen Datei ist ein gültiges OpenPGP-Objekt, aber kein OpenPGP-Schlüssel - Teile der geladenen Dateien sind gültige OpenPGP-Objekte, aber keine OpenPGP-Schlüssel - - Die Suchanfrage ist zu kurz, bitte die Suchanfrage verfeinern! - Schlüsselsuchanfrage lieferte zu viele Kandidaten, bitte die Suchanfrage verfeinern! - Entweder keine oder zu viele Schlüssel wurden gefunden, bitte die Suchanfrage prä­zi­sie­ren! + Datei nicht gefunden! + Keine gültigen Schlüssel in Datei/Zwischenablage gefunden! + Die Schlüsselanfrage liefert zu viele Ergebnisse. Bitte präzisiere deine Suchanfrage! + Suchanfrage zu kurz. Bitte ändere deine Anfrage! + Keine oder zu viele Schlüssel wurden gefunden. Bitte präzisiere deine Anfrage! Beim Suchen der Schlüssel ist ein Fehler aufgetreten. Versuche Keybase.io-Verifikation für %s @@ -1344,6 +1346,7 @@ Verwende Smartcard (Fidesmo, YubiKey NEO, SIGILANCE, ...) Setup überspringen + Diese leere Smartcard mit OpenKeychain verwenden?\n\nBitte entferne die Smartcard jetzt. Du wirst aufgefordert, wenn sie erneut benötigt wird! Diese Smartcard verwenden Backups, die deine eigenen Schlüssel beinhalten, dürfen unter keinen Umständen an anderen Personen gegeben werden. Alle Schlüssel + deine eigenen Schlüssel @@ -1451,6 +1454,7 @@ Smartcard erwartete das letzte Kommando in einer Kette. Smartcard meldete ungültige %s Byte. Smartcard wurde zu früh abgenommen. Halte die Smartcard an die Rückseite bis der Vorgang beendet ist. + Smartcard unterstützt ISO-DEP (ISO 14443-4) nicht Erneut versuchen Originaldatei löschen Dateinamen sind verschlüsselt. @@ -1548,8 +1552,8 @@ Aktualisiere Schlüssel... Mit Github-Konto verknüpfen Authentifizierung fehlgeschlagen! - Zeitüberschreitung bei Verbindungsaufbau - Netzwerk Fehler! + Zeitüberschreitung beim Verbindungsaufbau! + Netzwerkfehler! Kommunikationsfehler: %s GitHub Authentifizierung Verknüpfte OpenKeychain-Identität @@ -1579,13 +1583,34 @@ Identitäten bearbeiten Unterschlüssel bearbeiten Suche nach\n\'%s\' - bis Bildschirm abschaltet + bis Bildschirm abgeschalten + für 10 Minuten + für 30 Minuten für eine Stunde für drei Stunden für einen Tag für drei Tage - Wähle bis zu drei - Mindestens eine Option muss gewählt werden - Höchstens 3 Optionen können gewählt werden + für immer + Wähle bis zu drei. + Mindestens eine Option muss gewählt werden! + Höchstens 3 Optionen können gewählt werden! Merken + Keine PGP-Anwendung auf Smartcard gefunden + PGP installieren? + Keine PGP-Anwendung verfügbar auf diesem Fidesmo-Gerät. + Installieren + Abbrechen + Fidesmo installieren? + Fidesmo Android App wird benötigt um PGP zu installieren. + Installieren + Abbrechen + OpenKeychain Spende + + 1 EUR + 3 EUR + 5 EUR + 10 EUR + 50 EUR + 100 EUR + diff --git a/OpenKeychain/src/main/res/values-es-rMX/strings.xml b/OpenKeychain/src/main/res/values-es-rMX/strings.xml index fb73ac050..f60e2bbdf 100644 --- a/OpenKeychain/src/main/res/values-es-rMX/strings.xml +++ b/OpenKeychain/src/main/res/values-es-rMX/strings.xml @@ -81,7 +81,6 @@ Agregar archivo(s) Compartir Abrir con... - Copiar texto descifrado Leer desde el portapapeles Elegir archivo de entrada Cifrar archivos diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index b5dd92164..6e81e12bd 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -13,7 +13,6 @@ Configuración Aplicaciones Servidores de claves OpenPGP - Personalizar opciones de \"Recordar\" Cambiar contraseña Compartir huella digital con... Compartir clave con... @@ -86,7 +85,6 @@ Añadir fichero(s) Compartir Abrir con... - Copiar texto descifrado Leer del portapapeles Seleccionar fichero de entrada Cifrar ficheros @@ -137,7 +135,6 @@ Algoritmo de cifrado Algoritmo hash Cifrar con contraseña - Personalizar opciones de \"Recordar\" Recordar contraseñas por subclave Compresión del texto Compresión del fichero @@ -1227,16 +1224,6 @@ Content-Type: %s Los datos se procesaron exitosamente Cuenta guardada - ¡Descargado con éxito! - ¡No se encontraron claves válidas en el fichero/portapapeles! - PENDIENTE: ¡plurales! - - parte del archivo cargado es un objeto OpenPGP válido pero no una clave OpenPGP - partes del archivo cargado son objetos OpenPGP válidos pero no claves OpenPGP - - Solicitud de búsqueda demasiado corta. ¡Por favor refine su petición! - La solicitud de búsqueda de clave devolvió demasiados candidatos. ¡Por favor refine su petición! - O bien no hay claves o se han encontrado demasiadas. ¡Por favor mejore su petición! Ocurrió un error al buscar claves. Intentando la verificación con Keybase para %s diff --git a/OpenKeychain/src/main/res/values-eu/strings.xml b/OpenKeychain/src/main/res/values-eu/strings.xml index ef19d48d8..d74485cf5 100644 --- a/OpenKeychain/src/main/res/values-eu/strings.xml +++ b/OpenKeychain/src/main/res/values-eu/strings.xml @@ -13,7 +13,7 @@ Ezarpenak Aplikazioak OpenPGP giltza-zerbitzariak - Norbereratu \'Gogoratu\' Hautapenak + Norbereratu \'Gogoratu\' hautapenak Aldatu Sarhitza Elkarbanatu hatz-aztarna honekin... Elkarbanatu giltza honekin... @@ -32,10 +32,12 @@ Laguntza Oharra Trukatu Giltzak + Aurreratua Ezabatu ZURE \'%s\' giltza? Kudeatu nire giltzak Nortasunak + Segurtasun Lekukoa Loturatutako Sistema Harremana Keybase.io Probak Fidatu behar zara giltza honetaz? @@ -86,7 +88,7 @@ Gehitu agiria(k) Elkarbanatu Ireki honekin... - Kopiatu dekriptaturiko idazkia + Kopiatu gakora Irakurri gakotik Hautatu sarrera agiria Enkriptatu agiriak @@ -96,6 +98,7 @@ Gehitu Gorde berezkoa bezala Gordeta! + Ez dator bat Enkriptatu agiriak Trukatu giltzak @@ -114,6 +117,7 @@ Hautatu denak Esportatu giltza guztiak Eguneratu giltza guztiak + Aurreratua Baieztatu hatz-aztarnarekin Baieztatu esaldiekin Elkarbanatu oharra @@ -135,6 +139,7 @@ Gaitu ASCII Armor Jakinarazi besteei OpenKeychain erabiltzen ari zarela \'OpenKeychain v2.7\' idazten du OpenPGP sinadura, idazkia zifratzen du eta giltzak esportatzen ditu + Erabili zenbaki teklatua Segurtasun Lekukoa PIN-erako Hasi saioa honekin: Enkriptatu hona Ezabatu agiriak enkriptatu ondoren @@ -142,7 +147,7 @@ Enkriptaketa algoritmoa Hash algoritmoa Enkriptatu sarhitzarekin - Norbereratu \'Gogoratu\' Hautapenak + Norbereratu \'Gogoratu\' hautapenak Gogoratu sarhitzak azpigiltzaz Idazki konpresioa Agiri konpresioa @@ -273,6 +278,8 @@ Sartu babeskopia kodea Sartu \'%s\'-rako sarhitza Sartu PIN-a \'%s\'-rako + Sartu PIN-a Segurtasun Lekukoara sartzeko \'%s\'-rentzat + Utzi Segurtasun Lekukoa orain. Ezabatu jatorrizko agiriak? Hurrengo agiriak ezabatu egingo dira: %s %1$d -> %2$d-tik agiri ezbatu dira.%3$s @@ -440,6 +447,7 @@ Aldaketa-oharra Honi buruz Bertsioa: + Dirulaguntza Giltza-zerbitzaria Giltza Bilaketa @@ -527,6 +535,8 @@ Enkriptatu OpenKeychain-rekin Dekriptatu OpenKeychain-rekin + Erakutsi argibide aurreratuak + Ezkutatu argibide aurreratuak Ez da giltzarik hautatu Hautatu giltza Sortu giltza berria @@ -539,6 +549,7 @@ Pakete Izena Pakete Egiaztagiriaren SHA-256 Kontuak (API zaharra) + Aurreratua Ahalbidetutako Giltzak Ezarpenak Kontuaren giltza: @@ -593,6 +604,7 @@ Elkarbanatu NFC gain Igo giltza-zerbitzarira Argibide Nagusiak + Hasi Elkarbanatu Azpigiltzak Egiaztagiriak @@ -633,6 +645,7 @@ Txio bat DNS TXT grabaketa bat Idazki agiri bat + JSON agiri bat Egiaztatu @@ -649,10 +662,18 @@ Nortasun hau ukatua izan da. Hau ezin da desegin. Hautatu ekintza bat! + + Aldatu Epemuga + Ukatu Azpigiltza + Strip Azpigiltza + Mugitu Azpigiltza Segurtasun Lekukora + azpigiltza berria Mesedez hautatu gutxienez ikur bat! Gehitu nortasun bat gutxienez! Gehitu azpigiltza bat gutxienez! + Algoritmoa ez dago Segurtasun Lekukoak sostengatua! + Giltza neurria ez dago Segurtasun Lekukoak sostengatua! Aldiberetu Internetekin Eremu hau beharrezkoa da @@ -894,6 +915,7 @@ Akats larria giltza maisua dekriptatzerakoan! Hau programazio akats bat da, mesedez agiritu akats jakinarazpen bat! Barneko OpenPGP akatsa! Sinadura salbuespena! + Giltza ikur ezegokiak Segurtasun Lekukoa giltzarako. Maisu egiaztagiriak aldatzen Ohar pakete hutsa gehitzen PIN jakinarazpen paketea gehitzen @@ -912,6 +934,8 @@ Azpigiltza berriaren ID-a: %s Iraungitze eguna ezin da iraganean izan! %s azpigiltza ukatzen + %s azpigiltza Segurtasun Lekukora mugitzen + Mugituta %1$s -> %2$s Segurtasun Lekukora Giltza-uztaia ongi aldatu da Erabiltzaile ID-a %s gehitzen Lehen erabiltzaile ID-a %s-ra aldatzen @@ -1086,6 +1110,7 @@ Ezin da giltza berreskuratu giltza-zerbitzarietatik: %s Ezin da giltza inportatu giltza-zerbitzaritik! keybase.io-tik berreskuratzen: %s + Facebook-etik berreskuratzen: %s Giltza-zerbitzaritik berreskuratzen: %s Giltza ongi berreskuratu da %s giltza-zerbitzaria erabiltzen @@ -1159,7 +1184,9 @@ Baliabidea ez da aurkitu! Zenbait eragiketaren alderaketa-azterketa egiten... Enkriptaketa denbora: %ss + Bataz-besteko denbora 5M enkriptatzeko: %ss Dekriptaketa denbora: %ss + Bataz-besteko denbora 5M dekriptatzeko: %ss Alderaketa-azterketa osatuta! Sarrera datuak prozesatzen OpenPGP datuak prozesatzen saitzen @@ -1172,6 +1199,7 @@ Ezin da MIME datu bezala aztertu Agirizena: \'%s\' Edukia-Luzera: %s + Hizkikodea ezezaguna da, edo datua ez da idazkia. MIME datu egitura aztertzen Azterketa amaituta Ez da MIME egiturarik aurkitu @@ -1181,14 +1209,10 @@ MIME azterketa jauzi egiten Kontua gordeta Ongi jeitsi da! + Sarrera agiria ez da aurkitu! Ez da baliozko giltzarik aurkitu agiri/gakoan! - TODO: anitzak! - - gertatutako agiriaren zati bat baliozko OpenPGP objetua da baina ez OpenPGP giltza - gertatutako agiriaren zati batzuk baliozko OpenPGP objetuak dira baina ez OpenPGP giltzak - - Bilaketa eskaera laburregia. Mesedez zehaztu zure eskaera! Giltza bilaketa eskaerak hautagai gehiegi itzuli ditu. Mesedez zehaztu zure eskaera! + Bilaketa eskaera laburregia. Mesedez zehaztu zure eskaera! Ez dago giltzarik edo gehiegi aurkitu dira. Mesedez hobetu zure eskaera! Akats bat gertatu da giltzak bilatzerakoan. @@ -1221,7 +1245,10 @@ Berreskuratu zure pribatutasuna OpenKeychain-ekin! Sortu nire giltza Inportatu giltza agiritik + Erabili Segurtasun Lekukoa + (Fidesmo, YubiKey NEO, SIGILANCE, …) Jauzi Ezarpena + Erabili Segurtasun Lekuko hau Zure jabetzako giltzak dituzten babeskopiak inoiz ez dira besteekin elkarbanatu behar! Giltza guztiak + zeure jabetzako giltzak Giltza guztiak @@ -1242,6 +1269,7 @@ Mota Giltza ez da aurkitu! Akatsa giltza prozesatzerakoan! + desbideratu Segurtasun Lekukoara sarhitzik gabe eskuraezina Zure jabetzako giltzak banaka bakarrik ezabatu daitezke! @@ -1290,11 +1318,34 @@ Etiketa Okerra. Mesedez saiatu berriro. Mesedez gaitu NFC zure ezarpenetan Gailu honek ez du NFC sostengatzen + Ongi idatzi da NFC etiketan Desblokeatuta Ezarpenak + Ikusi + Inportatu Blindatu Giltza + Serie Zbk: %s + ]]> Inportatu Berrezarri + Inportatu giltza + Berrezarri Segurtasun Lekukoa + Akatsa: %s + + PIN okerra!\n%d saiakera gelditzen da. + PIN okerra!\n%d saiakera gelditzen dira. + + Segurtasun Lekukoa amaiera egoeran. + Sartutako PIN-a laburregia da. PIN-ek gutxienez 6 digitoko luzera dute. + Erabilpen baldintzak ez dira bete. + Segurtasun egoera ez da bete. + PIN-a blokeatuta saiakera gehiegiren ondoren. + Giltza edo objetua ez da aurkitu. + Akats Ezezaguna + Segurtasun Lekukoak datu baliogabeak jakinarazi ditu. + Segurtasun Lekukoak %s byte baliogabe jakinarazi ditu. + Etiketak ez du ISO-DEP (ISO 14443-4) sostengatzen + Saitu berriro Ezabatu jatorrizko agiria Agirizenak enkriptatuta daude. Agirizenak ez daude enkriptatuta. @@ -1420,13 +1471,34 @@ Editatu Nortasunak Editatu Azpigiltzak Bilatu\n\'%s\' - Ikusleihoa Itzali arte - Ordubetez - Hiru Orduz - Egun batez - Hiru Egunez + ikusleihoa itzali arte + hamar minutuz + hogeita-hamar minutuz + ordubetez + hiru orduz + egun batez + hiru egunez + betirako Hautatu hiru. Gai bat hautatu behar da gutxienez! Ezin dira hiru gai baino gehiago hautatu! Gogoratu + Ez da PGP aplikaziorik aurkitu segurtasun lekukoan + Ezarri PGP? + Ez dago PGP aplikazio eskuragarririk zure Fidesmo gailuan. + Ezarri + Ezeztatu + Ezarri Fidesmo? + PGP ezartzeko Fidesmo Android aplikazioa behar duzu. + Ezarri + Ezeztatu + OpenKeychain Dirulaguntza + + 1 EUR + 3 EUR + 5 EUR + 10 EUR + 50 EUR + 100 EUR + diff --git a/OpenKeychain/src/main/res/values-fa/strings.xml b/OpenKeychain/src/main/res/values-fa/strings.xml index 4794b676a..837d96bf2 100644 --- a/OpenKeychain/src/main/res/values-fa/strings.xml +++ b/OpenKeychain/src/main/res/values-fa/strings.xml @@ -62,7 +62,6 @@ اثر انگشت‌ها مطابقت دارد ساخت کلید اضافه کردن فایل(ها) - کپی متن رمزگشایی شده خواندن از متن کپی‌شده انتخاب فایل ورودی رمزگذاری فایلها diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index 0a989fcca..6534a41d4 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -88,7 +88,7 @@ Ajouter un/des fichier(s) Partager Ouvrir avec... - Copier le texte déchiffré + Copier vers le presse-papiers Lire du presse-papiers Choisir le fichier d\'entrée Chiffrer des fichiers @@ -147,7 +147,7 @@ Algorithme de chiffrement Algorithme de hachage Chiffrer avec un mot de passe - Personnaliser les choix « Se souvenir » + Personnaliser les choix « Mémorisation » Mémoriser les mots de passe par sous-clefs Compression de texte Compression des fichiers @@ -451,6 +451,7 @@ Journal des changements À propos de l\'appli Version : + Faire un don Serveur de clefs Recherche de clefs @@ -1292,6 +1293,10 @@ Nom de fichier : « %s » Le type MIME est deviné à partir de l\'extension Longueur du contenu : %s + Le jeu de caractères est « %s » + Le jeu de caractères est « %s » mais le décodage a échoué ! + Le jeu de caractères semble être « %s » + Le jeu de caractères est inconnu ou les données ne sont pas du texte. Analyse de la structure des données MIME Fin de l\'analyse Aucune structure MIME trouvée @@ -1301,15 +1306,11 @@ L\'analyse MIME est ignorée Compte enregistré Téléchargement réussi ! - Aucune clef valide n\'a été trouvée dans le fichier/presse-papiers | - À FAIRE : les pluriels ! - - une partie du fichier chargé est un objet OpenPGP valide mais pas une clef OpenPGP - certaines parties du fichier chargé sont des objets OpenPGP valides mais pas des clefs OpenPGP - - La requête de recherche est trop courte. Veuillez raffiner votre requête ! - La requête de recherche de clef a retourné trop de candidats. Veuillez raffiner votre requête ! - Soit aucune clef ou trop de clefs ont été trouvées. Veuillez améliorer votre requête ! + Fichier d\'entrée introuvable ! + Aucune clef valide n\'a été trouvée dans le fichier/presse-papiers ! + La requête de recherche de clef a retourné trop de candidats. Veuillez la préciser ! + La requête de recherche est trop courte. Veuillez la préciser ! + Soit aucune clef n\'a été trouvée, ou trop de clefs. Veuillez améliorer votre requête ! Une erreur est survenue lors de la recherche de clefs. Tentative de vérification « keybase » pour %s @@ -1581,7 +1582,7 @@ Modifier les identités Modifier les sous-clefs Rechercher\n« %s » - jusqu\'à ce que l\'écran soit éteint + jusqu\'à l\'extinction de l\'écran pendant dix minutes pendant trente minutes pendant une heure @@ -1593,4 +1594,22 @@ Vous devez choisir au moins un élément ! Vous ne pouvez pas choisir plus de trois éléments ! Mémorisation + Aucune appli PGP n\'a été trouvée sur le jeton de sécurité + Installer PGP ? + Il n\'y avait aucune appli PGP disponible sur votre appareil Fidesmo. + Installer + Annuler + Installer Fidesmo ? + Pour installer PGP, il vous faut l\'appli Fidesmo pour Android. + Installer + Annuler + Don à OpenKeychain + + 1 EUR + 3 EUR + 5 EUR + 10 EUR + 50 EUR + 100 EUR + diff --git a/OpenKeychain/src/main/res/values-hi/strings.xml b/OpenKeychain/src/main/res/values-hi/strings.xml index b0e2fc1b8..677e5eefa 100644 --- a/OpenKeychain/src/main/res/values-hi/strings.xml +++ b/OpenKeychain/src/main/res/values-hi/strings.xml @@ -2,11 +2,23 @@ + ओपनकीचैन + एन्क्रिप्ट + एन्क्रिप्ट + डिक्रिप्ट + उपकुंजी जोड़ें + संपादित कुंजी + एक लिंक्डन पहचान बनाने + सेटिंग + एप्लिकेशन + पासवर्ड परिवर्तन + एन्क्रिप्ट + सेटिंग @@ -16,6 +28,7 @@ + एन्क्रिप्ट + सेटिंग @@ -51,10 +65,13 @@ + +पासवर्ड परिवर्तन + एप्लिकेशन @@ -84,5 +101,6 @@ + सेटिंग diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 17f2d2798..94f9ce429 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -72,7 +72,6 @@ Mostra chiave di certificazione Crea chiave Aggiungi file(s) - Copia testo decifrato Leggi dagli appunti Seleziona input file Codifica file @@ -696,11 +695,6 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars Niente da cancellare! Account salvato - DA FARE: plurali! - - parte del file caricato e\' un oggetto OpenPGP valido, ma non una chave OpenPGP - parti del file caricato sono oggetti OpenPGP validi, ma non chavi OpenPGP - diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index a986025ce..80fed8316 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -88,7 +88,7 @@ ファイルの追加 共有 ...で開く - 復号化したテキストのコピー + クリップボードへコピー クリップボードから読み取り 入力ファイルの選択 ファイルの暗号化 @@ -451,6 +451,7 @@ Changelog これについて バージョン: + 寄付 鍵サーバ 鍵の検索 @@ -1269,6 +1270,10 @@ ファイル名: \'%s\' 拡張子からMIME種別を推測しています コンテンツ長: %s + キャラクタセットは \'%s\' です + キャラクタセットは \'%s\' ですが、でコードに失敗しました! + キャラクタセットは \'%s\' のようです + キャラクタセットが不明か、データはテキストではありません。 MIMEデータ構造の解析中 解析完了 MIME構造が見つかりません @@ -1278,14 +1283,11 @@ MIME解析をスキップしています アカウント保存 ダウンロードに成功しました! + 入力ファイルが見付かりません! ファイル/クリップボードにて正しい鍵が見付かりません! - TODO: 複数部分! - - 読み込んだファイルのOpenPGPオブジェクト部分は正しいですが、OpenPGPの鍵ではありません - - 鍵検索のクエリが短かすぎます。クエリを精密化してください! - 鍵検索のクエリが沢山の候補を返しました。クエリを精密化してください! - 鍵がまったく無いか、多すぎる鍵が見付かりました。クエリを改善してください! + 鍵検索のクエリが沢山の候補を返しました; クエリを精緻化してください + 鍵検索のクエリが短かすぎます。クエリを精緻化してください! + 鍵が無いか、見付かった鍵が多すぎます。クエリを改善してください! 鍵の検索時にエラーが発生しました。 %s のkeybase検証を試行中 @@ -1566,4 +1568,22 @@ 少なくとも項目を1つ選択する必要があります! 3つ以上の項目を選択することはできません! 記憶する + セキュリティトークンでPGPアプリが見つかりません + PGPをインストールしますか? + お使いのFidesmoデバイスには利用できるPGPアプリがありません。 + インストール + キャンセル + Fidesmoをインストールしますか? + PGPをインストールするにはFidesmo Androidアプリが必要です。 + インストール + キャンセル + OpenKeychain の寄付 + + 1 ユーロ + 3 ユーロ + 5 ユーロ + 10 ユーロ + 50 ユーロ + 100 ユーロ + diff --git a/OpenKeychain/src/main/res/values-kn/strings.xml b/OpenKeychain/src/main/res/values-kn/strings.xml new file mode 100644 index 000000000..b0e2fc1b8 --- /dev/null +++ b/OpenKeychain/src/main/res/values-kn/strings.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/values-ko/strings.xml b/OpenKeychain/src/main/res/values-ko/strings.xml index e20f309ce..56924b973 100644 --- a/OpenKeychain/src/main/res/values-ko/strings.xml +++ b/OpenKeychain/src/main/res/values-ko/strings.xml @@ -84,7 +84,6 @@ 파일(들) 추가 공유 다음으로 열기 - 복호화 된 텍스트 복사 클립보드에서 읽기 입력 파일 선택 파일들 암호화 diff --git a/OpenKeychain/src/main/res/values-nb/strings.xml b/OpenKeychain/src/main/res/values-nb/strings.xml new file mode 100644 index 000000000..b0e2fc1b8 --- /dev/null +++ b/OpenKeychain/src/main/res/values-nb/strings.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/values-nl/strings.xml b/OpenKeychain/src/main/res/values-nl/strings.xml index 41a207016..0e9f2e3bd 100644 --- a/OpenKeychain/src/main/res/values-nl/strings.xml +++ b/OpenKeychain/src/main/res/values-nl/strings.xml @@ -64,7 +64,6 @@ Toon certificatiesleutel Sleutel aanmaken Bestand(en) toevoegen - Ontsleutelde tekst kopiëren Lezen van klembord Kies invoerbestand Bestanden versleutelen @@ -1040,16 +1039,6 @@ Account opgeslaan - Succesvol gedownload! - Geen geldige sleutels gevonden in bestand/klembord! - TODO: meervouden! - - Deel van het geladen bestand is geldig OpenPGP object maar niet een OpenPGP sleutel - Delen van het geladen bestand zijn geldige OpenPGP objecten maar niet OpenPGP sleutels - - Zoekopdracht te kort. Gelieve je zoekopdracht te verfijnen! - Zoekopdracht gaf te veel kandidaten. Gelieve je zoekopdracht te verfijnen! - Geen of te veel sleutels werden gevonden. Gelieve je zoekopdracht te verfijnen! Er trad een fout op bij het zoeken naar sleutels. Keybaseverificatie voor %s wordt geprobeerd diff --git a/OpenKeychain/src/main/res/values-pl/strings.xml b/OpenKeychain/src/main/res/values-pl/strings.xml index 85e9f83bb..0de3a09ca 100644 --- a/OpenKeychain/src/main/res/values-pl/strings.xml +++ b/OpenKeychain/src/main/res/values-pl/strings.xml @@ -517,12 +517,6 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw Zapisano konto - Pobrano pomyślnie! - - Część wczytanego pliku jest poprawnym obiektem OpenPGP, ale nie jest kluczem OpenPGP - Część wczytanego pliku to poprawne obiekty OpenPGP, ale nie są kluczami OpenPGP - Część wczytanego pliku to poprawne obiekty OpenPGP, ale nie są kluczami OpenPGP - diff --git a/OpenKeychain/src/main/res/values-pt-rBR/strings.xml b/OpenKeychain/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000..b0e2fc1b8 --- /dev/null +++ b/OpenKeychain/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index 229bbeb39..d98d9d1d8 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -13,6 +13,7 @@ Настройки Приложения Серверы OpenPGP + Настройка \'Запоминания\' Изменить пароль Отправить отпечаток... Отправить ключ... @@ -31,10 +32,12 @@ Помощь Журнал Обмен ключами + Дополнительно Удалить ВАШ ключ \'%s\'? Управление ключами Идентификаторы + Токены безопасности Связанные контакты Доказательства Keybase.io Должны ли Вы доверять этому ключу? @@ -47,7 +50,7 @@ Tor, настройки прокси Интерфейс Синхронизация - Автоматическое обновление ключей, + Автоматическое обновление ключей, связывание контактов Экспериментальные возможности Подтвердить Действия @@ -78,12 +81,12 @@ Совпадающие фразы Зашифровать/подписать и поделиться текстом Зашифровать/подписать и скопировать текст + Зашифровать/подписать и вставить текст Просмотр ключа Создать ключ Добавить файл(ы) Опубликовать Открыть с помощью... - Копировать расшифрованный текст Прочитать из буфера Выберите входной файл Зашифровать файлы @@ -93,7 +96,12 @@ Добавить Сохранить по умолчанию Сохранено! + Не совпадают + Шифровать файлы + Обмен ключами + Шифровать текст + Отправить через NFC Настройки Помощь @@ -107,6 +115,11 @@ Выбрать все Экспорт всех ключей Обновить все ключи + Дополнительно + Подтверждение отпечатком + Подтверждение кодовой фразой + Отправить журнал + Изменить пароль Добавить Текст @@ -115,6 +128,7 @@ Файл: Без пароля Пароль + PIN-код Идет разблокировка... Повторите пароль Показать пароль @@ -124,12 +138,14 @@ Добавить комментарий об использовании OpenKeychain Дописывать \'OpenKeychain v2.x\' в OpenPGP подписи, шифры, и экспортируемые ключи Подписать: + Зашифровать для Удалить файлы после шифрования Удалить после шифрования Алгоритм шифрования ХЭШ-алгоритм Зашифровать с паролем - Запомнить пароли для подключей + Настройка \'Запоминания\' + Запомнить пароли для доп. ключей Сжатие текста Сжатие файла Выберите серверы OpenPGP @@ -162,17 +178,24 @@ Искать ключи на выбранных серверах OpenPGP (протокол HKP) keybase.io Искать ключи на Keybase.io + Искать ключи на Facebook по имени пользователя + Автообновление ключей + Каждые три дня ключи будут обновляться с предпочитаемого сервера ключей + Ключи не обновляются автоматически Связать ключи с контактами Связывать ключи с контактами основываясь на именах и адресах электронной почты. Это происходит полностью в автономном режиме на вашем устройстве. Новые ключи не будут связаны с контактами + Автообновление ключей Предупреждение Эти новые возможности ещё не закончены и/или пока только изучаются. Проще говоря, не стоит полагаться на их безопасность. Пожалуйста, не сообщайте о связанных с ними проблемах! + Подтверждение фразами Подтвердить ключи с помощью фраз, вместо шестнадцатеричных отпечатков Связанные идентификаторы Привязать ключи к Twitter, GitHub, веб-сайту или DNS (по аналогии с keybase.io но децентрализованно) Keybase.io подтверждение Опрашивать keybase.io для подтверждения ключей и показывать это каждый раз при отображении ключей + (Значки и многие экраны ещё не скорректированы для тёмной темы) Использовать Tor Требуется установка Orbot @@ -195,6 +218,7 @@ Не использовать Tor Запустить Orbot? + Похоже, что Orbot не запущен. Хотите запустить и соединиться с Tor? Запустить Orbot Запустить Orbot Отмена @@ -235,7 +259,7 @@ Открыть... Ошибка Ошибка: %s - Темная + Тёмная Светлая Сертификация @@ -248,6 +272,7 @@ Пароли не совпадают. Пожалуйста, введите пароль. Введите пароль + Введите код восстановления Введите пароль для \'%s\' Введите PIN для \'%s\' @@ -260,7 +285,11 @@ Выберите хотя бы один ключ для шифрования или подписи. Пожалуйста, укажите, в какой файл произвести шифрование.\nВНИМАНИЕ: Файл будет перезаписан, если он уже существует! Пожалуйста, укажите, в какой файл произвести расшифровку.\nВНИМАНИЕ: Файл будет перезаписан, если он уже существует! + Будет произведено резервное копирование без ваших ключей , просьба указать файл назначения.\nВНИМАНИЕ! Файл будет перезаписан, если он существует! + Будет произведено полное резервное копирование ваших ключей, просьба указать файл назначения.\nВНИМАНИЕ! Файл будет переписан, если он существует! + Будет произведено полное резервное копирование всех ключей, включая ваш, просьба указать файл назначения.\nВНИМАНИЕ! Файл будет переписан, если он существует! Вы правда хотите удалить выбранные ключи? + После удаления вы не сможете расшифровать сообщения/файлы, зашифрованные этим ключом и потеряете все сделанные им подтверждения ключей! Удалить ключ \'%s\'? Экспортировать секретные ключи Вы столкнулись с багом Андроид. Пожалуйста, переустановите OpenKeychain чтобы связать ваши контакты и ключи. @@ -275,6 +304,7 @@ Отпечаток ключа скопирован в буфер обмена! Выберите ключ, используемый для подтверждения! Тест скопирован в буфер обмена! + Как это импортировать на моём ПК? @@ -301,9 +331,11 @@ Ключи для импорта не выбраны! Ошибка извлечения идентификатора ключа из контактов! Выявлена ошибка. Пожалуйста, сообщите о ней разработчику. + Невозможно прочитать файлы с накопителя, потому что доступ запрещён! Не подписано Неверная подпись! + Неправильная подпись (небезопасная криптография)! Подписано неподтверждённым ключом! Подписано Вашим ключом Подписано подтверждённым ключом @@ -312,8 +344,10 @@ Подписано неизвестным ключом! Зашифровано Не зашифровано + Небезопасное шифрование Показать Искать + Или подпись недействительна, или ключ был аннулирован. Вы не можете быть уверены в том, кто написал текст. Вы всё ещё хотите посмотреть его? Мне понятны все риски, показать! Мой ключ: @@ -323,6 +357,8 @@ отмена... сохранение... импорт... + проверка производительности… + Аннулирование и отправка ключа ... Обновление ключей... экспорт... загружается... @@ -344,6 +380,7 @@ отделение доп.ключей... добавление доп. ключей... изменение пароля... + смена PIN-кода… экспорт ключа... экспорт ключей... @@ -370,6 +407,8 @@ удаление ключей... объединение: сохранение в кэш... объединение: реимпорт... + проверка соединения… + Запуск Orbot… Искать через Имя, Email... @@ -400,6 +439,7 @@ Изменения О программе Версия: + Пожертвование Сервер ключей Поиск ключа @@ -412,6 +452,7 @@ Сканировать QR код... Расположите вашу камеру над QR кодом! + Поисковый запрос не определён. Вы можете вручную искать на этом сервере ключей. Сведения , с предупреждениями @@ -423,6 +464,10 @@ Нет данных для удаления! Удаление отменено. + Ключ успешно аннулирован. + Ошибка при аннулировании ключа! + Нечего аннулировать. + Операция аннулирования отменена. OpenKeychain: Расшифровать файл @@ -430,6 +475,8 @@ OpenKeychain: Зашифровать OpenKeychain: Расшифровать + Показать подробную информацию + Скрыть подробную информацию Ключ не выбран Выбрать ключ Создать новый ключ @@ -441,6 +488,7 @@ Удалить аккаунт Наименование пакета Аккаунты (устаревший API) + Дополнительно Разрешённые ключи Настройки Ключ аккаунта: @@ -451,6 +499,8 @@ Разрешить доступ Запретить доступ Пожалуйста, выберите ключ! + Не найдены ключи для этих адресов электронной почты: + Больше чем один ключ существует для этих адресов электронной почты: Пожалуйста, проверьте получателей! Пожалуйста, выберите получателей! Проверка подписи пакета не удалась! Если вы установили программу из другого источника, отзовите для неё доступ к этой программе или обновите право доступа. @@ -460,8 +510,18 @@ Отправить как QR код Отправить через NFC + Загрузка не удалась + Загрузка не удалась. Хотите повторить операцию? + Повторить операцию + Отменить операцию + Если вы больше не хотите использовать этот ключ, его следует аннулировать и загрузить на сервер. Выберите «Только удалить», если вы хотите удалить ключ из OpenKeychain, но продолжать использовать его от где-нибудь ещё. + Аннулирование/Удаление ключа \'%s\' + Аннулировать и отправить + Удалить только + Удалить только + Аннулировать и отправить 1 ключ выбран. @@ -471,8 +531,12 @@ Ключи не найдены! Показать все ключи + Показывать только подтверждённые ключи + Сканировать QR-код Поиск ключа + Импорт из файла + Изменить Зашифровать текст файлы Подтвердить ключ @@ -481,17 +545,29 @@ Отправить через NFC Загрузить на сервер ключей Основные данные + Начать Отправить... Доп. ключи Сертификация Keybase.io Аннулировано Этот идентификатор отозван владельцем ключа. Он больше недействителен. + Подтверждён + Эта идентичность была подтверждена Вами. + Не подтверждён + Эта идентичность ещё не была подтверждена. Вы не можете быть уверены, соответствует ли идентичность действительно определённому человеку. Недействительно Что-то не так с идентификатором! + Отсутствуют подтверждения из Интернета о достоверности этого ключа. Начать поиск + Keybase.io предлагает “доказательства”, которые подтверждают, что владелец этого ключа: + Публикация на Twitter как %s + Известен на GitHub как %s + Публикация на Reddit как %s + Известен на Coinbase как %s + Публикация на Hacker News как %s К сожалению это доказательство не может быть верифицировано. Неопознанная проблема с проверкой доказательства Проблема с доказательством @@ -501,6 +577,8 @@ Расшифрованная доказательная запись не соответствует ожидаемому значению Получение подтверждения Подтверждение успешно проверено! + для домена + содержит сообщение, которое могло быть создано только владельцем этого ключа. Запись DNS TXT Текстовый файл JSON file @@ -523,6 +601,8 @@ Пожалуйста, выберите хотя бы один флаг! Добавьте хотя бы один идентификатор! Добавьте хотя бы один доп. ключ! + Алгоритм не поддерживается токеном безопасности! + Размер ключа не поддерживается токеном безопасности! Синхронизация с Интернет Это обязательне поле @@ -532,13 +612,20 @@ (3 доп. ключа, RSA, 4096 bit) (произвольная конфигурация ключа) Выберите имя для данного ключа. Это может быть полное имя, например, \'Иван Петров\', или сокращенно, как например, \'Ванька\'. - Введите Ваш главный адрес эл.почты, используемый для безопасной переписки. - Выберите надежный пароль. Он защитит Ваш ключ, в случае кражи вашего устройства. + Введите ваш главный адрес эл. почты, используемый для безопасной переписки. + Выберите надежный пароль. Он защитит ваш ключ, в случае кражи вашего устройства. Полное имя или псевдоним Изменить конфигурацию ключа - Введите адрес эл.почты + Введите адрес эл. почты + Дополнительные адреса электронной почты также связаны с этим ключом и могут быть использованы для безопасной связи. Почтовый адрес уже был добавлен Неправильный формат почтового адреса + Пожалуйста, выберите PIN-код с 6 цифрами. + PIN-код + Повторите PIN-код + PIN-код неверен! + PIN-код должен быть не менее 6 цифр! + Пожалуйста, введите сложный PIN-код, а не 000000, 123456 или подобные комбинации. Аннулирован: Ключ не должен использоваться когда-либо в будущем! Срок годности истёк: Контакт должен продлить срок! @@ -549,8 +636,12 @@ <нет> Добавить сервер ключей + Изменить сервер ключей + Соединение проверено! Сервер ключей добавлен без подтверждения. Неправильный адрес! + %s удалено + Невозможно удалить последний сервер ключей. По крайней мере один требуется! Ключи Зашифровать/Расшифровать @@ -558,6 +649,7 @@ Открыть панель навигации Закрыть панель навигации Мои ключи + Резервирование/Восстановление Напишите текст @@ -583,6 +675,8 @@ Действие прервано из-за ошибки базы Действие прервано из-за внутренней ошибки Импорт связки публичных ключей %s + Отпечаток импортируемого ключа не соответствует ожидаемому! + Проверка отпечатка пройдена Кодирование связки ключей Разбор ключей Подготовка операций @@ -607,6 +701,7 @@ Основные флаги: удостоверить Основные флаги: нет Объединение импортированных данных с существующей связкой публичных ключей + Объединение импортированных данных с существующей связкой секретных ключей Обработка доп. ключа %s Срок годности доп. ключа истек %s Срок годности доп. ключа истекает %s @@ -660,10 +755,12 @@ Обработка секретных доп. ключей Ошибка кодирования ключа Объединение импортированных данных с существующей связкой публичных ключей + Объединение импортированных данных с существующей связкой секретных ключей Объединение само-сертифицированных данных из публичных ключей Формирование публичной связки из секретной связки Доп. ключ %s недоступен в секретном ключе Секретный доп. ключ %s отмечен как доступный + Секретный доп. ключ %s отмечен как доступный, с пустым паролем Секретный доп. ключ %s отмечен как доступный, с PIN Секретный доп. ключ %s отмечен как отделённый Связка ключей не содержит новых данных, нечего делать @@ -677,18 +774,22 @@ Доп. ключ %s найден дважды в связке. Связка некорректна, не импортируется! Подготовка основного ключа Удаление сертификата основного ключа неизвестного типа (%s) + Удаление сертификата основного ключа с \"локальным\" флагом Удаление плохого сертификата основного ключа Удаление сертификата аннулирования ключа с отметкой времени, находящейся в будущем Удаление сертификата ID в некорректном положении Удаление плохого сертификата основного ключа + Удаление сертификата основного ключа с \"локальным\" флагом Удаление лишнего сертификата аннулирования ключа Удаление лишнего сертификата обозначения Удаление пустого сертификата обозначения Обработка доп. ключа %s Удаление неверного сертификата связывания доп. ключа Удаление плохого сертификата связывания доп. ключа + Удаление сертификата связывания доп. ключа \"локальным\" флагом Несоответствие id издателя связывания доп. ключа Удаление сертификата связывания доп. ключа с отметкой времени, находящейся в будущем + Сертификата связывания доп. ключа создан ранее, чем его ключ! Неизвестный тип сертификата доп. ключа: %s Удаление лишнего сертификата связывания доп. ключа Удаление сертификата связывания доп. ключа вследствие неверного основного сертификата связывания @@ -715,6 +816,7 @@ Нет допустимого самостоятельного сертификата для ID \'%s\', удаление из связки Удаление неверного ID \'%s\' Удаление повторяющегося ID \'%s\'. Связка содержит их два. Это может привести к отсутствию сертификатов! + Удаление ID пользователя \'%s\'. Более 100 идентификаторов пользователей не импортируются! ID пользователя не соответствует UTF-8! Обработка атрибута пользователя типа JPEG Обработка атрибута пользователя неизвестного типа @@ -746,6 +848,7 @@ Связки должны создаваться с хотя бы одним ID пользователя! Основной ключ должен иметь флаг сертификата! Срок годности не может быть \'такой же как раньше\' при создании ключа. Это программная ошибка, пожалуйста, сообщите об этом! + Размер ключа должен быть больше или равен 2048! Не задан размер ключа! Это программная ошибка, пожалуйста, сообщите об этом! Не задана эллиптическая кривая! Это программная ошибка, пожалуйста, сообщите об этом! Внутренняя ошибка OpenPGP! @@ -756,70 +859,127 @@ Выбраны плохие флаги ключа, ECDH не может быть использован для подписи! Изменение связки %s + Будет отвлекать на токен безопасности для криптографических операций Ошибка кодирования! Отпечаток ключа не совпадает с представленным! Нет ID ключа. Это программная ошибка. Пожалуйста, сообщите об этом! Внутренняя ошибка, сбой проверки целостности! Не найден основной сертификат! (Все отозваны?) + Указан некорректный ID основного пользователя! + Для аннулирования определён некорректный ID пользователя! + Попытка выполнить ограниченную операцию без пароля! Это ошибка программирования, пожалуйста, сообщите об ошибке! Аннулированные идентификаторы не могут быть основными! + При создании доп. ключа время окончания срока годности не может быть \'такое же как раньше\'. Это ошибка программирования, пожалуйста, сообщите об ошибке! Выполнять нечего! + Неустранимая ошибка расшифровки главного ключа! Это, вероятно, ошибка программирования, отправьте сообщение об ошибке! Внутренняя ошибка OpenPGP! Ошибка подписи! + Невозможно изменить отделённый доп. ключ %s! Попытка работы с отсутствующим доп. ключом %s! + Невозможно переместить ключ в токен безопасности в той же операции, которая создаёт подпись на карте. + Смарт-карта поддерживает только один слот для каждого типа ключа. Изменение основного сертификата Изменение пароля для связки ключей + Изменение PIN-кода карты + Изменение PIN-кода администратора карты + Перешифровка доп. ключа %s с новым паролем Ошибка установки нового пароля, пробую снова используя старый пустой пароль + Замена сертификата ID предыдущего основного пользователя Создание нового сертификата для основного идентификатора + Переход в ограниченный режим работы Изменение доп. ключа %s Для действий необходим пароль Добавление нового доп. ключа типа %s Идентификатор нового доп. ключа: %s Срок годности не может быть в прошлом! Аннулирование доп. ключа %s + Отделение доп. ключа %s + Перемещение доп. ключа %s в токен безопасности Связка успешно изменена + Добавление ID пользователя %s Изменение основного идентификатора на %s + Аннулирование ID пользователя %s Идентификатор пользователя не может быть пустой + Атрибут пользователя не должен быть пустым! + Добавление атрибута пользователя неизвестного типа Ошибка разблокирования связки! Разблокирование связки Консолидация базы данных Консолидация началась но база не кэширована! Это программная ошибка, пожалуйста, сообщите об этом. + Консолидация прервана, уже запущена на другом потоке! Сохранение секретной связки ключей Сохранение публичной связки ключей Очистка базы данных + Успешно консолидированная база данных + Удаление кэша связки публичных ключей + Удаление кэша связки секретных ключей Ошибка открытия базы данных! Ошибка записи публичных ключей в кэш! Ошибка записи приватных ключей в кэш! Ошибка переимпортирования публичных ключей! Ошибка переимпортирования приватных ключей! + Возобновление процесса консолидации + Пропуск рекурсивной консолидации + Возобновление процесса консолидации из неизвестного состояния + Нет публичных ключей для повторного импорта, пропуск… + Нет секретных ключей для повторного импорта, пропуск… Выполнение операции ключа Кэширование нового пароля Ключ не найден! + Ошибка извлечения публичного ключа для загрузки! Операция с ключом успешна! Ключ не найден! Ключ не найден! + Ключ не является ключом шифрования, пропуск... + Ключ недоступен, пропуск… + Данные зашифрованы неизвестным ключом, пропуск... + Данные не зашифрованы допустимым ключом, пропуск... + Обработка символьных данных Распаковка сжатых данных + Имя файла: %s + MIME-тип: %s + Размер файла: %s Неизвестный размер файла + Время изменения: %s Проверка подписи НЕ ПРОЙДЕНА! Проверка подписи данных Проверка подписи ПРОЙДЕНА Сохранение данных подписи Ошибка разблокировки ключа, неправильный пароль! + Ошибка расшифровки данных! (Неправильная ключевая фраза?) + Данные повреждены! Неизвестная ошибка разблокировения ключа! + Ошибка проверки целостности! + Зашифрованные или подписанные данные OpenPGP не найдены! + Ошибка при открытии входного потока данных! + Ошибка при открытии входного потока данных! Зашифрованные данные не найдены! Зашифрованные данные с известным приватным ключом не найдены! + Отсутствуют данные подписи! + Проверка целостности пройдена! Расшифрование/проверка закончена Применяю кэшированный пароль + Требуется NFC-токен, жду действий пользователя... Требуется пароль, жду действий пользователя... + Подготовка потоков для расшифровки Расшифровка началась... + Симметричные данные не допускаются, пропуск... Обнаружена симметрично зашифрованная информация Разблокировка секретного ключа + Начинается проверка подписи + Отсутствуют данные подписи! + Имя файла: %s + MIME-тип: %s + Время изменения: %s + Размер: %s Проверка подписи данных + Ошибка проверки целостности! ОК Начало операции подписи/шифровки @@ -842,6 +1002,7 @@ Внутренняя ошибка OpenPGP! Шифрование для ключа: %s Подпись/Шифрование успешно произведены! + Требуется NFC-токен, жду действий пользователя... Требуется пароль, жду действий пользователя... Подпись и/или шифрование начаты Подготовка симметричного шифрования @@ -849,26 +1010,30 @@ Основной ключ не найден! Нет сертифицированных ключей! Ошибка разблокирования основного ключа! + Сертификация связок + Возвращение к экрану NFC + Сохранение сертифицированного ключа %s Сохранение связки Разблокировка основного ключа + Подписанные идентификаторы Ключ не найден! Создание сертификата не удалось! Ошибка операции сохранения! Ключ успешно загружен на сервер Ошибка операции импорта! Операция импорта прервана из-за ошибки ввода/вывода! + Операция импорта успешна, но с ошибками! Операция импорта успешна! + Ошибка базы данных! + Ошибка ввода/вывода! + Сервер: %s + ID ключа: %s + Ключ не найден! Нет данных для удаления! Секретные ключи можно удалять только по одному! + Поиск токена Аккаунт сохранен - Загрузка завершена! - - часть загруженного файла содержит данные OpenPGP, но это не ключ - части загруженного файла содержат данные OpenPGP, но это не ключ - части загруженного файла содержат данные OpenPGP, но это не ключ - части загруженного файла содержат данные OpenPGP, но это не ключ - @@ -878,7 +1043,9 @@ Верните вашу приватность с помощью OpenKeychain! Создать свой ключ Импорт ключа из файла + Использовать токен безопасности Пропустить настройку + Использовать этот токен безопасности Кем подписан Детали сертификации @@ -896,6 +1063,7 @@ Показать ключ (%s) Выберите хотя бы один файл для шифрования! Введите текст для шифрования! + Внутренняя ошибка при подготовке журнала! Ключ: Начать обмен @@ -919,13 +1087,138 @@ Разблокирован Настройки + Просмотр + Импорт + Серийный номер: %s + Владелец ключа: + Этот токен безопасности уже содержит ключ. Вы можете импортировать ключ через облако или сбросить токен безопасности. + Импорт + Сброс + Импортировать ключ + Сбросить токен безопасности + Ошибка: %s + Введённый PIN-код слишком короткий. Коды должны быть не менее 6 цифр. + Условия использования неудовлетворительные. + Статус безопасности неудовлетворительный. + PIN-код заблокирован после слишком многих попыток. + Ключ или объект не найден. + Неизвестная ошибка + Токен безопасности сообщил о повреждённых данных. + Токен безопасности ожидал последней команды в цепочке. + Попробовать ещё раз + Удалить оригинальный файл + Имена файлов шифруются. + Имена файлов не шифруются. + Результат кодируется как текст. + Результат кодируется как двоичный. + Сжатие включено. + Сжатие отключено. + Ошибка загрузки ключей! + (ошибка, пустой журнал) + Не удалось прочитать ввод для расшифровки! + Ошибка чтения данных, это ошибка в клиенте электронной почты Android! (Статья #290) + Получены неполные данные, попробуйте включить \'Загружать полное сообщение\' в K-9 Mail! + Неизвестное имя файла (нажмите для открытия) + Текст (нажмите для просмотра) + Резервный ключ (нажмите для импортирования) + Показать Подписанное/Зашифрованное содержимое + Отправить Подписанное/Зашифрованное содержимое + Смотреть в OpenKeychain + Ошибка подготовки данных! + Зашифрованные данные + Обработка... + Ошибка при сохранении файла! + Файл сохранён! + Оригинальный файл удалён. + Файл не удаляется! (Уже удалён?) + Оригинальный файл не может быть удалён! + Буфер обмена пуст! + Ошибка копирования данных в буфер обмена! + Ошибка сканирования отпечатка! + Отпечатки не совпадают! + Дата истечения срока действия в прошлом! + Например: https://example.com/pgpkey.txt + Для следующего шага вы должны сохранить и загрузить этот файл. + Пожалуйста, введите свой псевдоним в Twitter, чтобы продолжить. + Проверить + Текст был скопирован в буфер обмена + Всё выглядит в порядке. + Всё выглядит в порядке. + Всё выглядит в порядке. + Всё выглядит в порядке. Пожалуйста, выберите тип: + Проверка… + Проверено! + Ошибка проверки! + Ещё не проверено + Ресурс должен быть проверен, прежде чем продолжать! + Связать с аккаунтом Связанные идентификаторы Завершить + Сайт (HTTPS) + Доменное имя (DNS) Твиттер + Проверить Повторить + Повторить последний шаг Подтвердить + Просмотр + Проверка… Ошибка - Опубликовать + Подтверждение… + Авторизация при помощи GitHub... + Обновить ключ... + Ссылка на аккаунт GitHub + Авторизация не удалась! + Время соединения вышло! + Ошибка сети! + Коммуникационная ошибка: %s + Авторизация GitHub + Перезаписать + Резервная копия будет защищена кодом. Запишите его, прежде чем продолжить! + Пожалуйста, введите резервный код: + Код принят! + ОК, я записал его! + Резервный код введён неверно!\nВы записали его правильно? + Отправить резервную копию + Сохранить резервную копию + Ошибка при сохранении резервной копии! + Резервная копия сохранена + Резервная копия уже существует! + Сохранено в папке OpenKeychain + Вернуться для проверки + Текст слишком длинный, чтобы показать его полностью! + Общий текст был сокращён, потому что он был слишком большим! + Отправить журнал? + Хотя журналы могут быть супер полезными для разработчиков, чтобы найти ошибки в OpenKeychain, они могут потенциально содержать конфиденциальную информацию, такую как данные об обновлённых ключах. Пожалуйста, убедитесь, что у вас всё в порядке с распространением этой информации. + Отправить... + Отмена + Неправильный тип данных, ожидался текст! + Сохранить + Изменить соответствия + Изменить доп. ключи + Искать\n\'%s\' + до отключения экрана + в течение десяти минут + в течение тридцати минут + в течение часа + в течение трёх часов + в течение дня + в течение трёх дней + всегда + Выберите до трёх. + По крайней мере один элемент должен быть выбран! + Нельзя выбрать более трёх элементов! + Помнить + Нет приложения PGP на токене безопасности + Установить PGP? + На вашем устройстве Fidesmo нет приложения PGP. + Установить + Отмена + Установить Fidesmo? + Для установки PGP вам необходимо приложение Fidesmo. + Установить + Отмена + Пожертвование на OpenKeychain diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml index 79b70f9f3..33dfe40a7 100644 --- a/OpenKeychain/src/main/res/values-sl/strings.xml +++ b/OpenKeychain/src/main/res/values-sl/strings.xml @@ -742,12 +742,6 @@ Ključ ni bil najden! Generacija potrdila ni uspela! - - Del naložene datoteke je veljavnen objekt OpenPGP a ni ključ. - Deli naložene datoteke so veljavni objekti OpenPGP a niso ključi. - Deli naložene datoteke so veljavni objekti OpenPGP a niso ključi. - Deli naložene datoteke so veljavni objekti OpenPGP a niso ključi. - diff --git a/OpenKeychain/src/main/res/values-sr/strings.xml b/OpenKeychain/src/main/res/values-sr/strings.xml index 84558d0e8..b267557f4 100644 --- a/OpenKeychain/src/main/res/values-sr/strings.xml +++ b/OpenKeychain/src/main/res/values-sr/strings.xml @@ -13,7 +13,6 @@ Поставке Апликације ОпенПГП сервери кључева - Прилагођавање избора „памћења“ Измена лозинке Подели отисак помоћу… Подели кључ помоћу… @@ -87,7 +86,6 @@ Додај фајл(ове) Дели Отвори помоћу… - Копирај дешифровани текст Учитај са клипборда Изабери фајл Шифруј фајлове @@ -145,7 +143,6 @@ Алгоритам шифровања Алгоритам хеша Шифровање са лозинком - Прилагодите изборе „памћења“ Памти лозинке по поткључу Компресија текста Компресија фајла @@ -448,6 +445,7 @@ Дневник измена О програму Издање: + Донирај Сервер кључева Претрага кључа @@ -1303,6 +1301,10 @@ Назив фајла: „%s“ Погађам МИМЕ тип на основу екстензије Дужина садржаја: %s + Кодирање је „%s“ + Кодирање је „%s“, али декодирање није успело! + Чини се да је кодирање „%s“ + Кодирање је непознато, или подаци нису текстуални. Рашчлањујем структуру МИМЕ података Рашчлањивање завршено Није нађена МИМЕ структура @@ -1312,15 +1314,10 @@ Прескачем рашчлањивање МИМЕ-а Налог је сачуван Успешно преузето! + Улазни фајл није нађен! Нема исправних кључева у фајлу/клипборду! - УРАДИТИ: множине! - - део учитаног фајла је исправан ОпенПГП објекат али није ОпенПГП кључ - дела учитаног фајла су исправни ОпенПГП објекти али нису ОпенПГП кључеви - делови учитаног фајла су исправни ОпенПГП објекти али нису ОпенПГП кључеви - - Упит за претрагу је прекратак. Прецизирајте упит! Претрага кључева је вратила превише кандидата. Прецизирајте упит! + Упит за претрагу је прекратак. Прецизирајте упит! Или није нађен ниједан кључ или их је нађено превише. Побољшајте ваш упит! Дошло је до грешке приликом претраге кључева. @@ -1551,6 +1548,7 @@ Резерва сачувана Резерва већ постоји! Сачувано у директоријум „OpenKeychain“ + Назад на проверу Текст је предугачак да би био приказан у целости! Дељени текст је одсечен јер је био предугачак! Поделити запис? @@ -1574,4 +1572,21 @@ Бар једна ставка мора бити изабрана! Не можете изабрати више од три ставке! Запамти + Инсталирати ПГП? + Нема апликације за ПГП на вашем „Fidesmo“ уређају. + Инсталирај + Одустани + Инсталирати „Fidesmo“? + Да бисте инсталирали ПГП потребна вам је „Fidesmo“ апликација за Андроид. + Инсталирај + Одустани + Донација Отвореном кључарнику + + 1 евро + 3 евра + 5 евра + 10 евра + 50 евра + 100 евра + diff --git a/OpenKeychain/src/main/res/values-sv/strings.xml b/OpenKeychain/src/main/res/values-sv/strings.xml index 5ae46d286..c5103d879 100644 --- a/OpenKeychain/src/main/res/values-sv/strings.xml +++ b/OpenKeychain/src/main/res/values-sv/strings.xml @@ -73,7 +73,6 @@ Visa nyckel för certifiering Skapa nyckel Lägg till fil(er) - Kopiera dekrypterad text Läs från urklipp Kryptera filer Kryptera text @@ -830,12 +829,6 @@ Konto sparat - Hämtning lyckades! - Inga giltiga nycklar hittades i fil/urklipp! - - en del av den inlästa filen är ett giltigt OpenPGP-objekt men inte en OpenPGP-nyckel - delar av den inlästa filen är giltiga OpenPGP-objekt men inte OpenPGP-nycklar - diff --git a/OpenKeychain/src/main/res/values-tr/strings.xml b/OpenKeychain/src/main/res/values-tr/strings.xml index 87005eaed..32b24712f 100644 --- a/OpenKeychain/src/main/res/values-tr/strings.xml +++ b/OpenKeychain/src/main/res/values-tr/strings.xml @@ -387,7 +387,6 @@ Silinecek bir şey yok! Hesap kaydedildi - Başarıyla indirildi! diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index d3cef1390..df0667f31 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -475,11 +475,6 @@ - - частина завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP - частини завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP - частин завантаженого файлу є вірним об\'єктом OpenPGP, але не ключем OpenPGP - diff --git a/OpenKeychain/src/main/res/values-zh-rTW/strings.xml b/OpenKeychain/src/main/res/values-zh-rTW/strings.xml index ff063b72f..08b63d13b 100644 --- a/OpenKeychain/src/main/res/values-zh-rTW/strings.xml +++ b/OpenKeychain/src/main/res/values-zh-rTW/strings.xml @@ -64,7 +64,6 @@ 檢視簽署的金鑰 建立金鑰 加入檔案 - 複製已解密的訊息 從剪貼簿中讀取 選擇要解密的檔案 加密檔案 @@ -660,8 +659,6 @@ 私鑰只能分別刪除! 帳戶已儲存 - 下載成功! - 在檔案/剪貼簿中找不到有效的金鑰! 查詢金鑰的時候發生錯誤。 diff --git a/OpenKeychain/src/main/res/values-zh/strings.xml b/OpenKeychain/src/main/res/values-zh/strings.xml index 8859a6471..301057794 100644 --- a/OpenKeychain/src/main/res/values-zh/strings.xml +++ b/OpenKeychain/src/main/res/values-zh/strings.xml @@ -13,6 +13,7 @@ 设置 已注册应用 OenPGP 密钥服务器 + 自定义记忆时间选项 变更密码 分享指纹 分享密钥 @@ -31,24 +32,26 @@ 帮助 日志 交换密钥 + 更多密钥详情 删除你的密钥 \'%s\' ? 管理我的密钥 用户名 + 安全凭证 关联系统联系人 Keybase.io 证书 - 信任此密钥? + 信任此密钥? 验证 子密钥 搜索密钥 密钥服务器, keybase.io - 密码和PIN码 + 密码和 PIN 码 处理,用户界面,记忆时间 匿名网络 Tor,代理服务器设置 界面 同步 - 密钥自动更新,contact linking + 密钥自动更新,关联联系人 试验性功能 确认 动作 @@ -82,10 +85,10 @@ 加密/签名并粘贴文本 显示密钥 创建密钥 - 添加文件(多个) + 添加文件(多个) 分享 打开为 - 复制解密文本 + 复制到剪贴板 从剪贴板导入 选择导入文件 加密文件 @@ -100,7 +103,7 @@ 加密文件 交换密钥 加密文本 - 使用NFC分享 + 使用 NFC 分享 参数设置 帮助 @@ -108,12 +111,13 @@ 删除密钥 管理我的密钥 搜索 - NFC设置 + NFC 设置 参数 加密到... 选择全部 导出全部密钥 更新所有密钥 + 更多密钥详情 通过指纹确认 通过短语认证 分享记录 @@ -135,6 +139,7 @@ 启用ASCII文本化 写入文件头信息 在OpenPGP签名、加密文本和导出密钥中写入 \'OpenKeychain v2.7\' 标记。 + 使用数字键盘输入安全令牌识别码 签名为: 加密到 加密文件后删除 @@ -142,11 +147,12 @@ 加密算法 哈希算法 用密码加密 + 自定义记忆时间选项 用公钥记录密码 文本压缩 文件压缩 - 选择OpenPGP 密钥服务器 - 密钥ID + 选择 OpenPGP 密钥服务器 + 密钥 ID 创建密钥 %s 创建 过期时间 @@ -173,16 +179,16 @@ 删除密钥服务器 主题 OpenPGP 密钥服务器 - 在指定的OpenPGP密钥服务器上搜索(HKP协议) + 在指定的 OpenPGP 密钥服务器上搜索(HKP协议) keybase.io - 在keybase.io搜索密钥 + 在 keybase.io 搜索密钥 脸书 根据用户名在脸书上搜索密钥 自动更新密钥 每三天,自动从密钥服务器更新 不自动更新密钥 关联联系方式 - 关联密钥到联系方式基于名字和email地址。这发生在设备离线时。 + 根据名字和 email 地址将密钥关联到联系人。这是本地操作,不需要联网。 新密钥将不关联到联系方式 自动更新密钥 @@ -194,10 +200,10 @@ 关联密钥到Twitter,GitHub,网页或者DNS(类似Keybase.io但是分布式) Keybase.io 证书 每次展示密钥时自动从keybase.io获取证明并显示它们 - 图标和 + (图标和某些界面还未根据深色主题进行调整) - 启用Tor代理 - 必需已安装Orbot + 启用 Tor 代理 + 必需已安装 Orbot 启用其它代理服务器 服务器地址 服务器地址不能为空 @@ -208,16 +214,16 @@ HTTP SOCKS - 不使用Tor代理 + 不使用 Tor 代理 - 为了使用Tor代理而安装Orbot? + 安装 Orbot 以使用 Tor 代理? 安装 - 必需安装Orbot并启用代理传输.你希望安装么? + 必需安装 Orbot 并启用代理传输。您希望安装么? 取消 - 不使用Tor + 不使用 Tor - 运行Orbot? - Orbot未运行。你希望打开并连接Tor? + 运行 Orbot ? + Orbot 未运行。你希望打开并连接 Tor ? 打开Orbot 运行Orbot 取消 @@ -268,8 +274,13 @@ 请输入一个密码 输入密码 输入备份码 - 输入密码为 \'%s\' - 输入PIN码为 \'%s\' + 为 \'%s\' 输入密码 + 为 \'%s\' 输入PIN码 + 输入 PIN 码以访问 \'%s\' 的安全令牌 + 保持安全令牌与设备背面的NFC标志对应 + 保持安全令牌在后面 + 移开安全令牌 + 移开安全令牌并触摸重试 删除源文件? 这些文件将被删除:%s 共%2$d个文件 %1$d 个文件已删除.%3$s @@ -293,9 +304,9 @@ 成功导出多个密钥 没有密钥被导出 注意: 只有公钥支持ElGamal。 - 没有找到密钥 + 没有找到密钥 %08X - 其他 + 忽略了 %d 个无效密钥。您也许在导出密钥时使用了选项\n --export-secret-subkeys\n请确认您是用\n --export-secret-keys\n选项导出密钥。 这个列表是空的! 成功通过NFC发送密钥 @@ -325,7 +336,7 @@ 使用Android\'s NFC Beam功能需要Android 4.1及以上 必须开启NFC! - Bean 必须开启! + Beam 必须开启! 未发现密钥! 未选择导入的密钥! 从联系人取回密钥ID失败! @@ -436,6 +447,7 @@ 更新日志 关于 版本: + 捐赠 密钥服务器 搜索密钥 @@ -510,6 +522,8 @@ 用 OpenKeychain 加密文件 用 OpenKeychain 解密 + 显示高级信息 + 隐藏高级信息 尚未选择密钥 选择密钥 创建密钥 @@ -522,6 +536,7 @@ 包名字 证书的指纹(sha256) 账户(使用旧的应用接口) + 更多密钥详情 允许的密钥 设置 账户密钥 @@ -580,6 +595,7 @@ 通过NFC分享 上传至服务器 主要信息 + 开始 分享 子密钥 证书列表 @@ -637,10 +653,18 @@ 该用户标识已被吊销,该情况不能恢复 选择一个操作 + + 更改有效期 + 吊销子密钥 + 溢出子密钥 + 把子密钥转移到安全令牌 + 新建子密钥 至少选择一个标志! 至少要有一个用户标识! 至少要有一个子密钥! + 安全令牌不支持该算法 + 安全令牌不支持密钥大小 网络同步 该内容是必须的 @@ -697,6 +721,7 @@ 默认 + 正面的 已吊销 正常 失败! @@ -708,6 +733,7 @@ 开始批量导入 已将私钥导入为公钥,这是一个BUG,请提交报告! + 没有旧密钥被删除(创建一个新密钥?) 已从数据库中删除旧的密钥 由于编码错误,操作失败 由于i/o异常,操作失败 @@ -723,21 +749,66 @@ 钥匙环过期于 %s 钥匙环过期于 %s 主标志:未指定的(假定全部 ) + 主标志:证书,加密,签名,验证 + 主标志:证书,加密,签名 + 主标志:证书,加密,验证 + 主标志:证书,加密 + 主标志:证书,签名,验证 + 主标志:证书,签名,验证 + 主标志:证书,验证 + 主标志:证书 + 主标志:加密,签名,验证 + 主标志:加密,签名 + 主标志:加密,验证 + 主标志:加密 + 主标志:签名,验证 + 主标志:签名 + 主标志:验证 + 主标志:无 正在合并已导入的数据到现有的公共钥匙环 正在合并已导入的数据到现有的私有钥匙环 正在处理子密钥 %s 子密钥过期于 %s 子密钥过期于 %s + 子密钥标志:未指定的(假设所有) + 子密钥标志:证书,加密,签名,验证 + 子密钥标志:证书,加密,签名 + 子密钥标志:证书,加密,验证 + 子密钥标志:证书,加密 + 子密钥标志:证书,签名,验证 + 子密钥标志:证书,签名 + 子密钥标志:证书,验证 + 子密钥标志:证书 + 子密钥标志:加密,签名,验证 + 子密钥标志:加密,签名 + 子密钥标志:加密,验证 + 子密钥标志:加密 + 子密钥标志:签名,验证 + 子密钥标志:签名 + 子密钥标志:验证 + 子密钥标志:无 成功导入公共钥匙环 钥匙环不包含任何新的数据,无动作 重新插入私钥 发现损坏的证书! + 证书处理错误 + 已有一个未吊销的证书,跳过 + 证书比前一个更老,跳过 + 证书是最近的,代替前一个 + %1$s 发现良好的证书 发现损坏的证书! + 证书处理错误 + 已有一个未吊销的证书,跳过 + 证书比前一个更老,跳过 + 证书是最近的,代替前一个 + %1$s 发现良好的证书 试图把公钥导入为私钥,这是一个漏洞,请报告错误! + 数据库错误! 正在合并导入的数据到现有的公钥钥匙环 正在合并已导入的数据到现有的私有钥匙环 钥匙环不包含任何新的数据,无动作 + 成功导入私密钥匙环 正在处理主密钥 正在移除未知类型 (%s) 的主密钥 @@ -750,14 +821,29 @@ + 正在清空数据库 + 成功整理数据库 + 重新导入公共密钥时出错 + 重新导入私有密钥时出错 + 未找到密钥 + 未找到密钥 + 未找到密钥 + 正在开始解密操作... + 正在解密私钥 正常 + 没有密钥被签名 + 正在为密钥环签名... + 保存密钥环中.... + 未找到密钥 + 数据库错误! + 未找到密钥 证明内容与该密钥指纹不匹配 @@ -772,6 +858,7 @@ 备份 恢复 + 未找到密钥 ]]> -- cgit v1.2.3 From eef8abcf80db8869ca138823bb7a7c1fb358e763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 3 Mar 2016 13:34:08 +0100 Subject: Version 3.9 --- OpenKeychain/build.gradle | 4 ++-- OpenKeychain/src/main/AndroidManifest.xml | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 01e221aca..0eedb8394 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -147,8 +147,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 23 - versionCode 38200 - versionName "3.8.2" + versionCode 39000 + versionName "3.9" applicationId "org.sufficientlysecure.keychain" // the androidjunitrunner is broken regarding coverage, see here: // https://code.google.com/p/android/issues/detail?id=170607 diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 771f1b2e9..50ab9aaae 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -5,11 +5,6 @@ android:installLocation="auto"> + + + diff --git a/OpenKeychain/src/main/res/values-sw400dp/styles.xml b/OpenKeychain/src/main/res/values-sw400dp/styles.xml new file mode 100644 index 000000000..b18c708d9 --- /dev/null +++ b/OpenKeychain/src/main/res/values-sw400dp/styles.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/OpenKeychain/src/main/res/values/styles.xml b/OpenKeychain/src/main/res/values/styles.xml index 55c4e2220..5d7486d19 100644 --- a/OpenKeychain/src/main/res/values/styles.xml +++ b/OpenKeychain/src/main/res/values/styles.xml @@ -1,5 +1,5 @@ - + + + + -- cgit v1.2.3 From 305fee5ea1bb8c52deeb9f43672f104d7f86f0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 8 Mar 2016 16:20:48 +0100 Subject: Open keyboard for backup code --- .../keychain/ui/PassphraseDialogActivity.java | 53 +++++++++++++--------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java index fd4f27176..e7f91a07e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java @@ -192,6 +192,8 @@ public class PassphraseDialogActivity extends FragmentActivity { mBackupCodeEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE); mBackupCodeEditText.setOnEditorActionListener(this); + openKeyboard(mBackupCodeEditText); + AlertDialog dialog = alert.create(); dialog.setButton(DialogInterface.BUTTON_POSITIVE, activity.getString(R.string.btn_unlock), (DialogInterface.OnClickListener) null); @@ -281,28 +283,7 @@ public class PassphraseDialogActivity extends FragmentActivity { mPassphraseText.setText(message); mPassphraseEditText.setHint(hint); - // Hack to open keyboard. - // This is the only method that I found to work across all Android versions - // http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/ - // Notes: * onCreateView can't be used because we want to add buttons to the dialog - // * opening in onActivityCreated does not work on Android 4.4 - mPassphraseEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - mPassphraseEditText.post(new Runnable() { - @Override - public void run() { - if (getActivity() == null || mPassphraseEditText == null) { - return; - } - InputMethodManager imm = (InputMethodManager) getActivity() - .getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mPassphraseEditText, InputMethodManager.SHOW_IMPLICIT); - } - }); - } - }); - mPassphraseEditText.requestFocus(); + openKeyboard(mPassphraseEditText); mPassphraseEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE); mPassphraseEditText.setOnEditorActionListener(this); @@ -324,6 +305,34 @@ public class PassphraseDialogActivity extends FragmentActivity { return dialog; } + /** + * Hack to open keyboard. + * + * This is the only method that I found to work across all Android versions + * http://turbomanage.wordpress.com/2012/05/02/show-soft-keyboard-automatically-when-edittext-receives-focus/ + * Notes: * onCreateView can't be used because we want to add buttons to the dialog + * * opening in onActivityCreated does not work on Android 4.4 + */ + private void openKeyboard(final TextView textView) { + textView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + textView.post(new Runnable() { + @Override + public void run() { + if (getActivity() == null || textView == null) { + return; + } + InputMethodManager imm = (InputMethodManager) getActivity() + .getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(textView, InputMethodManager.SHOW_IMPLICIT); + } + }); + } + }); + textView.requestFocus(); + } + /** * Automatic line break with max 6 lines for smaller displays *

-- cgit v1.2.3 From 4a33cc83171cbb868a9bca61638ee230de19f30e Mon Sep 17 00:00:00 2001 From: Durgesh <007durgesh219@gmail.com> Date: Tue, 8 Mar 2016 21:14:50 +0530 Subject: Fix NullPointerException in ImportKeysListFragment.checkAndRequestReadPermission, #1766 Signed-off-by: Durgesh <007durgesh219@gmail.com> --- .../java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 18063ed1a..4d4219f56 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -335,7 +335,7 @@ public class ImportKeysListFragment extends ListFragment implements if (mLoaderState instanceof BytesLoaderState) { BytesLoaderState ls = (BytesLoaderState) mLoaderState; - if ( ! checkAndRequestReadPermission(ls.mDataUri)) { + if ( ls.mDataUri != null && ! checkAndRequestReadPermission(ls.mDataUri)) { return; } } -- cgit v1.2.3 From 4d347f1a8e8736a988974abf74dee1734f3b22f7 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Thu, 10 Mar 2016 01:05:19 +0100 Subject: Fix display of keyserver item in dark theme --- .../sufficientlysecure/keychain/ui/SettingsKeyserverFragment.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyserverFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyserverFragment.java index 5a8ab36bc..488558aa3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyserverFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsKeyserverFragment.java @@ -40,6 +40,7 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.dialog.AddEditKeyserverDialogFragment; +import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.recyclerview.ItemTouchHelperAdapter; import org.sufficientlysecure.keychain.ui.util.recyclerview.ItemTouchHelperViewHolder; import org.sufficientlysecure.keychain.ui.util.recyclerview.ItemTouchHelperDragCallback; @@ -312,19 +313,19 @@ public class SettingsKeyserverFragment extends Fragment implements RecyclerItemC public void showAsSelectedKeyserver() { isSelectedKeyserver = true; selectedServerLabel.setVisibility(View.VISIBLE); - outerLayout.setBackgroundColor(getResources().getColor(R.color.android_green_dark)); + outerLayout.setBackgroundColor(FormattingUtils.getColorFromAttr(getContext(), R.attr.colorPrimaryDark)); } public void showAsUnselectedKeyserver() { isSelectedKeyserver = false; selectedServerLabel.setVisibility(View.GONE); - outerLayout.setBackgroundColor(Color.WHITE); + outerLayout.setBackgroundColor(0); } @Override public void onItemSelected() { selectedServerLabel.setVisibility(View.GONE); - itemView.setBackgroundColor(Color.LTGRAY); + itemView.setBackgroundColor(FormattingUtils.getColorFromAttr(getContext(), R.attr.colorBrightToolbar)); } @Override -- cgit v1.2.3 From 48867e89bda3a816f120798f436a2740304b1d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 10 Mar 2016 12:25:13 +0100 Subject: Update okhttp2, tokenautomcomplete, zxing --- OpenKeychain/build.gradle | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index b95546089..3b7d03187 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -43,20 +43,20 @@ dependencies { // JCenter etc. compile 'com.eftimoff:android-patternview:1.0.5@aar' - compile 'com.journeyapps:zxing-android-embedded:3.1.0@aar' + compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar' compile 'com.google.zxing:core:3.2.1' compile 'com.jpardogo.materialtabstrip:library:1.1.0' compile 'com.getbase:floatingactionbutton:1.10.1' compile 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.0' compile 'org.ocpsoft.prettytime:prettytime:4.0.1.Final' - compile 'com.splitwise:tokenautocomplete:2.0.2@aar' + compile 'com.splitwise:tokenautocomplete:2.0.5@aar' compile 'com.github.pinball83:masked-edittext:1.0.3' compile 'se.emilsjolander:stickylistheaders:2.7.0' compile 'org.sufficientlysecure:html-textview:1.3' compile 'org.sufficientlysecure:donations:2.4' compile 'com.nispok:snackbar:2.11.0' - compile 'com.squareup.okhttp:okhttp:2.7.1' - compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.1' + compile 'com.squareup.okhttp:okhttp:2.7.5' + compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.5' compile 'org.apache.james:apache-mime4j-core:0.7.2' compile 'org.apache.james:apache-mime4j-dom:0.7.2' compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' @@ -94,21 +94,21 @@ dependencyVerification { 'com.android.support:recyclerview-v7:81aad9ff4104a20d8d5cda49dbbe0f2925e7dcd607a689374db843c6f2eca20a', 'com.android.support:cardview-v7:b2c2c070a78fbf7683ab4d84b23f9eecf2af3848f126775d048ae62238b55aed', 'com.eftimoff:android-patternview:594dde382fb9a445ef0c92d614f6f127727ce699f124de8167929e10f298bf8b', - 'com.journeyapps:zxing-android-embedded:90840a4457e68962fdfb74f691c6a736be7596291001045241901f1f0e6db2ac', + 'com.journeyapps:zxing-android-embedded:afe4cd51d95ba0fd3a4bfe08c5a160bd32602aa174d511600ac824b6de4c79f1', 'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259', 'com.jpardogo.materialtabstrip:library:24d19232b319f8c73e25793432357919a7ed972186f57a3b2c9093ea74ad8311', 'com.getbase:floatingactionbutton:3edefa511aac4d90794c7b0496aca59cff2eee1e32679247b4f85acbeee05240', 'org.commonjava.googlecode.markdown4j:markdown4j:e952e825d29e1317d96f79f346bfb6786c7c5eef50bd26e54a80823704b62e13', 'org.ocpsoft.prettytime:prettytime:ef7098d973ae78b57d1a22dc37d3b8a771bf030301300e24055d676b6cdc5e75', - 'com.splitwise:tokenautocomplete:2fc238424130b42155b5f2e39799a90bbbd13b148850afbe534ab08bb913c7f7', + 'com.splitwise:tokenautocomplete:f86b8cd80e8fa1336f47d86b8ce862e1a40bdc8e206ac38c56c8e41a3d05a331', 'com.github.pinball83:masked-edittext:b1913d86482c7066ebb7831696773ac131865dc441cf8a3fc41d3b7d5691724e', 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'org.sufficientlysecure:donations:96f8197bab26dfe41900d824f10f8f1914519cd62eedb77bdac5b223eccdf0a6', 'org.sufficientlysecure:html-textview:39048e35894e582adada388e6c00631803283f8defed8e07ad58a5f284f272ee', - 'com.squareup.okhttp:okhttp:8df336e3e93b22ba8c05da5d94caf968950db845869c7ca16ed682e065135aa8', + 'com.squareup.okhttp:okhttp:88ac9fd1bb51f82bcc664cc1eb9c225c90dc4389d660231b4cc737bebfe7d0aa', 'com.nispok:snackbar:46b5eb9d630d329e13c2ce00ee9fb115ffb66c23c72cff32ee97eedd76824c6f', 'org.apache.james:apache-mime4j-core:4d7434c68f94b81a253c12f28e6bbb4d6239c361d6086a46e22e594bb43ac660', - 'com.squareup.okhttp:okhttp-urlconnection:8dce03792fd7b5f089dc4fc0fdcecbbe50ae6cca21cb08a787a3b902a9914111', + 'com.squareup.okhttp:okhttp-urlconnection:6ae7c527abd2253e7c499ded790174f8f37d9676add63d9e23a76f3ba0588c07', 'org.thoughtcrime.ssl.pinning:AndroidPinning:afa1d74e699257fa75cb109ff29bac50726ef269c6e306bdeffe8223cee06ef4', 'org.apache.james:apache-mime4j-dom:7e6b06ee164a1c21b7e477249ea0b74a18fddce44764e5764085f58dd8c34633', 'com.mikepenz:materialdrawer:4e2644f454cc2ce48b956536d3339957c3f592adb2e0b6dad72d477da29f7677', @@ -119,15 +119,15 @@ dependencyVerification { 'com.mikepenz:google-material-typeface:48b2712de87d542e9b050846e9f602238a367f38e2d5e8ea4557c5b12adfcbec', 'com.fidesmo:nordpol-android:56f43fe2b1676817bcb4085926de14a08282ef6729c855c198d81aec62b20d65', 'com.mikepenz:community-material-typeface:990acfcfb892a733d36748fe29176bd61dd5ab34bc8ca1c591200e639d955b99', -// 'OpenKeychain.extern.bouncycastle:core:b22dfb37e09fb520683dd0ba089351787560a75b59b60822143f633ec984cab5', -// 'OpenKeychain.extern.openpgp-api-lib:openpgp-api:fbd9a53022747bdc3c5b0926c6f9cbcbee19e766dd96f090a4310dc65026b393', -// 'OpenKeychain.extern.openkeychain-api-lib:openkeychain-intents:9263330c00497b7bb70502160f50c8396228129376f48f4f5656d28360a2edac', -// 'OpenKeychain.extern.bouncycastle:prov:2d93a52e1b519995b18c0a92a1e59a2773d67d9b466a9cce6af5202a66502577', -// 'OpenKeychain.extern.bouncycastle:pg:1397025acf36be36d329c0345b136af776be82fe5d6dad70cc06db09d2f02201', -// 'OpenKeychain.extern.safeslinger-exchange:safeslinger-exchange:989fcc0eba663489a41aa166f6bb39f21271d980faddea5f06ab75339e792d10', +// 'OpenKeychain.extern.bouncycastle:core:5321ccaae5c49cd681d6cc222252d8fc4fe033978a3c79ae63f842e701bb5197', +// 'OpenKeychain.extern.openpgp-api-lib:openpgp-api:e7121ea04a39bdc62e56db30e273de3c53c1e3baf21416cfeb551e6652bef639', +// 'OpenKeychain.extern.openkeychain-api-lib:openkeychain-intents:bd88737b61c0efa8cf9fc2cf3da2e2b827c77e4c0b5342b7a665bcc58daca17f', +// 'OpenKeychain.extern.bouncycastle:prov:7fe09ee4fc9e7653f430f1fa30eacb2ef594f4cc3f1b27edcce17da27af7af10', +// 'OpenKeychain.extern.bouncycastle:pg:1efe7abff1d94630064606f1a1c8b55e41a57953d3792524b2a07bc9821b3802', +// 'OpenKeychain.extern.safeslinger-exchange:safeslinger-exchange:202943c4c9affdf52ee85840b0ff65ceea12b7c3f4e5f1e378e906815769613e', 'com.android.support:support-annotations:7f21659b084da073b77b6f7fe7ab250c4f23346238d4efdbbbb937e017ae4693', -// 'OpenKeychain.extern:minidns:109d5851ab351d7628ed62a0ed96b40598952424e56657c17debbeb4a704f0ce', -// 'OpenKeychain.extern.KeybaseLib:Lib:c5b1567ff781c311240e83f865c4ba76ae435eb00994529b8364371abf0d76de', +// 'OpenKeychain.extern:minidns:c026deb65796d29d347ee6a0d61daf4e8cd97e714eb540386dc0764bddf96cd3', +// 'OpenKeychain.extern.KeybaseLib:Lib:83be9cc36fd6807dbec5b4ba7e3c2c1287a70e43bbe564abf20d096299848b73', 'com.android.support:animated-vector-drawable:4d8366192dedc8ca9e6ff62e9be9ba6145166554d61befc9df312e8328836f55', 'com.android.support:support-vector-drawable:0f43fc47b0d2797c4e1851aba61ab87a4fd33323348c2bd022821aaac052a266', 'com.squareup.okio:okio:114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266', -- cgit v1.2.3 From 69e6e404bf77305c80511bbc904734655cd8865c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 10 Mar 2016 18:34:15 +0100 Subject: service: add opportunistic mode to encryption --- .../keychain/remote/OpenPgpService.java | 46 ++++++++++++---------- extern/openpgp-api-lib | 2 +- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java index 0e807e9ba..02d9ba62d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -103,20 +103,20 @@ public class OpenPgpService extends Service { } private static class KeyIdResult { - final Intent mRequiredUserInteraction; + final Intent mResultIntent; final HashSet mKeyIds; - KeyIdResult(Intent requiredUserInteraction) { - mRequiredUserInteraction = requiredUserInteraction; + KeyIdResult(Intent resultIntent) { + mResultIntent = resultIntent; mKeyIds = null; } KeyIdResult(HashSet keyIds) { - mRequiredUserInteraction = null; + mResultIntent = null; mKeyIds = keyIds; } } - private KeyIdResult returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds) { + private KeyIdResult returnKeyIdsFromEmails(Intent data, String[] encryptionUserIds, boolean isOpportunistic) { boolean noUserIdsCheck = (encryptionUserIds == null || encryptionUserIds.length == 0); boolean missingUserIdsCheck = false; boolean duplicateUserIdsCheck = false; @@ -159,9 +159,15 @@ public class OpenPgpService extends Service { } } - if (noUserIdsCheck || missingUserIdsCheck || duplicateUserIdsCheck) { - // allow the user to verify pub key selection + if (isOpportunistic && (noUserIdsCheck || missingUserIdsCheck)) { + Intent result = new Intent(); + result.putExtra(OpenPgpApi.RESULT_ERROR, + new OpenPgpError(OpenPgpError.OPPORTUNISTIC_MISSING_KEYS, "missing keys in opportunistic mode")); + result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR); + return new KeyIdResult(result); + } + if (noUserIdsCheck || missingUserIdsCheck || duplicateUserIdsCheck) { // convert ArrayList to long[] long[] keyIdsArray = getUnboxedLongArray(keyIds); ApiPendingIntentFactory piFactory = new ApiPendingIntentFactory(getBaseContext()); @@ -173,15 +179,14 @@ public class OpenPgpService extends Service { result.putExtra(OpenPgpApi.RESULT_INTENT, pi); result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED); return new KeyIdResult(result); - } else { - // everything was easy, we have exactly one key for every email - - if (keyIds.isEmpty()) { - Log.e(Constants.TAG, "keyIdsArray.length == 0, should never happen!"); - } + } - return new KeyIdResult(keyIds); + // everything was easy, we have exactly one key for every email + if (keyIds.isEmpty()) { + Log.e(Constants.TAG, "keyIdsArray.length == 0, should never happen!"); } + + return new KeyIdResult(keyIds); } private Intent signImpl(Intent data, InputStream inputStream, @@ -302,11 +307,12 @@ public class OpenPgpService extends Service { // get key ids based on given user ids if (data.hasExtra(OpenPgpApi.EXTRA_USER_IDS)) { String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); + boolean isOpportunistic = data.getBooleanExtra(OpenPgpApi.EXTRA_OPPORTUNISTIC_ENCRYPTION, false); // give params through to activity... - KeyIdResult result = returnKeyIdsFromEmails(data, userIds); + KeyIdResult result = returnKeyIdsFromEmails(data, userIds, isOpportunistic); - if (result.mRequiredUserInteraction != null) { - return result.mRequiredUserInteraction; + if (result.mResultIntent != null) { + return result.mResultIntent; } encryptKeyIds.addAll(result.mKeyIds); } @@ -694,9 +700,9 @@ public class OpenPgpService extends Service { } else { // get key ids based on given user ids String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS); - KeyIdResult keyResult = returnKeyIdsFromEmails(data, userIds); - if (keyResult.mRequiredUserInteraction != null) { - return keyResult.mRequiredUserInteraction; + KeyIdResult keyResult = returnKeyIdsFromEmails(data, userIds, false); + if (keyResult.mResultIntent != null) { + return keyResult.mResultIntent; } if (keyResult.mKeyIds == null) { diff --git a/extern/openpgp-api-lib b/extern/openpgp-api-lib index 8ca0f578b..710a0d8fe 160000 --- a/extern/openpgp-api-lib +++ b/extern/openpgp-api-lib @@ -1 +1 @@ -Subproject commit 8ca0f578bb843db7744dbd5724b32f6664b5c3db +Subproject commit 710a0d8fe8d89cb9a1f247007000a7f49a29c527 -- cgit v1.2.3 From 6087b0a6e048dbc4cfeae6d71e825ece6253994e Mon Sep 17 00:00:00 2001 From: fjodor Date: Thu, 10 Mar 2016 21:09:28 +0200 Subject: Updated HAS_DUPLICATE_USER_ID in KeychainProvider to use name and email address instead of user id #1745 --- .../org/sufficientlysecure/keychain/provider/KeychainProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 9fbee0a67..e6789bc7b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -316,8 +316,8 @@ public class KeychainProvider extends ContentProvider { + " WHERE dups." + UserPackets.MASTER_KEY_ID + " != " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " AND dups." + UserPackets.RANK + " = 0" - + " AND dups." + UserPackets.USER_ID - + " = "+ Tables.USER_PACKETS + "." + UserPackets.USER_ID + + " AND dups." + UserPackets.NAME + " = "+ Tables.USER_PACKETS + "." + UserPackets.NAME + + " AND dups." + UserPackets.EMAIL + " = "+ Tables.USER_PACKETS + "." + UserPackets.EMAIL + ")) AS " + KeyRings.HAS_DUPLICATE_USER_ID); projectionMap.put(KeyRings.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); projectionMap.put(KeyRings.PUBKEY_DATA, -- cgit v1.2.3 From b5211b33de683f5e903a2ad2d5028e2176c88eb8 Mon Sep 17 00:00:00 2001 From: Alex Fong Date: Sat, 12 Mar 2016 10:32:38 +0800 Subject: Provisional backup-code text selection fix For issue #1779, a provisional fix where selection is still possible, but more difficult. Preventing selection altogether is not possible due to the implementation in the Masked-Edittext dependency. To be updated when Masked-Edittext fixes this bug. --- .../keychain/ui/BackupCodeFragment.java | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java index f1d9b270d..e7ff6ce46 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java @@ -43,6 +43,7 @@ import android.support.v4.app.FragmentManager.OnBackStackChangedListener; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; +import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -237,6 +238,30 @@ public class BackupCodeFragment extends CryptoOperationFragment Date: Sat, 12 Mar 2016 19:32:36 +0100 Subject: okhttp3 --- OpenKeychain/build.gradle | 8 ++-- .../keychain/keyimport/FacebookKeyserver.java | 14 ++++-- .../keychain/keyimport/HkpKeyserver.java | 55 +++++++--------------- .../keychain/linked/LinkedTokenResource.java | 18 ++++--- .../linked/resources/GenericHttpsResource.java | 2 +- .../keychain/linked/resources/GithubResource.java | 2 +- .../keychain/linked/resources/TwitterResource.java | 6 +-- .../ui/dialog/AddEditKeyserverDialogFragment.java | 15 ++---- .../keychain/util/OkHttpClientFactory.java | 55 ++++++++++++++++++++++ .../keychain/util/OkHttpKeybaseClient.java | 45 +++++------------- .../keychain/util/TlsHelper.java | 24 +++++----- 11 files changed, 131 insertions(+), 113 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 3b7d03187..8f7f31bed 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -55,8 +55,8 @@ dependencies { compile 'org.sufficientlysecure:html-textview:1.3' compile 'org.sufficientlysecure:donations:2.4' compile 'com.nispok:snackbar:2.11.0' - compile 'com.squareup.okhttp:okhttp:2.7.5' - compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.5' + compile 'com.squareup.okhttp3:okhttp:3.2.0' + compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0' compile 'org.apache.james:apache-mime4j-core:0.7.2' compile 'org.apache.james:apache-mime4j-dom:0.7.2' compile 'org.thoughtcrime.ssl.pinning:AndroidPinning:1.0.0' @@ -105,10 +105,10 @@ dependencyVerification { 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'org.sufficientlysecure:donations:96f8197bab26dfe41900d824f10f8f1914519cd62eedb77bdac5b223eccdf0a6', 'org.sufficientlysecure:html-textview:39048e35894e582adada388e6c00631803283f8defed8e07ad58a5f284f272ee', - 'com.squareup.okhttp:okhttp:88ac9fd1bb51f82bcc664cc1eb9c225c90dc4389d660231b4cc737bebfe7d0aa', + 'com.squareup.okhttp3:okhttp:a41cdb7b024c56436a21e38f00b4d12e3b7e01451ffe6c4f545acba805bba03b', + 'com.squareup.okhttp3:okhttp-urlconnection:7d6598a6665c166e2d4b78956a96056b9be7de192b3c923ccf4695d08e580833', 'com.nispok:snackbar:46b5eb9d630d329e13c2ce00ee9fb115ffb66c23c72cff32ee97eedd76824c6f', 'org.apache.james:apache-mime4j-core:4d7434c68f94b81a253c12f28e6bbb4d6239c361d6086a46e22e594bb43ac660', - 'com.squareup.okhttp:okhttp-urlconnection:6ae7c527abd2253e7c499ded790174f8f37d9676add63d9e23a76f3ba0588c07', 'org.thoughtcrime.ssl.pinning:AndroidPinning:afa1d74e699257fa75cb109ff29bac50726ef269c6e306bdeffe8223cee06ef4', 'org.apache.james:apache-mime4j-dom:7e6b06ee164a1c21b7e477249ea0b74a18fddce44764e5764085f58dd8c34633', 'com.mikepenz:materialdrawer:4e2644f454cc2ce48b956536d3339957c3f592adb2e0b6dad72d477da29f7677', 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 faa2a1848..1c592003c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java @@ -23,10 +23,10 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; @@ -34,6 +34,8 @@ import org.sufficientlysecure.keychain.pgp.UncachedPublicKey; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.OkHttpClientFactory; +import org.sufficientlysecure.keychain.util.TlsHelper; import java.io.IOException; import java.net.Proxy; @@ -104,8 +106,7 @@ public class FacebookKeyserver extends Keyserver { String request = String.format(FB_KEY_URL_FORMAT, fbUsername); Log.d(Constants.TAG, "fetching from Facebook with: " + request + " proxy: " + mProxy); - OkHttpClient client = new OkHttpClient(); - client.setProxy(mProxy); + OkHttpClient client = OkHttpClientFactory.getClient(mProxy); URL url = new URL(request); @@ -126,6 +127,9 @@ public class FacebookKeyserver extends Keyserver { throw new QueryFailedException("Cannot connect to Facebook. " + "Check your Internet connection!" + (mProxy == Proxy.NO_PROXY ? "" : " Using proxy " + mProxy)); + } catch (TlsHelper.TlsHelperException e) { + Log.e(Constants.TAG, "Exception in cert pinning", e); + throw new QueryFailedException("Exception in cert pinning. "); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index c2190318b..bdf43b6da 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -18,16 +18,18 @@ package org.sufficientlysecure.keychain.keyimport; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; -import com.squareup.okhttp.Response; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.OkHttpClientFactory; import org.sufficientlysecure.keychain.util.TlsHelper; import java.io.IOException; @@ -42,7 +44,6 @@ import java.util.Comparator; import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; -import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -199,43 +200,12 @@ public class HkpKeyserver extends Keyserver { return mSecure ? "https://" : "http://"; } - /** - * returns a client with pinned certificate if necessary - * - * @param url url to be queried by client - * @param proxy proxy to be used by client - * @return client with a pinned certificate if necessary - */ - public static OkHttpClient getClient(URL url, Proxy proxy) throws IOException { - OkHttpClient client = new OkHttpClient(); - - try { - TlsHelper.usePinnedCertificateIfAvailable(client, url); - } catch (TlsHelper.TlsHelperException e) { - Log.w(Constants.TAG, e); - } - - // don't follow any redirects - client.setFollowRedirects(false); - client.setFollowSslRedirects(false); - - if (proxy != null) { - client.setProxy(proxy); - client.setConnectTimeout(30000, TimeUnit.MILLISECONDS); - } else { - client.setProxy(Proxy.NO_PROXY); - client.setConnectTimeout(5000, TimeUnit.MILLISECONDS); - } - client.setReadTimeout(45000, TimeUnit.MILLISECONDS); - - return client; - } private String query(String request, @NonNull Proxy proxy) throws QueryFailedException, HttpError { try { URL url = new URL(getUrlPrefix() + mHost + ":" + mPort + request); Log.d(Constants.TAG, "hkp keyserver query: " + url + " Proxy: " + proxy); - OkHttpClient client = getClient(url, proxy); + OkHttpClient client = OkHttpClientFactory.getPinnedClient(url, proxy); Response response = client.newCall(new Request.Builder().url(url).build()).execute(); String responseBody = response.body().string(); // contains body both in case of success or failure @@ -249,6 +219,9 @@ public class HkpKeyserver extends Keyserver { Log.e(Constants.TAG, "IOException at HkpKeyserver", e); throw new QueryFailedException("Keyserver '" + mHost + "' is unavailable. Check your Internet connection!" + (proxy == Proxy.NO_PROXY ? "" : " Using proxy " + proxy)); + } catch (TlsHelper.TlsHelperException e) { + Log.e(Constants.TAG, "Exception in pinning certs", e); + throw new QueryFailedException("Exception in pinning certs"); } } @@ -413,6 +386,7 @@ public class HkpKeyserver extends Keyserver { Log.d(Constants.TAG, "hkp keyserver add: " + url); Log.d(Constants.TAG, "params: " + params); + RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), params); Request request = new Request.Builder() @@ -422,7 +396,7 @@ public class HkpKeyserver extends Keyserver { .post(body) .build(); - Response response = getClient(url, mProxy).newCall(request).execute(); + Response response = OkHttpClientFactory.getPinnedClient(url, mProxy).newCall(request).execute(); Log.d(Constants.TAG, "response code: " + response.code()); Log.d(Constants.TAG, "answer: " + response.body().string()); @@ -434,6 +408,9 @@ public class HkpKeyserver extends Keyserver { } catch (IOException e) { Log.e(Constants.TAG, "IOException", e); throw new AddKeyException(); + } catch (TlsHelper.TlsHelperException e) { + Log.e(Constants.TAG, "Exception in pinning certs", e); + throw new AddKeyException(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java index 6a584a939..24fa3bd67 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java @@ -2,10 +2,10 @@ package org.sufficientlysecure.keychain.linked; import android.content.Context; -import com.squareup.okhttp.CertificatePinner; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.Response; +import okhttp3.CertificatePinner; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; import org.json.JSONException; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.linked.resources.GenericHttpsResource; @@ -16,6 +16,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.LogTyp import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.OkHttpClientFactory; import java.io.IOException; import java.net.MalformedURLException; @@ -236,13 +237,16 @@ public abstract class LinkedTokenResource extends LinkedResource { return builder.build(); } + public static String getResponseBody(Request request, String... pins) throws IOException, HttpStatusException { - Log.d("Connection to: "+request.url().getHost(),""); - OkHttpClient client = new OkHttpClient(); + Log.d("Connection to: "+request.url().url().getHost(),""); + OkHttpClient client; if(pins !=null){ - client.setCertificatePinner(getCertificatePinner(request.url().getHost(),pins)); + client = OkHttpClientFactory.getPinnedSimpleClient(getCertificatePinner(request.url().url().getHost(),pins)); + }else{ + client = OkHttpClientFactory.getSimpleClient(); } Response response = client.newCall(request).execute(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GenericHttpsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GenericHttpsResource.java index d6b8640e3..da531e8fa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GenericHttpsResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GenericHttpsResource.java @@ -6,7 +6,7 @@ import android.net.Uri; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; -import com.squareup.okhttp.Request; +import okhttp3.Request; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GithubResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GithubResource.java index 134582ae1..0e87ca6e5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GithubResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/GithubResource.java @@ -6,7 +6,7 @@ import android.net.Uri; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; -import com.squareup.okhttp.Request; +import okhttp3.Request; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/TwitterResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/TwitterResource.java index b0f02c43c..db3b64225 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/TwitterResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/resources/TwitterResource.java @@ -7,11 +7,11 @@ import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; import android.util.Log; -import com.squareup.okhttp.MediaType; -import com.squareup.okhttp.Request; -import com.squareup.okhttp.RequestBody; import com.textuality.keybase.lib.JWalk; +import okhttp3.MediaType; +import okhttp3.Request; +import okhttp3.RequestBody; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java index 3d96f3c6d..7abef97d2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java @@ -50,14 +50,13 @@ import android.widget.EditText; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.Request; +import okhttp3.OkHttpClient; +import okhttp3.Request; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; -import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.OkHttpClientFactory; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.TlsHelper; import org.sufficientlysecure.keychain.util.orbot.OrbotHelper; @@ -354,14 +353,10 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On Log.d("Converted URL", newKeyserver.toString()); - OkHttpClient client = HkpKeyserver.getClient(newKeyserver.toURL(), proxy); - - // don't follow any redirects - client.setFollowRedirects(false); - client.setFollowSslRedirects(false); + OkHttpClient client = OkHttpClientFactory.getPinnedClient(newKeyserver.toURL(), proxy); if (onlyTrustedKeyserver - && !TlsHelper.usePinnedCertificateIfAvailable(client, newKeyserver.toURL())) { + && TlsHelper.getPinnedSslSocketFactory(newKeyserver.toURL())==null) { Log.w(Constants.TAG, "No pinned certificate for this host in OpenKeychain's assets."); reason = FailureReason.NO_PINNED_CERTIFICATE; return reason; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java new file mode 100644 index 000000000..2bf3b7e14 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java @@ -0,0 +1,55 @@ +package org.sufficientlysecure.keychain.util; + +import okhttp3.CertificatePinner; +import okhttp3.OkHttpClient; +import org.sufficientlysecure.keychain.Constants; + +import java.io.IOException; +import java.net.Proxy; +import java.net.URL; +import java.util.concurrent.TimeUnit; + +/** + * Created by Michał Kępkowski on 11/03/16. + */ +public class OkHttpClientFactory { + private static OkHttpClient client; + + public static OkHttpClient getSimpleClient(){ + if(client == null){ + client = new OkHttpClient.Builder().build(); + } + return client; + } + + public static OkHttpClient getPinnedSimpleClient(CertificatePinner pinner){ + return new OkHttpClient.Builder() + .certificatePinner(pinner) + .build(); + } + + + public static OkHttpClient getPinnedClient(URL url, Proxy proxy) throws IOException, TlsHelper.TlsHelperException { + + return new OkHttpClient.Builder() + .followRedirects(false) + .followSslRedirects(false) + .proxy(proxy) + .connectTimeout(30000, TimeUnit.MILLISECONDS) + .readTimeout(45000, TimeUnit.MILLISECONDS) + .sslSocketFactory(TlsHelper.getPinnedSslSocketFactory(url)) + .build(); + } + + public static OkHttpClient getClient( Proxy proxy) throws IOException, TlsHelper.TlsHelperException { + + return new OkHttpClient.Builder() + .followRedirects(false) + .followSslRedirects(false) + .proxy(proxy) + .connectTimeout(30000, TimeUnit.MILLISECONDS) + .readTimeout(45000, TimeUnit.MILLISECONDS) + .build(); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index d2c90cfcd..04527c730 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -17,55 +17,36 @@ package org.sufficientlysecure.keychain.util; -import com.squareup.okhttp.OkHttpClient; -import com.squareup.okhttp.OkUrlFactory; + import com.textuality.keybase.lib.KeybaseUrlConnectionClient; +import okhttp3.OkHttpClient; import org.sufficientlysecure.keychain.Constants; import java.io.IOException; import java.net.Proxy; import java.net.URL; -import java.net.URLConnection; -import java.util.concurrent.TimeUnit; /** * Wrapper for Keybase Lib */ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { - private OkUrlFactory generateUrlFactory() { - OkHttpClient client = new OkHttpClient(); - return new OkUrlFactory(client); - } @Override - public URLConnection openConnection(URL url, Proxy proxy, boolean isKeybase) throws IOException { - OkUrlFactory factory = generateUrlFactory(); - if (proxy != null) { - factory.client().setProxy(proxy); - factory.client().setConnectTimeout(30000, TimeUnit.MILLISECONDS); - factory.client().setReadTimeout(40000, TimeUnit.MILLISECONDS); - } else { - factory.client().setConnectTimeout(5000, TimeUnit.MILLISECONDS); - factory.client().setReadTimeout(25000, TimeUnit.MILLISECONDS); - } - - factory.client().setFollowSslRedirects(false); - - // forced the usage of api.keybase.io pinned certificate - if (isKeybase) { - try { - if (!TlsHelper.usePinnedCertificateIfAvailable(factory.client(), url)) { - throw new IOException("no pinned certificate found for URL!"); - } - } catch (TlsHelper.TlsHelperException e) { - Log.e(Constants.TAG, "TlsHelper failed", e); - throw new IOException("TlsHelper failed"); + public OkHttpClient getClient(URL url, Proxy proxy, boolean pin) throws IOException { + try { + if(pin) { + return OkHttpClientFactory.getPinnedClient(url, proxy); + }else{ + return OkHttpClientFactory.getClient( proxy); } + } catch (IOException e) { + throw new IOException("no pinned certificate found for URL!"); + } catch (TlsHelper.TlsHelperException e) { + Log.e(Constants.TAG, "TlsHelper failed", e); + throw new IOException("TlsHelper failed"); } - - return factory.open(url); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java index 1492abdeb..d1b8f768b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java @@ -19,8 +19,8 @@ package org.sufficientlysecure.keychain.util; import android.content.res.AssetManager; -import com.squareup.okhttp.OkHttpClient; +import okhttp3.OkHttpClient; import org.sufficientlysecure.keychain.Constants; import java.io.ByteArrayInputStream; @@ -39,6 +39,7 @@ import java.util.HashMap; import java.util.Map; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; public class TlsHelper { @@ -80,30 +81,30 @@ public class TlsHelper { * @throws TlsHelperException * @throws IOException */ - public static boolean usePinnedCertificateIfAvailable(OkHttpClient client, URL url) throws TlsHelperException, IOException { + public static SSLSocketFactory getPinnedSslSocketFactory(URL url) throws TlsHelperException, IOException { if (url.getProtocol().equals("https")) { // use certificate PIN from assets if we have one for (String host : sPinnedCertificates.keySet()) { if (url.getHost().endsWith(host)) { - pinCertificate(sPinnedCertificates.get(host), client); - return true; + return pinCertificate(sPinnedCertificates.get(host)); + //return true; } } } - return false; + return null; } /** - * Modifies the client to accept only requests with a given certificate. Applies to all URLs requested by the - * client. - * Therefore a client that is pinned this way should be used to only make requests to URLs with passed certificate. + * Modifies the builder to accept only requests with a given certificate. Applies to all URLs requested by the + * builder. + * Therefore a builder that is pinned this way should be used to only make requests to URLs with passed certificate. * * @param certificate certificate to pin - * @param client OkHttpClient to enforce pinning on + * @param builder OkHttpBuilder to enforce pinning on * @throws TlsHelperException * @throws IOException */ - private static void pinCertificate(byte[] certificate, OkHttpClient client) + private static SSLSocketFactory pinCertificate(byte[] certificate) throws TlsHelperException, IOException { // We don't use OkHttp's CertificatePinner since it can not be used to pin self-signed // certificate if such certificate is not accepted by TrustManager. @@ -130,7 +131,8 @@ public class TlsHelper { SSLContext context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); - client.setSslSocketFactory(context.getSocketFactory()); + return context.getSocketFactory(); + //builder.sslSocketFactory(context.getSocketFactory()); } catch (CertificateException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) { throw new TlsHelperException(e); } -- cgit v1.2.3 From 966948d79b8e791a2ae95fc1593a43adb97bc0eb Mon Sep 17 00:00:00 2001 From: fiaxh Date: Mon, 14 Mar 2016 23:06:49 +0100 Subject: Set MIME application/pgp-keys when sending a key --- .../org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index ce2f2def8..0aa8330ea 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -238,7 +238,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements // let user choose application Intent sendIntent = new Intent(Intent.ACTION_SEND); - sendIntent.setType("text/plain"); + sendIntent.setType(Constants.MIME_TYPE_KEYS); // NOTE: Don't use Intent.EXTRA_TEXT to send the key // better send it via a Uri! -- cgit v1.2.3 From 2b43ba438bd9956ceef8ccf1dc229e5dbb52a286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 15 Mar 2016 18:01:27 +0100 Subject: Version 3.9.3 --- OpenKeychain/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 3b7d03187..523750d74 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -145,8 +145,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 23 - versionCode 39200 - versionName "3.9.2" + versionCode 39300 + versionName "3.9.3" applicationId "org.sufficientlysecure.keychain" // the androidjunitrunner is broken regarding coverage, see here: // https://code.google.com/p/android/issues/detail?id=170607 -- cgit v1.2.3 From eb5eb95a9ffb0f340c85c0710b451a5895988e21 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 15 Mar 2016 23:30:50 +0100 Subject: fix ridiculous database migration bug introduced by d6e4936fa54dc3577296dbadaeb556178dcad2c3 --- .../keychain/provider/KeychainDatabase.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 2a4d898bc..c3697997f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -279,37 +279,35 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL("ALTER TABLE user_ids ADD COLUMN type INTEGER"); db.execSQL("ALTER TABLE user_ids ADD COLUMN attribute_data BLOB"); case 7: - // consolidate - case 8: // new table for allowed key ids in API try { db.execSQL(CREATE_API_APPS_ALLOWED_KEYS); } catch (Exception e) { // never mind, the column probably already existed } - case 9: + case 8: // tbale name for user_ids changed to user_packets db.execSQL("DROP TABLE IF EXISTS certs"); db.execSQL("DROP TABLE IF EXISTS user_ids"); db.execSQL(CREATE_USER_PACKETS); db.execSQL(CREATE_CERTS); - case 10: + case 9: // do nothing here, just consolidate - case 11: + case 10: // fix problems in database, see #1402 for details // https://github.com/open-keychain/open-keychain/issues/1402 db.execSQL("DELETE FROM api_accounts WHERE key_id BETWEEN 0 AND 3"); - case 12: + case 11: db.execSQL(CREATE_UPDATE_KEYS); - case 13: + case 12: // do nothing here, just consolidate - case 14: + case 13: db.execSQL("CREATE INDEX keys_by_rank ON keys (" + KeysColumns.RANK + ");"); db.execSQL("CREATE INDEX uids_by_rank ON user_packets (" + UserPacketsColumns.RANK + ", " + UserPacketsColumns.USER_ID + ", " + UserPacketsColumns.MASTER_KEY_ID + ");"); db.execSQL("CREATE INDEX verified_certs ON certs (" + CertsColumns.VERIFIED + ", " + CertsColumns.MASTER_KEY_ID + ");"); - case 15: + case 14: db.execSQL("ALTER TABLE user_packets ADD COLUMN name TEXT"); db.execSQL("ALTER TABLE user_packets ADD COLUMN email TEXT"); db.execSQL("ALTER TABLE user_packets ADD COLUMN comment TEXT"); -- cgit v1.2.3 From 6029564d68afeba980bbdd5509622653efef1673 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 15 Mar 2016 23:51:21 +0100 Subject: small update to duplicate detection --- .../org/sufficientlysecure/keychain/provider/KeychainProvider.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 e6789bc7b..75a5e89b8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -316,8 +316,11 @@ public class KeychainProvider extends ContentProvider { + " WHERE dups." + UserPackets.MASTER_KEY_ID + " != " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " AND dups." + UserPackets.RANK + " = 0" - + " AND dups." + UserPackets.NAME + " = "+ Tables.USER_PACKETS + "." + UserPackets.NAME - + " AND dups." + UserPackets.EMAIL + " = "+ Tables.USER_PACKETS + "." + UserPackets.EMAIL + + " AND (dups." + UserPackets.USER_ID + " = " + Tables.USER_PACKETS + "." + UserPackets.USER_ID + " COLLATE NOCASE" + + " OR (dups." + UserPackets.NAME + " = " + Tables.USER_PACKETS + "." + UserPackets.NAME + " COLLATE NOCASE" + + " AND dups." + UserPackets.EMAIL + " = " + Tables.USER_PACKETS + "." + UserPackets.EMAIL + " COLLATE NOCASE" + + ")" + + ")" + ")) AS " + KeyRings.HAS_DUPLICATE_USER_ID); projectionMap.put(KeyRings.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); projectionMap.put(KeyRings.PUBKEY_DATA, -- cgit v1.2.3 From f3712101c145d9e546885e516ef89c9a82e9da8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 15 Mar 2016 23:53:03 +0100 Subject: Version 3.9.4 --- OpenKeychain/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 523750d74..95332f7af 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -145,8 +145,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 23 - versionCode 39300 - versionName "3.9.3" + versionCode 39400 + versionName "3.9.4" applicationId "org.sufficientlysecure.keychain" // the androidjunitrunner is broken regarding coverage, see here: // https://code.google.com/p/android/issues/detail?id=170607 -- cgit v1.2.3 From ce5e5f36c56fe14cb4a90a912eece07e4cb92285 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 16 Mar 2016 00:33:09 +0100 Subject: update null-check for duplicates, and add matching indexes to name and email columns --- .../keychain/provider/KeychainDatabase.java | 9 ++++++++- .../keychain/provider/KeychainProvider.java | 11 +++++------ 2 files changed, 13 insertions(+), 7 deletions(-) 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 c3697997f..04c14491b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -54,7 +54,7 @@ import java.io.IOException; */ public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "openkeychain.db"; - private static final int DATABASE_VERSION = 15; + private static final int DATABASE_VERSION = 16; static Boolean apgHack = false; private Context mContext; @@ -311,6 +311,13 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL("ALTER TABLE user_packets ADD COLUMN name TEXT"); db.execSQL("ALTER TABLE user_packets ADD COLUMN email TEXT"); db.execSQL("ALTER TABLE user_packets ADD COLUMN comment TEXT"); + case 15: + db.execSQL("CREATE INDEX uids_by_name ON user_packets (name COLLATE NOCASE)"); + db.execSQL("CREATE INDEX uids_by_email ON user_packets (email COLLATE NOCASE)"); + if (oldVersion == 14) { + // no consolidate necessary + return; + } } // always do consolidate after upgrade 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 75a5e89b8..9c5d0c054 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -312,15 +312,14 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRings.EMAIL, Tables.USER_PACKETS + "." + UserPackets.EMAIL); projectionMap.put(KeyRings.COMMENT, Tables.USER_PACKETS + "." + UserPackets.COMMENT); projectionMap.put(KeyRings.HAS_DUPLICATE_USER_ID, - "(EXISTS (SELECT * FROM " + Tables.USER_PACKETS + " AS dups" + "(EXISTS (SELECT * FROM " + Tables.USER_PACKETS + " AS dups" + " WHERE dups." + UserPackets.MASTER_KEY_ID + " != " + Tables.KEYS + "." + Keys.MASTER_KEY_ID + " AND dups." + UserPackets.RANK + " = 0" - + " AND (dups." + UserPackets.USER_ID + " = " + Tables.USER_PACKETS + "." + UserPackets.USER_ID + " COLLATE NOCASE" - + " OR (dups." + UserPackets.NAME + " = " + Tables.USER_PACKETS + "." + UserPackets.NAME + " COLLATE NOCASE" - + " AND dups." + UserPackets.EMAIL + " = " + Tables.USER_PACKETS + "." + UserPackets.EMAIL + " COLLATE NOCASE" - + ")" - + ")" + + " AND dups." + UserPackets.NAME + + " = " + Tables.USER_PACKETS + "." + UserPackets.NAME + " COLLATE NOCASE" + + " AND dups." + UserPackets.EMAIL + + " = " + Tables.USER_PACKETS + "." + UserPackets.EMAIL + " COLLATE NOCASE" + ")) AS " + KeyRings.HAS_DUPLICATE_USER_ID); projectionMap.put(KeyRings.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); projectionMap.put(KeyRings.PUBKEY_DATA, -- cgit v1.2.3 From 7efeebc6381784a9362e5514fb50084c662dd335 Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Sun, 20 Mar 2016 11:52:36 +0100 Subject: #1661 - Don't expose CertifyActivity *Add new activity - RedirectImportKeysActivity, which prompts user to use Openkeychain directly *Add intent filter for the activity *Change intent filter for CertifyActivity --- OpenKeychain/src/main/AndroidManifest.xml | 17 +++-- .../keychain/ui/RedirectImportKeysActivity.java | 60 ++++++++++++++++++ .../res/layout/redirect_import_keys_activity.xml | 73 ++++++++++++++++++++++ OpenKeychain/src/main/res/values-w820dp/dimens.xml | 6 ++ OpenKeychain/src/main/res/values/dimens.xml | 3 + OpenKeychain/src/main/res/values/strings.xml | 2 + 6 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java create mode 100644 OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml create mode 100644 OpenKeychain/src/main/res/values-w820dp/dimens.xml diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 50ab9aaae..8031606fb 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -711,6 +711,15 @@ + + + > + @@ -726,11 +735,9 @@ - - + + - + \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java new file mode 100644 index 000000000..a59d3ba80 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -0,0 +1,60 @@ +/* + * + * + * 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.sufficientlysecure.keychain.ui; + +import android.app.Activity; + +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.base.BaseActivity; + +public class RedirectImportKeysActivity extends BaseActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setFullScreenDialogClose(Activity.RESULT_CANCELED, true); + final Intent intent = new Intent(this, org.sufficientlysecure.keychain.ui.ImportKeysActivity.class); + + new AlertDialog.Builder(this) + .setTitle("Import key attempt") + .setMessage("You scanned a fingerprint with another app, please scan with Openkeychain directly to be safe" ) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + // intent directly to ImportKeyChain activity + startActivity(intent); + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + // close window + finish(); + } + }) + .setIcon(android.R.drawable.ic_dialog_alert) + .show(); + } + + @Override + protected void initLayout() { + setContentView(R.layout.redirect_import_keys_activity); + } +} \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml b/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml new file mode 100644 index 000000000..2f63d143d --- /dev/null +++ b/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/values-w820dp/dimens.xml b/OpenKeychain/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 000000000..63fc81644 --- /dev/null +++ b/OpenKeychain/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/OpenKeychain/src/main/res/values/dimens.xml b/OpenKeychain/src/main/res/values/dimens.xml index 2aae06e2e..254dc02bb 100644 --- a/OpenKeychain/src/main/res/values/dimens.xml +++ b/OpenKeychain/src/main/res/values/dimens.xml @@ -5,4 +5,7 @@ 120dp 222dp 0dp + + 16dp + 16dp \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 70db4029b..acc0c7f20 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1740,4 +1740,6 @@ 50 EUR 100 EUR + RedirectKeyActivity + Settings -- cgit v1.2.3 From a8603d69749f0609e07f8894c695ba500b8404cb Mon Sep 17 00:00:00 2001 From: Durgesh <007durgesh219@gmail.com> Date: Mon, 7 Mar 2016 21:51:03 +0530 Subject: Fix CertifyKeyActivity back button on action bar not working #1758 Signed-off-by: Durgesh <007durgesh219@gmail.com> --- .../org/sufficientlysecure/keychain/ui/base/BaseActivity.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java index beaf68372..063181dfe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java @@ -26,6 +26,7 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; @@ -65,6 +66,16 @@ public abstract class BaseActivity extends AppCompatActivity { } } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home : + onBackPressed(); + return true; + } + return super.onOptionsItemSelected(item); + } + public static void onResumeChecks(Context context) { KeyserverSyncAdapterService.cancelUpdates(context); // in case user has disabled sync from Android account settings -- cgit v1.2.3 From cab3fa7874f90f9aa8f5d3b9244e78ac4dd96638 Mon Sep 17 00:00:00 2001 From: Advaita Date: Tue, 15 Mar 2016 23:07:27 +0530 Subject: Final commit All changes included Improvements -Reformatted code wherever required -Only active wifi connections trigger events -Improve sync reliability -Removed extra permission Minor Changes -Refactored 2 variables for easier readbility -Wifi-Only-Sync is now enabled by default --- OpenKeychain/src/main/AndroidManifest.xml | 10 +++++ .../org/sufficientlysecure/keychain/Constants.java | 1 + .../keychain/receiver/NetworkReceiver.java | 52 ++++++++++++++++++++++ .../service/ContactSyncAdapterService.java | 9 ++-- .../service/KeyserverSyncAdapterService.java | 24 +++++++++- .../keychain/ui/SettingsActivity.java | 6 +-- .../keychain/util/Preferences.java | 32 +++++++------ OpenKeychain/src/main/res/values/strings.xml | 1 + OpenKeychain/src/main/res/xml/sync_preferences.xml | 6 +++ 9 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/receiver/NetworkReceiver.java diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 50ab9aaae..74bf936b4 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -76,6 +76,7 @@ + @@ -89,6 +90,15 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.Keychain.Light"> + + + + + + "Automatic key updates" "Every three days, keys are updated from the preferred keyserver" "Keys are not automatically updated" + "Sync only on Wi-Fi" "Link keys to contacts" "Link keys to contacts based on names and email addresses. This happens completely offline on your device." "New keys will not be linked to contacts" diff --git a/OpenKeychain/src/main/res/xml/sync_preferences.xml b/OpenKeychain/src/main/res/xml/sync_preferences.xml index de41ff030..600ccc9e8 100644 --- a/OpenKeychain/src/main/res/xml/sync_preferences.xml +++ b/OpenKeychain/src/main/res/xml/sync_preferences.xml @@ -3,6 +3,12 @@ android:key="syncKeyserver" android:persistent="false" android:title="@string/label_sync_settings_keyserver_title"/> + Date: Wed, 23 Mar 2016 17:49:26 +0100 Subject: get rid of code path for pin and notation data handling --- .../operations/results/OperationResult.java | 2 - .../keychain/pgp/PgpKeyOperation.java | 113 ++++----------------- .../keychain/pgp/UncachedKeyRing.java | 42 ++++++++ .../keychain/service/SaveKeyringParcel.java | 16 +-- .../keychain/ui/CreateKeyFinalFragment.java | 4 +- .../keychain/ui/EditKeyFragment.java | 3 +- .../keychain/ui/ViewKeyActivity.java | 3 +- .../keychain/operations/ExportTest.java | 7 +- .../keychain/pgp/PgpKeyOperationTest.java | 42 +------- 9 files changed, 75 insertions(+), 157 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java index ec2fddbd0..a3979904c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java @@ -566,8 +566,6 @@ public abstract class OperationResult implements Parcelable { MSG_MF_ERROR_BAD_SECURITY_TOKEN_SIZE(LogLevel.ERROR, R.string.edit_key_error_bad_security_token_size), MSG_MF_ERROR_BAD_SECURITY_TOKEN_STRIPPED(LogLevel.ERROR, R.string.edit_key_error_bad_security_token_stripped), MSG_MF_MASTER (LogLevel.DEBUG, R.string.msg_mf_master), - MSG_MF_NOTATION_PIN (LogLevel.DEBUG, R.string.msg_mf_notation_pin), - MSG_MF_NOTATION_EMPTY (LogLevel.DEBUG, R.string.msg_mf_notation_empty), MSG_MF_PASSPHRASE (LogLevel.INFO, R.string.msg_mf_passphrase), MSG_MF_PIN (LogLevel.INFO, R.string.msg_mf_pin), MSG_MF_ADMIN_PIN (LogLevel.INFO, R.string.msg_mf_admin_pin), diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java index e43548165..102e11674 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java @@ -18,6 +18,23 @@ package org.sufficientlysecure.keychain.pgp; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.spec.ECGenParameterSpec; +import java.util.Arrays; +import java.util.Date; +import java.util.Iterator; +import java.util.Stack; +import java.util.concurrent.atomic.AtomicBoolean; + import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.S2K; import org.bouncycastle.bcpg.sig.Features; @@ -57,13 +74,12 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; -import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Curve; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyAdd; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; -import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcKeyToCardOperationsBuilder; +import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.NfcSignOperationsBuilder; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.Log; @@ -71,22 +87,6 @@ import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Primes; import org.sufficientlysecure.keychain.util.ProgressScaler; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SecureRandom; -import java.security.SignatureException; -import java.security.spec.ECGenParameterSpec; -import java.util.Arrays; -import java.util.Date; -import java.util.Iterator; -import java.util.Stack; -import java.util.concurrent.atomic.AtomicBoolean; - /** * This class is the single place where ALL operations that actually modify a PGP public or secret * key take place. @@ -1058,8 +1058,8 @@ public class PgpKeyOperation { log.add(LogType.MSG_MF_PASSPHRASE, indent); indent += 1; - sKR = applyNewUnlock(sKR, masterPublicKey, masterPrivateKey, - cryptoInput.getPassphrase(), saveParcel.mNewUnlock, log, indent); + sKR = applyNewPassphrase(sKR, masterPublicKey, cryptoInput.getPassphrase(), + saveParcel.mNewUnlock.mNewPassphrase, log, indent); if (sKR == null) { // The error has been logged above, just return a bad state return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null); @@ -1191,76 +1191,6 @@ public class PgpKeyOperation { } - - private static PGPSecretKeyRing applyNewUnlock( - PGPSecretKeyRing sKR, - PGPPublicKey masterPublicKey, - PGPPrivateKey masterPrivateKey, - Passphrase passphrase, - ChangeUnlockParcel newUnlock, - OperationLog log, int indent) throws PGPException { - - if (newUnlock.mNewPassphrase != null) { - sKR = applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPassphrase, log, indent); - - // if there is any old packet with notation data - if (hasNotationData(sKR)) { - - log.add(LogType.MSG_MF_NOTATION_EMPTY, indent); - - // add packet with EMPTY notation data (updates old one, but will be stripped later) - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPrivateKey.getPublicKeyPacket().getAlgorithm(), - PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - { // set subpackets - PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); - hashedPacketsGen.setExportable(false, false); - sGen.setHashedSubpackets(hashedPacketsGen.generate()); - } - sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey); - PGPSignature emptySig = sGen.generateCertification(masterPublicKey); - - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig); - sKR = PGPSecretKeyRing.insertSecretKey(sKR, - PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey)); - } - - return sKR; - } - - if (newUnlock.mNewPin != null) { - sKR = applyNewPassphrase(sKR, masterPublicKey, passphrase, newUnlock.mNewPin, log, indent); - - log.add(LogType.MSG_MF_NOTATION_PIN, indent); - - // add packet with "pin" notation data - PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( - masterPrivateKey.getPublicKeyPacket().getAlgorithm(), - PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); - { // set subpackets - PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); - hashedPacketsGen.setExportable(false, false); - hashedPacketsGen.setNotationData(false, true, "unlock.pin@sufficientlysecure.org", "1"); - sGen.setHashedSubpackets(hashedPacketsGen.generate()); - } - sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey); - PGPSignature emptySig = sGen.generateCertification(masterPublicKey); - - masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig); - sKR = PGPSecretKeyRing.insertSecretKey(sKR, - PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey)); - - return sKR; - } - - throw new UnsupportedOperationException("PIN passphrases not yet implemented!"); - - } - /** This method returns true iff the provided keyring has a local direct key signature * with notation data. */ @@ -1294,8 +1224,7 @@ public class PgpKeyOperation { PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(newPassphrase.getCharArray()); - // noinspection unchecked - for (PGPSecretKey sKey : new IterableIterator(sKR.getSecretKeys())) { + for (PGPSecretKey sKey : new IterableIterator<>(sKR.getSecretKeys())) { log.add(LogType.MSG_MF_PASSPHRASE_KEY, indent, KeyFormattingUtils.convertKeyIdToHex(sKey.getKeyID())); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java index d696b9d70..b0db36b06 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/UncachedKeyRing.java @@ -35,6 +35,8 @@ import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; +import android.support.annotation.VisibleForTesting; + import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.bcpg.SignatureSubpacketTags; @@ -42,15 +44,22 @@ import org.bouncycastle.bcpg.UserAttributeSubpacketTags; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.openpgp.PGPKeyRing; import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -1310,4 +1319,37 @@ public class UncachedKeyRing { || algorithm == PGPPublicKey.ECDH; } + // ONLY TO BE USED FOR TESTING!! + @VisibleForTesting + public static UncachedKeyRing forTestingOnlyAddDummyLocalSignature( + UncachedKeyRing uncachedKeyRing, String passphrase) throws Exception { + PGPSecretKeyRing sKR = (PGPSecretKeyRing) uncachedKeyRing.mRing; + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.toCharArray()); + PGPPrivateKey masterPrivateKey = sKR.getSecretKey().extractPrivateKey(keyDecryptor); + PGPPublicKey masterPublicKey = uncachedKeyRing.mRing.getPublicKey(); + + // add packet with "pin" notation data + PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder( + masterPrivateKey.getPublicKeyPacket().getAlgorithm(), + PgpSecurityConstants.SECRET_KEY_BINDING_SIGNATURE_HASH_ALGO) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator sGen = new PGPSignatureGenerator(signerBuilder); + { // set subpackets + PGPSignatureSubpacketGenerator hashedPacketsGen = new PGPSignatureSubpacketGenerator(); + hashedPacketsGen.setExportable(false, false); + hashedPacketsGen.setNotationData(false, true, "dummynotationdata", "some data"); + sGen.setHashedSubpackets(hashedPacketsGen.generate()); + } + sGen.init(PGPSignature.DIRECT_KEY, masterPrivateKey); + PGPSignature emptySig = sGen.generateCertification(masterPublicKey); + + masterPublicKey = PGPPublicKey.addCertification(masterPublicKey, emptySig); + sKR = PGPSecretKeyRing.insertSecretKey(sKR, + PGPSecretKey.replacePublicKey(sKR.getSecretKey(), masterPublicKey)); + + return new UncachedKeyRing(sKR); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java index 472eb3b18..dc892ecc8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java @@ -356,29 +356,21 @@ public class SaveKeyringParcel implements Parcelable { // The new passphrase to use public final Passphrase mNewPassphrase; - // A new pin to use. Must only contain [0-9]+ - public final Passphrase mNewPin; public ChangeUnlockParcel(Passphrase newPassphrase) { - this(newPassphrase, null); - } - public ChangeUnlockParcel(Passphrase newPassphrase, Passphrase newPin) { - if (newPassphrase == null && newPin == null) { - throw new RuntimeException("Cannot set both passphrase and pin. THIS IS A BUG!"); + if (newPassphrase == null) { + throw new AssertionError("newPassphrase must be non-null. THIS IS A BUG!"); } mNewPassphrase = newPassphrase; - mNewPin = newPin; } public ChangeUnlockParcel(Parcel source) { mNewPassphrase = source.readParcelable(Passphrase.class.getClassLoader()); - mNewPin = source.readParcelable(Passphrase.class.getClassLoader()); } @Override public void writeToParcel(Parcel destination, int flags) { destination.writeParcelable(mNewPassphrase, flags); - destination.writeParcelable(mNewPin, flags); } @Override @@ -397,9 +389,7 @@ public class SaveKeyringParcel implements Parcelable { }; public String toString() { - return mNewPassphrase != null - ? ("passphrase (" + mNewPassphrase + ")") - : ("pin (" + mNewPin + ")"); + return "passphrase (" + mNewPassphrase + ")"; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index b53bfc1d0..58a28da51 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -278,7 +278,7 @@ public class CreateKeyFinalFragment extends Fragment { 2048, null, KeyFlags.AUTHENTICATION, 0L)); // use empty passphrase - saveKeyringParcel.mNewUnlock = new ChangeUnlockParcel(new Passphrase(), null); + saveKeyringParcel.mNewUnlock = new ChangeUnlockParcel(new Passphrase()); } else { saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, 4096, null, KeyFlags.CERTIFY_OTHER, 0L)); @@ -288,7 +288,7 @@ public class CreateKeyFinalFragment extends Fragment { 4096, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); saveKeyringParcel.mNewUnlock = createKeyActivity.mPassphrase != null - ? new ChangeUnlockParcel(createKeyActivity.mPassphrase, null) + ? new ChangeUnlockParcel(createKeyActivity.mPassphrase) : null; } String userId = KeyRing.createUserId( diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 2d94d0d93..2184f91f1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -339,8 +339,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment Date: Wed, 23 Mar 2016 17:49:35 +0100 Subject: fix build instructions in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d7a07e232..1c61e3fcf 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Development mailinglist at https://lists.riseup.net/www/subscribe/openkeychain 3. Have Android SDK "tools", "platform-tools", and "build-tools" directories in your PATH (http://developer.android.com/sdk/index.html) 4. Open the Android SDK Manager (shell command: ``android``). Expand the Tools directory and select "Android SDK Build-tools (Version 23.0.1)". -Expand the Extras directory and install "Android Support Repository" +Expand the Extras directory and install "Android Support Library", as well as "Local Maven repository for Support Libraries" Select SDK Platform for API levels 21, 22, and 23. 5. Export ANDROID_HOME pointing to your Android SDK 6. Execute ``./gradlew assembleFdroidDebug`` -- cgit v1.2.3 From 4c61b4c892f70859e2178fc173b00a48d9ff209c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 23 Mar 2016 22:46:25 +0100 Subject: use new TokenAutoComplete 2.0.7, fixes #1636 --- OpenKeychain/build.gradle | 4 ++-- .../keychain/ui/EncryptModeAsymmetricFragment.java | 3 --- .../org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java | 8 -------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 95332f7af..3eeeb9503 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -49,7 +49,7 @@ dependencies { compile 'com.getbase:floatingactionbutton:1.10.1' compile 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.0' compile 'org.ocpsoft.prettytime:prettytime:4.0.1.Final' - compile 'com.splitwise:tokenautocomplete:2.0.5@aar' + compile 'com.splitwise:tokenautocomplete:2.0.7@aar' compile 'com.github.pinball83:masked-edittext:1.0.3' compile 'se.emilsjolander:stickylistheaders:2.7.0' compile 'org.sufficientlysecure:html-textview:1.3' @@ -100,7 +100,7 @@ dependencyVerification { 'com.getbase:floatingactionbutton:3edefa511aac4d90794c7b0496aca59cff2eee1e32679247b4f85acbeee05240', 'org.commonjava.googlecode.markdown4j:markdown4j:e952e825d29e1317d96f79f346bfb6786c7c5eef50bd26e54a80823704b62e13', 'org.ocpsoft.prettytime:prettytime:ef7098d973ae78b57d1a22dc37d3b8a771bf030301300e24055d676b6cdc5e75', - 'com.splitwise:tokenautocomplete:f86b8cd80e8fa1336f47d86b8ce862e1a40bdc8e206ac38c56c8e41a3d05a331', + 'com.splitwise:tokenautocomplete:f56239588390f103b270b7c12361d99b06313a5a0410dc7f66e241ac4baf9baa', 'com.github.pinball83:masked-edittext:b1913d86482c7066ebb7831696773ac131865dc441cf8a3fc41d3b7d5691724e', 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'org.sufficientlysecure:donations:96f8197bab26dfe41900d824f10f8f1914519cd62eedb77bdac5b223eccdf0a6', diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java index ca5d20fb9..b2b85ec14 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java @@ -79,9 +79,6 @@ public class EncryptModeAsymmetricFragment extends EncryptModeFragment { mSignKeySpinner = (KeySpinner) view.findViewById(R.id.sign); mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list); mEncryptKeyView.setThreshold(1); // Start working from first character - // TODO: workaround for bug in TokenAutoComplete, - // see https://github.com/open-keychain/open-keychain/issues/1636 - mEncryptKeyView.setDeletionStyle(TokenCompleteTextView.TokenDeleteStyle.ToString); final ViewAnimator vSignatureIcon = (ViewAnimator) view.findViewById(R.id.result_signature_icon); mSignKeySpinner.setOnKeyChangedListener(new OnKeyChangedListener() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java index fb72a263e..4a68c55fe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java @@ -333,14 +333,6 @@ public class KeyAdapter extends CursorAdapter { return mUserId.email; } } - - // TODO: workaround for bug in TokenAutoComplete, - // see https://github.com/open-keychain/open-keychain/issues/1636 - @Override - public String toString() { - return " "; - } - } public static String[] getProjectionWith(String[] projection) { -- cgit v1.2.3 From 298f89d36e5239f272709b6ec86e4b4b5d29b2a6 Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Thu, 24 Mar 2016 00:54:28 +0100 Subject: upgrade of Redirect import activity -> RedirectImportActivity is transparent now -> some poinlessly data removed -> String moved into sources -> xml for activity simplified --- OpenKeychain/src/main/AndroidManifest.xml | 3 +- .../keychain/ui/RedirectImportKeysActivity.java | 51 ++++++++------- .../res/layout/redirect_import_keys_activity.xml | 73 +--------------------- OpenKeychain/src/main/res/values/dimens.xml | 2 - OpenKeychain/src/main/res/values/strings.xml | 7 ++- 5 files changed, 38 insertions(+), 98 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index 8031606fb..f44e184a8 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -718,7 +718,8 @@ > + android:label="@string/title_activity_redirect_key" + android:theme="@android:style/Theme.Translucent"> diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java index a59d3ba80..d32981c60 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -1,27 +1,26 @@ /* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ package org.sufficientlysecure.keychain.ui; -import android.app.Activity; - import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AlertDialog; +import android.view.Window; + import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.base.BaseActivity; @@ -29,21 +28,32 @@ public class RedirectImportKeysActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); + setContentView(R.layout.redirect_import_keys_activity); + + startScanActivity(); + } + + @Override + protected void initLayout() { + + } - setFullScreenDialogClose(Activity.RESULT_CANCELED, true); + private void startScanActivity() { final Intent intent = new Intent(this, org.sufficientlysecure.keychain.ui.ImportKeysActivity.class); new AlertDialog.Builder(this) - .setTitle("Import key attempt") - .setMessage("You scanned a fingerprint with another app, please scan with Openkeychain directly to be safe" ) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + .setTitle(R.string.redirect_import_key_title) + .setMessage(R.string.redirect_import_key_message) + .setPositiveButton(R.string.redirect_import_key_yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // intent directly to ImportKeyChain activity startActivity(intent); + finish(); } }) - .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + .setNegativeButton(R.string.redirect_import_key_no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // close window finish(); @@ -52,9 +62,4 @@ public class RedirectImportKeysActivity extends BaseActivity { .setIcon(android.R.drawable.ic_dialog_alert) .show(); } - - @Override - protected void initLayout() { - setContentView(R.layout.redirect_import_keys_activity); - } } \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml b/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml index 2f63d143d..af9a8add6 100644 --- a/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml +++ b/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml @@ -1,73 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="match_parent"> diff --git a/OpenKeychain/src/main/res/values/dimens.xml b/OpenKeychain/src/main/res/values/dimens.xml index 254dc02bb..2630c407f 100644 --- a/OpenKeychain/src/main/res/values/dimens.xml +++ b/OpenKeychain/src/main/res/values/dimens.xml @@ -5,7 +5,5 @@ 120dp 222dp 0dp - - 16dp 16dp \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index acc0c7f20..95e089275 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1740,6 +1740,9 @@ 50 EUR 100 EUR - RedirectKeyActivity - Settings + "Import key attempt" + "You scanned a fingerprint with another app, please scan with Openkeychain directly to be safe" + Scan again + Close + Key import redirection -- cgit v1.2.3 From 4b6df7d17c6eae43b1db5f858d925103258f207e Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Thu, 24 Mar 2016 19:40:18 +0530 Subject: change sync interval on change in code --- .../keychain/KeychainApplication.java | 5 ++++ .../service/KeyserverSyncAdapterService.java | 31 +++++++++++++++++----- .../keychain/ui/SettingsActivity.java | 16 ++++++++--- .../keychain/util/Preferences.java | 23 ++++++++++++++-- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java index e1f61a5ef..2f0ebe904 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/KeychainApplication.java @@ -100,6 +100,11 @@ public class KeychainApplication extends Application { // Add OpenKeychain account to Android to link contacts with keys and keyserver sync createAccountIfNecessary(this); + if (Preferences.getKeyserverSyncEnabled(this)) { + // will update a keyserver sync if the interval has changed + KeyserverSyncAdapterService.enableKeyserverSync(this); + } + // if first time, enable keyserver and contact sync if (Preferences.getPreferences(this).isFirstTime()) { KeyserverSyncAdapterService.enableKeyserverSync(this); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java index f92c0d229..b71fbada8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeyserverSyncAdapterService.java @@ -11,6 +11,7 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.PeriodicSync; import android.content.SyncResult; import android.database.Cursor; import android.graphics.Bitmap; @@ -529,6 +530,10 @@ public class KeyserverSyncAdapterService extends Service { return builder.build(); } + /** + * creates a new sync if one does not exist, or updates an existing sync if the sync interval + * has changed. + */ public static void enableKeyserverSync(Context context) { Account account = KeychainApplication.createAccountIfNecessary(context); @@ -539,12 +544,26 @@ public class KeyserverSyncAdapterService extends Service { ContentResolver.setIsSyncable(account, Constants.PROVIDER_AUTHORITY, 1); ContentResolver.setSyncAutomatically(account, Constants.PROVIDER_AUTHORITY, true); - ContentResolver.addPeriodicSync( - account, - Constants.PROVIDER_AUTHORITY, - new Bundle(), - SYNC_INTERVAL - ); + + boolean intervalChanged = false; + boolean syncExists = Preferences.getKeyserverSyncEnabled(context); + + if (syncExists) { + long oldInterval = ContentResolver.getPeriodicSyncs( + account, Constants.PROVIDER_AUTHORITY).get(0).period; + if (oldInterval != SYNC_INTERVAL) { + intervalChanged = true; + } + } + + if (!syncExists || intervalChanged) { + ContentResolver.addPeriodicSync( + account, + Constants.PROVIDER_AUTHORITY, + new Bundle(), + SYNC_INTERVAL + ); + } } private boolean isSyncEnabled() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java index a01637d84..4fd327c8f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SettingsActivity.java @@ -47,6 +47,7 @@ import android.view.ViewGroup; import android.widget.LinearLayout; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.KeychainApplication; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.AppCompatPreferenceActivity; import org.sufficientlysecure.keychain.service.ContactSyncAdapterService; @@ -422,8 +423,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity { super.onResume(); // this needs to be done in onResume since the user can change sync values from Android // settings and we need to reflect that change when the user navigates back - AccountManager manager = AccountManager.get(getActivity()); - final Account account = manager.getAccountsByType(Constants.ACCOUNT_TYPE)[0]; + final Account account = KeychainApplication.createAccountIfNecessary(getActivity()); // for keyserver sync initializeSyncCheckBox( (SwitchPreference) findPreference(Constants.Pref.SYNC_KEYSERVER), @@ -441,8 +441,11 @@ public class SettingsActivity extends AppCompatPreferenceActivity { private void initializeSyncCheckBox(final SwitchPreference syncCheckBox, final Account account, final String authority) { - boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority) - && checkContactsPermission(authority); + // account is null if it could not be created for some reason + boolean syncEnabled = + account != null + && ContentResolver.getSyncAutomatically(account, authority) + && checkContactsPermission(authority); syncCheckBox.setChecked(syncEnabled); setSummary(syncCheckBox, authority, syncEnabled); @@ -464,6 +467,11 @@ public class SettingsActivity extends AppCompatPreferenceActivity { return false; } } else { + if (account == null) { + // if account could not be created for some reason, + // we can't have our sync + return false; + } // disable syncs ContentResolver.setSyncAutomatically(account, authority, false); // immediately delete any linked contacts diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java index e0e50abf7..5f53845d8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Preferences.java @@ -19,7 +19,9 @@ package org.sufficientlysecure.keychain.util; +import android.accounts.Account; import android.annotation.SuppressLint; +import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; import android.os.Parcel; @@ -29,6 +31,7 @@ import android.support.annotation.NonNull; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants.Pref; +import org.sufficientlysecure.keychain.KeychainApplication; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.service.KeyserverSyncAdapterService; @@ -76,9 +79,8 @@ public class Preferences { /** * Makes android's preference framework write to our file instead of default. - * This allows us to use the "persistent" attribute to simplify code, which automatically + * This allows us to use the xml "persistent" attribute to simplify code, which automatically * writes and reads preference values. - * @param manager */ public static void setPreferenceManagerFileAndMode(PreferenceManager manager) { manager.setSharedPreferencesName(PREF_FILE_NAME); @@ -302,6 +304,23 @@ public class Preferences { } + /** + * @return true if a periodic sync exists and is set to run automatically, false otherwise + */ + public static boolean getKeyserverSyncEnabled(Context context) { + Account account = KeychainApplication.createAccountIfNecessary(context); + + if (account == null) { + // if the account could not be created for some reason, we can't have a sync + return false; + } + + String authority = Constants.PROVIDER_AUTHORITY; + + return ContentResolver.getSyncAutomatically(account, authority) && + !ContentResolver.getPeriodicSyncs(account, authority).isEmpty(); + } + public CacheTTLPrefs getPassphraseCacheTtl() { Set pref = mSharedPreferences.getStringSet(Constants.Pref.PASSPHRASE_CACHE_TTLS, null); if (pref == null) { -- cgit v1.2.3 From 05da8afad94ffa5f7c773e5bc0c6304b517e5419 Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Thu, 24 Mar 2016 19:45:59 +0100 Subject: Theme change Theme.Keychain.Transparet is used --- OpenKeychain/src/main/AndroidManifest.xml | 2 +- .../org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index f44e184a8..8fa5f52c4 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -719,7 +719,7 @@ android:name=".ui.RedirectImportKeysActivity" android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:label="@string/title_activity_redirect_key" - android:theme="@android:style/Theme.Translucent"> + android:theme="@style/Theme.Keychain.Transparent"> diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java index d32981c60..1f6a62f47 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -28,7 +28,6 @@ public class RedirectImportKeysActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { - requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); setContentView(R.layout.redirect_import_keys_activity); -- cgit v1.2.3 From 360b5a658a412d9402a5fc9ea204329c91d306c3 Mon Sep 17 00:00:00 2001 From: Andrea Torlaschi Date: Fri, 11 Mar 2016 00:50:11 +0100 Subject: Handle encrypted files while importing keys --- .../keychain/ui/ImportKeysActivity.java | 15 ++- .../keychain/ui/ImportKeysFileFragment.java | 103 +++++++++++++++++++-- .../keychain/util/FileHelper.java | 27 ++++++ OpenKeychain/src/main/res/values/strings.xml | 1 + 4 files changed, 136 insertions(+), 10 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 72e42eec3..7d2d30c35 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -416,11 +416,18 @@ public class ImportKeysActivity extends BaseActivity intent.putExtra(ImportKeyResult.EXTRA_RESULT, result); setResult(RESULT_OK, intent); finish(); - return; + } else if (result.isOkNew() || result.isOkUpdated()) { + // User has successfully imported a key, hide first time dialog + Preferences.getPreferences(this).setFirstTime(false); + + // Close activities opened for importing keys and go to the list of keys + Intent intent = new Intent(this, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + } else { + result.createNotify(ImportKeysActivity.this) + .show((ViewGroup) findViewById(R.id.import_snackbar)); } - - result.createNotify(ImportKeysActivity.this) - .show((ViewGroup) findViewById(R.id.import_snackbar)); } // methods from CryptoOperationHelper.Callback diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index 8de60dfd3..133cf299f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -17,29 +17,46 @@ package org.sufficientlysecure.keychain.ui; +import android.Manifest; import android.app.Activity; +import android.content.ContentResolver; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.pgp.PgpHelper; +import org.sufficientlysecure.keychain.ui.ImportKeysListFragment.BytesLoaderState; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.util.FileHelper; +import org.sufficientlysecure.keychain.util.Log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; public class ImportKeysFileFragment extends Fragment { private ImportKeysActivity mImportActivity; private View mBrowse; private View mClipboardButton; - public static final int REQUEST_CODE_FILE = 0x00007003; + private Uri mCurrentUri; + + private static final int REQUEST_CODE_FILE = 0x00007003; + private static final int REQUEST_PERMISSION_READ_EXTERNAL_STORAGE = 12; /** * Creates new instance of this fragment @@ -83,10 +100,10 @@ public class ImportKeysFileFragment extends Fragment { sendText = clipboardText.toString(); sendText = PgpHelper.getPgpKeyContent(sendText); if (sendText == null) { - Notify.create(mImportActivity, "Bad data!", Style.ERROR).show(); + Notify.create(mImportActivity, R.string.error_bad_data, Style.ERROR).show(); return; } - mImportActivity.loadCallback(new ImportKeysListFragment.BytesLoaderState(sendText.getBytes(), null)); + mImportActivity.loadCallback(new BytesLoaderState(sendText.getBytes(), null)); } } }); @@ -106,11 +123,12 @@ public class ImportKeysFileFragment extends Fragment { switch (requestCode) { case REQUEST_CODE_FILE: { if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) { + mCurrentUri = data.getData(); - // load data - mImportActivity.loadCallback(new ImportKeysListFragment.BytesLoaderState(null, data.getData())); + if (checkAndRequestReadPermission(mCurrentUri)) { + startImportingKeys(); + } } - break; } @@ -121,4 +139,77 @@ public class ImportKeysFileFragment extends Fragment { } } + private void startImportingKeys() { + boolean isEncrypted; + try { + isEncrypted = FileHelper.isEncryptedFile(mImportActivity, mCurrentUri); + } catch (IOException e) { + Log.e(Constants.TAG, "Error opening file", e); + + Notify.create(mImportActivity, R.string.error_bad_data, Style.ERROR).show(); + return; + } + + if (isEncrypted) { + Intent intent = new Intent(mImportActivity, DecryptActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(mCurrentUri); + startActivity(intent); + } else { + mImportActivity.loadCallback(new BytesLoaderState(null, mCurrentUri)); + } + } + + /** + * Request READ_EXTERNAL_STORAGE permission on Android >= 6.0 to read content from "file" Uris. + *

+ * This method returns true on Android < 6, or if permission is already granted. It + * requests the permission and returns false otherwise. + *

+ * see https://commonsware.com/blog/2015/10/07/runtime-permissions-files-action-send.html + */ + private boolean checkAndRequestReadPermission(final Uri uri) { + if (!ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { + return true; + } + + // Additional check due to https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return true; + } + + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED) { + return true; + } + + requestPermissions( + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + REQUEST_PERMISSION_READ_EXTERNAL_STORAGE); + + return false; + } + + @Override + public void onRequestPermissionsResult(int requestCode, + @NonNull String[] permissions, + @NonNull int[] grantResults) { + + if (requestCode != REQUEST_PERMISSION_READ_EXTERNAL_STORAGE) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + return; + } + + boolean permissionWasGranted = grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED; + + if (permissionWasGranted) { + startImportingKeys(); + } else { + Toast.makeText(getActivity(), R.string.error_denied_storage_permission, Toast.LENGTH_LONG).show(); + getActivity().setResult(Activity.RESULT_CANCELED); + getActivity().finish(); + } + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileHelper.java index 106775201..62dd87baa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/FileHelper.java @@ -20,11 +20,13 @@ package org.sufficientlysecure.keychain.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.SecureRandom; @@ -223,6 +225,31 @@ public class FileHelper { } } + public static boolean isEncryptedFile(Context context, Uri uri) throws IOException { + boolean isEncrypted = false; + + BufferedReader br = null; + try { + InputStream is = context.getContentResolver().openInputStream(uri); + br = new BufferedReader(new InputStreamReader(is)); + + String header = "-----BEGIN PGP MESSAGE-----"; + int length = header.length(); + char[] buffer = new char[length]; + if (br.read(buffer, 0, length) == length) { + isEncrypted = new String(buffer).equals(header); + } + } finally { + try { + if (br != null) + br.close(); + } catch (IOException e) { + Log.e(Constants.TAG, "Error closing file", e); + } + } + return isEncrypted; + } + public static String readableFileSize(long size) { if (size <= 0) return "0"; final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"}; diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index c8a07c8ef..f9838ba72 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -359,6 +359,7 @@ "have not been deleted. Delete them manually!" %s has already been added. "file not found" + "Bad data!" "no suitable secret key found" "external storage not ready" "key size must be at least 512bit" -- cgit v1.2.3 From 0f716f7b9f3a3a820723415a2351b883f320874a Mon Sep 17 00:00:00 2001 From: Durgesh <007durgesh219@gmail.com> Date: Mon, 7 Mar 2016 16:03:52 +0530 Subject: Display Key moved to Fragment Signed-off-by: Durgesh <007durgesh219@gmail.com> --- .../keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/CertifyKeyFragment.java | 176 +---------------- .../keychain/ui/MultiUserIdsFragment.java | 217 +++++++++++++++++++++ .../src/main/res/layout/certify_key_fragment.xml | 5 +- .../main/res/layout/multi_user_ids_fragment.xml | 6 + 5 files changed, 233 insertions(+), 173 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java create mode 100644 OpenKeychain/src/main/res/layout/multi_user_ids_fragment.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 3845e07cb..32da02efe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -28,7 +28,7 @@ import org.sufficientlysecure.keychain.ui.base.BaseActivity; public class CertifyKeyActivity extends BaseActivity { public static final String EXTRA_RESULT = "operation_result"; - public static final String EXTRA_KEY_IDS = "extra_key_ids"; + public static final String EXTRA_KEY_IDS = MultiUserIdsFragment.EXTRA_KEY_IDS ; public static final String EXTRA_CERTIFY_KEY_ID = "certify_key_id"; @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 357b445f0..22cfabcc9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -62,52 +62,19 @@ import java.util.ArrayList; import java.util.Date; public class CertifyKeyFragment - extends CachingCryptoOperationFragment - implements LoaderManager.LoaderCallbacks { - - public static final String ARG_CHECK_STATES = "check_states"; + extends CachingCryptoOperationFragment { private CheckBox mUploadKeyCheckbox; - ListView mUserIds; private CertifyKeySpinner mCertifyKeySpinner; - private long[] mPubMasterKeyIds; - - public static final String[] USER_IDS_PROJECTION = new String[]{ - UserPackets._ID, - UserPackets.MASTER_KEY_ID, - UserPackets.USER_ID, - UserPackets.IS_PRIMARY, - UserPackets.IS_REVOKED - }; - private static final int INDEX_MASTER_KEY_ID = 1; - private static final int INDEX_USER_ID = 2; - @SuppressWarnings("unused") - private static final int INDEX_IS_PRIMARY = 3; - @SuppressWarnings("unused") - private static final int INDEX_IS_REVOKED = 4; - - private MultiUserIdsAdapter mUserIdsAdapter; + private MultiUserIdsFragment mMultiUserIdsFragment; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mPubMasterKeyIds = getActivity().getIntent().getLongArrayExtra(CertifyKeyActivity.EXTRA_KEY_IDS); - if (mPubMasterKeyIds == null) { - Log.e(Constants.TAG, "List of key ids to certify missing!"); - getActivity().finish(); - return; - } - - ArrayList checkedStates; - if (savedInstanceState != null) { - checkedStates = (ArrayList) savedInstanceState.getSerializable(ARG_CHECK_STATES); - // key spinner and the checkbox keep their own state - } else { - checkedStates = null; - + if (savedInstanceState == null){ // preselect certify key id if given long certifyKeyId = getActivity().getIntent() .getLongExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, Constants.key.none); @@ -124,12 +91,6 @@ public class CertifyKeyFragment } - mUserIdsAdapter = new MultiUserIdsAdapter(getActivity(), null, 0, checkedStates); - mUserIds.setAdapter(mUserIdsAdapter); - mUserIds.setDividerHeight(0); - - getLoaderManager().initLoader(0, null, this); - OperationResult result = getActivity().getIntent().getParcelableExtra(CertifyKeyActivity.EXTRA_RESULT); if (result != null) { // display result from import @@ -137,22 +98,14 @@ public class CertifyKeyFragment } } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - ArrayList states = mUserIdsAdapter.getCheckStates(); - // no proper parceling method available :( - outState.putSerializable(ARG_CHECK_STATES, states); - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.certify_key_fragment, null); mCertifyKeySpinner = (CertifyKeySpinner) view.findViewById(R.id.certify_key_spinner); mUploadKeyCheckbox = (CheckBox) view.findViewById(R.id.sign_key_upload_checkbox); - mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids); + mMultiUserIdsFragment = (MultiUserIdsFragment) + getChildFragmentManager().findFragmentById(R.id.multi_user_ids_fragment); // make certify image gray, like action icons ImageView vActionCertifyImage = @@ -183,128 +136,11 @@ public class CertifyKeyFragment return view; } - @Override - public Loader onCreateLoader(int id, Bundle args) { - Uri uri = UserPackets.buildUserIdsUri(); - - String selection, ids[]; - { - // generate placeholders and string selection args - ids = new String[mPubMasterKeyIds.length]; - StringBuilder placeholders = new StringBuilder("?"); - for (int i = 0; i < mPubMasterKeyIds.length; i++) { - ids[i] = Long.toString(mPubMasterKeyIds[i]); - if (i != 0) { - placeholders.append(",?"); - } - } - // put together selection string - selection = UserPackets.IS_REVOKED + " = 0" + " AND " - + Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID - + " IN (" + placeholders + ")"; - } - - return new CursorLoader(getActivity(), uri, - USER_IDS_PROJECTION, selection, ids, - Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " ASC" - + ", " + Tables.USER_PACKETS + "." + UserPackets.USER_ID + " ASC" - ); - } - - @Override - public void onLoadFinished(Loader loader, Cursor data) { - - MatrixCursor matrix = new MatrixCursor(new String[]{ - "_id", "user_data", "grouped" - }) { - @Override - public byte[] getBlob(int column) { - return super.getBlob(column); - } - }; - data.moveToFirst(); - - long lastMasterKeyId = 0; - String lastName = ""; - ArrayList uids = new ArrayList<>(); - - boolean header = true; - - // Iterate over all rows - while (!data.isAfterLast()) { - long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); - String userId = data.getString(INDEX_USER_ID); - KeyRing.UserId pieces = KeyRing.splitUserId(userId); - - // Two cases: - - boolean grouped = masterKeyId == lastMasterKeyId; - boolean subGrouped = data.isFirst() || grouped && lastName.equals(pieces.name); - // Remember for next loop - lastName = pieces.name; - - Log.d(Constants.TAG, Long.toString(masterKeyId, 16) + (grouped ? "grouped" : "not grouped")); - - if (!subGrouped) { - // 1. This name should NOT be grouped with the previous, so we flush the buffer - - Parcel p = Parcel.obtain(); - p.writeStringList(uids); - byte[] d = p.marshall(); - p.recycle(); - - matrix.addRow(new Object[]{ - lastMasterKeyId, d, header ? 1 : 0 - }); - // indicate that we have a header for this masterKeyId - header = false; - - // Now clear the buffer, and add the new user id, for the next round - uids.clear(); - - } - - // 2. This name should be grouped with the previous, just add to buffer - uids.add(userId); - lastMasterKeyId = masterKeyId; - - // If this one wasn't grouped, the next one's gotta be a header - if (!grouped) { - header = true; - } - - // Regardless of the outcome, move to next entry - data.moveToNext(); - - } - - // If there is anything left in the buffer, flush it one last time - if (!uids.isEmpty()) { - - Parcel p = Parcel.obtain(); - p.writeStringList(uids); - byte[] d = p.marshall(); - p.recycle(); - - matrix.addRow(new Object[]{ - lastMasterKeyId, d, header ? 1 : 0 - }); - - } - - mUserIdsAdapter.swapCursor(matrix); - } - - @Override - public void onLoaderReset(Loader loader) { - mUserIdsAdapter.swapCursor(null); - } - @Override public CertifyActionsParcel createOperationInput() { // Bail out if there is not at least one user id selected - ArrayList certifyActions = mUserIdsAdapter.getSelectedCertifyActions(); + ArrayList certifyActions = mMultiUserIdsFragment.getSelectedCertifyActions(); if (certifyActions.isEmpty()) { Notify.create(getActivity(), "No identities selected!", Notify.Style.ERROR).show(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java new file mode 100644 index 000000000..b61ec79ee --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java @@ -0,0 +1,217 @@ +package org.sufficientlysecure.keychain.ui; + +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.Parcel; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainDatabase; +import org.sufficientlysecure.keychain.service.CertifyActionsParcel; +import org.sufficientlysecure.keychain.ui.adapter.MultiUserIdsAdapter; +import org.sufficientlysecure.keychain.util.Log; + +import java.util.ArrayList; + +/** + * Created by durgeshchoudhary on 07/03/16. + */ +public class MultiUserIdsFragment extends Fragment implements LoaderManager.LoaderCallbacks{ + public static final String ARG_CHECK_STATES = "check_states"; + public static final String EXTRA_KEY_IDS = "extra_key_ids"; + + ListView mUserIds; + private MultiUserIdsAdapter mUserIdsAdapter; + + private long[] mPubMasterKeyIds; + + public static final String[] USER_IDS_PROJECTION = new String[]{ + KeychainContract.UserPackets._ID, + KeychainContract.UserPackets.MASTER_KEY_ID, + KeychainContract.UserPackets.USER_ID, + KeychainContract.UserPackets.IS_PRIMARY, + KeychainContract.UserPackets.IS_REVOKED + }; + private static final int INDEX_MASTER_KEY_ID = 1; + private static final int INDEX_USER_ID = 2; + @SuppressWarnings("unused") + private static final int INDEX_IS_PRIMARY = 3; + @SuppressWarnings("unused") + private static final int INDEX_IS_REVOKED = 4; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.multi_user_ids_fragment, null); + + mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids); + + return view; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mPubMasterKeyIds = getActivity().getIntent().getLongArrayExtra(EXTRA_KEY_IDS); + if (mPubMasterKeyIds == null) { + Log.e(Constants.TAG, "List of key ids to certify missing!"); + getActivity().finish(); + return; + } + + ArrayList checkedStates = null; + if (savedInstanceState != null) { + checkedStates = (ArrayList) savedInstanceState.getSerializable(ARG_CHECK_STATES); + } + + mUserIdsAdapter = new MultiUserIdsAdapter(getActivity(), null, 0, checkedStates); + mUserIds.setAdapter(mUserIdsAdapter); + mUserIds.setDividerHeight(0); + + getLoaderManager().initLoader(0, null, this); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + ArrayList states = mUserIdsAdapter.getCheckStates(); + // no proper parceling method available :( + outState.putSerializable(ARG_CHECK_STATES, states); + } + + public ArrayList getSelectedCertifyActions() { + return mUserIdsAdapter.getSelectedCertifyActions(); + } + + @Override + public Loader onCreateLoader(int id, Bundle args) { + Uri uri = KeychainContract.UserPackets.buildUserIdsUri(); + + String selection, ids[]; + { + // generate placeholders and string selection args + ids = new String[mPubMasterKeyIds.length]; + StringBuilder placeholders = new StringBuilder("?"); + for (int i = 0; i < mPubMasterKeyIds.length; i++) { + ids[i] = Long.toString(mPubMasterKeyIds[i]); + if (i != 0) { + placeholders.append(",?"); + } + } + // put together selection string + selection = KeychainContract.UserPackets.IS_REVOKED + " = 0" + " AND " + + KeychainDatabase.Tables.USER_PACKETS + "." + KeychainContract.UserPackets.MASTER_KEY_ID + + " IN (" + placeholders + ")"; + } + + return new CursorLoader(getActivity(), uri, + USER_IDS_PROJECTION, selection, ids, + KeychainDatabase.Tables.USER_PACKETS + "." + KeychainContract.UserPackets.MASTER_KEY_ID + " ASC" + + ", " + KeychainDatabase.Tables.USER_PACKETS + "." + KeychainContract.UserPackets.USER_ID + " ASC" + ); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + + MatrixCursor matrix = new MatrixCursor(new String[]{ + "_id", "user_data", "grouped" + }) { + @Override + public byte[] getBlob(int column) { + return super.getBlob(column); + } + }; + data.moveToFirst(); + + long lastMasterKeyId = 0; + String lastName = ""; + ArrayList uids = new ArrayList<>(); + + boolean header = true; + + // Iterate over all rows + while (!data.isAfterLast()) { + long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); + String userId = data.getString(INDEX_USER_ID); + KeyRing.UserId pieces = KeyRing.splitUserId(userId); + + // Two cases: + + boolean grouped = masterKeyId == lastMasterKeyId; + boolean subGrouped = data.isFirst() || grouped && lastName.equals(pieces.name); + // Remember for next loop + lastName = pieces.name; + + Log.d(Constants.TAG, Long.toString(masterKeyId, 16) + (grouped ? "grouped" : "not grouped")); + + if (!subGrouped) { + // 1. This name should NOT be grouped with the previous, so we flush the buffer + + Parcel p = Parcel.obtain(); + p.writeStringList(uids); + byte[] d = p.marshall(); + p.recycle(); + + matrix.addRow(new Object[]{ + lastMasterKeyId, d, header ? 1 : 0 + }); + // indicate that we have a header for this masterKeyId + header = false; + + // Now clear the buffer, and add the new user id, for the next round + uids.clear(); + + } + + // 2. This name should be grouped with the previous, just add to buffer + uids.add(userId); + lastMasterKeyId = masterKeyId; + + // If this one wasn't grouped, the next one's gotta be a header + if (!grouped) { + header = true; + } + + // Regardless of the outcome, move to next entry + data.moveToNext(); + + } + + // If there is anything left in the buffer, flush it one last time + if (!uids.isEmpty()) { + + Parcel p = Parcel.obtain(); + p.writeStringList(uids); + byte[] d = p.marshall(); + p.recycle(); + + matrix.addRow(new Object[]{ + lastMasterKeyId, d, header ? 1 : 0 + }); + + } + + mUserIdsAdapter.swapCursor(matrix); + } + + @Override + public void onLoaderReset(Loader loader) { + mUserIdsAdapter.swapCursor(null); + } +} diff --git a/OpenKeychain/src/main/res/layout/certify_key_fragment.xml b/OpenKeychain/src/main/res/layout/certify_key_fragment.xml index 23685ce15..01837240b 100644 --- a/OpenKeychain/src/main/res/layout/certify_key_fragment.xml +++ b/OpenKeychain/src/main/res/layout/certify_key_fragment.xml @@ -22,8 +22,9 @@ android:id="@+id/textView" android:layout_weight="1" /> - diff --git a/OpenKeychain/src/main/res/layout/multi_user_ids_fragment.xml b/OpenKeychain/src/main/res/layout/multi_user_ids_fragment.xml new file mode 100644 index 000000000..560934f50 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/multi_user_ids_fragment.xml @@ -0,0 +1,6 @@ + + -- cgit v1.2.3 From 8f4238df28bea3473fb1414f64ad959368575e28 Mon Sep 17 00:00:00 2001 From: Victor Hazali Date: Wed, 30 Mar 2016 04:21:33 +0800 Subject: Fixes #1298 --- .../main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 35c1615c7..6c96a40ba 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -32,6 +32,7 @@ import android.app.ActivityOptions; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; +import android.graphics.Color; import android.net.Uri; import android.nfc.NfcAdapter; import android.os.AsyncTask; @@ -923,6 +924,7 @@ public class ViewKeyActivity extends BaseSecurityTokenNfcActivity implements } mPhoto.setImageBitmap(photo); + mPhoto.setColorFilter(Color.argb(30, 120, 166, 69)); mPhotoLayout.setVisibility(View.VISIBLE); } }; -- cgit v1.2.3 From ce70568ff3f87e194ef1dd9ff04501610b7661db Mon Sep 17 00:00:00 2001 From: Victor Hazali Date: Wed, 30 Mar 2016 05:37:31 +0800 Subject: Extracted method --- .../ui/dialog/EditSubkeyDialogFragment.java | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java index c34312e79..ba8920d4f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java @@ -75,22 +75,7 @@ public class EditSubkeyDialogFragment extends DialogFragment { sendMessageToHandler(MESSAGE_REVOKE, null); break; case 2: - CustomAlertDialogBuilder stripAlertDialog = new CustomAlertDialogBuilder(getActivity()); - stripAlertDialog.setTitle(getResources().getString(R.string.title_alert_strip)). - setMessage(R.string.alert_strip).setCancelable(true); - stripAlertDialog.setPositiveButton(R.string.strip, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - sendMessageToHandler(MESSAGE_STRIP, null); - } - }); - stripAlertDialog.setNegativeButton(R.string.btn_do_not_save, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - dismiss(); - } - }); - stripAlertDialog.show(); + showAlertDialog(); break; case 3: sendMessageToHandler(MESSAGE_MOVE_KEY_TO_CARD, null); @@ -110,6 +95,25 @@ public class EditSubkeyDialogFragment extends DialogFragment { return builder.show(); } + private void showAlertDialog() { + CustomAlertDialogBuilder stripAlertDialog = new CustomAlertDialogBuilder(getActivity()); + stripAlertDialog.setTitle(getResources().getString(R.string.title_alert_strip)). + setMessage(R.string.alert_strip).setCancelable(true); + stripAlertDialog.setPositiveButton(R.string.strip, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + sendMessageToHandler(MESSAGE_STRIP, null); + } + }); + stripAlertDialog.setNegativeButton(R.string.btn_do_not_save, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + dismiss(); + } + }); + stripAlertDialog.show(); + } + /** * Send message back to handler which is initialized in a activity * -- cgit v1.2.3 From 5411963aff0ed017f949de5cdbcf9a83d0e2087a Mon Sep 17 00:00:00 2001 From: Victor Hazali Date: Wed, 30 Mar 2016 06:07:59 +0800 Subject: Refactored switch statements to use constants --- .../keychain/ui/dialog/EditSubkeyDialogFragment.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java index ba8920d4f..01decf2ef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java @@ -36,6 +36,10 @@ public class EditSubkeyDialogFragment extends DialogFragment { public static final int MESSAGE_REVOKE = 2; public static final int MESSAGE_STRIP = 3; public static final int MESSAGE_MOVE_KEY_TO_CARD = 4; + public static final int SUBKEY_MENU_CHANGE_EXPIRY = 0; + public static final int SUBKEY_MENU_REVOKE_SUBKEY = 1; + public static final int SUBKEY_MENU_STRIP_SUBKEY = 2; + public static final int SUBKEY_MENU_MOVE_TO_SECURITY_TOKEN = 3; private Messenger mMessenger; @@ -68,16 +72,16 @@ public class EditSubkeyDialogFragment extends DialogFragment { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { - case 0: + case SUBKEY_MENU_CHANGE_EXPIRY: sendMessageToHandler(MESSAGE_CHANGE_EXPIRY, null); break; - case 1: + case SUBKEY_MENU_REVOKE_SUBKEY: sendMessageToHandler(MESSAGE_REVOKE, null); break; - case 2: + case SUBKEY_MENU_STRIP_SUBKEY: showAlertDialog(); break; - case 3: + case SUBKEY_MENU_MOVE_TO_SECURITY_TOKEN: sendMessageToHandler(MESSAGE_MOVE_KEY_TO_CARD, null); break; default: @@ -98,7 +102,7 @@ public class EditSubkeyDialogFragment extends DialogFragment { private void showAlertDialog() { CustomAlertDialogBuilder stripAlertDialog = new CustomAlertDialogBuilder(getActivity()); stripAlertDialog.setTitle(getResources().getString(R.string.title_alert_strip)). - setMessage(R.string.alert_strip).setCancelable(true); + setMessage(R.string.alert_strip).setCancelable(true); stripAlertDialog.setPositiveButton(R.string.strip, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { -- cgit v1.2.3 From 705a55a7a3090024575c28a68658ff59e34e179d Mon Sep 17 00:00:00 2001 From: Victor Hazali Date: Wed, 30 Mar 2016 06:09:13 +0800 Subject: Corrected capitalisation of subkey --- OpenKeychain/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 23ac87841..9a21f95f7 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -40,7 +40,7 @@ "Advanced" "Delete YOUR key '%s'?" "Manage my keys" - "Strip this Subkey" + "Strip this subkey" "Identities" @@ -334,7 +334,7 @@ "Delete key '%s'?" "Also export secret keys" "You encountered a known bug with Android. Please reinstall OpenKeychain if you want to link your contacts with keys." - "Stripping this Subkey will render it useless." + "Stripping this subkey will render it useless." "Successfully exported 1 key." "Successfully exported %d keys." -- cgit v1.2.3 From 990948e3fbb52b879b517c18c06328e7d005d236 Mon Sep 17 00:00:00 2001 From: Durgesh <007durgesh219@gmail.com> Date: Mon, 7 Mar 2016 17:29:06 +0530 Subject: Fix Display Key in UploadKeyActivity, Issue #506 --- .../keychain/ui/CertifyKeyActivity.java | 1 + .../keychain/ui/CertifyKeyFragment.java | 6 +++--- .../keychain/ui/MultiUserIdsFragment.java | 14 ++++++++++---- .../keychain/ui/UploadKeyActivity.java | 21 +++++++-------------- .../keychain/ui/ViewKeyAdvShareFragment.java | 11 +++++++++++ .../keychain/ui/adapter/MultiUserIdsAdapter.java | 7 +++++++ OpenKeychain/src/main/res/layout/certify_item.xml | 2 -- .../src/main/res/layout/upload_key_activity.xml | 6 ++++++ 8 files changed, 45 insertions(+), 23 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 32da02efe..09149716c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -28,6 +28,7 @@ import org.sufficientlysecure.keychain.ui.base.BaseActivity; public class CertifyKeyActivity extends BaseActivity { public static final String EXTRA_RESULT = "operation_result"; + // For sending masterKeyIds to MultiUserIdsFragment to display list of keys public static final String EXTRA_KEY_IDS = MultiUserIdsFragment.EXTRA_KEY_IDS ; public static final String EXTRA_CERTIFY_KEY_ID = "certify_key_id"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 22cfabcc9..ad39ff43d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -74,13 +74,14 @@ public class CertifyKeyFragment public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - if (savedInstanceState == null){ + if (savedInstanceState == null) { // preselect certify key id if given long certifyKeyId = getActivity().getIntent() .getLongExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, Constants.key.none); if (certifyKeyId != Constants.key.none) { try { - CachedPublicKeyRing key = (new ProviderHelper(getActivity())).getCachedPublicKeyRing(certifyKeyId); + CachedPublicKeyRing key = (new ProviderHelper(getActivity())) + .getCachedPublicKeyRing(certifyKeyId); if (key.canCertify()) { mCertifyKeySpinner.setPreSelectedKeyId(certifyKeyId); } @@ -88,7 +89,6 @@ public class CertifyKeyFragment Log.e(Constants.TAG, "certify certify check failed", e); } } - } OperationResult result = getActivity().getIntent().getParcelableExtra(CertifyKeyActivity.EXTRA_RESULT); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java index b61ec79ee..8ba695cf7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MultiUserIdsFragment.java @@ -26,12 +26,10 @@ import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; -/** - * Created by durgeshchoudhary on 07/03/16. - */ public class MultiUserIdsFragment extends Fragment implements LoaderManager.LoaderCallbacks{ public static final String ARG_CHECK_STATES = "check_states"; public static final String EXTRA_KEY_IDS = "extra_key_ids"; + private boolean checkboxVisibility = true; ListView mUserIds; private MultiUserIdsAdapter mUserIdsAdapter; @@ -78,7 +76,7 @@ public class MultiUserIdsFragment extends Fragment implements LoaderManager.Load checkedStates = (ArrayList) savedInstanceState.getSerializable(ARG_CHECK_STATES); } - mUserIdsAdapter = new MultiUserIdsAdapter(getActivity(), null, 0, checkedStates); + mUserIdsAdapter = new MultiUserIdsAdapter(getActivity(), null, 0, checkedStates, checkboxVisibility); mUserIds.setAdapter(mUserIdsAdapter); mUserIds.setDividerHeight(0); @@ -95,6 +93,10 @@ public class MultiUserIdsFragment extends Fragment implements LoaderManager.Load } public ArrayList getSelectedCertifyActions() { + if (!checkboxVisibility) { + throw new AssertionError("Item selection not allowed"); + } + return mUserIdsAdapter.getSelectedCertifyActions(); } @@ -214,4 +216,8 @@ public class MultiUserIdsFragment extends Fragment implements LoaderManager.Load public void onLoaderReset(Loader loader) { mUserIdsAdapter.swapCursor(null); } + + public void setCheckboxVisibility(boolean checkboxVisibility) { + this.checkboxVisibility = checkboxVisibility; + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index f38e4928d..306b022c1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -31,10 +31,7 @@ import android.widget.Spinner; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.UploadResult; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.UploadKeyringParcel; import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; @@ -53,7 +50,6 @@ public class UploadKeyActivity extends BaseActivity // CryptoOperationHelper.Callback vars private String mKeyserver; - private long mMasterKeyId; private CryptoOperationHelper mUploadOpHelper; @Override @@ -63,6 +59,10 @@ public class UploadKeyActivity extends BaseActivity mUploadButton = findViewById(R.id.upload_key_action_upload); mKeyServerSpinner = (Spinner) findViewById(R.id.upload_key_keyserver); + MultiUserIdsFragment mMultiUserIdsFragment = (MultiUserIdsFragment) + getSupportFragmentManager().findFragmentById(R.id.multi_user_ids_fragment); + mMultiUserIdsFragment.setCheckboxVisibility(false); + ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, Preferences.getPreferences(this) .getKeyServers() @@ -89,15 +89,6 @@ public class UploadKeyActivity extends BaseActivity return; } - try { - mMasterKeyId = new ProviderHelper(this).getCachedPublicKeyRing( - KeyRings.buildUnifiedKeyRingUri(mDataUri)).getMasterKeyId(); - } catch (PgpKeyNotFoundException e) { - Log.e(Constants.TAG, "Intent data pointed to bad key!"); - finish(); - return; - } - } @Override @@ -136,7 +127,9 @@ public class UploadKeyActivity extends BaseActivity @Override public UploadKeyringParcel createOperationInput() { - return new UploadKeyringParcel(mKeyserver, mMasterKeyId); + long[] masterKeyIds = getIntent().getLongArrayExtra(MultiUserIdsFragment.EXTRA_KEY_IDS); + + return new UploadKeyringParcel(mKeyserver, masterKeyIds[0]); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 0aa8330ea..02eae1b2b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -455,8 +455,19 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements } private void uploadToKeyserver() { + long keyId; + try { + keyId = new ProviderHelper(getActivity()) + .getCachedPublicKeyRing(mDataUri) + .extractOrGetMasterKeyId(); + } catch (PgpKeyNotFoundException e) { + Log.e(Constants.TAG, "key not found!", e); + Notify.create(getActivity(), "key not found", Style.ERROR).show(); + return; + } Intent uploadIntent = new Intent(getActivity(), UploadKeyActivity.class); uploadIntent.setData(mDataUri); + uploadIntent.putExtra(MultiUserIdsFragment.EXTRA_KEY_IDS, new long[]{keyId}); startActivityForResult(uploadIntent, 0); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java index b91abf076..d247faddc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java @@ -39,6 +39,7 @@ import java.util.ArrayList; public class MultiUserIdsAdapter extends CursorAdapter { private LayoutInflater mInflater; private final ArrayList mCheckStates; + private boolean checkboxVisibility = true; public MultiUserIdsAdapter(Context context, Cursor c, int flags, ArrayList preselectStates) { super(context, c, flags); @@ -46,6 +47,11 @@ public class MultiUserIdsAdapter extends CursorAdapter { mCheckStates = preselectStates == null ? new ArrayList() : preselectStates; } + public MultiUserIdsAdapter(Context context, Cursor c, int flags, ArrayList preselectStates, boolean checkboxVisibility) { + this(context,c,flags,preselectStates); + this.checkboxVisibility = checkboxVisibility; + } + @Override public Cursor swapCursor(Cursor newCursor) { if (newCursor != null) { @@ -138,6 +144,7 @@ public class MultiUserIdsAdapter extends CursorAdapter { } }); vCheckBox.setClickable(false); + vCheckBox.setVisibility(checkboxVisibility?View.VISIBLE:View.GONE); View vUidBody = view.findViewById(R.id.user_id_body); vUidBody.setClickable(true); diff --git a/OpenKeychain/src/main/res/layout/certify_item.xml b/OpenKeychain/src/main/res/layout/certify_item.xml index 71838c2fc..8aff5823e 100644 --- a/OpenKeychain/src/main/res/layout/certify_item.xml +++ b/OpenKeychain/src/main/res/layout/certify_item.xml @@ -13,7 +13,6 @@ android:layout_height="wrap_content" android:orientation="vertical" android:clickable="true" - android:layout_marginLeft="8dip" android:layout_marginTop="8dip"/> + + Date: Fri, 1 Apr 2016 10:34:27 +0800 Subject: Corrected warning message --- OpenKeychain/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 9a21f95f7..efa2c80d2 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -334,7 +334,7 @@ "Delete key '%s'?" "Also export secret keys" "You encountered a known bug with Android. Please reinstall OpenKeychain if you want to link your contacts with keys." - "Stripping this subkey will render it useless." + "Stripping this subkey will make it unusable on this device!" "Successfully exported 1 key." "Successfully exported %d keys." -- cgit v1.2.3 From e627006fcfecdc84b28298bdf4815aaa7d67cdfa Mon Sep 17 00:00:00 2001 From: Victor Hazali Date: Fri, 1 Apr 2016 10:34:52 +0800 Subject: setTitle now uses resource id directly --- .../sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java index 01decf2ef..9f5ffc358 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyDialogFragment.java @@ -101,7 +101,7 @@ public class EditSubkeyDialogFragment extends DialogFragment { private void showAlertDialog() { CustomAlertDialogBuilder stripAlertDialog = new CustomAlertDialogBuilder(getActivity()); - stripAlertDialog.setTitle(getResources().getString(R.string.title_alert_strip)). + stripAlertDialog.setTitle(R.string.title_alert_strip). setMessage(R.string.alert_strip).setCancelable(true); stripAlertDialog.setPositiveButton(R.string.strip, new DialogInterface.OnClickListener() { @Override -- cgit v1.2.3 From cb9bdb3cf72ec387e6f34d29a31e701f5f5e7d92 Mon Sep 17 00:00:00 2001 From: Alex Fong Date: Mon, 21 Mar 2016 21:37:19 +0800 Subject: Redesigned subkey creation dialog and changed default key type created to RSA, 3072 bit. Added code to prevent removal of master subkey when modifying a new key. --- .../keychain/ui/CreateKeyFinalFragment.java | 6 +- .../keychain/ui/EditKeyFragment.java | 10 +- .../keychain/ui/adapter/SubkeysAddedAdapter.java | 48 ++- .../ui/dialog/AddSubkeyDialogFragment.java | 473 +++++++-------------- .../ui/util/spinner/FocusFirstItemSpinner.java | 77 ++++ .../sufficientlysecure/keychain/util/Choice.java | 9 +- .../main/res/drawable-hdpi/ic_change_grey_24dp.png | Bin 0 -> 923 bytes .../main/res/drawable-mdpi/ic_change_grey_24dp.png | Bin 0 -> 623 bytes .../res/drawable-xhdpi/ic_change_grey_24dp.png | Bin 0 -> 1066 bytes .../res/drawable-xxhdpi/ic_change_grey_24dp.png | Bin 0 -> 1612 bytes .../res/drawable-xxxhdpi/ic_change_grey_24dp.png | Bin 0 -> 2223 bytes .../src/main/res/layout/add_subkey_dialog.xml | 163 ++----- .../res/layout/two_line_spinner_dropdown_item.xml | 32 ++ OpenKeychain/src/main/res/values/strings.xml | 29 +- 14 files changed, 362 insertions(+), 485 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/spinner/FocusFirstItemSpinner.java create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_change_grey_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_change_grey_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_change_grey_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_change_grey_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxxhdpi/ic_change_grey_24dp.png create mode 100644 OpenKeychain/src/main/res/layout/two_line_spinner_dropdown_item.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index b53bfc1d0..e1d20f2e1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -281,11 +281,11 @@ public class CreateKeyFinalFragment extends Fragment { saveKeyringParcel.mNewUnlock = new ChangeUnlockParcel(new Passphrase(), null); } else { saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, - 4096, null, KeyFlags.CERTIFY_OTHER, 0L)); + 3072, null, KeyFlags.CERTIFY_OTHER, 0L)); saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, - 4096, null, KeyFlags.SIGN_DATA, 0L)); + 3072, null, KeyFlags.SIGN_DATA, 0L)); saveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, - 4096, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); + 3072, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); saveKeyringParcel.mNewUnlock = createKeyActivity.mPassphrase != null ? new ChangeUnlockParcel(createKeyActivity.mPassphrase, null) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 2d94d0d93..1571a7104 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -562,15 +562,9 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment> choices = new ArrayList<>(); - choices.add(new Choice<>(Algorithm.DSA, getResources().getString( - R.string.dsa))); - if (!mWillBeMasterKey) { - choices.add(new Choice<>(Algorithm.ELGAMAL, getResources().getString( - R.string.elgamal))); - } - choices.add(new Choice<>(Algorithm.RSA, getResources().getString( - R.string.rsa))); - choices.add(new Choice<>(Algorithm.ECDSA, getResources().getString( - R.string.ecdsa))); - choices.add(new Choice<>(Algorithm.ECDH, getResources().getString( - R.string.ecdh))); - ArrayAdapter> adapter = new ArrayAdapter<>(context, + ArrayList> choices = new ArrayList<>(); + choices.add(new Choice<>(SupportedKeyType.RSA_2048, getResources().getString( + R.string.rsa_2048), getResources().getString(R.string.rsa_2048_description_html))); + choices.add(new Choice<>(SupportedKeyType.RSA_3072, getResources().getString( + R.string.rsa_3072), getResources().getString(R.string.rsa_3072_description_html))); + choices.add(new Choice<>(SupportedKeyType.RSA_4096, getResources().getString( + R.string.rsa_4096), getResources().getString(R.string.rsa_4096_description_html))); + choices.add(new Choice<>(SupportedKeyType.ECC_P256, getResources().getString( + R.string.ecc_p256), getResources().getString(R.string.ecc_p256_description_html))); + choices.add(new Choice<>(SupportedKeyType.ECC_P521, getResources().getString( + R.string.ecc_p521), getResources().getString(R.string.ecc_p521_description_html))); + TwoLineArrayAdapter adapter = new TwoLineArrayAdapter(context, android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mAlgorithmSpinner.setAdapter(adapter); - // make RSA the default + mKeyTypeSpinner.setAdapter(adapter); + // make RSA 3072 the default for (int i = 0; i < choices.size(); ++i) { - if (choices.get(i).getId() == Algorithm.RSA) { - mAlgorithmSpinner.setSelection(i); - break; - } - } - } - - // dynamic ArrayAdapter must be created (instead of ArrayAdapter.getFromResource), because it's content may change - ArrayAdapter keySizeAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, - new ArrayList(Arrays.asList(getResources().getStringArray(R.array.rsa_key_size_spinner_values)))); - keySizeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mKeySizeSpinner.setAdapter(keySizeAdapter); - mKeySizeSpinner.setSelection(1); // Default to 4096 for the key length - - { - ArrayList> choices = new ArrayList<>(); - - choices.add(new Choice<>(Curve.NIST_P256, getResources().getString( - R.string.key_curve_nist_p256))); - choices.add(new Choice<>(Curve.NIST_P384, getResources().getString( - R.string.key_curve_nist_p384))); - choices.add(new Choice<>(Curve.NIST_P521, getResources().getString( - R.string.key_curve_nist_p521))); - - /* @see SaveKeyringParcel - choices.add(new Choice(Curve.BRAINPOOL_P256, getResources().getString( - R.string.key_curve_bp_p256))); - choices.add(new Choice(Curve.BRAINPOOL_P384, getResources().getString( - R.string.key_curve_bp_p384))); - choices.add(new Choice(Curve.BRAINPOOL_P512, getResources().getString( - R.string.key_curve_bp_p512))); - */ - - ArrayAdapter> adapter = new ArrayAdapter<>(context, - android.R.layout.simple_spinner_item, choices); - mCurveSpinner.setAdapter(adapter); - // make NIST P-256 the default - for (int i = 0; i < choices.size(); ++i) { - if (choices.get(i).getId() == Curve.NIST_P256) { - mCurveSpinner.setSelection(i); + if (choices.get(i).getId() == SupportedKeyType.RSA_3072) { + mKeyTypeSpinner.setSelection(i); break; } } @@ -215,45 +177,35 @@ public class AddSubkeyDialogFragment extends DialogFragment { final AlertDialog alertDialog = dialog.show(); - mCustomKeyEditText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } + mKeyTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void afterTextChanged(Editable s) { - setOkButtonAvailability(alertDialog); - } - }); - - mKeySizeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - setCustomKeyVisibility(); - setOkButtonAvailability(alertDialog); - } + // noinspection unchecked + SupportedKeyType keyType = ((Choice) parent.getSelectedItem()).getId(); - @Override - public void onNothingSelected(AdapterView parent) { - } - }); + // RadioGroup.getCheckedRadioButtonId() gives the wrong RadioButton checked + // when programmatically unchecking children radio buttons. Clearing all is the only option. + mUsageRadioGroup.clearCheck(); - mAlgorithmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - updateUiForAlgorithm(((Choice) parent.getSelectedItem()).getId()); + if(mWillBeMasterKey) { + mUsageNone.setChecked(true); + } - setCustomKeyVisibility(); - setOkButtonAvailability(alertDialog); + if (keyType == SupportedKeyType.ECC_P521 || keyType == SupportedKeyType.ECC_P256) { + mUsageSignAndEncrypt.setEnabled(false); + if (mWillBeMasterKey) { + mUsageEncrypt.setEnabled(false); + } + } else { + // need to enable if previously disabled for ECC masterkey + mUsageEncrypt.setEnabled(true); + mUsageSignAndEncrypt.setEnabled(true); + } } @Override - public void onNothingSelected(AdapterView parent) { - } + public void onNothingSelected(AdapterView parent) {} }); return alertDialog; @@ -269,36 +221,74 @@ public class AddSubkeyDialogFragment extends DialogFragment { positiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (!mFlagCertify.isChecked() && !mFlagSign.isChecked() - && !mFlagEncrypt.isChecked() && !mFlagAuthenticate.isChecked()) { - Toast.makeText(getActivity(), R.string.edit_key_select_flag, Toast.LENGTH_LONG).show(); + if (mUsageRadioGroup.getCheckedRadioButtonId() == -1) { + Toast.makeText(getActivity(), R.string.edit_key_select_usage, Toast.LENGTH_LONG).show(); return; } - Algorithm algorithm = ((Choice) mAlgorithmSpinner.getSelectedItem()).getId(); + // noinspection unchecked + SupportedKeyType keyType = ((Choice) mKeyTypeSpinner.getSelectedItem()).getId(); Curve curve = null; Integer keySize = null; - // For EC keys, add a curve - if (algorithm == Algorithm.ECDH || algorithm == Algorithm.ECDSA) { - curve = ((Choice) mCurveSpinner.getSelectedItem()).getId(); - // Otherwise, get a keysize - } else { - keySize = getProperKeyLength(algorithm, getSelectedKeyLength()); + Algorithm algorithm = null; + + // set keysize & curve, for RSA & ECC respectively + switch (keyType) { + case RSA_2048: { + keySize = 2048; + break; + } + case RSA_3072: { + keySize = 3072; + break; + } + case RSA_4096: { + keySize = 4096; + break; + } + case ECC_P256: { + curve = Curve.NIST_P256; + break; + } + case ECC_P521: { + curve = Curve.NIST_P521; + break; + } } + // set algorithm + switch (keyType) { + case RSA_2048: + case RSA_3072: + case RSA_4096: { + algorithm = Algorithm.RSA; + break; + } + + case ECC_P256: + case ECC_P521: { + if(mUsageEncrypt.isChecked()) { + algorithm = Algorithm.ECDH; + } else { + algorithm = Algorithm.ECDSA; + } + break; + } + } + + // set flags int flags = 0; - if (mFlagCertify.isChecked()) { + if (mWillBeMasterKey) { flags |= KeyFlags.CERTIFY_OTHER; } - if (mFlagSign.isChecked()) { + if (mUsageSign.isChecked()) { flags |= KeyFlags.SIGN_DATA; - } - if (mFlagEncrypt.isChecked()) { + } else if (mUsageEncrypt.isChecked()) { flags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; + } else if (mUsageSignAndEncrypt.isChecked()) { + flags |= KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE; } - if (mFlagAuthenticate.isChecked()) { - flags |= KeyFlags.AUTHENTICATION; - } + long expiry; if (mNoExpiryCheckBox.isChecked()) { @@ -332,206 +322,29 @@ public class AddSubkeyDialogFragment extends DialogFragment { } } - private int getSelectedKeyLength() { - final String selectedItemString = (String) mKeySizeSpinner.getSelectedItem(); - final String customLengthString = getResources().getString(R.string.key_size_custom); - final boolean customSelected = customLengthString.equals(selectedItemString); - String keyLengthString = customSelected ? mCustomKeyEditText.getText().toString() : selectedItemString; - int keySize; - try { - keySize = Integer.parseInt(keyLengthString); - } catch (NumberFormatException e) { - keySize = 0; - } - return keySize; - } - - /** - *

RSA

- *

for RSA algorithm, key length must be greater than 2048. Possibility to generate keys bigger - * than 8192 bits is currently disabled, because it's almost impossible to generate them on a mobile device (check - * RSA key length plot and - * Cryptographic Key Length Recommendation). Also, key length must be a - * multiplicity of 8.

- *

ElGamal

- *

For ElGamal algorithm, supported key lengths are 2048, 3072, 4096 or 8192 bits.

- *

DSA

- *

For DSA algorithm key length must be between 2048 and 3072. Also, it must me dividable by 64.

- * - * @return correct key length, according to BouncyCastle specification. Returns -1, if key length is - * inappropriate. - */ - private int getProperKeyLength(Algorithm algorithm, int currentKeyLength) { - final int[] elGamalSupportedLengths = {2048, 3072, 4096, 8192}; - int properKeyLength = -1; - switch (algorithm) { - case RSA: { - if (currentKeyLength >= 2048 && currentKeyLength <= 16384) { - properKeyLength = currentKeyLength + ((8 - (currentKeyLength % 8)) % 8); - } - break; - } - case ELGAMAL: { - int[] elGammalKeyDiff = new int[elGamalSupportedLengths.length]; - for (int i = 0; i < elGamalSupportedLengths.length; i++) { - elGammalKeyDiff[i] = Math.abs(elGamalSupportedLengths[i] - currentKeyLength); - } - int minimalValue = Integer.MAX_VALUE; - int minimalIndex = -1; - for (int i = 0; i < elGammalKeyDiff.length; i++) { - if (elGammalKeyDiff[i] <= minimalValue) { - minimalValue = elGammalKeyDiff[i]; - minimalIndex = i; - } - } - properKeyLength = elGamalSupportedLengths[minimalIndex]; - break; - } - case DSA: { - // Bouncy Castle supports 4096 maximum - if (currentKeyLength >= 2048 && currentKeyLength <= 4096) { - properKeyLength = currentKeyLength + ((64 - (currentKeyLength % 64)) % 64); - } - break; - } + private class TwoLineArrayAdapter extends ArrayAdapter> { + public TwoLineArrayAdapter(Context context, int resource, List> objects) { + super(context, resource, objects); } - return properKeyLength; - } - private void setOkButtonAvailability(AlertDialog alertDialog) { - Algorithm algorithm = ((Choice) mAlgorithmSpinner.getSelectedItem()).getId(); - boolean enabled = algorithm == Algorithm.ECDSA || algorithm == Algorithm.ECDH - || getProperKeyLength(algorithm, getSelectedKeyLength()) > 0; - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled); - } - private void setCustomKeyVisibility() { - final String selectedItemString = (String) mKeySizeSpinner.getSelectedItem(); - final String customLengthString = getResources().getString(R.string.key_size_custom); - final boolean customSelected = customLengthString.equals(selectedItemString); - final int visibility = customSelected ? View.VISIBLE : View.GONE; - - mCustomKeyEditText.setVisibility(visibility); - mCustomKeyTextView.setVisibility(visibility); - mCustomKeyInfoTextView.setVisibility(visibility); - - // hide keyboard after setting visibility to gone - if (visibility == View.GONE) { - InputMethodManager imm = (InputMethodManager) - getActivity().getSystemService(FragmentActivity.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mCustomKeyEditText.getWindowToken(), 0); - } - } + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + // inflate view if not given one + if (convertView == null) { + convertView = getActivity().getLayoutInflater() + .inflate(R.layout.two_line_spinner_dropdown_item, parent, false); + } - private void updateUiForAlgorithm(Algorithm algorithm) { - final ArrayAdapter keySizeAdapter = (ArrayAdapter) mKeySizeSpinner.getAdapter(); - keySizeAdapter.clear(); - switch (algorithm) { - case RSA: { - replaceArrayAdapterContent(keySizeAdapter, R.array.rsa_key_size_spinner_values); - mKeySizeSpinner.setSelection(1); - mKeySizeRow.setVisibility(View.VISIBLE); - mCurveRow.setVisibility(View.GONE); - mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_rsa)); - // allowed flags: - mFlagSign.setEnabled(true); - mFlagEncrypt.setEnabled(true); - mFlagAuthenticate.setEnabled(true); - - if (mWillBeMasterKey) { - mFlagCertify.setEnabled(true); - - mFlagCertify.setChecked(true); - mFlagSign.setChecked(false); - mFlagEncrypt.setChecked(false); - } else { - mFlagCertify.setEnabled(false); + Choice c = this.getItem(position); - mFlagCertify.setChecked(false); - mFlagSign.setChecked(true); - mFlagEncrypt.setChecked(true); - } - mFlagAuthenticate.setChecked(false); - break; - } - case ELGAMAL: { - replaceArrayAdapterContent(keySizeAdapter, R.array.elgamal_key_size_spinner_values); - mKeySizeSpinner.setSelection(3); - mKeySizeRow.setVisibility(View.VISIBLE); - mCurveRow.setVisibility(View.GONE); - mCustomKeyInfoTextView.setText(""); // ElGamal does not support custom key length - // allowed flags: - mFlagCertify.setChecked(false); - mFlagCertify.setEnabled(false); - mFlagSign.setChecked(false); - mFlagSign.setEnabled(false); - mFlagEncrypt.setChecked(true); - mFlagEncrypt.setEnabled(true); - mFlagAuthenticate.setChecked(false); - mFlagAuthenticate.setEnabled(false); - break; - } - case DSA: { - replaceArrayAdapterContent(keySizeAdapter, R.array.dsa_key_size_spinner_values); - mKeySizeSpinner.setSelection(2); - mKeySizeRow.setVisibility(View.VISIBLE); - mCurveRow.setVisibility(View.GONE); - mCustomKeyInfoTextView.setText(getResources().getString(R.string.key_size_custom_info_dsa)); - // allowed flags: - mFlagCertify.setChecked(false); - mFlagCertify.setEnabled(false); - mFlagSign.setChecked(true); - mFlagSign.setEnabled(true); - mFlagEncrypt.setChecked(false); - mFlagEncrypt.setEnabled(false); - mFlagAuthenticate.setChecked(false); - mFlagAuthenticate.setEnabled(false); - break; - } - case ECDSA: { - mKeySizeRow.setVisibility(View.GONE); - mCurveRow.setVisibility(View.VISIBLE); - mCustomKeyInfoTextView.setText(""); - // allowed flags: - mFlagCertify.setEnabled(mWillBeMasterKey); - mFlagCertify.setChecked(mWillBeMasterKey); - mFlagSign.setEnabled(true); - mFlagSign.setChecked(!mWillBeMasterKey); - mFlagEncrypt.setEnabled(false); - mFlagEncrypt.setChecked(false); - mFlagAuthenticate.setEnabled(true); - mFlagAuthenticate.setChecked(false); - break; - } - case ECDH: { - mKeySizeRow.setVisibility(View.GONE); - mCurveRow.setVisibility(View.VISIBLE); - mCustomKeyInfoTextView.setText(""); - // allowed flags: - mFlagCertify.setChecked(false); - mFlagCertify.setEnabled(false); - mFlagSign.setChecked(false); - mFlagSign.setEnabled(false); - mFlagEncrypt.setChecked(true); - mFlagEncrypt.setEnabled(true); - mFlagAuthenticate.setChecked(false); - mFlagAuthenticate.setEnabled(false); - break; - } - } - keySizeAdapter.notifyDataSetChanged(); + TextView text1 = (TextView) convertView.findViewById(android.R.id.text1); + TextView text2 = (TextView) convertView.findViewById(android.R.id.text2); - } + text1.setText(c.getName()); + text2.setText(Html.fromHtml(c.getDescription())); - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - private void replaceArrayAdapterContent(ArrayAdapter arrayAdapter, int stringArrayResourceId) { - final String[] spinnerValuesStringArray = getResources().getStringArray(stringArrayResourceId); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - arrayAdapter.addAll(spinnerValuesStringArray); - } else { - for (final String value : spinnerValuesStringArray) { - arrayAdapter.add(value); - } + return convertView; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/spinner/FocusFirstItemSpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/spinner/FocusFirstItemSpinner.java new file mode 100644 index 000000000..7919a0918 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/spinner/FocusFirstItemSpinner.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 Alex Fong Jie Wen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui.util.spinner; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.Spinner; + +/** + * Custom spinner which uses a hack to + * always set focus on first item in list + * + */ +public class FocusFirstItemSpinner extends Spinner { + /** + * Spinner is originally designed to set focus on the currently selected item. + * When Spinner is selected to show dropdown, 'performClick()' is called internally. + * 'getSelectedItemPosition()' is then called to obtain the item to focus on. + * We use a toggle to have 'getSelectedItemPosition()' return the 0th index + * for this particular case. + */ + + private boolean mToggleFlag = true; + + public FocusFirstItemSpinner(Context context, AttributeSet attrs, + int defStyle, int mode) { + super(context, attrs, defStyle, mode); + } + + public FocusFirstItemSpinner(Context context, AttributeSet attrs, + int defStyle) { + super(context, attrs, defStyle); + } + + public FocusFirstItemSpinner(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public FocusFirstItemSpinner(Context context, int mode) { + super(context, mode); + } + + public FocusFirstItemSpinner(Context context) { + super(context); + } + + @Override + public int getSelectedItemPosition() { + if (!mToggleFlag) { + return 0; + } + return super.getSelectedItemPosition(); + } + + @Override + public boolean performClick() { + mToggleFlag = false; + boolean result = super.performClick(); + mToggleFlag = true; + return result; + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java index 48f10d4b9..5ffce9f24 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Choice.java @@ -18,12 +18,15 @@ package org.sufficientlysecure.keychain.util; public class Choice { + private String mName; private E mId; + private String mDescription; - public Choice(E id, String name) { + public Choice(E id, String name, String description) { mId = id; mName = name; + mDescription = description; } public E getId() { @@ -34,6 +37,10 @@ public class Choice { return mName; } + public String getDescription() { + return mDescription; + } + @Override public String toString() { return mName; diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_change_grey_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_change_grey_24dp.png new file mode 100644 index 000000000..f625ba425 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-hdpi/ic_change_grey_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_change_grey_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_change_grey_24dp.png new file mode 100644 index 000000000..6cf9d044a Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-mdpi/ic_change_grey_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_change_grey_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_change_grey_24dp.png new file mode 100644 index 000000000..1c30b6f22 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xhdpi/ic_change_grey_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_change_grey_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_change_grey_24dp.png new file mode 100644 index 000000000..672a9c96c Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_change_grey_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_change_grey_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_change_grey_24dp.png new file mode 100644 index 000000000..5be101001 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_change_grey_24dp.png differ diff --git a/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml b/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml index 4b5058a81..b232ed423 100644 --- a/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml +++ b/OpenKeychain/src/main/res/layout/add_subkey_dialog.xml @@ -13,147 +13,68 @@ android:paddingRight="24dp" android:stretchColumns="1"> - - - + android:paddingRight="10dp" + android:text="@string/label_key_type" /> - + - - - - - - - - - - - - - - - - - - - - + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp"> - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 70db4029b..4ac0037ac 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -13,6 +13,7 @@ "Encrypt" "Decrypt" "Add subkey" + Change master key "Edit Key" "Create a Linked Identity" "Settings" @@ -165,6 +166,7 @@ "Select OpenPGP keyservers" "Key ID" "Key created %s" + "Type" "Creation" "Expiry" "Usage" @@ -281,23 +283,26 @@ "8 hours" "forever" "Select a Key" - "DSA" - "ElGamal" - "RSA" - "ECDH" - "ECDSA" "Open…" + "RSA 2048" + "smaller filesize, considered secure until 2030" + "RSA 3072" + "recommended, considered secure until 2040" + "RSA 4096" + "larger file size, considered secure until 2040+" + "ECC P-256" + "very tiny filesize, considered secure until 2040 <br/> <u>experimental and not supported by all implementations</u>" + "ECC P-521" + "tiny filesize, considered secure until 2040+ <br/> <u>experimental and not supported by all implementations"</u> + "None (subkey binding only)" + "Sign" + "Encrypt" + "Sign & Encrypt" "Error" "Error: %s" "Dark" "Light" - - "Certify" - "Sign" - "Encrypt" - "Authenticate" - "Wrong password." "No compatible file manager installed." @@ -746,7 +751,7 @@ "Move Subkey to Security Token" "new subkey" - "Please select at least one flag!" + "Please select key usage!" "Add at least one identity!" "Add at least one subkey!" "Algorithm not supported by Security Token!" -- cgit v1.2.3 From f5d9d33bbcc15c4ecbc0962852702909eff62087 Mon Sep 17 00:00:00 2001 From: Bernd Date: Sat, 2 Apr 2016 00:51:29 +0200 Subject: Fix link to open-keychain/bouncycastle fork --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c61e3fcf..940699fb4 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ We are using the newest [Android Studio](http://developer.android.com/sdk/instal OpenKeychain uses a forked version with some small changes. These changes will been sent to Bouncy Castle. see -* Fork: https://github.com/openpgp-keychain/bouncycastle +* Fork: https://github.com/open-keychain/bouncycastle #### Bouncy Castle resources -- cgit v1.2.3 From db3e90821cfff9ac8fe369fdcbbf8ce7e708ba15 Mon Sep 17 00:00:00 2001 From: Victor Hazali Date: Mon, 4 Apr 2016 18:52:22 +0800 Subject: Used a constant instead of magic number for colour Explicitly stated the blending mode --- .../main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java | 3 ++- OpenKeychain/src/main/res/values/colors.xml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 6c96a40ba..d81797454 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -33,6 +33,7 @@ import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; +import android.graphics.PorterDuff; import android.net.Uri; import android.nfc.NfcAdapter; import android.os.AsyncTask; @@ -924,7 +925,7 @@ public class ViewKeyActivity extends BaseSecurityTokenNfcActivity implements } mPhoto.setImageBitmap(photo); - mPhoto.setColorFilter(Color.argb(30, 120, 166, 69)); + mPhoto.setColorFilter(getResources().getColor(R.color.toolbar_photo_tint), PorterDuff.Mode.SRC_ATOP); mPhotoLayout.setVisibility(View.VISIBLE); } }; diff --git a/OpenKeychain/src/main/res/values/colors.xml b/OpenKeychain/src/main/res/values/colors.xml index 93cf126f7..d9075b587 100644 --- a/OpenKeychain/src/main/res/values/colors.xml +++ b/OpenKeychain/src/main/res/values/colors.xml @@ -35,5 +35,6 @@ #7bad45 + #1E7bad45
-- cgit v1.2.3 From 1e97149ce12939ec9c073141e6f1816745a346a2 Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Mon, 4 Apr 2016 19:56:00 +0200 Subject: Changed activity during RedirectKeysActivity QrCodeCaptureActivity is open instead ImportKeysActivity --- .../sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java index 1f6a62f47..fd3148a6c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -34,13 +34,8 @@ public class RedirectImportKeysActivity extends BaseActivity { startScanActivity(); } - @Override - protected void initLayout() { - - } - private void startScanActivity() { - final Intent intent = new Intent(this, org.sufficientlysecure.keychain.ui.ImportKeysActivity.class); + final Intent intent = new Intent(this, QrCodeCaptureActivity.class); new AlertDialog.Builder(this) .setTitle(R.string.redirect_import_key_title) -- cgit v1.2.3 From 30afa3a1934b41d03adf89b0030eaba7ac6bf932 Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Mon, 4 Apr 2016 20:03:05 +0200 Subject: Activity renamed Activity renamed from startScanActivity to startQrCodeCaptureActivity --- .../sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java index fd3148a6c..635cdcaef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -31,10 +31,10 @@ public class RedirectImportKeysActivity extends BaseActivity { super.onCreate(savedInstanceState); setContentView(R.layout.redirect_import_keys_activity); - startScanActivity(); + startQrCodeCaptureActivity(); } - private void startScanActivity() { + private void startQrCodeCaptureActivity() { final Intent intent = new Intent(this, QrCodeCaptureActivity.class); new AlertDialog.Builder(this) -- cgit v1.2.3 From aec4744b31b74e697a147b30a3eda2f5b381c9e2 Mon Sep 17 00:00:00 2001 From: Durgesh <007durgesh219@gmail.com> Date: Tue, 5 Apr 2016 02:07:29 +0530 Subject: Fix Unusable signing key not properly disabled, Issue #1468 Signed-off-by: Durgesh <007durgesh219@gmail.com> --- .../org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java | 5 ----- .../org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java | 5 ----- 2 files changed, 10 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java index 6a51085f3..63afb1e8b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java @@ -113,11 +113,6 @@ public class CertifyKeySpinner extends KeySpinner { @Override boolean isItemEnabled(Cursor cursor) { - // "none" entry is always enabled! - if (cursor.getPosition() == 0) { - return true; - } - if (cursor.getInt(KeyAdapter.INDEX_IS_REVOKED) != 0) { return false; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java index 8fb9e38aa..0c2d93ad9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SignKeySpinner.java @@ -72,11 +72,6 @@ public class SignKeySpinner extends KeySpinner { @Override boolean isItemEnabled(Cursor cursor) { - // "none" entry is always enabled! - if (cursor.getPosition() == 0) { - return true; - } - if (cursor.getInt(KeyAdapter.INDEX_IS_REVOKED) != 0) { return false; } -- cgit v1.2.3 From dac5f1db08b4dea5893d9fe0a1ab0daad5b44f09 Mon Sep 17 00:00:00 2001 From: Michal Kepkowski Date: Wed, 6 Apr 2016 19:10:00 +0200 Subject: OKhttp url factory --- .../keychain/util/OkHttpClientFactory.java | 7 +++++- .../keychain/util/OkHttpKeybaseClient.java | 27 ++++++++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java index 2bf3b7e14..cbbbf6e71 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java @@ -17,13 +17,18 @@ public class OkHttpClientFactory { public static OkHttpClient getSimpleClient(){ if(client == null){ - client = new OkHttpClient.Builder().build(); + client = new OkHttpClient.Builder() + .connectTimeout(30000, TimeUnit.MILLISECONDS) + .readTimeout(45000, TimeUnit.MILLISECONDS) + .build(); } return client; } public static OkHttpClient getPinnedSimpleClient(CertificatePinner pinner){ return new OkHttpClient.Builder() + .connectTimeout(30000, TimeUnit.MILLISECONDS) + .readTimeout(45000, TimeUnit.MILLISECONDS) .certificatePinner(pinner) .build(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index 04527c730..e9fe7f724 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -21,32 +21,45 @@ package org.sufficientlysecure.keychain.util; import com.textuality.keybase.lib.KeybaseUrlConnectionClient; import okhttp3.OkHttpClient; +import okhttp3.OkUrlFactory; import org.sufficientlysecure.keychain.Constants; import java.io.IOException; import java.net.Proxy; import java.net.URL; +import java.net.URLConnection; +import java.util.concurrent.TimeUnit; /** * Wrapper for Keybase Lib */ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { + private OkUrlFactory generateUrlFactory() { + OkHttpClient client = new OkHttpClient(); + return new OkUrlFactory(client); + } @Override - public OkHttpClient getClient(URL url, Proxy proxy, boolean pin) throws IOException { + public URLConnection openConnection(URL url, Proxy proxy, boolean isKeybase) throws IOException { + OkHttpClient client = OkHttpClientFactory.getSimpleClient(); + + OkUrlFactory factory = generateUrlFactory(); try { - if(pin) { - return OkHttpClientFactory.getPinnedClient(url, proxy); - }else{ - return OkHttpClientFactory.getClient( proxy); + if (isKeybase && proxy != null) { + client = OkHttpClientFactory.getPinnedClient(url, proxy); + } else if (proxy != null) { + client = OkHttpClientFactory.getClient(proxy); + } else { + client = OkHttpClientFactory.getSimpleClient(); } - } catch (IOException e) { - throw new IOException("no pinned certificate found for URL!"); } catch (TlsHelper.TlsHelperException e) { Log.e(Constants.TAG, "TlsHelper failed", e); throw new IOException("TlsHelper failed"); } + factory.setClient(client); + + return factory.open(url); } @Override -- cgit v1.2.3 From 26bfe06d80f4114da298a7e7e05a59db823a8d40 Mon Sep 17 00:00:00 2001 From: Michal Kepkowski Date: Wed, 6 Apr 2016 19:25:10 +0200 Subject: cleaning --- .../keychain/util/OkHttpKeybaseClient.java | 1 - .../org/sufficientlysecure/keychain/util/TlsHelper.java | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index e9fe7f724..4700da5f3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.net.Proxy; import java.net.URL; import java.net.URLConnection; -import java.util.concurrent.TimeUnit; /** * Wrapper for Keybase Lib diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java index d1b8f768b..c23985ac0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java @@ -44,12 +44,6 @@ import javax.net.ssl.TrustManagerFactory; public class TlsHelper { - public static class TlsHelperException extends Exception { - public TlsHelperException(Exception e) { - super(e); - } - } - private static Map sPinnedCertificates = new HashMap<>(); /** @@ -87,7 +81,6 @@ public class TlsHelper { for (String host : sPinnedCertificates.keySet()) { if (url.getHost().endsWith(host)) { return pinCertificate(sPinnedCertificates.get(host)); - //return true; } } } @@ -138,4 +131,10 @@ public class TlsHelper { } } + public static class TlsHelperException extends Exception { + public TlsHelperException(Exception e) { + super(e); + } + } + } -- cgit v1.2.3 From 7b97c2bbede48713255520b74d608575df857dc8 Mon Sep 17 00:00:00 2001 From: Michal Kepkowski Date: Fri, 8 Apr 2016 19:10:59 +0200 Subject: KeyBaseLib response Client --- .../ui/linked/LinkedIdCreateTwitterStep1Fragment.java | 2 +- .../keychain/util/OkHttpKeybaseClient.java | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java index c25f775b0..334a7361b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java @@ -119,7 +119,7 @@ public class LinkedIdCreateTwitterStep1Fragment extends Fragment { private static Boolean checkHandle(String handle) { try { HttpURLConnection nection = - (HttpURLConnection) new URL("https://twitter.com/" + handle).openConnection(); + (HttpURLConnection) new URL("https://twitter.com/" + handle).getUrlResponse(); nection.setRequestMethod("HEAD"); nection.setRequestProperty("User-Agent", "OpenKeychain"); return nection.getResponseCode() == 200; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index 4700da5f3..afe688bbe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -22,6 +22,8 @@ import com.textuality.keybase.lib.KeybaseUrlConnectionClient; import okhttp3.OkHttpClient; import okhttp3.OkUrlFactory; +import okhttp3.Request; +import okhttp3.Response; import org.sufficientlysecure.keychain.Constants; import java.io.IOException; @@ -34,16 +36,12 @@ import java.net.URLConnection; */ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { - private OkUrlFactory generateUrlFactory() { - OkHttpClient client = new OkHttpClient(); - return new OkUrlFactory(client); - } + @Override - public URLConnection openConnection(URL url, Proxy proxy, boolean isKeybase) throws IOException { - OkHttpClient client = OkHttpClientFactory.getSimpleClient(); + public Response getUrlResponse(URL url, Proxy proxy, boolean isKeybase) throws IOException { + OkHttpClient client = null; - OkUrlFactory factory = generateUrlFactory(); try { if (isKeybase && proxy != null) { client = OkHttpClientFactory.getPinnedClient(url, proxy); @@ -56,9 +54,11 @@ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { Log.e(Constants.TAG, "TlsHelper failed", e); throw new IOException("TlsHelper failed"); } - factory.setClient(client); - return factory.open(url); + Request request = new Request.Builder() + .url(url).build(); + okhttp3.Response okResponse = client.newCall(request).execute(); + return new Response(okResponse.body().byteStream(),okResponse.code(),okResponse.message(), okResponse.headers().toMultimap()); } @Override -- cgit v1.2.3 From 4edb805ba1d0e6de966692bbf0ba045fb11211e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 9 Apr 2016 11:45:09 +0200 Subject: Update keybase submodule --- extern/KeybaseLib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/KeybaseLib b/extern/KeybaseLib index bc02742a5..0a99c130e 160000 --- a/extern/KeybaseLib +++ b/extern/KeybaseLib @@ -1 +1 @@ -Subproject commit bc02742a59f4cc984cd497e14ac48cb61fe6e8ce +Subproject commit 0a99c130e6d1bc25a313a113d7f7777bf65b2e39 -- cgit v1.2.3 From 2d762e55da92ef45576967c0d1befef55e7935ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 9 Apr 2016 11:53:37 +0200 Subject: Okhttp3 cleanups, docs, and fix timeouts for default client --- .../keychain/linked/LinkedTokenResource.java | 8 ++-- .../ui/dialog/AddEditKeyserverDialogFragment.java | 2 +- .../keychain/util/OkHttpClientFactory.java | 51 ++++++++++++++-------- .../keychain/util/OkHttpKeybaseClient.java | 5 +-- .../keychain/util/TlsHelper.java | 4 -- 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java index 24fa3bd67..4a8882d50 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java @@ -241,11 +241,11 @@ public abstract class LinkedTokenResource extends LinkedResource { public static String getResponseBody(Request request, String... pins) throws IOException, HttpStatusException { - Log.d("Connection to: "+request.url().url().getHost(),""); + Log.d("Connection to: " + request.url().url().getHost(), ""); OkHttpClient client; - if(pins !=null){ - client = OkHttpClientFactory.getPinnedSimpleClient(getCertificatePinner(request.url().url().getHost(),pins)); - }else{ + if (pins != null) { + client = OkHttpClientFactory.getPinnedSimpleClient(getCertificatePinner(request.url().url().getHost(), pins)); + } else { client = OkHttpClientFactory.getSimpleClient(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java index 7abef97d2..a10b94b8e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java @@ -356,7 +356,7 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On OkHttpClient client = OkHttpClientFactory.getPinnedClient(newKeyserver.toURL(), proxy); if (onlyTrustedKeyserver - && TlsHelper.getPinnedSslSocketFactory(newKeyserver.toURL())==null) { + && TlsHelper.getPinnedSslSocketFactory(newKeyserver.toURL()) == null) { Log.w(Constants.TAG, "No pinned certificate for this host in OpenKeychain's assets."); reason = FailureReason.NO_PINNED_CERTIFICATE; return reason; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java index cbbbf6e71..f3606aa2f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java @@ -1,57 +1,74 @@ -package org.sufficientlysecure.keychain.util; +/* + * Copyright (C) 2016 Michał Kępkowski + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ -import okhttp3.CertificatePinner; -import okhttp3.OkHttpClient; -import org.sufficientlysecure.keychain.Constants; +package org.sufficientlysecure.keychain.util; import java.io.IOException; import java.net.Proxy; import java.net.URL; import java.util.concurrent.TimeUnit; -/** - * Created by Michał Kępkowski on 11/03/16. - */ +import okhttp3.CertificatePinner; +import okhttp3.OkHttpClient; + public class OkHttpClientFactory { private static OkHttpClient client; - public static OkHttpClient getSimpleClient(){ - if(client == null){ - client = new OkHttpClient.Builder() - .connectTimeout(30000, TimeUnit.MILLISECONDS) - .readTimeout(45000, TimeUnit.MILLISECONDS) + public static OkHttpClient getSimpleClient() { + if (client == null) { + client = new OkHttpClient.Builder() + .connectTimeout(5000, TimeUnit.MILLISECONDS) + .readTimeout(25000, TimeUnit.MILLISECONDS) .build(); } return client; } - public static OkHttpClient getPinnedSimpleClient(CertificatePinner pinner){ + public static OkHttpClient getPinnedSimpleClient(CertificatePinner pinner) { return new OkHttpClient.Builder() - .connectTimeout(30000, TimeUnit.MILLISECONDS) - .readTimeout(45000, TimeUnit.MILLISECONDS) + .connectTimeout(5000, TimeUnit.MILLISECONDS) + .readTimeout(25000, TimeUnit.MILLISECONDS) .certificatePinner(pinner) .build(); } - public static OkHttpClient getPinnedClient(URL url, Proxy proxy) throws IOException, TlsHelper.TlsHelperException { return new OkHttpClient.Builder() + // don't follow any redirects for keyservers, as discussed in the security audit .followRedirects(false) .followSslRedirects(false) .proxy(proxy) + // higher timeouts for Tor .connectTimeout(30000, TimeUnit.MILLISECONDS) .readTimeout(45000, TimeUnit.MILLISECONDS) + // use pinned cert with SocketFactory .sslSocketFactory(TlsHelper.getPinnedSslSocketFactory(url)) .build(); } - public static OkHttpClient getClient( Proxy proxy) throws IOException, TlsHelper.TlsHelperException { + public static OkHttpClient getClient(Proxy proxy) throws IOException, TlsHelper.TlsHelperException { return new OkHttpClient.Builder() + // don't follow any redirects for keyservers, as discussed in the security audit .followRedirects(false) .followSslRedirects(false) .proxy(proxy) + // higher timeouts for Tor .connectTimeout(30000, TimeUnit.MILLISECONDS) .readTimeout(45000, TimeUnit.MILLISECONDS) .build(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index afe688bbe..9b7b31d68 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -24,6 +24,7 @@ import okhttp3.OkHttpClient; import okhttp3.OkUrlFactory; import okhttp3.Request; import okhttp3.Response; + import org.sufficientlysecure.keychain.Constants; import java.io.IOException; @@ -36,8 +37,6 @@ import java.net.URLConnection; */ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { - - @Override public Response getUrlResponse(URL url, Proxy proxy, boolean isKeybase) throws IOException { OkHttpClient client = null; @@ -58,7 +57,7 @@ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { Request request = new Request.Builder() .url(url).build(); okhttp3.Response okResponse = client.newCall(request).execute(); - return new Response(okResponse.body().byteStream(),okResponse.code(),okResponse.message(), okResponse.headers().toMultimap()); + return new Response(okResponse.body().byteStream(), okResponse.code(), okResponse.message(), okResponse.headers().toMultimap()); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java index c23985ac0..77ed6fe0b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java @@ -19,8 +19,6 @@ package org.sufficientlysecure.keychain.util; import android.content.res.AssetManager; - -import okhttp3.OkHttpClient; import org.sufficientlysecure.keychain.Constants; import java.io.ByteArrayInputStream; @@ -93,7 +91,6 @@ public class TlsHelper { * Therefore a builder that is pinned this way should be used to only make requests to URLs with passed certificate. * * @param certificate certificate to pin - * @param builder OkHttpBuilder to enforce pinning on * @throws TlsHelperException * @throws IOException */ @@ -125,7 +122,6 @@ public class TlsHelper { context.init(null, tmf.getTrustManagers(), null); return context.getSocketFactory(); - //builder.sslSocketFactory(context.getSocketFactory()); } catch (CertificateException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) { throw new TlsHelperException(e); } -- cgit v1.2.3 From c8e5395d4e3c3dcc349ebe6bb300016f44d430d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 9 Apr 2016 18:34:00 +0200 Subject: Use cert pinning only if available --- .../keychain/keyimport/FacebookKeyserver.java | 4 +- .../keychain/keyimport/HkpKeyserver.java | 4 +- .../keychain/linked/LinkedTokenResource.java | 2 +- .../ui/dialog/AddEditKeyserverDialogFragment.java | 4 +- .../keychain/util/OkHttpClientFactory.java | 47 +++++++++++----------- .../keychain/util/OkHttpKeybaseClient.java | 9 +---- .../keychain/util/TlsHelper.java | 7 ++-- 7 files changed, 36 insertions(+), 41 deletions(-) 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 1c592003c..6217d1a01 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/FacebookKeyserver.java @@ -106,10 +106,10 @@ public class FacebookKeyserver extends Keyserver { String request = String.format(FB_KEY_URL_FORMAT, fbUsername); Log.d(Constants.TAG, "fetching from Facebook with: " + request + " proxy: " + mProxy); - OkHttpClient client = OkHttpClientFactory.getClient(mProxy); - URL url = new URL(request); + OkHttpClient client = OkHttpClientFactory.getClientPinnedIfAvailable(url, mProxy); + Response response = client.newCall(new Request.Builder().url(url).build()).execute(); // contains body both in case of success or failure diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java index bdf43b6da..5e3d2ebc6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/HkpKeyserver.java @@ -205,7 +205,7 @@ public class HkpKeyserver extends Keyserver { try { URL url = new URL(getUrlPrefix() + mHost + ":" + mPort + request); Log.d(Constants.TAG, "hkp keyserver query: " + url + " Proxy: " + proxy); - OkHttpClient client = OkHttpClientFactory.getPinnedClient(url, proxy); + OkHttpClient client = OkHttpClientFactory.getClientPinnedIfAvailable(url, proxy); Response response = client.newCall(new Request.Builder().url(url).build()).execute(); String responseBody = response.body().string(); // contains body both in case of success or failure @@ -396,7 +396,7 @@ public class HkpKeyserver extends Keyserver { .post(body) .build(); - Response response = OkHttpClientFactory.getPinnedClient(url, mProxy).newCall(request).execute(); + Response response = OkHttpClientFactory.getClientPinnedIfAvailable(url, mProxy).newCall(request).execute(); Log.d(Constants.TAG, "response code: " + response.code()); Log.d(Constants.TAG, "answer: " + response.body().string()); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java index 4a8882d50..a5f882dd0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/linked/LinkedTokenResource.java @@ -244,7 +244,7 @@ public abstract class LinkedTokenResource extends LinkedResource { Log.d("Connection to: " + request.url().url().getHost(), ""); OkHttpClient client; if (pins != null) { - client = OkHttpClientFactory.getPinnedSimpleClient(getCertificatePinner(request.url().url().getHost(), pins)); + client = OkHttpClientFactory.getSimpleClientPinned(getCertificatePinner(request.url().url().getHost(), pins)); } else { client = OkHttpClientFactory.getSimpleClient(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java index a10b94b8e..3dcc2f58b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java @@ -353,8 +353,6 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On Log.d("Converted URL", newKeyserver.toString()); - OkHttpClient client = OkHttpClientFactory.getPinnedClient(newKeyserver.toURL(), proxy); - if (onlyTrustedKeyserver && TlsHelper.getPinnedSslSocketFactory(newKeyserver.toURL()) == null) { Log.w(Constants.TAG, "No pinned certificate for this host in OpenKeychain's assets."); @@ -362,6 +360,8 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On return reason; } + OkHttpClient client = OkHttpClientFactory.getClientPinnedIfAvailable(newKeyserver.toURL(), proxy); + client.newCall(new Request.Builder().url(newKeyserver.toURL()).build()).execute(); } catch (TlsHelper.TlsHelperException e) { reason = FailureReason.CONNECTION_FAILED; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java index f3606aa2f..ea2ae8368 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpClientFactory.java @@ -38,7 +38,7 @@ public class OkHttpClientFactory { return client; } - public static OkHttpClient getPinnedSimpleClient(CertificatePinner pinner) { + public static OkHttpClient getSimpleClientPinned(CertificatePinner pinner) { return new OkHttpClient.Builder() .connectTimeout(5000, TimeUnit.MILLISECONDS) .readTimeout(25000, TimeUnit.MILLISECONDS) @@ -46,32 +46,31 @@ public class OkHttpClientFactory { .build(); } - public static OkHttpClient getPinnedClient(URL url, Proxy proxy) throws IOException, TlsHelper.TlsHelperException { + public static OkHttpClient getClientPinnedIfAvailable(URL url, Proxy proxy) throws IOException, + TlsHelper.TlsHelperException { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); - return new OkHttpClient.Builder() - // don't follow any redirects for keyservers, as discussed in the security audit - .followRedirects(false) - .followSslRedirects(false) - .proxy(proxy) - // higher timeouts for Tor - .connectTimeout(30000, TimeUnit.MILLISECONDS) - .readTimeout(45000, TimeUnit.MILLISECONDS) - // use pinned cert with SocketFactory - .sslSocketFactory(TlsHelper.getPinnedSslSocketFactory(url)) - .build(); - } + // don't follow any redirects for keyservers, as discussed in the security audit + builder.followRedirects(false) + .followSslRedirects(false); + + if (proxy != null) { + // set proxy and higher timeouts for Tor + builder.proxy(proxy); + builder.connectTimeout(30000, TimeUnit.MILLISECONDS) + .readTimeout(45000, TimeUnit.MILLISECONDS); + } else { + builder.connectTimeout(5000, TimeUnit.MILLISECONDS) + .readTimeout(25000, TimeUnit.MILLISECONDS); + } - public static OkHttpClient getClient(Proxy proxy) throws IOException, TlsHelper.TlsHelperException { + // If a pinned cert is available, use it! + // NOTE: this fails gracefully back to "no pinning" if no cert is available. + if (url != null && TlsHelper.getPinnedSslSocketFactory(url) != null) { + builder.sslSocketFactory(TlsHelper.getPinnedSslSocketFactory(url)); + } - return new OkHttpClient.Builder() - // don't follow any redirects for keyservers, as discussed in the security audit - .followRedirects(false) - .followSslRedirects(false) - .proxy(proxy) - // higher timeouts for Tor - .connectTimeout(30000, TimeUnit.MILLISECONDS) - .readTimeout(45000, TimeUnit.MILLISECONDS) - .build(); + return builder.build(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java index 9b7b31d68..8d3eb6963 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/OkHttpKeybaseClient.java @@ -21,16 +21,13 @@ package org.sufficientlysecure.keychain.util; import com.textuality.keybase.lib.KeybaseUrlConnectionClient; import okhttp3.OkHttpClient; -import okhttp3.OkUrlFactory; import okhttp3.Request; -import okhttp3.Response; import org.sufficientlysecure.keychain.Constants; import java.io.IOException; import java.net.Proxy; import java.net.URL; -import java.net.URLConnection; /** * Wrapper for Keybase Lib @@ -42,10 +39,8 @@ public class OkHttpKeybaseClient implements KeybaseUrlConnectionClient { OkHttpClient client = null; try { - if (isKeybase && proxy != null) { - client = OkHttpClientFactory.getPinnedClient(url, proxy); - } else if (proxy != null) { - client = OkHttpClientFactory.getClient(proxy); + if (proxy != null) { + client = OkHttpClientFactory.getClientPinnedIfAvailable(url, proxy); } else { client = OkHttpClientFactory.getSimpleClient(); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java index 77ed6fe0b..fe62eff55 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/TlsHelper.java @@ -86,9 +86,10 @@ public class TlsHelper { } /** - * Modifies the builder to accept only requests with a given certificate. Applies to all URLs requested by the - * builder. - * Therefore a builder that is pinned this way should be used to only make requests to URLs with passed certificate. + * Modifies the builder to accept only requests with a given certificate. + * Applies to all URLs requested by the builder. + * Therefore a builder that is pinned this way should be used to only make requests + * to URLs with passed certificate. * * @param certificate certificate to pin * @throws TlsHelperException -- cgit v1.2.3 From 84769999224c22a645b68d1ffa3e9d767bc408ed Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Mon, 11 Apr 2016 00:02:05 +0600 Subject: Add missing keyholder string param --- OpenKeychain/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index d77d64a27..8bb5093eb 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1553,7 +1553,7 @@ "Import" "Bind Key" "Serial No: %s" - "Key holder: " + "Key holder: %s" ]]> "Security Token matches and is bound to key" "Security Token matches, can be bound to key" -- cgit v1.2.3 From 2d73b74dde85f67b4302606938fdcc708bafc4c0 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Mon, 4 Apr 2016 17:42:21 +0200 Subject: Use email field to match email in KeychainProvider fixes #1699 --- .../sufficientlysecure/keychain/provider/KeychainProvider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 9c5d0c054..8a5d09d7b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -456,12 +456,12 @@ public class KeychainProvider extends ContentProvider { if (i != 0) { emailWhere += " OR "; } - emailWhere += "tmp." + UserPackets.USER_ID + " LIKE "; - // match '*', so it has to be at the *end* of the user id if (match == KEY_RINGS_FIND_BY_EMAIL) { - emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">"); + emailWhere += "tmp." + UserPackets.EMAIL + " LIKE " + + DatabaseUtils.sqlEscapeString(chunks[i]); } else { - emailWhere += DatabaseUtils.sqlEscapeString("%" + chunks[i] + "%"); + emailWhere += "tmp." + UserPackets.USER_ID + " LIKE " + + DatabaseUtils.sqlEscapeString("%" + chunks[i] + "%"); } gotCondition = true; } -- cgit v1.2.3 From 6881754062dcd0b83431cfe36398d20e30922096 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Mon, 4 Apr 2016 17:40:31 +0200 Subject: Better handle user_id sidecases while splitting --- .../sufficientlysecure/keychain/pgp/KeyRing.java | 11 ++- .../keychain/provider/KeychainDatabase.java | 2 +- .../keychain/pgp/KeyRingTest.java | 57 -------------- .../keychain/pgp/SplitUserIdTest.java | 88 ++++++++++++++++++++++ 4 files changed, 99 insertions(+), 59 deletions(-) delete mode 100644 OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/KeyRingTest.java create mode 100644 OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/SplitUserIdTest.java diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java index 77977b691..94949d749 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/KeyRing.java @@ -61,6 +61,8 @@ public abstract class KeyRing { private static final Pattern USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$"); + private static final Pattern EMAIL_PATTERN = Pattern.compile("^.*@.*\\..*$"); + /** * Splits userId string into naming part, email part, and comment part *

@@ -71,7 +73,14 @@ public abstract class KeyRing { if (!TextUtils.isEmpty(userId)) { final Matcher matcher = USER_ID_PATTERN.matcher(userId); if (matcher.matches()) { - return new UserId(matcher.group(1), matcher.group(3), matcher.group(2)); + String name = matcher.group(1).isEmpty() ? null : matcher.group(1); + String comment = matcher.group(2); + String email = matcher.group(3); + if (comment == null && email == null && name != null && EMAIL_PATTERN.matcher(name).matches()) { + email = name; + name = null; + } + return new UserId(name, email, comment); } } return new UserId(null, null, null); 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 04c14491b..0eb7a0cdb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -54,7 +54,7 @@ import java.io.IOException; */ public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "openkeychain.db"; - private static final int DATABASE_VERSION = 16; + private static final int DATABASE_VERSION = 17; static Boolean apgHack = false; private Context mContext; diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/KeyRingTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/KeyRingTest.java deleted file mode 100644 index 64316b2a6..000000000 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/KeyRingTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015 Dominik Schürmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.pgp; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.sufficientlysecure.keychain.BuildConfig; -import org.sufficientlysecure.keychain.WorkaroundBuildConfig; - -@RunWith(RobolectricGradleTestRunner.class) -@Config(constants = WorkaroundBuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml") -public class KeyRingTest { - - @Test - public void splitCompleteUserIdShouldReturnAll3Components() throws Exception { - KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann (this is a comment) "); - Assert.assertEquals("Max Mustermann", info.name); - Assert.assertEquals("this is a comment", info.comment); - Assert.assertEquals("max@example.com", info.email); - } - - @Test - public void splitUserIdWithAllButCommentShouldReturnNameAndEmail() throws Exception { - KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann "); - Assert.assertEquals("Max Mustermann", info.name); - Assert.assertNull(info.comment); - Assert.assertEquals("max@example.com", info.email); - } - - @Test - public void splitUserIdWithAllButEmailShouldReturnNameAndComment() throws Exception { - KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann (this is a comment)"); - Assert.assertEquals(info.name, "Max Mustermann"); - Assert.assertEquals(info.comment, "this is a comment"); - Assert.assertNull(info.email); - } - -} \ No newline at end of file diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/SplitUserIdTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/SplitUserIdTest.java new file mode 100644 index 000000000..97feeea7b --- /dev/null +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/SplitUserIdTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.pgp; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.sufficientlysecure.keychain.BuildConfig; +import org.sufficientlysecure.keychain.WorkaroundBuildConfig; + +@RunWith(RobolectricGradleTestRunner.class) +@Config(constants = WorkaroundBuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml") +public class SplitUserIdTest { + + @Test + public void splitCompleteUserIdShouldReturnAll3Components() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann (this is a comment) "); + Assert.assertEquals("Max Mustermann", info.name); + Assert.assertEquals("this is a comment", info.comment); + Assert.assertEquals("max@example.com", info.email); + } + + @Test + public void splitUserIdWithAllButCommentShouldReturnNameAndEmail() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann "); + Assert.assertEquals("Max Mustermann", info.name); + Assert.assertNull(info.comment); + Assert.assertEquals("max@example.com", info.email); + } + + @Test + public void splitUserIdWithAllButEmailShouldReturnNameAndComment() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann (this is a comment)"); + Assert.assertEquals("Max Mustermann", info.name); + Assert.assertEquals("this is a comment", info.comment); + Assert.assertNull(info.email); + } + + @Test + public void splitUserIdWithCommentAndEmailShouldReturnCommentAndEmail() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId(" (this is a comment) "); + Assert.assertNull(info.name); + Assert.assertEquals("this is a comment", info.comment); + Assert.assertEquals("max@example.com", info.email); + } + + @Test + public void splitUserIdWithEmailShouldReturnEmail() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId("max@example.com"); + Assert.assertNull(info.name); + Assert.assertNull(info.comment); + Assert.assertEquals("max@example.com", info.email); + } + + @Test + public void splitUserIdWithNameShouldReturnName() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId("Max Mustermann"); + Assert.assertEquals("Max Mustermann", info.name); + Assert.assertNull(info.comment); + Assert.assertNull(info.email); + } + + @Test + public void splitUserIdWithCommentShouldReturnComment() throws Exception { + KeyRing.UserId info = KeyRing.splitUserId(" (this is a comment)"); + Assert.assertNull(info.name); + Assert.assertEquals("this is a comment", info.comment); + Assert.assertNull(info.email); + } +} \ No newline at end of file -- cgit v1.2.3 From a7a0d9dd4b545ea65444efad5ca96cb7bca919ef Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Tue, 12 Apr 2016 15:41:42 +0200 Subject: Unnecesary code removed and string repaired - Unnecesary import from RedirectImportKeyActivity.java removed - ..\value-w820dp\dimens.xml was unnecesary - \..value\dimens.xml unnecasary line - string sources repaired --- .../sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java | 2 +- OpenKeychain/src/main/res/values-w820dp/dimens.xml | 6 ------ OpenKeychain/src/main/res/values/dimens.xml | 1 - OpenKeychain/src/main/res/values/strings.xml | 6 +++--- 4 files changed, 4 insertions(+), 11 deletions(-) delete mode 100644 OpenKeychain/src/main/res/values-w820dp/dimens.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java index 635cdcaef..3d929636c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -19,7 +19,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AlertDialog; -import android.view.Window; + import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.base.BaseActivity; diff --git a/OpenKeychain/src/main/res/values-w820dp/dimens.xml b/OpenKeychain/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc81644..000000000 --- a/OpenKeychain/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/OpenKeychain/src/main/res/values/dimens.xml b/OpenKeychain/src/main/res/values/dimens.xml index 2630c407f..2aae06e2e 100644 --- a/OpenKeychain/src/main/res/values/dimens.xml +++ b/OpenKeychain/src/main/res/values/dimens.xml @@ -5,5 +5,4 @@ 120dp 222dp 0dp - 16dp \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 95e089275..725cd7b41 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1742,7 +1742,7 @@ "Import key attempt" "You scanned a fingerprint with another app, please scan with Openkeychain directly to be safe" - Scan again - Close - Key import redirection + "Scan again" + "Close" + "Key import redirection" -- cgit v1.2.3 From ff9226c25ce3a26e86c7dc9ed06e6ecc3e5f386d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 12 Apr 2016 16:15:07 +0200 Subject: Fix strings --- OpenKeychain/src/main/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 18007c53f..e6a336853 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -287,15 +287,15 @@ "Select a Key" "Open…" "RSA 2048" - "smaller filesize, considered secure until 2030" + "smaller file size, considered secure until 2030" "RSA 3072" "recommended, considered secure until 2040" "RSA 4096" "larger file size, considered secure until 2040+" "ECC P-256" - "very tiny filesize, considered secure until 2040 <br/> <u>experimental and not supported by all implementations</u>" + "very tiny file size, considered secure until 2040 <br/> <u>experimental and not supported by all implementations</u>" "ECC P-521" - "tiny filesize, considered secure until 2040+ <br/> <u>experimental and not supported by all implementations"</u> + "tiny file size, considered secure until 2040+ <br/> <u>experimental and not supported by all implementations"</u>" "None (subkey binding only)" "Sign" "Encrypt" -- cgit v1.2.3 From 8933263665c3f6fdb464b88828f47417820f39e8 Mon Sep 17 00:00:00 2001 From: Lubo Viluda Date: Tue, 12 Apr 2016 16:43:06 +0200 Subject: unnecesary code removed - setContentView removed - R.layout.redirect_import_keys_activity.xml removed --- .../sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java | 1 - OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml | 6 ------ 2 files changed, 7 deletions(-) delete mode 100644 OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java index 3d929636c..2abb98a03 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/RedirectImportKeysActivity.java @@ -29,7 +29,6 @@ public class RedirectImportKeysActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.redirect_import_keys_activity); startQrCodeCaptureActivity(); } diff --git a/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml b/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml deleted file mode 100644 index af9a8add6..000000000 --- a/OpenKeychain/src/main/res/layout/redirect_import_keys_activity.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - -- cgit v1.2.3 From f7654af00b510aa91badc52eeacb09bf3d0b24e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 12 Apr 2016 19:06:08 +0200 Subject: Revert usage of masked-edittext, back to plain edittexts for backup codes --- OpenKeychain/build.gradle | 2 - .../keychain/ui/BackupCodeFragment.java | 218 ++++++---- .../keychain/ui/PassphraseDialogActivity.java | 77 ++-- .../res/layout-w400dp/backup_code_fragment.xml | 459 +++++++++++++++++++++ .../passphrase_dialog_backup_code.xml | 201 +++++++++ .../res/layout-w600dp/backup_code_fragment.xml | 318 ++++++++++++-- .../src/main/res/layout/backup_code_fragment.xml | 344 +++++++++++++-- .../res/layout/passphrase_dialog_backup_code.xml | 173 +++++++- 8 files changed, 1604 insertions(+), 188 deletions(-) create mode 100644 OpenKeychain/src/main/res/layout-w400dp/backup_code_fragment.xml create mode 100644 OpenKeychain/src/main/res/layout-w400dp/passphrase_dialog_backup_code.xml diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index cd8142174..f4d18e82d 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -50,7 +50,6 @@ dependencies { compile 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.0' compile 'org.ocpsoft.prettytime:prettytime:4.0.1.Final' compile 'com.splitwise:tokenautocomplete:2.0.7@aar' - compile 'com.github.pinball83:masked-edittext:1.0.3' compile 'se.emilsjolander:stickylistheaders:2.7.0' compile 'org.sufficientlysecure:html-textview:1.3' compile 'org.sufficientlysecure:donations:2.4' @@ -101,7 +100,6 @@ dependencyVerification { 'org.commonjava.googlecode.markdown4j:markdown4j:e952e825d29e1317d96f79f346bfb6786c7c5eef50bd26e54a80823704b62e13', 'org.ocpsoft.prettytime:prettytime:ef7098d973ae78b57d1a22dc37d3b8a771bf030301300e24055d676b6cdc5e75', 'com.splitwise:tokenautocomplete:f56239588390f103b270b7c12361d99b06313a5a0410dc7f66e241ac4baf9baa', - 'com.github.pinball83:masked-edittext:b1913d86482c7066ebb7831696773ac131865dc441cf8a3fc41d3b7d5691724e', 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'org.sufficientlysecure:donations:96f8197bab26dfe41900d824f10f8f1914519cd62eedb77bdac5b223eccdf0a6', 'org.sufficientlysecure:html-textview:39048e35894e582adada388e6c00631803283f8defed8e07ad58a5f284f272ee', diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java index e7ff6ce46..65c51969e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeFragment.java @@ -18,14 +18,6 @@ package org.sufficientlysecure.keychain.ui; -import java.io.File; -import java.io.IOException; -import java.security.SecureRandom; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.Random; - import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; @@ -41,9 +33,8 @@ import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager.OnBackStackChangedListener; import android.text.Editable; -import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; -import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -52,12 +43,9 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; -import android.view.inputmethod.EditorInfo; import android.widget.EditText; import android.widget.TextView; -import com.github.pinball83.maskededittext.MaskedEditText; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.ExportResult; @@ -71,6 +59,14 @@ import org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator; import org.sufficientlysecure.keychain.util.FileHelper; import org.sufficientlysecure.keychain.util.Passphrase; +import java.io.File; +import java.io.IOException; +import java.security.SecureRandom; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Random; + public class BackupCodeFragment extends CryptoOperationFragment implements OnBackStackChangedListener { @@ -96,7 +92,7 @@ public class BackupCodeFragment extends CryptoOperationFragment=16 + textView.setBackgroundDrawable(null); } - }); - - - TextView codeDisplayText = (TextView) view.findViewById(R.id.backup_code_display); - setupAutomaticLinebreak(codeDisplayText); - - // set background to null in TextViews - this will retain padding from EditText style! - // noinspection deprecation, setBackground(Drawable) is API level >=16 - codeDisplayText.setBackgroundDrawable(null); + } - codeDisplayText.setText(mBackupCode); + setupEditTextFocusNext(mCodeEditText); + setupEditTextSuccessListener(mCodeEditText); mStatusAnimator = (ToolableViewAnimator) view.findViewById(R.id.status_animator); mTitleAnimator = (ToolableViewAnimator) view.findViewById(R.id.title_animator); @@ -347,67 +346,76 @@ public class BackupCodeFragment extends CryptoOperationFragment - * NOTE: I was not able to get this behaviour using XML! - * Looks like the order of these method calls matter, see http://stackoverflow.com/a/11171307 - */ - private void setupAutomaticLinebreak(TextView textview) { - textview.setSingleLine(true); - textview.setMaxLines(6); - textview.setHorizontallyScrolling(false); - } + private void setupEditTextSuccessListener(final EditText[] backupCodes) { + for (EditText backupCode : backupCodes) { - private void setupEditTextSuccessListener(final MaskedEditText backupCode) { - backupCode.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { + backupCode.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } + } - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } - @Override - public void afterTextChanged(Editable s) { - String currentBackupCode = backupCode.getText().toString(); - boolean inInputState = mCurrentState == BackupCodeState.STATE_INPUT - || mCurrentState == BackupCodeState.STATE_INPUT_ERROR; - boolean partIsComplete = (currentBackupCode.indexOf(' ') == -1); - if (!inInputState || !partIsComplete) { - return; + @Override + public void afterTextChanged(Editable s) { + if (s.length() > 4) { + throw new AssertionError("max length of each field is 4!"); + } + + boolean inInputState = mCurrentState == BackupCodeState.STATE_INPUT + || mCurrentState == BackupCodeState.STATE_INPUT_ERROR; + boolean partIsComplete = s.length() == 4; + if (!inInputState || !partIsComplete) { + return; + } + + checkIfCodeIsCorrect(); } + }); - checkIfCodeIsCorrect(currentBackupCode); - } - }); + } } - private void checkIfCodeIsCorrect(String currentBackupCode) { + private void checkIfCodeIsCorrect() { if (Constants.DEBUG && mDebugModeAcceptAnyCode) { switchState(BackupCodeState.STATE_OK, true); return; } - if (currentBackupCode.equals(mBackupCode)) { + StringBuilder backupCodeInput = new StringBuilder(26); + for (EditText editText : mCodeEditText) { + if (editText.getText().length() < 4) { + return; + } + backupCodeInput.append(editText.getText()); + backupCodeInput.append('-'); + } + backupCodeInput.deleteCharAt(backupCodeInput.length() - 1); + + // if they don't match, do nothing + if (backupCodeInput.toString().equals(mBackupCode)) { switchState(BackupCodeState.STATE_OK, true); return; } switchState(BackupCodeState.STATE_INPUT_ERROR, true); + } private static void animateFlashText( - final TextView textView, int color1, int color2, boolean staySecondColor) { + final TextView[] textViews, int color1, int color2, boolean staySecondColor) { ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), color1, color2); anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { - textView.setTextColor((Integer) animator.getAnimatedValue()); + for (TextView textView : textViews) { + textView.setTextColor((Integer) animator.getAnimatedValue()); + } } }); anim.setRepeatMode(ValueAnimator.REVERSE); @@ -418,6 +426,34 @@ public class BackupCodeFragment extends CryptoOperationFragment - * NOTE: I was not able to get this behaviour using XML! - * Looks like the order of these method calls matter, see http://stackoverflow.com/a/11171307 - */ - private void setupAutomaticLinebreak(TextView textview) { - textview.setSingleLine(true); - textview.setMaxLines(6); - textview.setHorizontallyScrolling(false); + private static void setupEditTextFocusNext(final EditText[] backupCodes) { + for (int i = 0; i < backupCodes.length - 1; i++) { + + final int next = i + 1; + + backupCodes[i].addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + boolean inserting = before < count; + boolean cursorAtEnd = (start + count) == 4; + + if (inserting && cursorAtEnd) { + backupCodes[next].requestFocus(); + } + } + + @Override + public void afterTextChanged(Editable s) { + } + }); + + } } + @Override public void onStart() { super.onStart(); @@ -356,8 +370,17 @@ public class PassphraseDialogActivity extends FragmentActivity { public void onClick(View v) { if (mRequiredInput.mType == RequiredInputType.BACKUP_CODE) { - Passphrase passphrase = - new Passphrase(mBackupCodeEditText.getText().toString()); + StringBuilder backupCodeInput = new StringBuilder(26); + for (EditText editText : mBackupCodeEditText) { + if (editText.getText().length() < 4) { + return; + } + backupCodeInput.append(editText.getText()); + backupCodeInput.append('-'); + } + backupCodeInput.deleteCharAt(backupCodeInput.length() - 1); + + Passphrase passphrase = new Passphrase(backupCodeInput.toString()); finishCaching(passphrase); return; diff --git a/OpenKeychain/src/main/res/layout-w400dp/backup_code_fragment.xml b/OpenKeychain/src/main/res/layout-w400dp/backup_code_fragment.xml new file mode 100644 index 000000000..407fa2d9e --- /dev/null +++ b/OpenKeychain/src/main/res/layout-w400dp/backup_code_fragment.xml @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +