From d75ea3f9e5b891e2dced2bb7cc0700c35f5bb7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 14:20:49 +0100 Subject: Certify not sign a key, added as button, does not belong to menu --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 4 +- .../keychain/pgp/PgpKeyOperation.java | 10 +- .../keychain/service/KeychainIntentService.java | 15 +- .../keychain/ui/CertifyKeyActivity.java | 319 ++++++++++++++++++++ .../keychain/ui/ImportKeysActivity.java | 8 +- .../keychain/ui/ImportKeysQrCodeFragment.java | 2 +- .../keychain/ui/SignKeyActivity.java | 321 --------------------- .../keychain/ui/ViewKeyActivity.java | 45 +-- .../src/main/res/layout/certify_key_activity.xml | 68 +++++ .../src/main/res/layout/sign_key_activity.xml | 68 ----- .../src/main/res/layout/view_key_activity.xml | 9 + OpenPGP-Keychain/src/main/res/menu/key_view.xml | 4 - .../src/main/res/values-de/strings.xml | 2 +- .../src/main/res/values-es-rCO/strings.xml | 2 +- .../src/main/res/values-fr/strings.xml | 2 +- .../src/main/res/values-it-rIT/strings.xml | 2 +- .../src/main/res/values-nl-rNL/strings.xml | 2 +- .../src/main/res/values-ru/strings.xml | 2 +- .../src/main/res/values-tr/strings.xml | 2 +- .../src/main/res/values-uk/strings.xml | 2 +- OpenPGP-Keychain/src/main/res/values/strings.xml | 8 +- 21 files changed, 455 insertions(+), 442 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java create mode 100644 OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml delete mode 100644 OpenPGP-Keychain/src/main/res/layout/sign_key_activity.xml (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 3ef04e4f6..4102a882e 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -249,9 +249,9 @@ android:label="@string/title_key_server_preference" android:windowSoftInputMode="stateHidden" /> + android:label="@string/title_certify_key" /> + * Copyright (C) 2011 Senecaso + * + * 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 java.util.Iterator; + +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.Preferences; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; +import org.sufficientlysecure.keychain.util.Log; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.Spinner; +import android.widget.Toast; + +import com.beardedhen.androidbootstrap.BootstrapButton; + +/** + * Signs the specified public key with the specified secret master key + */ +public class CertifyKeyActivity extends ActionBarActivity implements + SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { + private BootstrapButton mSignButton; + private CheckBox mUploadKeyCheckbox; + private Spinner mSelectKeyserverSpinner; + + private SelectSecretKeyLayoutFragment mSelectKeyFragment; + + private Uri mDataUri; + private long mPubKeyId = 0; + private long mMasterKeyId = 0; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.certify_key_activity); + + final ActionBar actionBar = getSupportActionBar(); + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(false); + actionBar.setHomeButtonEnabled(false); + + mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getSupportFragmentManager() + .findFragmentById(R.id.sign_key_select_key_fragment); + mSelectKeyFragment.setCallback(this); + mSelectKeyFragment.setFilterCertify(true); + + mSelectKeyserverSpinner = (Spinner) findViewById(R.id.sign_key_keyserver); + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_spinner_item, Preferences.getPreferences(this) + .getKeyServers()); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mSelectKeyserverSpinner.setAdapter(adapter); + + mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox); + if (!mUploadKeyCheckbox.isChecked()) { + mSelectKeyserverSpinner.setEnabled(false); + } else { + mSelectKeyserverSpinner.setEnabled(true); + } + + mUploadKeyCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { + + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (!isChecked) { + mSelectKeyserverSpinner.setEnabled(false); + } else { + mSelectKeyserverSpinner.setEnabled(true); + } + } + }); + + mSignButton = (BootstrapButton) findViewById(R.id.sign_key_sign_button); + mSignButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + if (mPubKeyId != 0) { + if (mMasterKeyId == 0) { + mSelectKeyFragment.setError(getString(R.string.select_key_to_sign)); + } else { + initiateSigning(); + } + } + } + }); + + mDataUri = getIntent().getData(); + if (mDataUri == null) { + Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!"); + finish(); + return; + } + + PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, mDataUri); + + if (signKey != null) { + mPubKeyId = PgpKeyHelper.getMasterKey(signKey).getKeyID(); + } + if (mPubKeyId == 0) { + Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!"); + finish(); + return; + } + } + + private void showPassphraseDialog(final long secretKeyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + startSigning(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(this, + messenger, secretKeyId); + + passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); + } catch (PgpGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + /** + * handles the UI bits of the signing process on the UI thread + */ + private void initiateSigning() { + PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, mPubKeyId); + if (pubring != null) { + // if we have already signed this key, dont bother doing it again + boolean alreadySigned = false; + + @SuppressWarnings("unchecked") + Iterator itr = pubring.getPublicKey(mPubKeyId).getSignatures(); + while (itr.hasNext()) { + PGPSignature sig = itr.next(); + if (sig.getKeyID() == mMasterKeyId) { + alreadySigned = true; + break; + } + } + + if (!alreadySigned) { + /* + * get the user's passphrase for this key (if required) + */ + String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); + if (passphrase == null) { + showPassphraseDialog(mMasterKeyId); + // bail out; need to wait until the user has entered the passphrase before trying again + return; + } else { + startSigning(); + } + } else { + Toast.makeText(this, R.string.key_has_already_been_signed, Toast.LENGTH_SHORT) + .show(); + + setResult(RESULT_CANCELED); + finish(); + } + } + } + + /** + * kicks off the actual signing process on a background thread + */ + private void startSigning() { + // Send all information needed to service to sign key in other thread + Intent intent = new Intent(this, KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_CERTIFY_KEYRING); + + // fill values for this action + Bundle data = new Bundle(); + + data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId); + data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after signing is done in ApgService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, + R.string.progress_signing, ProgressDialog.STYLE_SPINNER) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + + Toast.makeText(CertifyKeyActivity.this, R.string.key_sign_success, + Toast.LENGTH_SHORT).show(); + + // check if we need to send the key to the server or not + if (mUploadKeyCheckbox.isChecked()) { + // upload the newly signed key to the key server + uploadKey(); + } else { + setResult(RESULT_OK); + finish(); + } + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + private void uploadKey() { + // Send all information needed to service to upload key in other thread + Intent intent = new Intent(this, KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING); + + // set data uri as path to keyring + intent.setData(mDataUri); + + // fill values for this action + Bundle data = new Bundle(); + + Spinner keyServer = (Spinner) findViewById(R.id.sign_key_keyserver); + String server = (String) keyServer.getSelectedItem(); + data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Message is received after uploading is done in ApgService + KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, + R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + Toast.makeText(CertifyKeyActivity.this, R.string.key_send_success, + Toast.LENGTH_SHORT).show(); + + setResult(RESULT_OK); + finish(); + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + /** + * callback from select key fragment + */ + @Override + public void onKeySelected(long secretKeyId) { + mMasterKeyId = secretKeyId; + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index dc3a07def..70f3c955a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Dominik Schürmann + * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2011 Senecaso * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -127,7 +127,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa /* Scanning a fingerprint directly with Barcode Scanner */ getSupportActionBar().setSelectedNavigationItem(0); loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[0]); - loadFromFingerprintUri(dataUri); + loadFromFingerprintUri(savedInstanceState, dataUri); } else if (ACTION_IMPORT_KEY.equals(action)) { /* Keychain's own Actions */ getSupportActionBar().setSelectedNavigationItem(1); @@ -248,7 +248,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa ft.commit(); } - public void loadFromFingerprintUri(Uri dataUri) { + public void loadFromFingerprintUri(Bundle savedInstanceState, Uri dataUri) { String fingerprint = dataUri.toString().split(":")[1].toLowerCase(Locale.ENGLISH); Log.d(Constants.TAG, "fingerprint: " + fingerprint); @@ -267,7 +267,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa args.putString(ImportKeysServerFragment.ARG_QUERY, query); loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); - startListFragment(null, null, null, query); + startListFragment(savedInstanceState, null, null, query); } public void loadCallback(byte[] importData, Uri dataUri, String serverQuery, String keyServer) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java index 63727ad26..27628dad4 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java @@ -130,7 +130,7 @@ public class ImportKeysQrCodeFragment extends Fragment { } public void importFingerprint(Uri dataUri) { - mImportActivity.loadFromFingerprintUri(dataUri); + mImportActivity.loadFromFingerprintUri(null, dataUri); } private void importParts(String[] parts) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java deleted file mode 100644 index d9fb294d5..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SignKeyActivity.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * Copyright (C) 2011 Senecaso - * - * 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 java.util.Iterator; - -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.Preferences; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; -import org.sufficientlysecure.keychain.util.Log; - -import android.app.ProgressDialog; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.Spinner; -import android.widget.Toast; - -import com.beardedhen.androidbootstrap.BootstrapButton; - -/** - * Signs the specified public key with the specified secret master key - */ -public class SignKeyActivity extends ActionBarActivity implements - SelectSecretKeyLayoutFragment.SelectSecretKeyCallback { - private BootstrapButton mSignButton; - private CheckBox mUploadKeyCheckbox; - private Spinner mSelectKeyserverSpinner; - - private SelectSecretKeyLayoutFragment mSelectKeyFragment; - - private Uri mDataUri; - private long mPubKeyId = 0; - private long mMasterKeyId = 0; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.sign_key_activity); - - final ActionBar actionBar = getSupportActionBar(); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setDisplayHomeAsUpEnabled(false); - actionBar.setHomeButtonEnabled(false); - - mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getSupportFragmentManager() - .findFragmentById(R.id.sign_key_select_key_fragment); - mSelectKeyFragment.setCallback(this); - mSelectKeyFragment.setFilterCertify(true); - - mSelectKeyserverSpinner = (Spinner) findViewById(R.id.sign_key_keyserver); - ArrayAdapter adapter = new ArrayAdapter(this, - android.R.layout.simple_spinner_item, Preferences.getPreferences(this) - .getKeyServers()); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mSelectKeyserverSpinner.setAdapter(adapter); - - mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox); - if (!mUploadKeyCheckbox.isChecked()) { - mSelectKeyserverSpinner.setEnabled(false); - } else { - mSelectKeyserverSpinner.setEnabled(true); - } - - mUploadKeyCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (!isChecked) { - mSelectKeyserverSpinner.setEnabled(false); - } else { - mSelectKeyserverSpinner.setEnabled(true); - } - } - }); - - mSignButton = (BootstrapButton) findViewById(R.id.sign_key_sign_button); - mSignButton.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (mPubKeyId != 0) { - if (mMasterKeyId == 0) { - mSelectKeyFragment.setError(getString(R.string.select_key_to_sign)); - } else { - initiateSigning(); - } - } - } - }); - - mDataUri = getIntent().getData(); - if (mDataUri == null) { - Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!"); - finish(); - return; - } - - PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, mDataUri); - - if (signKey != null) { - mPubKeyId = PgpKeyHelper.getMasterKey(signKey).getKeyID(); - } - if (mPubKeyId == 0) { - Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!"); - finish(); - return; - } - } - - private void showPassphraseDialog(final long secretKeyId) { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - startSigning(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(this, - messenger, secretKeyId); - - passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); - } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - - /** - * handles the UI bits of the signing process on the UI thread - */ - private void initiateSigning() { - PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, mPubKeyId); - if (pubring != null) { - // if we have already signed this key, dont bother doing it again - boolean alreadySigned = false; - - @SuppressWarnings("unchecked") - Iterator itr = pubring.getPublicKey(mPubKeyId).getSignatures(); - while (itr.hasNext()) { - PGPSignature sig = itr.next(); - if (sig.getKeyID() == mMasterKeyId) { - alreadySigned = true; - break; - } - } - - if (!alreadySigned) { - /* - * get the user's passphrase for this key (if required) - */ - String passphrase = PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId); - if (passphrase == null) { - showPassphraseDialog(mMasterKeyId); - return; // bail out; need to wait until the user has entered the passphrase - // before trying again - } else { - startSigning(); - } - } else { - Toast.makeText(this, R.string.key_has_already_been_signed, Toast.LENGTH_SHORT) - .show(); - - setResult(RESULT_CANCELED); - finish(); - } - } - } - - /** - * kicks off the actual signing process on a background thread - */ - private void startSigning() { - // Send all information needed to service to sign key in other thread - Intent intent = new Intent(this, KeychainIntentService.class); - - intent.setAction(KeychainIntentService.ACTION_SIGN_KEYRING); - - // fill values for this action - Bundle data = new Bundle(); - - data.putLong(KeychainIntentService.SIGN_KEY_MASTER_KEY_ID, mMasterKeyId); - data.putLong(KeychainIntentService.SIGN_KEY_PUB_KEY_ID, mPubKeyId); - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // Message is received after signing is done in ApgService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, - R.string.progress_signing, ProgressDialog.STYLE_SPINNER) { - public void handleMessage(Message message) { - // handle messages by standard ApgHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - - Toast.makeText(SignKeyActivity.this, R.string.key_sign_success, - Toast.LENGTH_SHORT).show(); - - // check if we need to send the key to the server or not - if (mUploadKeyCheckbox.isChecked()) { - /* - * upload the newly signed key to the key server - */ - uploadKey(); - } else { - setResult(RESULT_OK); - finish(); - } - } - }; - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(this); - - // start service with intent - startService(intent); - } - - private void uploadKey() { - // Send all information needed to service to upload key in other thread - Intent intent = new Intent(this, KeychainIntentService.class); - - intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING); - - // set data uri as path to keyring - intent.setData(mDataUri); - - // fill values for this action - Bundle data = new Bundle(); - - Spinner keyServer = (Spinner) findViewById(R.id.sign_key_keyserver); - String server = (String) keyServer.getSelectedItem(); - data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server); - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // Message is received after uploading is done in ApgService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, - R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) { - public void handleMessage(Message message) { - // handle messages by standard ApgHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - Toast.makeText(SignKeyActivity.this, R.string.key_send_success, - Toast.LENGTH_SHORT).show(); - - setResult(RESULT_OK); - finish(); - } - }; - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(this); - - // start service with intent - startService(intent); - } - - /** - * callback from select key fragment - */ - @Override - public void onKeySelected(long secretKeyId) { - mMasterKeyId = secretKeyId; - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 99d93fbbd..0bfc51e67 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -75,6 +75,7 @@ public class ViewKeyActivity extends ActionBarActivity implements private TextView mCreation; private TextView mFingerprint; private BootstrapButton mActionEncrypt; + private BootstrapButton mActionCertify; private ListView mUserIds; private ListView mKeys; @@ -91,6 +92,7 @@ public class ViewKeyActivity extends ActionBarActivity implements mExportHelper = new ExportHelper(this); + // let the actionbar look like Android's contact app getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setIcon(android.R.color.transparent); getSupportActionBar().setHomeButtonEnabled(true); @@ -105,9 +107,10 @@ public class ViewKeyActivity extends ActionBarActivity implements mCreation = (TextView) findViewById(R.id.creation); mExpiry = (TextView) findViewById(R.id.expiry); mFingerprint = (TextView) findViewById(R.id.fingerprint); - mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt); mUserIds = (ListView) findViewById(R.id.user_ids); mKeys = (ListView) findViewById(R.id.keys); + mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt); + mActionCertify = (BootstrapButton) findViewById(R.id.action_certify); loadData(getIntent()); } @@ -130,9 +133,6 @@ public class ViewKeyActivity extends ActionBarActivity implements case R.id.menu_key_view_update: updateFromKeyserver(mDataUri); return true; - case R.id.menu_key_view_sign: - signKey(mDataUri); - return true; case R.id.menu_key_view_export_keyserver: uploadToKeyserver(mDataUri); return true; @@ -196,19 +196,18 @@ public class ViewKeyActivity extends ActionBarActivity implements @Override public void onClick(View v) { - long keyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, mDataUri); - - long[] encryptionKeyIds = new long[]{keyId}; - Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class); - intent.setAction(EncryptActivity.ACTION_ENCRYPT); - intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); - // used instead of startActivity set actionbar based on callingPackage - startActivityForResult(intent, 0); + encryptToContact(mDataUri); } }); + mActionCertify.setOnClickListener(new OnClickListener() { - mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0); + @Override + public void onClick(View v) { + certifyKey(mDataUri); + } + }); + mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0); mUserIds.setAdapter(mUserIdsAdapter); // mUserIds.setEmptyView(findViewById(android.R.id.empty)); // mUserIds.setClickable(true); @@ -219,11 +218,10 @@ public class ViewKeyActivity extends ActionBarActivity implements // }); mKeysAdapter = new ViewKeyKeysAdapter(this, null, 0); - mKeys.setAdapter(mKeysAdapter); - // Prepare the loader. Either re-connect with an existing one, - // or start a new one. + // Prepare the loaders. Either re-connect with an existing ones, + // or start new ones. getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this); getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this); @@ -405,8 +403,19 @@ public class ViewKeyActivity extends ActionBarActivity implements startActivityForResult(queryIntent, Id.request.look_up_key_id); } - private void signKey(Uri dataUri) { - Intent signIntent = new Intent(this, SignKeyActivity.class); + private void encryptToContact(Uri dataUri) { + long keyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri); + + long[] encryptionKeyIds = new long[]{keyId}; + Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class); + intent.setAction(EncryptActivity.ACTION_ENCRYPT); + intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); + // used instead of startActivity set actionbar based on callingPackage + startActivityForResult(intent, 0); + } + + private void certifyKey(Uri dataUri) { + Intent signIntent = new Intent(this, CertifyKeyActivity.class); signIntent.setData(dataUri); startActivity(signIntent); } diff --git a/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml new file mode 100644 index 000000000..1dbd2476c --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/sign_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/sign_key_activity.xml deleted file mode 100644 index 07f63b91b..000000000 --- a/OpenPGP-Keychain/src/main/res/layout/sign_key_activity.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml index 73a86a725..1c937430a 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml @@ -215,6 +215,15 @@ android:text="@string/key_view_action_encrypt" bootstrapbutton:bb_icon_left="fa-lock" bootstrapbutton:bb_type="info" /> + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/menu/key_view.xml b/OpenPGP-Keychain/src/main/res/menu/key_view.xml index acf3eb099..59247221a 100644 --- a/OpenPGP-Keychain/src/main/res/menu/key_view.xml +++ b/OpenPGP-Keychain/src/main/res/menu/key_view.xml @@ -64,10 +64,6 @@ android:title="@string/menu_export_key_to_server" /> - Schlüssel-Server abfragen Auf Schlüsselserver hochladen Unbekannter Signaturschlüssel - Schlüssel signieren + Schlüssel signieren Schlüsseldetails Hilfe diff --git a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml index 8f508a885..6c520988f 100644 --- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml @@ -22,7 +22,7 @@ Clave no encontrada Solicitar al servidor de claves Clave de firma desconocida - Clave de firma + Clave de firma Ayuda IDs de usuario diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index d427403dd..5f12275b9 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -25,7 +25,7 @@ Interroger le serveur de clefs Téléverser vers le serveur de clefs Clef de signature inconnue - Signer la clef + Signer la clef Détails sur la clef Aide diff --git a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml index 44424561b..71783d3b2 100644 --- a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml @@ -15,7 +15,7 @@ Esportare Chiave Esportare Chiavi Chiave Non Trovata - Firma Chiave + Firma Chiave Aiuto ID Utente diff --git a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml index b0d792708..7389664fe 100644 --- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml @@ -22,7 +22,7 @@ Sleutel niet gevonden Sleutelserver verzoek zenden Onbekende handtekeningssleutel - Sleutel ondertekenen + Sleutel ondertekenen Help Gebruikers-id\'s diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index 91ec2d1af..dd9eaf86d 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -25,7 +25,7 @@ Запросить сервер ключей Загрузить на сервер ключей Неизвестная подпись - Ключ для подписи + Ключ для подписи Сведения о ключе Помощь diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml index d9fe8713e..20d99ae2e 100644 --- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml @@ -14,7 +14,7 @@ Anahtar Bulunamadı Anahtar Sunucusunu Sorgula Bilinmeyen İmza Anahtarı - Anahtarı İmzala + Anahtarı İmzala Anahtar Detayları Yardım diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml index ac40311b0..b08c8edc2 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml @@ -25,7 +25,7 @@ Сервер запиту ключа Завантажити на сервер ключів Невідомий підпис ключа - Підписати ключ + Підписати ключ Подробиці про ключ Довідка diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index fb7b60b7c..0d8870a3e 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -26,7 +26,7 @@ Query Key Server Upload to Key Server Unknown Signature Key - Sign Key + Certify Key Key Details Help @@ -39,7 +39,7 @@ Master Key Master User ID Actions - Your Key used for Signing + Your Key used for certification Upload Key Key Server Encrypt and/or Sign @@ -47,6 +47,7 @@ Sign + Certify Decrypt Decrypt and Verify Select Recipients @@ -126,7 +127,7 @@ Name Comment Email - Upload key to selected key server after signing + Upload key to selected key server after certification Fingerprint Select @@ -406,6 +407,7 @@ Encrypt to this contact + Certify User ID of this contact Contacts -- cgit v1.2.3 From c434c426e7946a42df181921852e46a86db170df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 15:01:50 +0100 Subject: Show revoked status in key list --- .../keychain/provider/KeychainProvider.java | 2 ++ .../keychain/ui/KeyListPublicFragment.java | 38 ++++++++++++---------- .../keychain/ui/adapter/ImportKeysAdapter.java | 2 +- .../keychain/ui/adapter/KeyListPublicAdapter.java | 29 ++++++++++++----- .../src/main/res/layout/key_list_item.xml | 28 ++++++++++++---- OpenPGP-Keychain/src/main/res/values/strings.xml | 1 + 6 files changed, 68 insertions(+), 32 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index cd3007353..781f36758 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -359,7 +359,9 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID); // TODO: deprecated master key id //projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.KEY_ID); + projectionMap.put(KeysColumns.FINGERPRINT, Tables.KEYS + "." + KeysColumns.FINGERPRINT); + projectionMap.put(KeysColumns.IS_REVOKED, Tables.KEYS + "." + KeysColumns.IS_REVOKED); projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java index 6ae2b9bf9..98116290d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java @@ -30,6 +30,7 @@ import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import se.emilsjolander.stickylistheaders.ApiLevelTooLowException; import se.emilsjolander.stickylistheaders.StickyListHeadersListView; + import android.annotation.SuppressLint; import android.content.Intent; import android.database.Cursor; @@ -63,7 +64,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte private KeyListPublicAdapter mAdapter; private StickyListHeadersListView mStickyList; - // empty layout + // empty list layout private BootstrapButton mButtonEmptyCreate; private BootstrapButton mButtonEmptyImport; @@ -92,9 +93,9 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte @Override public void onClick(View v) { - Intent intentImportFromFile = new Intent(getActivity(), ImportKeysActivity.class); - intentImportFromFile.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE); - startActivityForResult(intentImportFromFile, 0); + Intent intent = new Intent(getActivity(), ImportKeysActivity.class); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE); + startActivityForResult(intent, 0); } }); @@ -109,7 +110,6 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - // mKeyListPublicActivity = (KeyListPublicActivity) getActivity(); mStickyList = (StickyListHeadersListView) getActivity().findViewById(R.id.list); mStickyList.setOnItemClickListener(this); @@ -159,16 +159,16 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte } switch (item.getItemId()) { - case R.id.menu_key_list_public_multi_encrypt: { - encrypt(ids); + case R.id.menu_key_list_public_multi_encrypt: { + encrypt(ids); - break; - } - case R.id.menu_key_list_public_multi_delete: { - showDeleteKeyDialog(ids); + break; + } + case R.id.menu_key_list_public_multi_delete: { + showDeleteKeyDialog(ids); - break; - } + break; + } } return false; } @@ -181,7 +181,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, - boolean checked) { + boolean checked) { if (checked) { count++; mAdapter.setNewSelection(position, checked); @@ -212,8 +212,12 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte } // These are the rows that we will retrieve. - static final String[] PROJECTION = new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID, - UserIds.USER_ID }; + static final String[] PROJECTION = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.UserIds.USER_ID, + KeychainContract.Keys.IS_REVOKED + }; static final int USER_ID_INDEX = 2; @@ -286,7 +290,7 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte /** * Show dialog to delete key - * + * * @param keyRingRowIds */ public void showDeleteKeyDialog(long[] keyRingRowIds) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index a850fc020..a282932dc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -129,7 +129,7 @@ public class ImportKeysAdapter extends ArrayAdapter { algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm); if (entry.revoked) { - status.setText("revoked"); + status.setText(R.string.revoked); } else { status.setVisibility(View.GONE); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java index f0e926655..5ab22eadd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java @@ -23,10 +23,12 @@ import java.util.Set; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.util.Log; import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; + import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; @@ -44,6 +46,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea private LayoutInflater mInflater; private int mSectionColumnIndex; private int mIndexUserId; + private int mIndexIsRevoked; @SuppressLint("UseSparseArrays") private HashMap mSelection = new HashMap(); @@ -66,27 +69,31 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea /** * Get column indexes for performance reasons just once in constructor and swapCursor. For a * performance comparison see http://stackoverflow.com/a/17999582 - * + * * @param cursor */ private void initIndex(Cursor cursor) { if (cursor != null) { - mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID); + mIndexUserId = cursor.getColumnIndexOrThrow(KeychainContract.UserIds.USER_ID); + mIndexIsRevoked = cursor.getColumnIndexOrThrow(KeychainContract.Keys.IS_REVOKED); } } /** * Bind cursor data to the item list view - * + *

* NOTE: CursorAdapter already implements the ViewHolder pattern in its getView() method. Thus * no ViewHolder is required here. */ @Override public void bindView(View view, Context context, Cursor cursor) { TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(R.string.user_id_no_name); TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); + TextView revoked = (TextView) view.findViewById(R.id.revoked); + + mainUserId.setText(R.string.user_id_no_name); mainUserIdRest.setText(""); + revoked.setVisibility(View.GONE); String userId = cursor.getString(mIndexUserId); String[] userIdSplit = PgpKeyHelper.splitUserId(userId); @@ -97,6 +104,11 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea if (userIdSplit[1] != null) { mainUserIdRest.setText(userIdSplit[1]); } + + boolean isRevoked = cursor.getInt(mIndexIsRevoked) > 0; + if (isRevoked) { + revoked.setVisibility(View.VISIBLE); + } } @Override @@ -107,7 +119,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea /** * Creates a new header view and binds the section headers to it. It uses the ViewHolder * pattern. Most functionality is similar to getView() from Android's CursorAdapter. - * + *

* NOTE: The variables mDataValid and mCursor are available due to the super class * CursorAdapter. */ @@ -159,8 +171,7 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea } // return the first character of the name as ID because this is what - // headers private HashMap mSelection = new HashMap();are based upon + // headers are based upon String userId = mCursor.getString(mSectionColumnIndex); if (userId != null && userId.length() > 0) { return userId.subSequence(0, 1).charAt(0); @@ -173,7 +184,9 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea TextView text; } - /** -------------------------- MULTI-SELECTION METHODS -------------- */ + /** + * -------------------------- MULTI-SELECTION METHODS -------------- + */ public void setNewSelection(int position, boolean value) { mSelection.put(position, value); notifyDataSetChanged(); diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml index 2571bb6e7..650485d71 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml @@ -1,24 +1,40 @@ - + android:singleLine="true"> + android:textAppearance="?android:attr/textAppearanceMedium" + android:layout_alignParentTop="true" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" /> + android:textAppearance="?android:attr/textAppearanceSmall" + android:layout_below="@+id/mainUserId" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" /> - \ No newline at end of file + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 0d8870a3e..8c26ac548 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -143,6 +143,7 @@ can encrypt can sign expired + revoked %d key server -- cgit v1.2.3 From 99ec57aeaad47afab1f6474280a648cb76decd65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 17:52:17 +0100 Subject: nicer list items --- .../keychain/ui/adapter/KeyListPublicAdapter.java | 26 ++++++++++---- .../keychain/ui/adapter/KeyListSecretAdapter.java | 2 +- .../main/res/layout/api_apps_adapter_list_item.xml | 9 +++-- .../src/main/res/layout/key_list_item.xml | 40 ---------------------- .../main/res/layout/key_list_secret_activity.xml | 10 ++++-- .../src/main/res/layout/key_list_secret_item.xml | 31 +++++++++++++++++ 6 files changed, 63 insertions(+), 55 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/res/layout/key_list_item.xml create mode 100644 OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java index 5ab22eadd..6b8eda1e8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java @@ -24,7 +24,6 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.util.Log; import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; @@ -37,6 +36,7 @@ import android.support.v4.widget.CursorAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.RelativeLayout; import android.widget.TextView; /** @@ -91,29 +91,43 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); TextView revoked = (TextView) view.findViewById(R.id.revoked); - mainUserId.setText(R.string.user_id_no_name); - mainUserIdRest.setText(""); - revoked.setVisibility(View.GONE); - String userId = cursor.getString(mIndexUserId); String[] userIdSplit = PgpKeyHelper.splitUserId(userId); if (userIdSplit[0] != null) { mainUserId.setText(userIdSplit[0]); + } else { + mainUserId.setText(R.string.user_id_no_name); } + if (userIdSplit[1] != null) { mainUserIdRest.setText(userIdSplit[1]); + mainUserIdRest.setVisibility(View.VISIBLE); + // disable centering of main user id field + RelativeLayout.LayoutParams layoutParams = + (RelativeLayout.LayoutParams) mainUserId.getLayoutParams(); + layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, 0); + mainUserId.setLayoutParams(layoutParams); + } else { + mainUserIdRest.setVisibility(View.INVISIBLE); + // center main user id field + RelativeLayout.LayoutParams layoutParams = + (RelativeLayout.LayoutParams) mainUserId.getLayoutParams(); + layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); + mainUserId.setLayoutParams(layoutParams); } boolean isRevoked = cursor.getInt(mIndexIsRevoked) > 0; if (isRevoked) { revoked.setVisibility(View.VISIBLE); + } else { + revoked.setVisibility(View.GONE); } } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.key_list_item, null); + return mInflater.inflate(R.layout.key_list_public_item, null); } /** diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java index ce9b48bff..34e2104c6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java @@ -88,7 +88,7 @@ public class KeyListSecretAdapter extends CursorAdapter { @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { - return mInflater.inflate(R.layout.key_list_item, null); + return mInflater.inflate(R.layout.key_list_secret_item, null); } /** -------------------------- MULTI-SELECTION METHODS -------------- */ diff --git a/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml index cb20a20af..c89540291 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml @@ -1,14 +1,13 @@ + android:layout_height="wrap_content" + android:paddingTop="4dp" + android:paddingBottom="4dp"> \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml deleted file mode 100644 index 650485d71..000000000 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_item.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_activity.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_activity.xml index 13370f2e5..cd208a545 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_activity.xml @@ -2,17 +2,21 @@ + android:layout_height="match_parent"> + android:layout_height="match_parent"> + android:layout_height="match_parent" + android:paddingBottom="16dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:scrollbarStyle="outsideOverlay" /> diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml new file mode 100644 index 000000000..3c9ec6aee --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file -- cgit v1.2.3 From 34ec841a0b536b68b98776ca36e4e618cf9bb985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 18:16:21 +0100 Subject: More layout fixes --- .../keychain/ui/adapter/ImportKeysAdapter.java | 11 +++--- .../keychain/ui/adapter/KeyListPublicAdapter.java | 12 +----- .../keychain/ui/adapter/KeyListSecretAdapter.java | 6 ++- .../ui/adapter/SelectKeyCursorAdapter.java | 12 ++++-- .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 13 ++++--- .../src/main/res/layout/key_list_public_item.xml | 45 ++++++++++++++++++++++ .../src/main/res/layout/key_list_secret_item.xml | 5 ++- 7 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index a282932dc..02a5fea9c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -90,16 +90,11 @@ public class ImportKeysAdapter extends ArrayAdapter { View view = mInflater.inflate(R.layout.import_keys_list_entry, null); TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(R.string.user_id_no_name); TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); - mainUserIdRest.setText(""); TextView keyId = (TextView) view.findViewById(R.id.keyId); - keyId.setText(R.string.no_key); TextView fingerprint = (TextView) view.findViewById(R.id.fingerprint); TextView algorithm = (TextView) view.findViewById(R.id.algorithm); - algorithm.setText(""); TextView status = (TextView) view.findViewById(R.id.status); - status.setText(""); // main user id String userId = entry.userIds.get(0); @@ -113,6 +108,8 @@ public class ImportKeysAdapter extends ArrayAdapter { mainUserId.setTextColor(Color.RED); } mainUserId.setText(userIdSplit[0]); + } else { + mainUserId.setText(R.string.user_id_no_name); } // email @@ -123,9 +120,13 @@ public class ImportKeysAdapter extends ArrayAdapter { mainUserIdRest.setVisibility(View.GONE); } + // TODO: need to set no key? + keyId.setText(R.string.no_key); keyId.setText(entry.hexKeyId); fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint); + // TODO: no need to set algorithm empty... + algorithm.setText(""); algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm); if (entry.revoked) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java index 6b8eda1e8..40cdb91ad 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java @@ -103,18 +103,8 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea if (userIdSplit[1] != null) { mainUserIdRest.setText(userIdSplit[1]); mainUserIdRest.setVisibility(View.VISIBLE); - // disable centering of main user id field - RelativeLayout.LayoutParams layoutParams = - (RelativeLayout.LayoutParams) mainUserId.getLayoutParams(); - layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, 0); - mainUserId.setLayoutParams(layoutParams); } else { - mainUserIdRest.setVisibility(View.INVISIBLE); - // center main user id field - RelativeLayout.LayoutParams layoutParams = - (RelativeLayout.LayoutParams) mainUserId.getLayoutParams(); - layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); - mainUserId.setLayoutParams(layoutParams); + mainUserIdRest.setVisibility(View.GONE); } boolean isRevoked = cursor.getInt(mIndexIsRevoked) > 0; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java index 34e2104c6..11d1e8c17 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java @@ -71,18 +71,20 @@ public class KeyListSecretAdapter extends CursorAdapter { @Override public void bindView(View view, Context context, Cursor cursor) { TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(R.string.user_id_no_name); TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); - mainUserIdRest.setText(""); String userId = cursor.getString(mIndexUserId); String[] userIdSplit = PgpKeyHelper.splitUserId(userId); if (userIdSplit[0] != null) { mainUserId.setText(userIdSplit[0]); + } else { + mainUserId.setText(R.string.user_id_no_name); } if (userIdSplit[1] != null) { mainUserIdRest.setText(userIdSplit[1]); + } else { + mainUserIdRest.setText(""); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java index 7e01faf9b..d44dd5890 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java @@ -96,27 +96,31 @@ public class SelectKeyCursorAdapter extends CursorAdapter { boolean valid = cursor.getInt(mIndexProjectionValid) > 0; TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(R.string.user_id_no_name); TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); - mainUserIdRest.setText(""); TextView keyId = (TextView) view.findViewById(R.id.keyId); - keyId.setText(R.string.no_key); TextView status = (TextView) view.findViewById(R.id.status); - status.setText(R.string.unknown_status); String userId = cursor.getString(mIndexUserId); String[] userIdSplit = PgpKeyHelper.splitUserId(userId); if (userIdSplit[0] != null) { mainUserId.setText(userIdSplit[0]); + } else { + mainUserId.setText(R.string.user_id_no_name); } if (userIdSplit[1] != null) { mainUserIdRest.setText(userIdSplit[1]); + } else { + mainUserIdRest.setText(""); } + // TODO: needed to key id to no? + keyId.setText(R.string.no_key); long masterKeyId = cursor.getLong(mIndexMasterKeyId); keyId.setText(PgpKeyHelper.convertKeyIdToHex(masterKeyId)); + // TODO: needed to set unknown_status? + status.setText(R.string.unknown_status); if (valid) { if (mKeyType == Id.type.public_key) { status.setText(R.string.can_encrypt); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java index d5162c403..54c7eb60e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java @@ -76,38 +76,39 @@ public class ViewKeyKeysAdapter extends CursorAdapter { @Override public void bindView(View view, Context context, Cursor cursor) { + TextView keyId = (TextView) view.findViewById(R.id.keyId); + TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); + ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); + ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); + ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); + ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); + String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId)); String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm), cursor.getInt(mIndexKeySize)); - TextView keyId = (TextView) view.findViewById(R.id.keyId); keyId.setText(keyIdStr); - TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); keyDetails.setText("(" + algorithmStr + ")"); - ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); if (cursor.getInt(mIndexIsMasterKey) != 1) { masterKeyIcon.setVisibility(View.INVISIBLE); } else { masterKeyIcon.setVisibility(View.VISIBLE); } - ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); if (cursor.getInt(mIndexCanCertify) != 1) { certifyIcon.setVisibility(View.GONE); } else { certifyIcon.setVisibility(View.VISIBLE); } - ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); if (cursor.getInt(mIndexCanEncrypt) != 1) { encryptIcon.setVisibility(View.GONE); } else { encryptIcon.setVisibility(View.VISIBLE); } - ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); if (cursor.getInt(mIndexCanSign) != 1) { signIcon.setVisibility(View.GONE); } else { diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml new file mode 100644 index 000000000..9307ab2e5 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_public_item.xml @@ -0,0 +1,45 @@ + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml index 3c9ec6aee..1ed86f730 100644 --- a/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/key_list_secret_item.xml @@ -1,8 +1,9 @@ Date: Tue, 4 Feb 2014 18:36:10 +0100 Subject: better help text --- .../keychain/ui/adapter/KeyListPublicAdapter.java | 2 -- .../src/main/res/raw-de/help_start.html | 30 +++++++++++----------- OpenPGP-Keychain/src/main/res/raw/help_start.html | 23 +++++++---------- 3 files changed, 24 insertions(+), 31 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java index 40cdb91ad..257136cbd 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java @@ -93,13 +93,11 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea String userId = cursor.getString(mIndexUserId); String[] userIdSplit = PgpKeyHelper.splitUserId(userId); - if (userIdSplit[0] != null) { mainUserId.setText(userIdSplit[0]); } else { mainUserId.setText(R.string.user_id_no_name); } - if (userIdSplit[1] != null) { mainUserIdRest.setText(userIdSplit[1]); mainUserIdRest.setVisibility(View.VISIBLE); diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index 1386e8cc1..e2841ac5c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -1,22 +1,22 @@ + - + + -

EXPERIMENTAL software

-

This is EXPERIMENTAL software. Use at your own risk!

-

Getting started

-

First you need some keys. Import or create them via the option menus in "My Secret Keys". -
It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

- -

Big ToDos

-
    -
  • K9 Mail integration not published
  • -
  • Importing existing keys will be stripped of certificates right now
  • -
  • PGP/MIME in K9 Mail is missing
  • -
-

If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

+

First you need some keys. Import or create them via the option menus in "My Keys". +
It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

I found a bug in OpenPGP Keychain!

-

Please report it in the issue tracker of OpenPGP Keychain.

+

Please report it in the issue tracker of OpenPGP Keychain.

+ +

Contribute

+

If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

+ +

Translations

+

Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

+ diff --git a/OpenPGP-Keychain/src/main/res/raw/help_start.html b/OpenPGP-Keychain/src/main/res/raw/help_start.html index 097e22ba8..8aedfb370 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_start.html @@ -5,23 +5,18 @@ And don't add newlines before or after p tags because of transifex --> -

EXPERIMENTAL software

-

This is EXPERIMENTAL software. Use at your own risk!

-

Getting started

-

First you need some keys. Import or create them via the option menus in "My Secret Keys". - +

First you need some keys. Import or create them via the option menus in "My Keys".
It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

-

Big ToDos

-
    -
  • K9 Mail integration not published
  • -
  • Importing existing keys will be stripped of certificates right now
  • -
  • PGP/MIME in K9 Mail is missing
  • -
-

If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

-

I found a bug in OpenPGP Keychain!

-

Please report it in the issue tracker of OpenPGP Keychain.

+

Please report it in the issue tracker of OpenPGP Keychain.

+ +

Contribute

+

If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

+ +

Translations

+

Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

+ -- cgit v1.2.3 From 82b0fba47dee42128335d172b2c3fb28927661d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 18:36:43 +0100 Subject: better help text --- OpenPGP-Keychain/src/main/res/raw-de/help_start.html | 2 +- OpenPGP-Keychain/src/main/res/raw/help_start.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index e2841ac5c..ec43b44d4 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -16,7 +16,7 @@ And don't add newlines before or after p tags because of transifex -->

If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

Translations

-

Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

+

Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

diff --git a/OpenPGP-Keychain/src/main/res/raw/help_start.html b/OpenPGP-Keychain/src/main/res/raw/help_start.html index 8aedfb370..a5acae3c3 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_start.html @@ -16,7 +16,7 @@ And don't add newlines before or after p tags because of transifex -->

If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

Translations

-

Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

+

Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

-- cgit v1.2.3 From b78a564de3d8c3771d2e8ae445e0a43b026531ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 18:59:40 +0100 Subject: temporary fix for nullpointer on orientation change in import activity --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 1 + .../keychain/ui/ImportKeysListFragment.java | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 4102a882e..d970770f5 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -254,6 +254,7 @@ android:label="@string/title_certify_key" /> diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 68d318491..cfcb202b9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -136,7 +136,7 @@ public class ImportKeysListFragment extends ListFragment implements getLoaderManager().initLoader(LOADER_ID_BYTES, null, this); } - if (mServerQuery != null) { + if (mServerQuery != null && mKeyServer != null) { // Start out with a progress indicator. setListShown(false); @@ -165,14 +165,19 @@ public class ImportKeysListFragment extends ListFragment implements mServerQuery = serverQuery; mKeyServer = keyServer; - // Start out with a progress indicator. - setListShown(false); + if (mKeyBytes != null || mDataUri != null) { + // Start out with a progress indicator. + setListShown(false); - if (mKeyBytes != null || mDataUri != null) getLoaderManager().restartLoader(LOADER_ID_BYTES, null, this); + } + + if (mServerQuery != null && mKeyServer != null) { + // Start out with a progress indicator. + setListShown(false); - if (mServerQuery != null && mKeyServer != null) getLoaderManager().restartLoader(LOADER_ID_SERVER_QUERY, null, this); + } } @Override -- cgit v1.2.3 From d090d4d332c9b1f5174890de531e2cc6936c038b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 19:53:50 +0100 Subject: work on lookup key, fix some illegal state exceptions with hack --- .../java/org/sufficientlysecure/keychain/Id.java | 2 +- .../keychain/pgp/PgpOperation.java | 12 +- .../keychain/service/KeychainIntentService.java | 6 +- .../service/KeychainIntentServiceHandler.java | 10 +- .../keychain/service/remote/OpenPgpService.java | 3 +- .../keychain/ui/DecryptActivity.java | 76 +++++------- .../keychain/ui/ViewKeyActivity.java | 6 +- .../ui/dialog/LookupUnknownKeyDialogFragment.java | 136 --------------------- .../src/main/res/layout/decrypt_activity.xml | 58 +++++---- OpenPGP-Keychain/src/main/res/values/strings.xml | 7 +- 10 files changed, 85 insertions(+), 231 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java index 22f30cb1f..a1571e491 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/Id.java @@ -78,7 +78,7 @@ public final class Id { public static final int filename = 0x00007003; // public static final int output_filename = 0x00007004; public static final int key_server_preference = 0x00007005; - public static final int look_up_key_id = 0x00007006; +// public static final int look_up_key_id = 0x00007006; public static final int export_to_server = 0x00007007; public static final int import_from_qr_code = 0x00007008; public static final int sign_key = 0x00007009; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java index 1402be435..1b08b65a1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java @@ -789,7 +789,7 @@ public class PgpOperation { return returnData; } - public Bundle verifyText(boolean lookupUnknownKey) throws IOException, PgpGeneralException, + public Bundle verifyText() throws IOException, PgpGeneralException, PGPException, SignatureException { Bundle returnData = new Bundle(); @@ -837,16 +837,6 @@ public class PgpOperation { if (signatureKeyId == 0) { signatureKeyId = signature.getKeyID(); } - // if key is not known and we want to lookup unknown ones... - if (signatureKey == null && lookupUnknownKey) { - - returnData = new Bundle(); - returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_LOOKUP_KEY, true); - - // return directly now, decrypt will be done again after importing unknown key - return returnData; - } if (signatureKey == null) { signature = null; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index ddb53736a..870e45ea5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -123,7 +123,6 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String DECRYPT_RETURN_BYTES = "return_binary"; public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; public static final String DECRYPT_ASSUME_SYMMETRIC = "assume_symmetric"; - public static final String DECRYPT_LOOKUP_UNKNOWN_KEY = "lookup_unknownKey"; // save keyring public static final String SAVE_KEYRING_NEW_PASSPHRASE = "new_passphrase"; @@ -188,7 +187,6 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String RESULT_SIGNATURE_SUCCESS = "signature_success"; public static final String RESULT_SIGNATURE_UNKNOWN = "signature_unknown"; - public static final String RESULT_SIGNATURE_LOOKUP_KEY = "lookup_key"; // import public static final String RESULT_IMPORT_ADDED = "added"; @@ -395,8 +393,6 @@ public class KeychainIntentService extends IntentService implements ProgressDial boolean returnBytes = data.getBoolean(DECRYPT_RETURN_BYTES); boolean assumeSymmetricEncryption = data.getBoolean(DECRYPT_ASSUME_SYMMETRIC); - boolean lookupUnknownKey = data.getBoolean(DECRYPT_LOOKUP_UNKNOWN_KEY); - InputStream inStream = null; long inLength = -1; InputData inputData = null; @@ -472,7 +468,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial // verification of signatures PgpOperation operation = new PgpOperation(this, this, inputData, outStream); if (signedOnly) { - resultData = operation.verifyText(lookupUnknownKey); + resultData = operation.verifyText(); } else { resultData = operation.decryptAndVerify( PassphraseCacheService.getCachedPassphrase(this, secretKeyId), diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java index 5a338c757..a9ec291e3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java @@ -25,6 +25,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; import android.widget.Toast; public class KeychainIntentServiceHandler extends Handler { @@ -60,7 +61,14 @@ public class KeychainIntentServiceHandler extends Handler { } public void showProgressDialog(FragmentActivity activity) { - mProgressDialogFragment.show(activity.getSupportFragmentManager(), "progressDialog"); + // TODO: THis is a hack!, see http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult + final FragmentManager manager = activity.getSupportFragmentManager(); + Handler handler = new Handler(); + handler.post(new Runnable() { + public void run() { + mProgressDialogFragment.show(manager, "progressDialog"); + } + }); } @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 575f76a22..6db091ed0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -420,8 +420,7 @@ public class OpenPgpService extends RemoteService { Bundle outputBundle; PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream); if (signedOnly) { - // TODO: download missing keys from keyserver? - outputBundle = operation.verifyText(false); + outputBundle = operation.verifyText(); } else { outputBundle = operation.decryptAndVerify(passphrase, false); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 26657479f..ccadaf39e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -43,7 +43,6 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.FileDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.LookupUnknownKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -62,6 +61,7 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import android.widget.ViewFlipper; @@ -78,6 +78,9 @@ public class DecryptActivity extends DrawerActivity { /* EXTRA keys for input */ public static final String EXTRA_TEXT = "text"; + private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; + private static final int RESULT_CODE_FILE = 0x00007003; + private long mSignatureKeyId = 0; private boolean mReturnResult = false; @@ -85,7 +88,7 @@ public class DecryptActivity extends DrawerActivity { private boolean mAssumeSymmetricEncryption = false; private EditText mMessage = null; - private LinearLayout mSignatureLayout = null; + private RelativeLayout mSignatureLayout = null; private ImageView mSignatureStatusImage = null; private TextView mUserId = null; private TextView mUserIdRest = null; @@ -100,6 +103,7 @@ public class DecryptActivity extends DrawerActivity { private EditText mFilename = null; private CheckBox mDeleteAfter = null; private BootstrapButton mBrowse = null; + private BootstrapButton mLookupKey = null; private String mInputFilename = null; private String mOutputFilename = null; @@ -107,14 +111,10 @@ public class DecryptActivity extends DrawerActivity { private Uri mContentUri = null; private boolean mReturnBinary = false; - private long mUnknownSignatureKeyId = 0; - private long mSecretKeyId = Id.key.none; private FileDialogFragment mFileDialog; - private boolean mLookupUnknownKey = true; - private boolean mDecryptImmediately = false; private BootstrapButton mDecryptButton; @@ -154,7 +154,7 @@ public class DecryptActivity extends DrawerActivity { mSourceLabel.setOnClickListener(nextSourceClickListener); mMessage = (EditText) findViewById(R.id.message); - mSignatureLayout = (LinearLayout) findViewById(R.id.signature); + mSignatureLayout = (RelativeLayout) findViewById(R.id.signature); mSignatureStatusImage = (ImageView) findViewById(R.id.ic_signature_status); mUserId = (TextView) findViewById(R.id.mainUserId); mUserIdRest = (TextView) findViewById(R.id.mainUserIdRest); @@ -171,7 +171,15 @@ public class DecryptActivity extends DrawerActivity { mBrowse.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { FileHelper.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*", - Id.request.filename); + RESULT_CODE_FILE); + } + }); + + mLookupKey = (BootstrapButton) findViewById(R.id.lookup_key); + mLookupKey.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + lookupUnknownKey(mSignatureKeyId); } }); @@ -587,28 +595,10 @@ public class DecryptActivity extends DrawerActivity { } private void lookupUnknownKey(long unknownKeyId) { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == LookupUnknownKeyDialogFragment.MESSAGE_OKAY) { - // the result is handled by onActivityResult() as LookupUnknownKeyDialogFragment - // starts a new Intent which then returns data - } else if (message.what == LookupUnknownKeyDialogFragment.MESSAGE_CANCEL) { - // decrypt again, but don't lookup unknown keys! - mLookupUnknownKey = false; - decryptStart(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - LookupUnknownKeyDialogFragment lookupKeyDialog = LookupUnknownKeyDialogFragment - .newInstance(messenger, unknownKeyId); - - lookupKeyDialog.show(getSupportFragmentManager(), "unknownKeyDialog"); + Intent intent = new Intent(this, ImportKeysActivity.class); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER); + intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); + startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); } private void decryptStart() { @@ -645,7 +635,6 @@ public class DecryptActivity extends DrawerActivity { data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); data.putBoolean(KeychainIntentService.DECRYPT_SIGNED_ONLY, mSignedOnly); - data.putBoolean(KeychainIntentService.DECRYPT_LOOKUP_UNKNOWN_KEY, mLookupUnknownKey); data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); @@ -662,15 +651,6 @@ public class DecryptActivity extends DrawerActivity { // get returned data bundle Bundle returnData = message.getData(); - // if key is unknown show lookup dialog - if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_LOOKUP_KEY) - && mLookupUnknownKey) { - mUnknownSignatureKeyId = returnData - .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID); - lookupUnknownKey(mUnknownSignatureKeyId); - return; - } - mSignatureKeyId = 0; mSignatureLayout.setVisibility(View.GONE); @@ -727,14 +707,17 @@ public class DecryptActivity extends DrawerActivity { if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) { mSignatureStatusImage.setImageResource(R.drawable.overlay_ok); + mLookupKey.setVisibility(View.GONE); } else if (returnData .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) { mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.VISIBLE); Toast.makeText(DecryptActivity.this, - R.string.unknown_signature_key_touch_to_look_up, + R.string.unknown_signature, Toast.LENGTH_LONG).show(); } else { mSignatureStatusImage.setImageResource(R.drawable.overlay_error); + mLookupKey.setVisibility(View.GONE); } mSignatureLayout.setVisibility(View.VISIBLE); } @@ -756,7 +739,7 @@ public class DecryptActivity extends DrawerActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case Id.request.filename: { + case RESULT_CODE_FILE: { if (resultCode == RESULT_OK && data != null) { try { String path = FileHelper.getPath(this, data.getData()); @@ -772,20 +755,19 @@ public class DecryptActivity extends DrawerActivity { // this request is returned after LookupUnknownKeyDialogFragment started // ImportKeysActivity and user looked uo key - case Id.request.look_up_key_id: { + case RESULT_CODE_LOOKUP_KEY: { Log.d(Constants.TAG, "Returning from Lookup Key..."); - // decrypt again without lookup - mLookupUnknownKey = false; + // decrypt again decryptStart(); return; } default: { + super.onActivityResult(requestCode, resultCode, data); + break; } } - - super.onActivityResult(requestCode, resultCode, data); } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 0bfc51e67..1f4afcd8b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -86,6 +86,8 @@ public class ViewKeyActivity extends ActionBarActivity implements private ViewKeyUserIdsAdapter mUserIdsAdapter; private ViewKeyKeysAdapter mKeysAdapter; + private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -399,8 +401,8 @@ public class ViewKeyActivity extends ActionBarActivity implements queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER); queryIntent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, updateKeyId); - // TODO: lookup?? - startActivityForResult(queryIntent, Id.request.look_up_key_id); + // TODO: lookup with onactivityresult! + startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY); } private void encryptToContact(Uri dataUri) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java deleted file mode 100644 index a0592285f..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/LookupUnknownKeyDialogFragment.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2012-2013 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.ui.dialog; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.ui.ImportKeysActivity; -import org.sufficientlysecure.keychain.util.Log; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.Intent; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.support.v4.app.DialogFragment; - -public class LookupUnknownKeyDialogFragment extends DialogFragment { - private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_UNKNOWN_KEY_ID = "unknown_key_id"; - - public static final int MESSAGE_OKAY = 1; - public static final int MESSAGE_CANCEL = 2; - - private Messenger mMessenger; - - /** - * Creates new instance of this dialog fragment - * - * @param messenger - * @param unknownKeyId - * @return - */ - public static LookupUnknownKeyDialogFragment newInstance(Messenger messenger, long unknownKeyId) { - LookupUnknownKeyDialogFragment frag = new LookupUnknownKeyDialogFragment(); - Bundle args = new Bundle(); - args.putLong(ARG_UNKNOWN_KEY_ID, unknownKeyId); - args.putParcelable(ARG_MESSENGER, messenger); - - frag.setArguments(args); - - return frag; - } - - /** - * Creates dialog - */ - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final Activity activity = getActivity(); - - final long unknownKeyId = getArguments().getLong(ARG_UNKNOWN_KEY_ID); - mMessenger = getArguments().getParcelable(ARG_MESSENGER); - - AlertDialog.Builder alert = new AlertDialog.Builder(activity); - - alert.setIcon(android.R.drawable.ic_dialog_alert); - alert.setTitle(R.string.title_unknown_signature_key); - alert.setMessage(getString(R.string.lookup_unknown_key, - PgpKeyHelper.convertKeyIdToHex(unknownKeyId))); - - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - dismiss(); - - sendMessageToHandler(MESSAGE_OKAY); - - Intent intent = new Intent(activity, ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER); - intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); - startActivityForResult(intent, Id.request.look_up_key_id); - } - }); - alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - dismiss(); - - sendMessageToHandler(MESSAGE_CANCEL); - } - }); - alert.setCancelable(true); - alert.setOnCancelListener(new OnCancelListener() { - - @Override - public void onCancel(DialogInterface dialog) { - sendMessageToHandler(MESSAGE_CANCEL); - } - }); - - return alert.create(); - } - - /** - * Send message back to handler which is initialized in a activity - * - * @param what - * Message integer you want to send - */ - private void sendMessageToHandler(Integer what) { - Message msg = Message.obtain(); - msg.what = what; - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml b/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml index c6834d745..91ee15c38 100644 --- a/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml @@ -20,10 +20,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:paddingTop="4dp" android:paddingLeft="10dp" android:paddingRight="10dp"> - + android:layout_height="wrap_content" + android:id="@+id/relativeLayout"> - + android:layout_height="50dp" + android:padding="4dp" + android:text="@string/btn_lookup_key" + bootstrapbutton:bb_icon_left="fa-download" + bootstrapbutton:bb_type="info" + bootstrapbutton:bb_size="small" + android:layout_alignParentTop="true" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" /> - + - - - + + Back
Clipboard Share with… - + Lookup key Settings @@ -233,15 +233,14 @@ Found %d keys. - Unknown signature, touch to look up key. + Unknown signature, click button to lookup the missing key. %d bad secret key ignored. Perhaps you exported with the option\n --export-secret-subkeys\nMake sure you export with\n --export-secret-keys\ninstead. %d bad secret keys ignored. Perhaps you exported with the option\n --export-secret-subkeys\nMake sure you export with\n --export-secret-keys\ninstead. - Unknown key %s, do you want to try finding it on a keyserver? - Successfully sent key to server + Successfully uploaded key to server Successfully signed key This list is empty! Successfully sent key with NFC Beam! -- cgit v1.2.3 From a56219a027e7956b19b3599426fa8ed8888273d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 19:55:40 +0100 Subject: reformat --- .../service/KeychainIntentServiceHandler.java | 2 +- .../keychain/ui/DecryptActivity.java | 126 +++++++++++---------- 2 files changed, 66 insertions(+), 62 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java index a9ec291e3..dfea7eb04 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java @@ -61,7 +61,7 @@ public class KeychainIntentServiceHandler extends Handler { } public void showProgressDialog(FragmentActivity activity) { - // TODO: THis is a hack!, see http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult + // TODO: This is a hack!, see http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult final FragmentManager manager = activity.getSupportFragmentManager(); Handler handler = new Handler(); handler.post(new Runnable() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index ccadaf39e..51c7c3257 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -271,14 +271,14 @@ public class DecryptActivity extends DrawerActivity { if (mDecryptImmediately || (mSource.getCurrentView().getId() == R.id.sourceMessage && (mMessage.getText() - .length() > 0 || mContentUri != null))) { + .length() > 0 || mContentUri != null))) { decryptClicked(); } } /** * Handles all actions with this intent - * + * * @param intent */ private void handleActions(Intent intent) { @@ -383,21 +383,21 @@ public class DecryptActivity extends DrawerActivity { private void updateSource() { switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mSourceLabel.setText(R.string.label_file); - mDecryptButton.setText(getString(R.string.btn_decrypt)); - break; - } + case R.id.sourceFile: { + mSourceLabel.setText(R.string.label_file); + mDecryptButton.setText(getString(R.string.btn_decrypt)); + break; + } - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - mDecryptButton.setText(getString(R.string.btn_decrypt)); - break; - } + case R.id.sourceMessage: { + mSourceLabel.setText(R.string.label_message); + mDecryptButton.setText(getString(R.string.btn_decrypt)); + break; + } - default: { - break; - } + default: { + break; + } } } @@ -535,7 +535,7 @@ public class DecryptActivity extends DrawerActivity { try { if (inStream.markSupported()) { inStream.mark(200); // should probably set this to the max size of two pgpF - // objects, if it even needs to be anything other than 0. + // objects, if it even needs to be anything other than 0. } mSecretKeyId = PgpHelper.getDecryptionKeyId(this, inStream); if (mSecretKeyId == Id.key.none) { @@ -567,7 +567,7 @@ public class DecryptActivity extends DrawerActivity { data = "\n\n" + data; intent.putExtra(EncryptActivity.EXTRA_TEXT, data); intent.putExtra(EncryptActivity.EXTRA_SIGNATURE_KEY_ID, mSecretKeyId); - intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, new long[] { mSignatureKeyId }); + intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, new long[]{mSignatureKeyId}); startActivity(intent); } @@ -665,26 +665,26 @@ public class DecryptActivity extends DrawerActivity { } switch (mDecryptTarget) { - case Id.target.message: - String decryptedMessage = returnData - .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); - mMessage.setText(decryptedMessage); - mMessage.setHorizontallyScrolling(false); - - break; - - case Id.target.file: - if (mDeleteAfter.isChecked()) { - // Create and show dialog to delete original file - DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment - .newInstance(mInputFilename); - deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); - } - break; - - default: - // shouldn't happen - break; + case Id.target.message: + String decryptedMessage = returnData + .getString(KeychainIntentService.RESULT_DECRYPTED_STRING); + mMessage.setText(decryptedMessage); + mMessage.setHorizontallyScrolling(false); + + break; + + case Id.target.file: + if (mDeleteAfter.isChecked()) { + // Create and show dialog to delete original file + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment + .newInstance(mInputFilename); + deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); + } + break; + + default: + // shouldn't happen + break; } @@ -722,7 +722,9 @@ public class DecryptActivity extends DrawerActivity { mSignatureLayout.setVisibility(View.VISIBLE); } } - }; + } + + ; }; // Create a new Messenger for the communication back @@ -739,34 +741,36 @@ public class DecryptActivity extends DrawerActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case RESULT_CODE_FILE: { - if (resultCode == RESULT_OK && data != null) { - try { - String path = FileHelper.getPath(this, data.getData()); - Log.d(Constants.TAG, "path=" + path); - - mFilename.setText(path); - } catch (NullPointerException e) { - Log.e(Constants.TAG, "Nullpointer while retrieving path!"); + case RESULT_CODE_FILE: { + if (resultCode == RESULT_OK && data != null) { + try { + String path = FileHelper.getPath(this, data.getData()); + Log.d(Constants.TAG, "path=" + path); + + mFilename.setText(path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!"); + } } + return; } - return; - } - // this request is returned after LookupUnknownKeyDialogFragment started - // ImportKeysActivity and user looked uo key - case RESULT_CODE_LOOKUP_KEY: { - Log.d(Constants.TAG, "Returning from Lookup Key..."); - // decrypt again - decryptStart(); - return; - } + // this request is returned after LookupUnknownKeyDialogFragment started + // ImportKeysActivity and user looked uo key + case RESULT_CODE_LOOKUP_KEY: { + Log.d(Constants.TAG, "Returning from Lookup Key..."); + if (resultCode == RESULT_OK) { + // decrypt again + decryptStart(); + } + return; + } - default: { - super.onActivityResult(requestCode, resultCode, data); + default: { + super.onActivityResult(requestCode, resultCode, data); - break; - } + break; + } } } -- cgit v1.2.3 From e2bd3ae83164dca93f938f5d41bd67e50a5f1408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 20:18:14 +0100 Subject: reworking some parts of import activity code --- .../keychain/ui/ImportKeysActivity.java | 52 ++++++++++++++-------- .../keychain/ui/ImportKeysServerFragment.java | 20 ++++----- 2 files changed, 43 insertions(+), 29 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 70f3c955a..443b9d71f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -57,6 +57,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa + "IMPORT_KEY_FROM_QR_CODE"; public static final String ACTION_IMPORT_KEY_FROM_KEY_SERVER = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER"; + public static final String ACTION_IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN = Constants.INTENT_PREFIX + + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN"; // Actions for internal use only: public static final String ACTION_IMPORT_KEY_FROM_FILE = Constants.INTENT_PREFIX @@ -125,21 +127,21 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa if (scheme != null && scheme.toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) { /* Scanning a fingerprint directly with Barcode Scanner */ - getSupportActionBar().setSelectedNavigationItem(0); - loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[0]); loadFromFingerprintUri(savedInstanceState, dataUri); } else if (ACTION_IMPORT_KEY.equals(action)) { /* Keychain's own Actions */ + + // display file fragment getSupportActionBar().setSelectedNavigationItem(1); loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]); if (dataUri != null) { - // directly load data + // action: directly load data startListFragment(savedInstanceState, null, dataUri, null); } else if (extras.containsKey(EXTRA_KEY_BYTES)) { byte[] importData = intent.getByteArrayExtra(EXTRA_KEY_BYTES); - // directly load data + // action: directly load data startListFragment(savedInstanceState, importData, null, null); } } else if (ACTION_IMPORT_KEY_FROM_KEY_SERVER.equals(action)) { @@ -161,28 +163,39 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa return; } - // search directly + // display key server fragment with query getSupportActionBar().setSelectedNavigationItem(0); Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); + // action: search immediately startListFragment(savedInstanceState, null, null, query); - } else { - // Other actions + } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) { + + // NOTE: this only displays the appropriate fragment, no actions are taken + getSupportActionBar().setSelectedNavigationItem(1); + loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]); + + // no immediate actions! startListFragment(savedInstanceState, null, null, null); + } else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) { + // also exposed in AndroidManifest - if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) { - getSupportActionBar().setSelectedNavigationItem(1); - loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]); - } else if (ACTION_IMPORT_KEY_FROM_QR_CODE.equals(action)) { - // also exposed in AndroidManifest - getSupportActionBar().setSelectedNavigationItem(2); - loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]); - } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) { - getSupportActionBar().setSelectedNavigationItem(3); - loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[3]); - } + // NOTE: this only displays the appropriate fragment, no actions are taken + getSupportActionBar().setSelectedNavigationItem(2); + loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]); + + // no immediate actions! + startListFragment(savedInstanceState, null, null, null); + } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) { + + // NOTE: this only displays the appropriate fragment, no actions are taken + getSupportActionBar().setSelectedNavigationItem(3); + loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[3]); + + // no immediate actions! + startListFragment(savedInstanceState, null, null, null); } } @@ -261,12 +274,13 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa String query = "0x" + fingerprint; - // search directly + // display key server fragment with query getSupportActionBar().setSelectedNavigationItem(0); Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); + // action: search directly startListFragment(savedInstanceState, null, null, query); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java index 2e0956d8b..d77015aa7 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java @@ -127,21 +127,21 @@ public class ImportKeysServerFragment extends Fragment { mImportActivity = (ImportKeysActivity) getActivity(); // set displayed values - if (getArguments() != null && getArguments().containsKey(ARG_QUERY)) { - String query = getArguments().getString(ARG_QUERY); - mQueryEditText.setText(query, TextView.BufferType.EDITABLE); + if (getArguments() != null) { + if (getArguments().containsKey(ARG_QUERY)) { + String query = getArguments().getString(ARG_QUERY); + mQueryEditText.setText(query, TextView.BufferType.EDITABLE); + + Log.d(Constants.TAG, "query: " + query); + } - String keyServer = null; if (getArguments().containsKey(ARG_KEY_SERVER)) { - keyServer = getArguments().getString(ARG_KEY_SERVER); + String keyServer = getArguments().getString(ARG_KEY_SERVER); int keyServerPos = mServerAdapter.getPosition(keyServer); mServerSpinner.setSelection(keyServerPos); - } else { - keyServer = (String) mServerSpinner.getSelectedItem(); - } - Log.d(Constants.TAG, "query: " + query); - Log.d(Constants.TAG, "keyServer: " + keyServer); + Log.d(Constants.TAG, "keyServer: " + keyServer); + } } } -- cgit v1.2.3 From ecd376961f81583c76b22ba149f9af03b289c9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 21:46:22 +0100 Subject: Fix double loading of navigation fragments --- .../keychain/ui/ImportKeysActivity.java | 119 ++++++++++++--------- 1 file changed, 66 insertions(+), 53 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 443b9d71f..611883a86 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -80,6 +80,16 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa private Fragment mCurrentFragment; private BootstrapButton mImportButton; + private static final Class[] NAVIGATION_CLASSES = new Class[]{ + ImportKeysServerFragment.class, + ImportKeysFileFragment.class, + ImportKeysQrCodeFragment.class, + ImportKeysClipboardFragment.class, + ImportKeysNFCFragment.class + }; + + private int mCurrentNavPostition = -1; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -109,6 +119,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa handleActions(savedInstanceState, getIntent()); } + protected void handleActions(Bundle savedInstanceState, Intent intent) { String action = intent.getAction(); Bundle extras = intent.getExtras(); @@ -132,8 +143,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa /* Keychain's own Actions */ // display file fragment - getSupportActionBar().setSelectedNavigationItem(1); - loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]); + loadNavFragment(1, null); if (dataUri != null) { // action: directly load data @@ -164,18 +174,16 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } // display key server fragment with query - getSupportActionBar().setSelectedNavigationItem(0); Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); - loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); + loadNavFragment(0, args); // action: search immediately startListFragment(savedInstanceState, null, null, query); } else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) { // NOTE: this only displays the appropriate fragment, no actions are taken - getSupportActionBar().setSelectedNavigationItem(1); - loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[1]); + loadNavFragment(1, null); // no immediate actions! startListFragment(savedInstanceState, null, null, null); @@ -183,73 +191,79 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // also exposed in AndroidManifest // NOTE: this only displays the appropriate fragment, no actions are taken - getSupportActionBar().setSelectedNavigationItem(2); - loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[2]); + loadNavFragment(2, null); // no immediate actions! startListFragment(savedInstanceState, null, null, null); } else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) { // NOTE: this only displays the appropriate fragment, no actions are taken - getSupportActionBar().setSelectedNavigationItem(3); - loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[3]); + loadNavFragment(3, null); // no immediate actions! startListFragment(savedInstanceState, null, null, null); + } else { + startListFragment(savedInstanceState, null, null, null); } } private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) { - // Check that the activity is using the layout version with - // the fragment_container FrameLayout - if (findViewById(R.id.import_keys_list_container) != null) { - - // However, if we're being restored from a previous state, - // then we don't need to do anything and should return or else - // we could end up with overlapping fragments. - if (savedInstanceState != null) { - return; - } + // However, if we're being restored from a previous state, + // then we don't need to do anything and should return or else + // we could end up with overlapping fragments. + if (savedInstanceState != null) { + return; + } - // Create an instance of the fragment - mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery); + // Create an instance of the fragment + mListFragment = ImportKeysListFragment.newInstance(bytes, dataUri, serverQuery); - // Add the fragment to the 'fragment_container' FrameLayout - // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! - getSupportFragmentManager().beginTransaction() - .replace(R.id.import_keys_list_container, mListFragment) - .commitAllowingStateLoss(); - // do it immediately! - getSupportFragmentManager().executePendingTransactions(); - } + // Add the fragment to the 'fragment_container' FrameLayout + // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! + getSupportFragmentManager().beginTransaction() + .replace(R.id.import_keys_list_container, mListFragment) + .commitAllowingStateLoss(); + // do it immediately! + getSupportFragmentManager().executePendingTransactions(); } + /** + * "Basically, when using a list navigation, onNavigationItemSelected() is automatically + * called when your activity is created/re-created, whether you like it or not. To prevent + * your Fragment's onCreateView() from being called twice, this initial automatic call to + * onNavigationItemSelected() should check whether the Fragment is already in existence + * inside your Activity." + *

+ * from http://stackoverflow.com/questions/10983396/fragment-oncreateview-and-onactivitycreated-called-twice/14295474#14295474 + * + * In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint, + * the fragment would be loaded twice resulting in the query being empty after the second load. + * + * Our solution: + * To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment + * checks against mCurrentNavPostition. + * + * @param itemPosition + * @param itemId + * @return + */ @Override public boolean onNavigationItemSelected(int itemPosition, long itemId) { - // Create new fragment from our own Fragment class - switch (itemPosition) { - case 0: - loadFragment(ImportKeysServerFragment.class, null, mNavigationStrings[itemPosition]); - break; - case 1: - loadFragment(ImportKeysFileFragment.class, null, mNavigationStrings[itemPosition]); - break; - case 2: - loadFragment(ImportKeysQrCodeFragment.class, null, mNavigationStrings[itemPosition]); - break; - case 3: - loadFragment(ImportKeysClipboardFragment.class, null, mNavigationStrings[itemPosition]); - break; - case 4: - loadFragment(ImportKeysNFCFragment.class, null, mNavigationStrings[itemPosition]); - break; - - default: - break; - } + Log.d(Constants.TAG, "onNavigationItemSelected"); + + loadNavFragment(itemPosition, null); + return true; } + private void loadNavFragment(int itemPosition, Bundle args) { + if (mCurrentNavPostition != itemPosition) { + getSupportActionBar().setSelectedNavigationItem(itemPosition); + loadFragment(NAVIGATION_CLASSES[itemPosition], args, mNavigationStrings[itemPosition]); + mCurrentNavPostition = itemPosition; + } + } + private void loadFragment(Class clss, Bundle args, String tag) { mCurrentFragment = Fragment.instantiate(this, clss.getName(), args); @@ -275,10 +289,9 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa String query = "0x" + fingerprint; // display key server fragment with query - getSupportActionBar().setSelectedNavigationItem(0); Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); - loadFragment(ImportKeysServerFragment.class, args, mNavigationStrings[0]); + loadNavFragment(0, args); // action: search directly startListFragment(savedInstanceState, null, null, query); -- cgit v1.2.3 From 9d074b01e9c99c463c8b5f0b653528ef745c38ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 22:28:08 +0100 Subject: fix display of fingerprint in key server query --- .../keychain/ui/adapter/ImportKeysAdapter.java | 12 +++++++----- .../org/sufficientlysecure/keychain/util/HkpKeyServer.java | 9 ++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 02a5fea9c..52186b662 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -120,13 +120,15 @@ public class ImportKeysAdapter extends ArrayAdapter { mainUserIdRest.setVisibility(View.GONE); } - // TODO: need to set no key? - keyId.setText(R.string.no_key); keyId.setText(entry.hexKeyId); - fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint); - // TODO: no need to set algorithm empty... - algorithm.setText(""); + if (entry.fingerPrint != null) { + fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint); + fingerprint.setVisibility(View.VISIBLE); + } else { + fingerprint.setVisibility(View.GONE); + } + algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm); if (entry.revoked) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java index 05e52fb47..61fe13ffb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/util/HkpKeyServer.java @@ -50,6 +50,13 @@ import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import android.text.Html; +/** + * TODO: + * rewrite to use machine readable output. + *

+ * see http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5 + * https://github.com/openpgp-keychain/openpgp-keychain/issues/259 + */ public class HkpKeyServer extends KeyServer { private static class HttpError extends Exception { private static final long serialVersionUID = 1718783705229428893L; @@ -181,8 +188,8 @@ public class HkpKeyServer extends KeyServer { ImportKeysListEntry info = new ImportKeysListEntry(); info.bitStrength = Integer.parseInt(matcher.group(1)); info.algorithm = matcher.group(2); + info.hexKeyId = "0x" + matcher.group(3); info.keyId = PgpKeyHelper.convertHexToKeyId(matcher.group(3)); - info.fingerPrint = PgpKeyHelper.convertKeyIdToHex(info.keyId); String chunks[] = matcher.group(4).split("-"); GregorianCalendar tmpGreg = new GregorianCalendar(TimeZone.getTimeZone("UTC")); -- cgit v1.2.3 From 9667245613f92edae955cb3b4e8634f7d9553543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 4 Feb 2014 22:53:53 +0100 Subject: small layout problem fixed --- .../sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java | 4 ++-- OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java index 5094e8abd..4a7a9c93a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java @@ -48,7 +48,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { private boolean selected; - private byte[] bytes = new byte[] {}; + private byte[] bytes = new byte[]{}; public ImportKeysListEntry(ImportKeysListEntry b) { this.userIds = b.userIds; @@ -167,7 +167,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable { this.revoked = pgpKeyRing.getPublicKey().isRevoked(); this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey() .getFingerprint(), true); - this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId); + this.hexKeyId = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId); this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength(); int algorithm = pgpKeyRing.getPublicKey().getAlgorithm(); if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL diff --git a/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml b/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml index 91ee15c38..e6c81c3fc 100644 --- a/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/decrypt_activity.xml @@ -83,9 +83,8 @@ android:layout_gravity="left" android:text="Main User Id Rest" android:textAppearance="?android:attr/textAppearanceSmall" - android:layout_alignBottom="@+id/relativeLayout" - android:layout_alignLeft="@+id/mainUserId" - android:layout_alignStart="@+id/mainUserId" /> + android:layout_below="@+id/mainUserId" + android:layout_toRightOf="@+id/relativeLayout" /> Date: Tue, 4 Feb 2014 23:06:19 +0100 Subject: again improving help text --- OpenPGP-Keychain/src/main/res/raw-de/help_start.html | 7 ++++--- OpenPGP-Keychain/src/main/res/raw/help_start.html | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index ec43b44d4..f8f0635e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -6,11 +6,12 @@ And don't add newlines before or after p tags because of transifex -->

Getting started

-

First you need some keys. Import or create them via the option menus in "My Keys". -
It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

+

First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

+ +

It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

I found a bug in OpenPGP Keychain!

-

Please report it in the issue tracker of OpenPGP Keychain.

+

Please report the bug using the issue tracker of OpenPGP Keychain.

Contribute

If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

diff --git a/OpenPGP-Keychain/src/main/res/raw/help_start.html b/OpenPGP-Keychain/src/main/res/raw/help_start.html index a5acae3c3..f8f0635e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_start.html @@ -6,11 +6,12 @@ And don't add newlines before or after p tags because of transifex -->

Getting started

-

First you need some keys. Import or create them via the option menus in "My Keys". -
It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

+

First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

+ +

It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

I found a bug in OpenPGP Keychain!

-

Please report it in the issue tracker of OpenPGP Keychain.

+

Please report the bug using the issue tracker of OpenPGP Keychain.

Contribute

If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

-- cgit v1.2.3 From 1f1de0ce06dabf533840fd346f61854b8b0c8330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 00:19:32 +0100 Subject: better alignment of navigation drawer icons --- .../src/main/res/layout/drawer_list_item.xml | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml index 14760e79d..bf70b2de7 100644 --- a/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml @@ -1,28 +1,33 @@ - + android:layout_height="wrap_content"> + android:layout_marginLeft="8dp" + fontawesometext:fa_icon="fa-github" + android:layout_centerVertical="true" + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" /> + android:textColor="#111" + android:layout_alignParentTop="true" + android:layout_toRightOf="@+id/drawer_item_icon" /> - + -- cgit v1.2.3 From 6498c3443b9d9d80670c51386c43c28d782e5c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 00:22:26 +0100 Subject: Update from transifex --- .../src/main/res/raw-de/help_about.html | 4 +- .../src/main/res/raw-de/help_changelog.html | 6 +- .../src/main/res/raw-de/help_nfc_beam.html | 2 +- .../src/main/res/raw-de/help_start.html | 29 ++-- .../src/main/res/raw-de/nfc_beam_share.html | 4 +- .../src/main/res/raw-es-rCO/help_about.html | 4 +- .../src/main/res/raw-es-rCO/help_changelog.html | 6 +- .../src/main/res/raw-es-rCO/help_nfc_beam.html | 2 +- .../src/main/res/raw-es-rCO/nfc_beam_share.html | 4 +- .../src/main/res/raw-es/help_about.html | 43 ++++++ .../src/main/res/raw-es/help_changelog.html | 108 +++++++++++++++ .../src/main/res/raw-es/help_nfc_beam.html | 12 ++ .../src/main/res/raw-es/help_start.html | 22 +++ .../src/main/res/raw-es/nfc_beam_share.html | 11 ++ .../src/main/res/raw-fr/help_about.html | 4 +- .../src/main/res/raw-fr/help_changelog.html | 6 +- .../src/main/res/raw-fr/help_nfc_beam.html | 2 +- .../src/main/res/raw-fr/nfc_beam_share.html | 2 +- .../src/main/res/raw-it-rIT/help_about.html | 4 +- .../src/main/res/raw-it-rIT/help_changelog.html | 6 +- .../src/main/res/raw-it-rIT/help_nfc_beam.html | 2 +- .../src/main/res/raw-it-rIT/nfc_beam_share.html | 4 +- .../src/main/res/raw-nl-rNL/help_about.html | 4 +- .../src/main/res/raw-nl-rNL/help_changelog.html | 6 +- .../src/main/res/raw-nl-rNL/help_nfc_beam.html | 2 +- .../src/main/res/raw-nl-rNL/nfc_beam_share.html | 4 +- .../src/main/res/raw-pt-rBR/help_about.html | 4 +- .../src/main/res/raw-pt-rBR/help_changelog.html | 6 +- .../src/main/res/raw-pt-rBR/help_nfc_beam.html | 2 +- .../src/main/res/raw-pt-rBR/nfc_beam_share.html | 4 +- .../src/main/res/raw-ru/help_about.html | 4 +- .../src/main/res/raw-ru/help_changelog.html | 6 +- .../src/main/res/raw-sl-rSI/help_about.html | 4 +- .../src/main/res/raw-sl-rSI/help_changelog.html | 6 +- .../src/main/res/raw-sl-rSI/help_nfc_beam.html | 2 +- .../src/main/res/raw-sl-rSI/nfc_beam_share.html | 4 +- .../src/main/res/raw-tr/help_about.html | 4 +- .../src/main/res/raw-tr/help_changelog.html | 6 +- .../src/main/res/raw-tr/help_nfc_beam.html | 2 +- .../src/main/res/raw-tr/nfc_beam_share.html | 4 +- .../src/main/res/raw-uk/help_about.html | 4 +- .../src/main/res/raw-uk/help_changelog.html | 6 +- .../src/main/res/raw-uk/help_nfc_beam.html | 2 +- .../src/main/res/raw-zh/help_about.html | 4 +- .../src/main/res/raw-zh/help_changelog.html | 6 +- .../src/main/res/raw-zh/help_nfc_beam.html | 2 +- .../src/main/res/raw-zh/nfc_beam_share.html | 4 +- .../src/main/res/values-de/strings.xml | 8 +- .../src/main/res/values-es-rCO/strings.xml | 7 +- .../src/main/res/values-es/strings.xml | 151 +++++++++++++++++++++ .../src/main/res/values-fr/strings.xml | 13 +- .../src/main/res/values-it-rIT/strings.xml | 4 +- .../src/main/res/values-nl-rNL/strings.xml | 8 +- .../src/main/res/values-ru/strings.xml | 13 +- .../src/main/res/values-tr/strings.xml | 7 +- .../src/main/res/values-uk/strings.xml | 13 +- 56 files changed, 499 insertions(+), 114 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/res/raw-es/help_about.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-es/help_start.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html create mode 100644 OpenPGP-Keychain/src/main/res/values-es/strings.xml (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html index 0ebedb1a1..89f74e9b0 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_about.html @@ -23,7 +23,9 @@

Bibliotheken

  • -ActionBarSherlock (Apache Lizenz v2)
  • +Android Support Library v4 (Apache License v2) +
  • +Android Support Library v7 'appcompat' (Apache License v2)
  • StickyListHeaders (Apache Lizenz v2)
  • diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html index f6f6844a2..b11adda4d 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html @@ -3,10 +3,14 @@

    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 key servers 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
    • -
    • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
    • fix upload of key from signing screen

    2.2

    diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-de/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_nfc_beam.html @@ -3,7 +3,7 @@

    How to receive keys

      -
    1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
    2. +
    3. Go to your partners contacts and open the contact you want to share.
    4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
    5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
    6. Tap the card and the content will then load on the your device.
    7. diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index f8f0635e1..1386e8cc1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -1,23 +1,22 @@ - - - + +

      EXPERIMENTAL software

      +

      This is EXPERIMENTAL software. Use at your own risk!

      +

      Getting started

      -

      First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

      +

      First you need some keys. Import or create them via the option menus in "My Secret Keys". +
      It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

      -

      It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

      +

      Big ToDos

      +
        +
      • K9 Mail integration not published
      • +
      • Importing existing keys will be stripped of certificates right now
      • +
      • PGP/MIME in K9 Mail is missing
      • +
      +

      If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

      I found a bug in OpenPGP Keychain!

      -

      Please report the bug using the issue tracker of OpenPGP Keychain.

      - -

      Contribute

      -

      If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

      - -

      Translations

      -

      Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

      - +

      Please report it in the issue tracker of OpenPGP Keychain.

      diff --git a/OpenPGP-Keychain/src/main/res/raw-de/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-de/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/nfc_beam_share.html @@ -3,8 +3,8 @@
      1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
      2. -
      3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
      4. -
      5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
      6. +
      7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
      8. +
      9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
      10. Tap the card and the content will then load on the other person’s device.
      diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html index 7db2f83de..773d11fa7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_about.html @@ -23,7 +23,9 @@

      Libraries

      • -ActionBarSherlock (Apache License v2)
      • +Android Support Library v4 (Apache License v2) +
      • +Android Support Library v7 'appcompat' (Apache License v2)
      • StickyListHeaders (Apache License v2)
      • diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html @@ -3,10 +3,14 @@

        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 key servers 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
        • -
        • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
        • fix upload of key from signing screen

        2.2

        diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_nfc_beam.html @@ -3,7 +3,7 @@

        How to receive keys

          -
        1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
        2. +
        3. Go to your partners contacts and open the contact you want to share.
        4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
        5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
        6. Tap the card and the content will then load on the your device.
        7. diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/nfc_beam_share.html @@ -3,8 +3,8 @@
          1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
          2. -
          3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
          4. -
          5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
          6. +
          7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
          8. +
          9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
          10. Tap the card and the content will then load on the other person’s device.
          diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html new file mode 100644 index 000000000..773d11fa7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html @@ -0,0 +1,43 @@ + + + +

          http://sufficientlysecure.org/keychain

          +

          OpenPGP Keychain is an OpenPGP implementation for Android. The development began as a fork of Android Privacy Guard (APG).

          +

          License: GPLv3+

          + +

          Developers OpenPGP Keychain

          +
            +
          • Dominik Schürmann (Lead developer)
          • +
          • Ash Hughes (crypto patches)
          • +
          • Brian C. Barnes
          • +
          • Bahtiar 'kalkin' Gadimov (UI)
          • + +
          +

          Developers APG 1.x

          +
            +
          • 'Thialfihar' (Lead developer)
          • +
          • 'Senecaso' (QRCode, sign key, upload key)
          • +
          • Oliver Runge
          • +
          • Markus Doits
          • +
          +

          Libraries

          + + + diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html new file mode 100644 index 000000000..28d025a9f --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html @@ -0,0 +1,108 @@ + + + +

          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 key servers 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 key server support
          • +
          • app2sd
          • +
          • more choices for pass phrase 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 pass phrase 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
          • +
          + + diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html new file mode 100644 index 000000000..88492731c --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html @@ -0,0 +1,12 @@ + + + +

          How to receive keys

          +
            +
          1. Go to your partners contacts and open the contact you want to share.
          2. +
          3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
          4. +
          5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
          6. +
          7. Tap the card and the content will then load on the your device.
          8. +
          + + diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html new file mode 100644 index 000000000..1386e8cc1 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html @@ -0,0 +1,22 @@ + + + +

          EXPERIMENTAL software

          +

          This is EXPERIMENTAL software. Use at your own risk!

          + +

          Getting started

          +

          First you need some keys. Import or create them via the option menus in "My Secret Keys". +
          It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

          + +

          Big ToDos

          +
            +
          • K9 Mail integration not published
          • +
          • Importing existing keys will be stripped of certificates right now
          • +
          • PGP/MIME in K9 Mail is missing
          • +
          +

          If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

          + +

          I found a bug in OpenPGP Keychain!

          +

          Please report it in the issue tracker of OpenPGP Keychain.

          + + diff --git a/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html new file mode 100644 index 000000000..083e055c7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html @@ -0,0 +1,11 @@ + + + +
            +
          1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
          2. +
          3. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
          4. +
          5. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
          6. +
          7. Tap the card and the content will then load on the other person’s device.
          8. +
          + + diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html index 6bede7bd6..0833c35d9 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_about.html @@ -23,7 +23,9 @@

          Bibliothèques

          • -ActionBarSherlock (Licence Apache v2)
          • +Bibliothèque de soutien Android v4 (Licence Apache v2) +
          • +Bibliothèque de soutien Android v7 « appcompat » (Licence Apache v2)
          • StickyListHeaders (Licence Apache v2)
          • diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_changelog.html index d85882a9b..c86c4a465 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_changelog.html @@ -3,10 +3,14 @@

            2.3

              +
            • supprimer l'exportation non nécessaire des clefs publiques lors de l'exportation d'une clef secrète
            • +
            • correctif de définition de la date date de péremption des clefs (merci à Ash Hughes)
            • +
            • autres correctifs internes affectant la modifications des clefs (merci à Ash hughes)
            • +
            • interrogation des serveurs de clefs directement depuis l'écran d'importation
            • +
            • correctif de mise en page et du style des fenêtres de dialogue sur Android 2.2-3.0
            • corrige un plantage pour les clefs avec des ID utilisateur vides
            • corrige un plantage et des listes vides en revenant de l'écran de signature
            • Bouncy Castle (bibliothèque cryptographique) mise à jour de 1.47 à 1.50 et compilée depuis la source
            • -
            • supprimer l'exportation non nécessaire des clefs publiques lors de l'exportation d'une clef secrète
            • correction du téléversement d'une clef depuis l'écran de signature

            2.2

            diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_nfc_beam.html index 6d6e7d693..673e5b224 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_nfc_beam.html @@ -3,7 +3,7 @@

            Comment recevoir des clefs

              -
            1. Aller à la « Gestion des clefs publiques » de votre partenaire et appuyer longuement sur la clef que vous voulez partager.
            2. +
            3. Allez aux contacts de votre partenaire et ouvrez le contact que vous voulez partager.
            4. Tenir les deux appareils dos à dos (se touchant presque) et une vibration sera ressentie.
            5. Après la vibration, le contenu de l'appareil de votre partenaire deviendra un objet en forme de carte avec une animation à la Star Trek en arrière-plan.
            6. Toquer la carte et le contenu se chargera alors sur votre appareil.
            7. diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-fr/nfc_beam_share.html index b2592fd8e..b63c9ac84 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/nfc_beam_share.html @@ -4,7 +4,7 @@
              1. Assurez-vous que la NFC est activée dans Paramètres > Paramètres supplémentaires > NFC, ainsi que Android Beam.
              2. Tenir les deux appareils dos à dos (se touchant presque) et une vibration sera ressentie.
              3. -
              4. Après la vibration, le contenu de l'appareil de votre partenaire deviendra un objet en forme de carte avec une animation à la Star Trek en arrière-plan.
              5. +
              6. Après la vibration, le contenu de votre appareil deviendra un objet en forme de carte avec une animation à la Star Trek en arrière-plan.
              7. Toquer la carte et le contenu se chargera alors sur votre appareil.
              diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html index 7db2f83de..773d11fa7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_about.html @@ -23,7 +23,9 @@

              Libraries

              • -ActionBarSherlock (Apache License v2)
              • +Android Support Library v4 (Apache License v2) +
              • +Android Support Library v7 'appcompat' (Apache License v2)
              • StickyListHeaders (Apache License v2)
              • diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html @@ -3,10 +3,14 @@

                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 key servers 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
                • -
                • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                • fix upload of key from signing screen

                2.2

                diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_nfc_beam.html @@ -3,7 +3,7 @@

                How to receive keys

                  -
                1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
                2. +
                3. Go to your partners contacts and open the contact you want to share.
                4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                6. Tap the card and the content will then load on the your device.
                7. diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/nfc_beam_share.html @@ -3,8 +3,8 @@
                  1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                  2. -
                  3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                  4. -
                  5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                  6. +
                  7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                  8. +
                  9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                  10. Tap the card and the content will then load on the other person’s device.
                  diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html index 7db2f83de..773d11fa7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_about.html @@ -23,7 +23,9 @@

                  Libraries

                  • -ActionBarSherlock (Apache License v2)
                  • +Android Support Library v4 (Apache License v2) +
                  • +Android Support Library v7 'appcompat' (Apache License v2)
                  • StickyListHeaders (Apache License v2)
                  • diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html @@ -3,10 +3,14 @@

                    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 key servers 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
                    • -
                    • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                    • fix upload of key from signing screen

                    2.2

                    diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_nfc_beam.html @@ -3,7 +3,7 @@

                    How to receive keys

                      -
                    1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
                    2. +
                    3. Go to your partners contacts and open the contact you want to share.
                    4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                    5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                    6. Tap the card and the content will then load on the your device.
                    7. diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/nfc_beam_share.html @@ -3,8 +3,8 @@
                      1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                      2. -
                      3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                      4. -
                      5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                      6. +
                      7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                      8. +
                      9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                      10. Tap the card and the content will then load on the other person’s device.
                      diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html index 7db2f83de..773d11fa7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_about.html @@ -23,7 +23,9 @@

                      Libraries

                      • -ActionBarSherlock (Apache License v2)
                      • +Android Support Library v4 (Apache License v2) +
                      • +Android Support Library v7 'appcompat' (Apache License v2)
                      • StickyListHeaders (Apache License v2)
                      • diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html @@ -3,10 +3,14 @@

                        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 key servers 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
                        • -
                        • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                        • fix upload of key from signing screen

                        2.2

                        diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_nfc_beam.html @@ -3,7 +3,7 @@

                        How to receive keys

                          -
                        1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
                        2. +
                        3. Go to your partners contacts and open the contact you want to share.
                        4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                        5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                        6. Tap the card and the content will then load on the your device.
                        7. diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/nfc_beam_share.html @@ -3,8 +3,8 @@
                          1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                          2. -
                          3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                          4. -
                          5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                          6. +
                          7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                          8. +
                          9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                          10. Tap the card and the content will then load on the other person’s device.
                          diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html index 566029511..b11aaab35 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_about.html @@ -23,7 +23,9 @@

                          Компоненты

                          • -ActionBarSherlock (Apache License v2)
                          • +Android Support Library v4 (Apache License v2) +
                          • +Android Support Library v7 'appcompat' (Apache License v2)
                          • StickyListHeaders (Apache License v2)
                          • diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html index d923de570..68c054917 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html @@ -3,10 +3,14 @@

                            2.3

                              +
                            • удален не требующийся экспорт публичного ключа при экспорте секретного ключа (спасибо, Ash Hughes)
                            • +
                            • исправлена ошибка срока годности ключей (спасибо, Ash Hughes)
                            • +
                            • исправления ошибок при изменении ключей (спасибо, Ash Hughes)
                            • +
                            • запрос ключа прямо из окна импорта ключей
                            • +
                            • исправление внешнего вида для Android 2.2-3.0
                            • исправлено падение когда ключ не содержал имя пользователя
                            • исправлено падение и пустой список при возвращении из окна подписания
                            • криптографическая библиотека Bouncy Castle обновлена до версии 1.50
                            • -
                            • удален не требующийся экспорт публичного ключа при экспорте секретного ключа (спасибо, Ash Hughes)
                            • исправлена загрузка ключа из окна подписания

                            2.2

                            diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html index 7db2f83de..773d11fa7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_about.html @@ -23,7 +23,9 @@

                            Libraries

                            • -ActionBarSherlock (Apache License v2)
                            • +Android Support Library v4 (Apache License v2) +
                            • +Android Support Library v7 'appcompat' (Apache License v2)
                            • StickyListHeaders (Apache License v2)
                            • diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html @@ -3,10 +3,14 @@

                              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 key servers 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
                              • -
                              • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                              • fix upload of key from signing screen

                              2.2

                              diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_nfc_beam.html @@ -3,7 +3,7 @@

                              How to receive keys

                                -
                              1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
                              2. +
                              3. Go to your partners contacts and open the contact you want to share.
                              4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                              5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                              6. Tap the card and the content will then load on the your device.
                              7. diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/nfc_beam_share.html @@ -3,8 +3,8 @@
                                1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                                2. -
                                3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                4. -
                                5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                6. +
                                7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                                8. +
                                9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                10. Tap the card and the content will then load on the other person’s device.
                                diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html index 3d4549cbd..3a95c8c16 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_about.html @@ -23,7 +23,9 @@

                                Kütüphaneler

                                • -ActionBarSherlock (Apache License v2)
                                • +Android Support Library v4 (Apache License v2) +
                                • +Android Support Library v7 'appcompat' (Apache License v2)
                                • StickyListHeaders (Apache License v2)
                                • diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html @@ -3,10 +3,14 @@

                                  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 key servers 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
                                  • -
                                  • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                                  • fix upload of key from signing screen

                                  2.2

                                  diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_nfc_beam.html @@ -3,7 +3,7 @@

                                  How to receive keys

                                    -
                                  1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
                                  2. +
                                  3. Go to your partners contacts and open the contact you want to share.
                                  4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                  5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                  6. Tap the card and the content will then load on the your device.
                                  7. diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-tr/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/nfc_beam_share.html @@ -3,8 +3,8 @@
                                    1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                                    2. -
                                    3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                    4. -
                                    5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                    6. +
                                    7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                                    8. +
                                    9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                    10. Tap the card and the content will then load on the other person’s device.
                                    diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html index 7b6f22e94..c6c2e1eed 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_about.html @@ -23,7 +23,9 @@

                                    Бібліотеки

                                    • -ActionBarSherlock (ліцензія Apache в.2)
                                    • +Бібліотека підтримки Android в.4 (Ліцензія Apache в. 2) +
                                    • +Бібліотека підтримки Android в.7 'appcompat' (Ліцензія Apache в.2)
                                    • StickyListHeaders (ліцензія Apache в. 2)
                                    • diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_changelog.html index 174a2b0d4..0b67fa3a9 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_changelog.html @@ -3,10 +3,14 @@

                                      2.3

                                        +
                                      • видалений непотрібний експорт публічного ключа при експорті секретного ключа (завдяки Ash Hughes)
                                      • +
                                      • виправлено налаштування дат дії ключів (завдяки Ash Hughes)
                                      • +
                                      • більше внутрішніх виправлень при редагуванні ключів (завдяки Ash Hughes)
                                      • +
                                      • сервери запитаного ключа безпосередньо з екрану імпорту
                                      • +
                                      • виправлено стиль розмітки і діалогу у Андроїд 2.2-3.0
                                      • виправлено збої, коли ключ мав порожній ідентифікатор користувача
                                      • виправлено збої та порожні списки при поверненні з екрану реєстрації
                                      • Bouncy Castle (криптографічна бібліотека) оновлена з версії 1.47 до 1.50 та зібрана з коду
                                      • -
                                      • видалений непотрібний експорт публічного ключа при експорті секретного ключа (завдяки Ash Hughes)
                                      • виправлено завантаження ключа з вікна реєстрації

                                      2.2

                                      diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_nfc_beam.html index 4a91477d4..dc34048d3 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_nfc_beam.html @@ -3,7 +3,7 @@

                                      Як обмінятися ключами

                                        -
                                      1. Натисніть і утримуйте ключ, який ви хочете передати.
                                      2. +
                                      3. Перейдіть до контактних даних ваших партнерів і відкрийте контакт, який ви хочете надіслати.
                                      4. Піднесіть обидва пристрої впритул зворотними сторонами (до повного торкання). Ви відчуєте невелику вібрацію.
                                      5. Після вібрації пристроїв на екрані з'явиться картка з передаваним вмістом.
                                      6. Натисніть на картку, що б передати дані з одного пристрою на інший.
                                      7. diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html index 7db2f83de..773d11fa7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_about.html @@ -23,7 +23,9 @@

                                        Libraries

                                        • -ActionBarSherlock (Apache License v2)
                                        • +Android Support Library v4 (Apache License v2) +
                                        • +Android Support Library v7 'appcompat' (Apache License v2)
                                        • StickyListHeaders (Apache License v2)
                                        • diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html index 32ad1a13d..28d025a9f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html @@ -3,10 +3,14 @@

                                          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 key servers 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
                                          • -
                                          • remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                                          • fix upload of key from signing screen

                                          2.2

                                          diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html index 2e7e637e5..88492731c 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_nfc_beam.html @@ -3,7 +3,7 @@

                                          How to receive keys

                                            -
                                          1. Go to your partners 'Manage Public Keys' and long press on the key you want to share.
                                          2. +
                                          3. Go to your partners contacts and open the contact you want to share.
                                          4. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                          5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                          6. Tap the card and the content will then load on the your device.
                                          7. diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html index 453d435e3..083e055c7 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/nfc_beam_share.html @@ -3,8 +3,8 @@
                                            1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                                            2. -
                                            3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                            4. -
                                            5. After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                            6. +
                                            7. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                                            8. +
                                            9. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                            10. Tap the card and the content will then load on the other person’s device.
                                            diff --git a/OpenPGP-Keychain/src/main/res/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml index 0758e9cde..0d96c27c1 100644 --- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml @@ -25,7 +25,7 @@ Schlüssel-Server abfragen Auf Schlüsselserver hochladen Unbekannter Signaturschlüssel - Schlüssel signieren + Schlüssel signieren Schlüsseldetails Hilfe @@ -41,13 +41,8 @@ Schlüssel hochladen Schlüsselserver - Signieren (Zwischenablage) - In die Zwischenablage verschlüsseln - Verschlüsseln und senden... - Signieren und senden... Signieren Entschlüsseln - Signatur prüfen Empfänger auswählen Datei verschlüsseln Speichern @@ -266,7 +261,6 @@ erstelle Hauptring... füge Unterschlüssel hinzu... Schlüssel wird gespeichert... - importiere private Schlüssel... Schlüssel wird exportiert… Schlüssel werden exportiert… diff --git a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml index 6c520988f..18c4bd8eb 100644 --- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml @@ -22,7 +22,7 @@ Clave no encontrada Solicitar al servidor de claves Clave de firma desconocida - Clave de firma + Clave de firma Ayuda IDs de usuario @@ -31,13 +31,8 @@ Por defecto Avanzado - Firmar (Portapapeles) - Cifrar a portapapeles - Cifrar y enviar - Firmar y enviar Firmar Descifrar - Verificar Escoger destinatarios Cifrar archivo Guardar diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml new file mode 100644 index 000000000..a06fe1803 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -0,0 +1,151 @@ + + + + Seleccionar clave pública + Seleccionar clave secreta + Cifrar + Descifrar + Frase de contraseña + Crear clave + Editar clave + Preferencias + Aplicaciones registradas + Prioridad de servidor de clave + Cambiar frase de contraseña + Establecer frase de contraseña + Enviar email... + Cifrar en archivo + Descifrar en archivo + Importar claves + Exportar clave + Exportar claves + Clave no encontrada + Consultar servidor de clave + Clave de firma desconocida + Clave de firma + Ayuda + + IDs de usuario + Claves + General + Predeterminados + Avanzado + + Firmar + Descifrar + Seleccionar destinatarios + Cifrar archivo + Guardar + Cancelar + Eliminar + Ninguno + De acuerdo + Cambiar frase de contraseña + Establecer frase de contraseña + Buscar + Siguiente + Volver + + Ajustes + Importar desde archivo + Importar desde código QR + Importar desde NFC + Exportar todas las claves + Exportar en archivo + Borrar clave + Crear clave + Crear clave (experto) + Buscar + Importar desde servidor de clave + Clave de firma + Ajustes de destello + + Firma + Mensaje + Archivo + No hay frase de contraseña + Frase de contraseña + De nuevo + Algoritmo + Armadura ASCII + Borrar después del cifrado + Borrar después del descifrado + Algoritmo de cifrado + Algoritmo de Hash + Clave pública + Frase de contraseña + Caché de frase de contraseña + Compresión de mensaje + Compresión de archivo + Forzar firmas V3 + Servidores de clave + ID de clave + Creación + Caducidad + Uso + Tamaño de clave + ID del usuario principal + Nombre + Comentario + Email + <ninguno> + <sin clave> + + se puede cifrar + se puede firmar + caducado + Huella digital: + Clave secreta: + + Ninguno + Solo firmar + Solo cifrar + Firmar y cifrar + 15 segs + 1 min + 3 mins + 5 mins + 10 mins + 20 mins + 40 mins + 1 hora + 2 horas + 4 horas + 8 horas + DSA + ElGamal + RSA + Abrir... + Advertencia + Error + Error: %s + + Frase de contraseña incorrecta. + Usando el contenido del portapapeles. + Establece una frase de contraseña antes. + No hay un gestor de archivos compatible instalado. + Las frases de contraseña no coinciden. + La frase de contraseña no puede estar vacía. + Cifrado simétrico. + Introducir frase de contraseña para \'%s\' + ¿Estas seguro que quieres borrar\n%s? + Borrado satisfactoriamente. + Selecciona un archivo antes. + Descifrado satisfactoriamente. + Descifrado satisfactoriamente. + + + + + + + + + + + + + + diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index 5f12275b9..45ad149d5 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -25,7 +25,7 @@ Interroger le serveur de clefs Téléverser vers le serveur de clefs Clef de signature inconnue - Signer la clef + Signer la clef Détails sur la clef Aide @@ -40,14 +40,12 @@ Votre clef utilisée pour la signature Téléverser la clef Serveur de clefs + Chiffrer et/ou signer + Déchiffrer et vérifier - Signer (presse-papiers) - Chiffrer vers le presse-papiers - Chiffrer et envoyer... - Signer et envoyer... Signer Déchiffrer - Vérifier + Déchiffrer et vérifier Choisir les destinataires Chiffrer le fichier Enregistrer @@ -61,6 +59,8 @@ Téléverser vers le serveur de clefs Suivant Retour + Presse-papiers + Partager avec... Paramètres Aide @@ -273,7 +273,6 @@ assemblage du trousseau maître... ajout des sous-clefs... sauvegarde de la clef... - Importation des clefs secrètes... exportation de la clef... exportation des clefs... diff --git a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml index 71783d3b2..4cb778ce4 100644 --- a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml @@ -15,7 +15,7 @@ Esportare Chiave Esportare Chiavi Chiave Non Trovata - Firma Chiave + Firma Chiave Aiuto ID Utente @@ -23,10 +23,8 @@ Generale Avanzato - Firmare ed inviare... Firmare Decifrare - Verificare Cifrare File Salva Cancella diff --git a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml index 7389664fe..17e61aca8 100644 --- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml @@ -22,7 +22,7 @@ Sleutel niet gevonden Sleutelserver verzoek zenden Onbekende handtekeningssleutel - Sleutel ondertekenen + Sleutel ondertekenen Help Gebruikers-id\'s @@ -31,13 +31,8 @@ Standaard Geavanceerd - Ondertekenen (klembord) - Versleutelen naar klembord - Versleutelen en verzenden... - Ondertekenen en verzenden... Ondertekenen Ontsleutelen - Verifiëren Ontvangers selecteren Bestand versleutelen Opslaan @@ -195,7 +190,6 @@ hoofdsleutel certificeren... hoofdsleutelbos maken... sub-sleutels toevoegen... - privésleutels importeren... ondertekeningssleutel uitpakken... sleutel uitpakken... streams voorbereiden... diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index dd9eaf86d..17fcf37b3 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -25,7 +25,7 @@ Запросить сервер ключей Загрузить на сервер ключей Неизвестная подпись - Ключ для подписи + Ключ для подписи Сведения о ключе Помощь @@ -40,14 +40,12 @@ Ваш ключ, используемый для подписания Загрузить ключ Сервер ключей + Зашифровать и/или Подписать + Расшифровать и проверить - Подписать (Буфер обмена) - Зашифровать в Буфер обмена - Зашифровать и отправить... - Подписать и отправить... Подписать Расшифровать - Проверить + Расшифровать и проверить Выбрать получателей Зашифровать файл Сохранить @@ -61,6 +59,8 @@ Загрузить на сервер ключей Далее Назад + Буфер обмена + Поделиться... Настройки Помощь @@ -281,7 +281,6 @@ создание основной связки... добавление доп. ключей... сохранение ключа... - импорт секретных ключей... экспорт ключа... экспорт ключей... diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml index 20d99ae2e..a20ff253e 100644 --- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml @@ -14,7 +14,7 @@ Anahtar Bulunamadı Anahtar Sunucusunu Sorgula Bilinmeyen İmza Anahtarı - Anahtarı İmzala + Anahtarı İmzala Anahtar Detayları Yardım @@ -26,12 +26,7 @@ Anahtar Yükle Anahtar Sunucusu - İmzala (Pano) - Panoya Şifrele - Şifrele ve gönder... - İmzala ve gönder... İmzala - Doğrula Alıcıları Seç Kaydet İptal diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml index b08c8edc2..3f735638d 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml @@ -25,7 +25,7 @@ Сервер запиту ключа Завантажити на сервер ключів Невідомий підпис ключа - Підписати ключ + Підписати ключ Подробиці про ключ Довідка @@ -40,14 +40,12 @@ Ваш ключ, використаний для підпису Завантажити ключ Сервер ключів + Шифрувати і/або підписати + Розшифрувати і Перевірити - Підпис (буфер обміну) - Зашифрувати у буфер обміну - Шифрувати і надіслати… - Підписати і надіслати… Підписати Розшифрувати - Перевірити + Розшифрувати і Перевірити Вибрати одержувачів Шифрувати файл Зберегти @@ -61,6 +59,8 @@ Завантажити на сервер ключів Далі Назад + Буфер обміну + Поділитися через… Параметри Довідка @@ -281,7 +281,6 @@ побудова основного кільця… додавання підключів… зберігається ключ… - імпортуються секретні ключі… експортується ключ… експортуються ключі… -- cgit v1.2.3 From e37190a76d3f50810de25a9bc6ef400707bf3fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 00:26:06 +0100 Subject: drawer icons have not the same width, fix this --- OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml index bf70b2de7..72f4fec50 100644 --- a/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/drawer_list_item.xml @@ -5,7 +5,7 @@ Date: Wed, 5 Feb 2014 12:52:25 +0100 Subject: fix small language confusion --- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index ff63ea58a..559b04469 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -407,7 +407,7 @@ Encrypt to this contact - Certify User ID of this contact + Certify key of this contact Contacts -- cgit v1.2.3 From d72b0e157ad85161cd7c2e840552c71155b474cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 12:56:40 +0100 Subject: Update from transifex --- .../src/main/res/raw-de/help_start.html | 23 +- .../src/main/res/raw-es-rCO/help_start.html | 23 +- .../src/main/res/raw-es/help_about.html | 36 +-- .../src/main/res/raw-es/help_changelog.html | 16 +- .../src/main/res/raw-es/help_start.html | 23 +- .../src/main/res/raw-fr/help_start.html | 23 +- .../src/main/res/raw-it-rIT/help_start.html | 23 +- .../src/main/res/raw-nl-rNL/help_start.html | 23 +- .../src/main/res/raw-pt-rBR/help_start.html | 23 +- .../src/main/res/raw-ru/help_start.html | 23 +- .../src/main/res/raw-sl-rSI/help_start.html | 23 +- .../src/main/res/raw-tr/help_start.html | 23 +- .../src/main/res/raw-uk/help_start.html | 23 +- .../src/main/res/raw-zh/help_start.html | 23 +- .../src/main/res/values-de/strings.xml | 27 +- .../src/main/res/values-es-rCO/strings.xml | 1 - .../src/main/res/values-es/strings.xml | 277 +++++++++++++++++++-- .../src/main/res/values-fr/strings.xml | 6 - .../src/main/res/values-it-rIT/strings.xml | 1 - .../src/main/res/values-nl-rNL/strings.xml | 4 - .../src/main/res/values-ru/strings.xml | 6 - .../src/main/res/values-tr/strings.xml | 2 - .../src/main/res/values-uk/strings.xml | 6 - 23 files changed, 422 insertions(+), 236 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html index 773d11fa7..a8ff31283 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html @@ -2,42 +2,42 @@

                                            http://sufficientlysecure.org/keychain

                                            -

                                            OpenPGP Keychain is an OpenPGP implementation for Android. The development began as a fork of Android Privacy Guard (APG).

                                            -

                                            License: GPLv3+

                                            +

                                            OpenPGP Keychain es una implementación de OpenPGP para Android. Su desarrollo comenzó como un fork de Android Privacy Guard (APG).

                                            +

                                            Licencia: GPLv3+

                                            -

                                            Developers OpenPGP Keychain

                                            +

                                            Desarrolladores de OpenPGP Keychain

                                              -
                                            • Dominik Schürmann (Lead developer)
                                            • -
                                            • Ash Hughes (crypto patches)
                                            • +
                                            • Dominik Schürmann (Desarrollador principal)
                                            • +
                                            • Ash Hughes (parches cryptográficos)
                                            • Brian C. Barnes
                                            • Bahtiar 'kalkin' Gadimov (UI)
                                            -

                                            Developers APG 1.x

                                            +

                                            Desarrolladores de APG 1.x

                                              -
                                            • 'Thialfihar' (Lead developer)
                                            • -
                                            • 'Senecaso' (QRCode, sign key, upload key)
                                            • +
                                            • 'Thialfihar' (Desarrollador principal)
                                            • +
                                            • 'Senecaso' (Código QR, clave de firma, carga de clave)
                                            • Oliver Runge
                                            • Markus Doits
                                            -

                                            Libraries

                                            +

                                            Librerías

                                            diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html index 28d025a9f..583ee25f4 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html @@ -33,7 +33,7 @@
                                            • lots of bug fixes
                                            • new API for developers
                                            • -
                                            • PRNG bug fix by Google
                                            • +
                                            • Bug PRNG corregido por Google

                                            2.0

                                              @@ -46,12 +46,12 @@

                                            1.0.8

                                              -
                                            • basic key server support
                                            • +
                                            • compatibilidad básica de servidor de claves
                                            • app2sd
                                            • -
                                            • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                            • -
                                            • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                            • -
                                            • bugfixes
                                            • -
                                            • optimizations
                                            • +
                                            • más opciones para la caché de la frase de contraseña: 1, 2, 4, 8 horas
                                            • +
                                            • traducciones: Noruego (gracias, Sander Danielsen), Chino (gracias, Zhang Fredrick)
                                            • +
                                            • correcciones de errores
                                            • +
                                            • optimizaciones

                                            1.0.7

                                              @@ -66,7 +66,7 @@
                                            • stream encryption/decryption (gallery, etc.)
                                            • new options (language, force v3 signatures)
                                            • interface changes
                                            • -
                                            • bugfixes
                                            • +
                                            • correcciones de errores

                                            1.0.5

                                              @@ -102,7 +102,7 @@
                                            • Slovenian translation
                                            • new database, much faster, less memory usage
                                            • defined Intents and content provider for other apps
                                            • -
                                            • bugfixes
                                            • +
                                            • correcciones de errores
                                            diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html index bec69318b..d45a27f55 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html @@ -1,22 +1,19 @@ -

                                            Logiciel EXPÉRIMENTAL

                                            -

                                            Ce logiciel est EXPÉRIMENTAL. À utiliser à vos propres risques !

                                            -

                                            Commencer

                                            -

                                            Il vous faut d'abord des clefs. Importez ou créez-les depuis le menu des options de « Mes clefs secrètes ». -
                                            Il est recommandé que vous installiez le Gestionnaire de fichiers OI afin de pouvoir utiliser le bouton Parcourir pour choisir des fichiers depuis le Porte-clefs OpenPGP.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Les gros morceaux à faire

                                            -
                                              -
                                            • L'intégration à K-9 Mail n'est pas publiée
                                            • -
                                            • L'importation de clefs existantes sera dépouillé de certificats pour l'instant
                                            • -
                                            • PGP/MIME est manquant dans K-9 Mail
                                            • -
                                            -

                                            Si vous voulez contribuer, bifurquer et faire une demande d'extraction sur Github : https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            J'ai trouvé un bogue dans le Porte-clefs OpenPGP !

                                            -

                                            Veuillez le rapporter avec le gestionnaire de bogues du Porte-clefs OpenPGP.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html index d55f3296b..4b5ea0a0b 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html @@ -1,22 +1,19 @@ -

                                            ЭКСПЕРИМЕНТАЛЬНАЯ программа

                                            -

                                            Это ЭКСПЕРИМЕНТАЛЬНАЯ версия. Используйте на свой страх и риск!

                                            -

                                            Приступая

                                            -

                                            Для начала Вам потребуются ключи. Воспользуйтесь функцией Импорт в меню раздела "Мои ключи". -
                                            Для удобства выбора файлов рекомендуется установить OI File Manager. Он будет вызываться при нажатии кнопки выбора файла.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Над чем еще ведётся работа

                                            -
                                              -
                                            • Интеграция с почтовой программой K9 Mail.
                                            • -
                                            • При импорте сущестующих ключей теряются подписи
                                            • -
                                            • Отсутсвует поддержка PGP/MIME в K9 Mail
                                            • -
                                            -

                                            Если вы ходите принять участие в доработке и развитии проекта, посетите страницу проекта на Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            Я нашел ошибку в OpenPGP Keychain!

                                            -

                                            Пожалуйста, сообщите о ней в разделе 'Проблемы с OpenPGP Keychain'.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html index c2b5a8019..c0dd0ae45 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html @@ -1,22 +1,19 @@ -

                                            ЕКСПЕРИМЕНТАЛЬНА програма

                                            -

                                            Це ЕКСПЕРИМЕНТАЛЬНА версія. Використовуйте на свій страх і ризик!

                                            -

                                            Приступаючи до роботи

                                            -

                                            Для початку Вам будуть потрібні ключі. Скористайтеся функцією Імпорт в меню розділу "Мої ключі". -
                                            Для зручності вибору файлів рекомендується встановити OI File Manager. Він буде викликатися при натисканні кнопки вибору файлу.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Над чим ще ведеться робота

                                            -
                                              -
                                            • Інтеграція з поштовою програмою K9 Mail.
                                            • -
                                            • При імпорті існуючих ключів губляться підписи
                                            • -
                                            • Відсутня підтримка PGP/MIME K9 Mail
                                            • -
                                            -

                                            Якщо ви ходите взяти участь у доопрацюванні та розвитку проекту, відвідайте сторінку проекту на Github: https://github.com/dschuermann/openpgp-брелок

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            Я знайшов помилку в OpenPGP Keychain!

                                            -

                                            Будь ласка, повідомте про неї в розділі 'Проблеми з В'язкою ключів OpenPGP'.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html index 1386e8cc1..2f7a788e1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html @@ -1,22 +1,19 @@ -

                                            EXPERIMENTAL software

                                            -

                                            This is EXPERIMENTAL software. Use at your own risk!

                                            -

                                            Getting started

                                            -

                                            First you need some keys. Import or create them via the option menus in "My Secret Keys". -
                                            It is recommended that you install OI File Manager to be able to use the browse button for file selection in OpenPGP Keychain.

                                            +

                                            First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                            -

                                            Big ToDos

                                            -
                                              -
                                            • K9 Mail integration not published
                                            • -
                                            • Importing existing keys will be stripped of certificates right now
                                            • -
                                            • PGP/MIME in K9 Mail is missing
                                            • -
                                            -

                                            If you want to contribute, fork it and do a pull request on Github: https://github.com/dschuermann/openpgp-keychain

                                            +

                                            It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                            I found a bug in OpenPGP Keychain!

                                            -

                                            Please report it in the issue tracker of OpenPGP Keychain.

                                            +

                                            Please report the bug using the issue tracker of OpenPGP Keychain.

                                            + +

                                            Contribute

                                            +

                                            If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                            + +

                                            Translations

                                            +

                                            Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                            + diff --git a/OpenPGP-Keychain/src/main/res/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml index 0d96c27c1..9091936d5 100644 --- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml @@ -25,7 +25,7 @@ Schlüssel-Server abfragen Auf Schlüsselserver hochladen Unbekannter Signaturschlüssel - Schlüssel signieren + Schlüssel beglaubigen Schlüsseldetails Hilfe @@ -37,12 +37,16 @@ Hauptschlüssel Hauptbenutzer-ID Aktionen - Dein Signaturschlüssel + Mit diesem Schlüssel beglaubigen Schlüssel hochladen Schlüsselserver + Verschlüsseln und/oder Signieren + Entschlüsseln und Verifizieren Signieren + Beglaubigen Entschlüsseln + Entschlüsseln und Verifizieren Empfänger auswählen Datei verschlüsseln Speichern @@ -56,6 +60,9 @@ Auf Schlüsselserver hochladen Weiter Zurück + Zwischenablage + Teilen mit… + Schlüssel nachschlagen Einstellungen Hilfe @@ -94,6 +101,7 @@ Wiederholen Algorithmus ASCII-Armor + Empfänger Nach Verschlüsselung löschen Nach Entschlüsselung löschen Verschlüsselungsalgorithmus @@ -114,19 +122,21 @@ Name Kommentar E-Mail - Lade Schlüssel nach dem Signieren auf den ausgewählten Schlüsselserver hoch + Schlüssel nach Beglaubigung auf ausgewählten Schlüsselserver hochladen Fingerabdruck Auswählen %d ausgewählt %d ausgewählt + <kein Name> <keine> <kein Schlüssel> kann verschlüsseln kann signieren abgelaufen + zurückgezogen %d Schlüsselserver %d Schlüsselserver @@ -208,9 +218,12 @@ %d Schlüssel gefunden. %d Schlüssel gefunden. - Unbekannte Unterschrift, zum Suchen berühren. - Unbekannter Schlüssel %s, soll dieser auf einem Schlüsselserver gesucht werden? - Schlüssel erfolgreich zum Server geschickt. + Unbekannte Signatur. Benutze den Button um den fehlenden Schlüssel nachzuschlagen. + + %d schlechter privater Schlüssel ignoriert. Evtl. wurde er mit folgender Option exportiert:\n --export-secret-subkeys\nUnbedingt mit der Option \n --export-secret-keys\nexportieren. + %d schlechte private Schlüssel ignoriert. Evtl. wurden sie mit folgender Option exportiert:\n --export-secret-subkeys\nUnbedingt mit der Option \n --export-secret-keys\nexportieren. + + Schlüssel wurde erfolgreich hochgeladen. Schlüssel erfolgreich signiert Diese Liste ist leer! Schlüssel erfolgreich mit NFC Beam gesendet! @@ -249,6 +262,7 @@ Android 4.1 alias Jelly Bean wird benötigt um Androids NFC-Beam nutzen zu können! NFC steht auf diesem Gerät nicht zur Verfügung! Nichts zu importieren! + Ablaufdatum muss später sein als das Erstellungsdatum fertig. speichern... @@ -357,6 +371,7 @@ existierende Schlüssel importierst. Für diesen Kontakt verschlüsseln + Schlüssel dieses Kontakts beglaubigen Kontakte Verschlüsseln diff --git a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml index 18c4bd8eb..16217156e 100644 --- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml @@ -22,7 +22,6 @@ Clave no encontrada Solicitar al servidor de claves Clave de firma desconocida - Clave de firma Ayuda IDs de usuario diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml index a06fe1803..df870d9f0 100644 --- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -1,8 +1,10 @@ - Seleccionar clave pública - Seleccionar clave secreta + Contactos + Claves secretas + Seleccionar la clave pública + Seleccionar la clave secreta Cifrar Descifrar Frase de contraseña @@ -10,19 +12,21 @@ Editar clave Preferencias Aplicaciones registradas - Prioridad de servidor de clave - Cambiar frase de contraseña + Prioridad del servidor de claves + Cambiar la frase de contraseña Establecer frase de contraseña - Enviar email... - Cifrar en archivo - Descifrar en archivo + Enviar correo electrónico... + Cifrar hacia archivo + Descifrar hacia archivo Importar claves Exportar clave Exportar claves Clave no encontrada - Consultar servidor de clave + Consultar servidor de claves + Cargar al servidor de claves Clave de firma desconocida - Clave de firma + Certificar clave + Detalles de la clave Ayuda IDs de usuario @@ -30,9 +34,19 @@ General Predeterminados Avanzado + Clave maestra + ID del usuario principal + Acciones + Tu clave usada para las certificaciones + Cargar clave + Servidor de claves + Cifrar y/o firmar + Descifrar y verificar Firmar + Certificar Descifrar + Descifrar y verificar Seleccionar destinatarios Cifrar archivo Guardar @@ -40,27 +54,46 @@ Eliminar Ninguno De acuerdo - Cambiar frase de contraseña + Cambiar la frase de contraseña Establecer frase de contraseña Buscar + Cargar al servidor de claves Siguiente Volver + Portapapeles + Compartir con... + Buscar clave Ajustes + Ayuda Importar desde archivo Importar desde código QR + Importar Importar desde NFC Exportar todas las claves - Exportar en archivo + Exportar hacia archivo Borrar clave Crear clave Crear clave (experto) Buscar - Importar desde servidor de clave + Importar desde servidor de claves + Actualizar desde el servidor de claves + Cargar al servidor de claves + Compartir + Compartir la huella digital... + Compartir la clave completa... + con... + con... + con código QR + con código QR + con NFC + Copiar al portapapeles Clave de firma - Ajustes de destello + Ajustes de Beam + Cancelar + Cifrar hacia... - Firma + Firmar Mensaje Archivo No hay frase de contraseña @@ -68,6 +101,7 @@ De nuevo Algoritmo Armadura ASCII + Destinatarios Borrar después del cifrado Borrar después del descifrado Algoritmo de cifrado @@ -78,7 +112,7 @@ Compresión de mensaje Compresión de archivo Forzar firmas V3 - Servidores de clave + Servidores de claves ID de clave Creación Caducidad @@ -87,17 +121,30 @@ ID del usuario principal Nombre Comentario - Email - <ninguno> + Correo electrónico + Cargar la clave al servidor de claves seleccionado después de la certificación + Huella digital + Seleccionar + + %d seleccionado + %d seleccionados + + <sin nombre> + <ninguna> <sin clave> se puede cifrar se puede firmar caducado + revocado + + %d servidor de claves + %d servidores de claves + Huella digital: Clave secreta: - Ninguno + Ninguna Solo firmar Solo cifrar Firmar y cifrar @@ -112,6 +159,7 @@ 2 horas 4 horas 8 horas + para siempre DSA ElGamal RSA @@ -125,27 +173,212 @@ Establece una frase de contraseña antes. No hay un gestor de archivos compatible instalado. Las frases de contraseña no coinciden. - La frase de contraseña no puede estar vacía. + Las frases de contraseña no pueden estar vacías. Cifrado simétrico. - Introducir frase de contraseña para \'%s\' - ¿Estas seguro que quieres borrar\n%s? + Introducir la frase de contraseña para \'%s\' + ¿Estás seguro de que quieres borrar\n%s? Borrado satisfactoriamente. Selecciona un archivo antes. Descifrado satisfactoriamente. - Descifrado satisfactoriamente. + Cifrado satisfactoriamente. + Cifrado satisfactoriamente al portapapeles. + Introduce la frase de contraseña dos veces. + Selecciona al menos una clave de cifrado. + Selecciona al menos una clave de cifrado o de firma. + Por favor, especifica hacia qué archivo quieres cifrar.\nADVERTENCIA: El archivo se sobreescribirá si ya existiese. + Por favor, especifica hacia qué archivo quieres descifrar.\nADVERTENCIA: El archivo se sobreescribirá si ya existiese. + Por favor, especifica hacia qué archivo quieres exportar.\nADVERTENCIA: El archivo se sobreescribirá si ya existiese. + Por favor, especifica hacia qué archivo quieres exportar.\nADVERTENCIA: Estás a punto de exportar claves SECRETAS.\nADVERTENCIA: El archivo se sobreescribirá si ya existiese. + ¿Quieres realmente borrar la clave \'%s\'?\n¡No podrás deshacerlo! + ¿Quieres realmente borrar todas las claves seleccionadas?\n¡No podrás deshacerlo! + ¿Quieres realmente borrar la clave SECRETA \'%s\'?\n¡No podrás deshacerlo! + + %d clave añadida satisfactoriamente + %d claves añadidas satisfactoriamente + + + y actualizada %d clave. + y actualizadas %d claves. + + + %d clave añadida satisfactoriamente. + %d claves añadidas satisfactoriamente. + + + %d clave actualizada satisfactoriamente. + %d claves actualizadas satisfactoriamente. + + No se han añadido o actualizado claves. + Se ha exportado 1 clave satisfactoriamente. + %d claves exportadas satisfactoriamente. + No se han exportado claves. + Nota: solo las subclaves son compatibles con ElGamal, y para ElGamal debe usarse el tamaño de clave más próximo de 1536, 2048, 3072, 4096, o 8192. + No se puede encontrar la clave %08X. + + Se ha encontrado %d clave. + Se han encontrado %d claves. + + Firma desconocida, pulsa el botón para buscar la clave extraviada. + + %d mala clave secreta ignorada. Quizás hayas exportado con la opción\n--export-secret-subkeys\nAsegúrate de que exportas con\n--export-secret-keys\nen su lugar. + %d malas claves secretas ignoradas. Quizás hayas exportado con la opción\n--export-secret-subkeys\nAsegúrate de que exportas con\n--export-secret-keys\nen su lugar. + + Clave cargada al servidor satisfactoriamente + Clave firmada satisfactoriamente + ¡Esta lista está vacía! + ¡Clave enviada satisfactoriamente con NFC Beam! + ¡La clave ha sido copiada al portapapeles! + ¡La clave ya ha sido firmada! + ¡Por favor, selecciona la clave que se usará para firmar! + ¡La clave es demasiado grande para ser compartida de esta forma! + ha fallado el borrado de \'%s\' + archivo no encontrado + no se ha encontrado una clave secreta adecuada + se ha encontrado un tipo de cifrado no conocido + el almacenamiento externo no está preparado + correo electrónico incorrecto \'%s\' + el tamaño de clave debe ser de al menos 512bit + la clave maestra no puede ser una clave ElGamal + elegido algoritmo desconocido + necesitas determinar un nombre + necesitas determinar una dirección de correo electrónica + necesitas al menos una ID de usuario + la ID del usuario principal no puede estar vacía + necesitas al menos una clave maestra + no has proporcionado ninguna clave de cifrado o frase de contraseña + la firma ha fallado + no has proporcionado una frase de contraseña + no has proporcionado una clave de firma + cifrado de datos no válido + datos corrompidos + no se ha podido encontrar un paquete con cifrado simétrico + frase de contraseña incorrecta + error al guardar algunas claves + no se puede extraer la clave privada + Dirigir datos binarios sin un archivo real en el sistema de archivos es incompatible. Esto solo es compatible con ACTION_ENCRYPT_STREAM_AND_RETURN. + !Necesitas Android 4.1 alias Jelly Bean para poder usar la característica NFC Beam! + ¡NFC no está disponible en tu dispositivo! + ¡Nada que importar! + la fecha de caducidad debe ser posterior a la fecha de creación + hecho. + guardando... + importando... + exportando... + generando la clave, esto puede tardar un rato... + construyendo la clave... + preparando la clave maestra... + certificando la clave maestra... + construyendo el anillo maestro... + añadiendo las subclaves... + guardando claves... + + exportando clave... + exportando claves... + + extrayendo la clave de firma... + extrayendo la clave... + preparando las transmisiones... + cifrando los datos... + descifrando los datos... + preparando la firma... + generando la firma... + procesando la firma... + verificando la firma... + firmando... + leyendo los datos... + localizando la clave... + descomprimiendo los datos... + verificando la integridad... + borrando \'%s\' de forma segura… + consultando... + Buscar las claves públicas + Buscar las claves secretas + Compartir la clave con... + 512 + 1024 + 2048 + 4096 + rápido + muy lento + Comenzar + NFC Beam + Registro de cambios + A cerca de + Versión: + Importar las claves seleccionadas + Importar, firmar y cargar las claves seleccionadas + Importar desde el portapapeles + + El código QR con ID %s se ha extraviado + Los códigos QR con IDs %s se han extraviado + + Por favor, comienza con el código QR de ID 1 + ¡El código QR está deformado! ¡Por favor, prueba de nuevo! + ¡El escaneo del código QR ha finalizado! + La huella digital contenida en este código QR es demasiado corta (< 16 caracteres) + Escanea el código QR con \'Barcode Scanner\' + Para recibir las claves a través de NFC, el dispositivo tiene que estar desbloqueado. + Ayuda + Tomar la clave desde el portapapeles + OpenPGP: Descifrar archivo + OpenPGP: Importar clave + OpenPGP: Cifrar + OpenPGP: Descifrar + ¡No hay aplicaciones registradas! + Mostrar la configuración avanzada + Ocultar la configuración avanzada + No se ha seleccionado ninguna clave + Seleccionar clave + Guardar + Cancelar + Revocar acceso + Nombre de paquete + SHA-256 de firma de paquete + La siguiente aplicación solicita acceso a la API de OpenPGP Keychain.\n\n¿Permitir el acceso permanentemente? + Permitir el acceso + Denegar el acceso + ¡Por favor, selecciona una clave! + No se han encontrado claves públicas para estas IDs de usuario: + Existe más de una clave pública para estos IDs de usuario: + ¡Por favor, revisa la lista de destinatarios! + ¡La comprobación de la firma ha fallado! ¿Has instalado esta app desde una fuente distinta? Si estás seguro de que esto no es un ataque, revoca el registro de esta app en OpenPGP Keychain y regístrala de nuevo. + Compartir con código QR + Pasa por todos los códigos QR usando \'Siguiente\', y escanéalos de uno en uno. + Huella digital: + Código QR con ID %1$d de %2$d + Compartir con NFC + + 1 clave seleccionada. + %d claves seleccionadas. + + No hay claves disponibles todavía... + Puedes empezar por + o + creando tu propia clave + importando claves. + Cifrar hacia este contacto + Certificar la ID de usuario de este contacto + Contactos + Cifrar + Descifrar + Importar claves + Mis claves + Aplicaciones registradas + Abrir el Navigation Drawer + Cerrar el Navigation Drawer diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index 45ad149d5..dc7bc172c 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -25,7 +25,6 @@ Interroger le serveur de clefs Téléverser vers le serveur de clefs Clef de signature inconnue - Signer la clef Détails sur la clef Aide @@ -37,7 +36,6 @@ Clef maîtresse ID utilisateur maître Actions - Votre clef utilisée pour la signature Téléverser la clef Serveur de clefs Chiffrer et/ou signer @@ -120,7 +118,6 @@ Nom Commentaire Courriel - Téléverser la clef vers le serveur de clefs choisi après signature Empreinte Choisir @@ -215,13 +212,10 @@ %d clef trouvée. %d clefs trouvées. - Signature inconnue. Toucher pour rechercher la clef. %d mauvaise clef ignorée. Vous avez peut-être exporté avec l\'option\n --export-secret-subkeys\nAssurez-vous d\'exporter plutôt avec\n --export-secret-keys. %d mauvaises clefs ignorées. Vous avez peut-être exporté avec l\'option\n --export-secret-subkeys\nAssurez-vous d\'exporter plutôt avec\n --export-secret-keys. - Clef %s inconnue, voulez-vous essayer de la trouver sur un serveur de clefs ? - Clef envoyée vers le serveur avec succès Clef signée avec succès Cette liste est vide ! Clef envoyée par NFC BEAM avec succès ! diff --git a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml index 4cb778ce4..e404addfa 100644 --- a/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-it-rIT/strings.xml @@ -15,7 +15,6 @@ Esportare Chiave Esportare Chiavi Chiave Non Trovata - Firma Chiave Aiuto ID Utente diff --git a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml index 17e61aca8..fdc7ce082 100644 --- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml @@ -22,7 +22,6 @@ Sleutel niet gevonden Sleutelserver verzoek zenden Onbekende handtekeningssleutel - Sleutel ondertekenen Help Gebruikers-id\'s @@ -144,9 +143,6 @@ Geen sleutels geëxporteerd. Opmerking: alleen sub-sleutels ondersteunen ElGamal, en voor ElGamal wordt de dichtstbijzijnde sleutelgrootte van 1536, 2048, 4096 of 8192 gebruikt. Kan de sleutel %08X niet vinden. - Onbekende handtekening, tik om sleutel op te zoeken. - Onbekende sleutel %s, wilt u het bij een sleutelserver opvragen? - Sleutel succesvol verzonden naar server Sleutel succesvol ondertekend Lijst is leeg Sleutel succesvol verzonden met Beam diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index 17fcf37b3..eb4b248f4 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -25,7 +25,6 @@ Запросить сервер ключей Загрузить на сервер ключей Неизвестная подпись - Ключ для подписи Сведения о ключе Помощь @@ -37,7 +36,6 @@ Основной ключ Владелец Действия - Ваш ключ, используемый для подписания Загрузить ключ Сервер ключей Зашифровать и/или Подписать @@ -120,7 +118,6 @@ Имя Комментарий Email - Загрузить подписанный ключ на сервер Отпечаток Выбрать @@ -222,14 +219,11 @@ Найдено %d ключей. Найдено %d ключей. - Неизвестная подпись. Нажмите для выбора ключа. %d плохой секретный ключ проигнорирован. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys %d плохих секретных ключей проигнорировано. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys\n %d плохих секретных ключей проигнорировано. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys\n - Неизвестный ключ %s. Хотите искать на сервере ключей? - Ключ успешно отправлен на сервер Ключ успешно подписан Список пуст! Ключ успешно передан через NFC! diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml index a20ff253e..587373301 100644 --- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml @@ -14,7 +14,6 @@ Anahtar Bulunamadı Anahtar Sunucusunu Sorgula Bilinmeyen İmza Anahtarı - Anahtarı İmzala Anahtar Detayları Yardım @@ -92,7 +91,6 @@ Önce bir dosya seçin. Başarıyla şifrelendi. Anahtar %08X bulunamadı. - Anahtar sunucuya başarıyla gönderildi Anahtar başarıyla imzalandı Liste boş! @@ -37,7 +36,6 @@ Основний ключ ІД основного ключа Дії - Ваш ключ, використаний для підпису Завантажити ключ Сервер ключів Шифрувати і/або підписати @@ -120,7 +118,6 @@ Назва Коментар Ел. пошта - Завантажити ключ на вибраний сервер ключів після підписування Відбиток Вибрати @@ -222,14 +219,11 @@ Знайдено %d ключі. Знайдено %d ключів. - Невідомий підпис, натисніть, щоб шукати ключ. %d поганий секретний ключ проігнорований. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість. %d погані секретні ключі проігноровані. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість. %d поганих секретних ключів проігноровано. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість. - Невідомий ключ %s, ви хочете віднайти його на сервері ключів? - Успішно надіслано ключ на сервер Успішно підписаний ключ Цей список - порожній! Успішно відправлений ключ з NFC променем! -- cgit v1.2.3 From 25080f45b1e094141c98ee04c6cb495dcdb0baaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 13:00:00 +0100 Subject: fix certify key resource --- OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml index 1dbd2476c..ddb424ee8 100644 --- a/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/certify_key_activity.xml @@ -18,7 +18,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="4dp" android:layout_marginTop="14dp" - android:text="@string/section_signing_key" /> + android:text="@string/section_certification_key" /> Date: Wed, 5 Feb 2014 13:09:59 +0100 Subject: keyserver instead of key server --- .../keychain/ui/CertifyKeyActivity.java | 2 +- .../keychain/ui/DecryptActivity.java | 5 ++--- .../keychain/ui/ImportKeysActivity.java | 14 +++++++------- .../keychain/ui/ImportKeysListFragment.java | 2 +- .../keychain/ui/UploadKeyActivity.java | 2 +- .../keychain/ui/ViewKeyActivity.java | 2 +- .../ui/adapter/ImportKeysListServerLoader.java | 2 +- .../src/main/res/raw-de/help_changelog.html | 2 +- .../src/main/res/raw-es/help_changelog.html | 2 +- .../src/main/res/raw/help_changelog.html | 4 ++-- OpenPGP-Keychain/src/main/res/values/strings.xml | 22 +++++++++++----------- 11 files changed, 29 insertions(+), 30 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index c60b1c2ed..ba6d7aa49 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -242,7 +242,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements // check if we need to send the key to the server or not if (mUploadKeyCheckbox.isChecked()) { - // upload the newly signed key to the key server + // upload the newly signed key to the keyserver uploadKey(); } else { setResult(RESULT_OK); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 51c7c3257..3dd077d12 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -60,7 +60,6 @@ import android.view.animation.AnimationUtils; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -247,7 +246,7 @@ public class DecryptActivity extends DrawerActivity { DecryptActivity.this, mSignatureKeyId); if (key != null) { Intent intent = new Intent(DecryptActivity.this, ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, mSignatureKeyId); startActivity(intent); } @@ -596,7 +595,7 @@ public class DecryptActivity extends DrawerActivity { private void lookupUnknownKey(long unknownKeyId) { Intent intent = new Intent(this, ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 611883a86..e0f25b632 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -55,9 +55,9 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY"; public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_QR_CODE"; - public static final String ACTION_IMPORT_KEY_FROM_KEY_SERVER = Constants.INTENT_PREFIX - + "IMPORT_KEY_FROM_KEY_SERVER"; - public static final String ACTION_IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN = Constants.INTENT_PREFIX + public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX + + "IMPORT_KEY_FROM_KEYSERVER"; + public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN"; // Actions for internal use only: @@ -69,7 +69,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // only used by ACTION_IMPORT_KEY public static final String EXTRA_KEY_BYTES = "key_bytes"; - // only used by ACTION_IMPORT_KEY_FROM_KEY_SERVER + // only used by ACTION_IMPORT_KEY_FROM_KEYSERVER public static final String EXTRA_QUERY = "query"; public static final String EXTRA_KEY_ID = "key_id"; public static final String EXTRA_FINGERPRINT = "fingerprint"; @@ -154,7 +154,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // action: directly load data startListFragment(savedInstanceState, importData, null, null); } - } else if (ACTION_IMPORT_KEY_FROM_KEY_SERVER.equals(action)) { + } else if (ACTION_IMPORT_KEY_FROM_KEYSERVER.equals(action)) { String query = null; if (extras.containsKey(EXTRA_QUERY)) { query = extras.getString(EXTRA_QUERY); @@ -173,7 +173,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa return; } - // display key server fragment with query + // display keyserver fragment with query Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); loadNavFragment(0, args); @@ -288,7 +288,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa String query = "0x" + fingerprint; - // display key server fragment with query + // display keyserver fragment with query Bundle args = new Bundle(); args.putString(ImportKeysServerFragment.ARG_QUERY, query); loadNavFragment(0, args); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index cfcb202b9..b52de5bc9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -122,7 +122,7 @@ public class ImportKeysListFragment extends ListFragment implements mKeyBytes = getArguments().getByteArray(ARG_BYTES); mServerQuery = getArguments().getString(ARG_SERVER_QUERY); - // TODO: this is used when scanning QR Code. Currently it simply uses key server nr 0 + // TODO: this is used when scanning QR Code. Currently it simply uses keyserver nr 0 mKeyServer = Preferences.getPreferences(getActivity()) .getKeyServers()[0]; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java index e3881503b..550d3047d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java @@ -40,7 +40,7 @@ import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; /** - * Sends the selected public key to a key server + * Sends the selected public key to a keyserver */ public class UploadKeyActivity extends ActionBarActivity { private BootstrapButton mUploadButton; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 1f4afcd8b..4d9d49c07 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -398,7 +398,7 @@ public class ViewKeyActivity extends ActionBarActivity implements } Intent queryIntent = new Intent(this, ImportKeysActivity.class); - queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEY_SERVER); + queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); queryIntent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, updateKeyId); // TODO: lookup with onactivityresult! diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java index 753994450..b3bc39127 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListServerLoader.java @@ -79,7 +79,7 @@ public class ImportKeysListServerLoader extends AsyncTaskLoaderremove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                                          8. fix setting expiry dates on keys (thanks to Ash Hughes)
                                          9. more internal fixes when editing keys (thanks to Ash Hughes)
                                          10. -
                                          11. querying key servers directly from the import screen
                                          12. +
                                          13. querying keyservers directly from the import screen
                                          14. fix layout and dialog style on Android 2.2-3.0
                                          15. fix crash on keys with empty user ids
                                          16. fix crash and empty lists when coming back from signing screen
                                          17. diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html index 583ee25f4..d42a1fbfd 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html @@ -6,7 +6,7 @@
                                          18. remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                                          19. fix setting expiry dates on keys (thanks to Ash Hughes)
                                          20. more internal fixes when editing keys (thanks to Ash Hughes)
                                          21. -
                                          22. querying key servers directly from the import screen
                                          23. +
                                          24. querying keyservers directly from the import screen
                                          25. fix layout and dialog style on Android 2.2-3.0
                                          26. fix crash on keys with empty user ids
                                          27. fix crash and empty lists when coming back from signing screen
                                          28. diff --git a/OpenPGP-Keychain/src/main/res/raw/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw/help_changelog.html index 7bb558a24..17ad853de 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_changelog.html @@ -10,7 +10,7 @@ And don't add newlines before or after p tags because of transifex -->
                                          29. remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)
                                          30. fix setting expiry dates on keys (thanks to Ash Hughes)
                                          31. more internal fixes when editing keys (thanks to Ash Hughes)
                                          32. -
                                          33. querying key servers directly from the import screen
                                          34. +
                                          35. querying keyservers directly from the import screen
                                          36. fix layout and dialog style on Android 2.2-3.0
                                          37. fix crash on keys with empty user ids
                                          38. fix crash and empty lists when coming back from signing screen
                                          39. @@ -55,7 +55,7 @@ And don't add newlines before or after p tags because of transifex -->

                                            1.0.8

                                              -
                                            • basic key server support
                                            • +
                                            • basic keyserver support
                                            • app2sd
                                            • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                            • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                            • diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 559b04469..ce919c8f0 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -13,7 +13,7 @@ Edit Key Preferences Registered Applications - Key Server Preference + Keyserver Preference Change Passphrase Set Passphrase "Send Mail…" @@ -23,8 +23,8 @@ Export Key Export Keys Key Not Found - Query Key Server - Upload to Key Server + Query Keyserver + Upload to Keyserver Unknown Signature Key Certify Key Key Details @@ -41,7 +41,7 @@ Actions Your Key used for certification Upload Key - Key Server + Keyserver Encrypt and/or Sign Decrypt and Verify @@ -60,7 +60,7 @@ Change Passphrase Set Passphrase Search - Upload To Key Server + Upload To Keyserver Next Back Clipboard @@ -80,8 +80,8 @@ Create key Create key (expert) Search - Import from key server - Update from key server + Import from keyserver + Update from keyserver Upload to key server Share Share fingerprint… @@ -117,7 +117,7 @@ Message Compression File Compression Force V3 Signatures - Key Servers + Keyservers Key ID Creation Expiry @@ -127,7 +127,7 @@ Name Comment Email - Upload key to selected key server after certification + Upload key to selected keyserver after certification Fingerprint Select @@ -146,8 +146,8 @@ revoked - %d key server - %d key servers + %d keyserver + %d keyservers Fingerprint: -- cgit v1.2.3 From e146deccc062d751f6a115a00f73e625ca5dda19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 13:18:45 +0100 Subject: Version 2.3 --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index d970770f5..e0732ea70 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="23000" + android:versionName="2.3">

                                              Getting started

                                              -

                                              First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                              +

                                              First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                              -

                                              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                              +

                                              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                              I found a bug in OpenPGP Keychain!

                                              Please report the bug using the issue tracker of OpenPGP Keychain.

                                              -- cgit v1.2.3 From cf499462c5d4c24a7708195c4bf461f4c2203293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 5 Feb 2014 19:55:32 +0100 Subject: Hotfix for database upgrade, version 2.3.1 --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 4 ++-- .../org/sufficientlysecure/keychain/provider/KeychainDatabase.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index e0732ea70..6de35571f 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="23100" + android:versionName="2.3.1"> done. -- cgit v1.2.3 From 76806ebd579620c5ab12f59fd021a967d3da1f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 8 Feb 2014 15:42:31 +0100 Subject: language fixes --- .../sufficientlysecure/keychain/ui/KeyListPublicFragment.java | 3 ++- .../org/sufficientlysecure/keychain/ui/ViewKeyActivity.java | 4 +++- OpenPGP-Keychain/src/main/res/values/strings.xml | 10 +++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java index eb0ae6309..c28d57627 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java @@ -313,7 +313,8 @@ public class KeyListPublicFragment extends Fragment implements AdapterView.OnIte for (String userId : notDeleted) { notDeletedMsg += userId + "\n"; } - Toast.makeText(getActivity(), getString(R.string.error_can_not_delete_contacts, notDeletedMsg), + Toast.makeText(getActivity(), getString(R.string.error_can_not_delete_contacts, notDeletedMsg) + + getResources().getQuantityString(R.plurals.error_can_not_delete_info, notDeleted.size()), Toast.LENGTH_LONG).show(); mode.finish(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 0a7e06a62..14640480e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -475,7 +475,9 @@ public class ViewKeyActivity extends ActionBarActivity implements if (returnData != null && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) { // we delete only this key, so MESSAGE_NOT_DELETED will solely contain this key - Toast.makeText(ViewKeyActivity.this, R.string.error_can_not_delete_contact, + Toast.makeText(ViewKeyActivity.this, + getString(R.string.error_can_not_delete_contact) + + getResources().getQuantityString(R.plurals.error_can_not_delete_info, 1), Toast.LENGTH_LONG).show(); } else { setResult(RESULT_CANCELED); diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 6fc4678fe..ddc3c9789 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -283,8 +283,12 @@ NFC is not available on your device! Nothing to import! expiry date must come after creation date - you can not delete this contact because it is your own. Please delete it from the \'My Keys\' screen! - you can not delete the following contacts because they are your own:\n%sPlease delete them from the \'My Keys\' screen! + you can not delete this contact because it is your own. + you can not delete the following contacts because they are your own:\n%s + + Please delete it from the \'My Keys\' screen! + Please delete them from the \'My Keys\' screen! + done. @@ -409,7 +413,7 @@ Encrypt to this contact - Certify key of this contact + Certify this contact's key Contacts -- cgit v1.2.3 From 35a123f53c87d2ff6130d44c2bed3c421775b9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 8 Feb 2014 15:44:18 +0100 Subject: Update from transifex --- .../src/main/res/raw-de/help_changelog.html | 2 +- .../src/main/res/raw-de/help_start.html | 4 +- .../src/main/res/raw-es-rCO/help_changelog.html | 4 +- .../src/main/res/raw-es-rCO/help_start.html | 4 +- .../src/main/res/raw-es/help_about.html | 2 +- .../src/main/res/raw-es/help_changelog.html | 112 ++++++++--------- .../src/main/res/raw-es/help_nfc_beam.html | 10 +- .../src/main/res/raw-es/help_start.html | 18 +-- .../src/main/res/raw-es/nfc_beam_share.html | 8 +- .../src/main/res/raw-fr/help_start.html | 14 +-- .../src/main/res/raw-it-rIT/help_changelog.html | 4 +- .../src/main/res/raw-it-rIT/help_start.html | 4 +- .../src/main/res/raw-nl-rNL/help_changelog.html | 4 +- .../src/main/res/raw-nl-rNL/help_start.html | 4 +- .../src/main/res/raw-pt-rBR/help_changelog.html | 4 +- .../src/main/res/raw-pt-rBR/help_start.html | 4 +- .../src/main/res/raw-ru/help_changelog.html | 4 +- .../src/main/res/raw-ru/help_start.html | 14 +-- .../src/main/res/raw-sl-rSI/help_changelog.html | 4 +- .../src/main/res/raw-sl-rSI/help_start.html | 4 +- .../src/main/res/raw-tr/help_changelog.html | 4 +- .../src/main/res/raw-tr/help_start.html | 4 +- .../src/main/res/raw-uk/help_start.html | 14 +-- .../src/main/res/raw-zh/help_changelog.html | 4 +- .../src/main/res/raw-zh/help_start.html | 4 +- .../src/main/res/values-de/strings.xml | 14 --- .../src/main/res/values-es-rCO/strings.xml | 4 - .../src/main/res/values-es/strings.xml | 24 ++-- .../src/main/res/values-fr/strings.xml | 19 ++- .../src/main/res/values-nl-rNL/strings.xml | 4 - .../src/main/res/values-ru/strings.xml | 20 ++- .../src/main/res/values-tr/strings.xml | 6 - .../src/main/res/values-uk/strings.xml | 13 +- .../src/main/res/values-zh/strings.xml | 139 +++++++++++++++++++++ 34 files changed, 315 insertions(+), 186 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html index 0faf0eb5e..56dcf0c8b 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_changelog.html @@ -46,7 +46,7 @@

                                            1.0.8

                                              -
                                            • Einfacher Schlüsselserversupport
                                            • +
                                            • basic keyserver support
                                            • app2sd
                                            • mehr Auswahlmöglichkeiten für den Passwortcache: 1, 2, 4, 8, Stunden
                                            • Übersetzungen: norwegisch (Danke, Sander Danielsen), chinesisch (danke, Zhang Fredrick)
                                            • diff --git a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-de/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-de/help_start.html @@ -2,9 +2,9 @@

                                              Getting started

                                              -

                                              First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                              +

                                              First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                              -

                                              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                              +

                                              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                              I found a bug in OpenPGP Keychain!

                                              Please report the bug using the issue tracker of OpenPGP Keychain.

                                              diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_changelog.html @@ -6,7 +6,7 @@
                                            • 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 key servers directly from the import screen
                                            • +
                                            • 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
                                            • @@ -46,7 +46,7 @@

                                            1.0.8

                                              -
                                            • basic key server support
                                            • +
                                            • basic keyserver support
                                            • app2sd
                                            • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                            • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                            • diff --git a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-es-rCO/help_start.html @@ -2,9 +2,9 @@

                                              Getting started

                                              -

                                              First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                              +

                                              First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                              -

                                              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                              +

                                              It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                              I found a bug in OpenPGP Keychain!

                                              Please report the bug using the issue tracker of OpenPGP Keychain.

                                              diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html index a8ff31283..a81789cec 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_about.html @@ -8,7 +8,7 @@

                                              Desarrolladores de OpenPGP Keychain

                                              • Dominik Schürmann (Desarrollador principal)
                                              • -
                                              • Ash Hughes (parches cryptográficos)
                                              • +
                                              • Ash Hughes (Parches cryptográficos)
                                              • Brian C. Barnes
                                              • Bahtiar 'kalkin' Gadimov (UI)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html index d42a1fbfd..18b42a296 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html @@ -3,105 +3,105 @@

                                                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
                                                • +
                                                • elimina la exportación innecesaria de claves públicas cuando se exporta la clave secreta (gracias a Ash Hughes)
                                                • +
                                                • corrige la configuración de la fecha de caducidad en las claves (gracias a Ash Hughes)
                                                • +
                                                • más correcciones internas cuando se editan claves (gracias a Ash Hughes)
                                                • +
                                                • consultar los servidores de claves directamente desde la ventana de importación
                                                • +
                                                • corrige el diseño y estilo de mensajes en Android 2.2-3.0
                                                • +
                                                • corrige error en claves con IDs de usuario vacías
                                                • +
                                                • corrige fallo y listados vacíos cuando se regresa desde la pantalla de firma
                                                • +
                                                • Bouncy Castle (librería criptográfica) actualizada de 1.47 a 1.50 y compilada desde la fuente
                                                • +
                                                • corrige la carga de la clave desde la pantalla de firma

                                                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
                                                • +
                                                • nuevo diseño con Navigation Drawer
                                                • +
                                                • nuevo diseño de la lista de clave pública
                                                • +
                                                • nueva vista de la clave pública
                                                • +
                                                • correcciones en la importación de claves
                                                • +
                                                • clave de certificación cruzada (gracias a Ash Hughes)
                                                • +
                                                • manejo correcto de las contraseñas UTF-8 (gracias a Ash Hughes)
                                                • +
                                                • primera versión con nuevos idiomas (gracias a los colaboradores en Transifex)
                                                • +
                                                • compartir claves a través de códigos QR corregido y mejorado
                                                • +
                                                • verificación por API del paquete de firma

                                                2.1.1

                                                  -
                                                • API Updates, preparation for K-9 Mail integration
                                                • +
                                                • Actualizaciones de la API, preparación para la integración con K-9 Mail

                                                2.1

                                                  -
                                                • lots of bug fixes
                                                • -
                                                • new API for developers
                                                • -
                                                • Bug PRNG corregido por Google
                                                • +
                                                • corrección de muchos bugs
                                                • +
                                                • nueva API para desarrolladores
                                                • +
                                                • corrección del bug PRNG por 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
                                                • +
                                                • completo rediseño
                                                • +
                                                • compartir claves públicas a través de códigos QR, NFC, Beam
                                                • +
                                                • claves de firma
                                                • +
                                                • cargar claves al servidor
                                                • +
                                                • corrige problemas importantes
                                                • +
                                                • nueva API AIDL

                                                1.0.8

                                                  -
                                                • compatibilidad básica de servidor de claves
                                                • -
                                                • app2sd
                                                • +
                                                • compatibilidad básica de los servidores de claves
                                                • +
                                                • app-a-sd
                                                • más opciones para la caché de la frase de contraseña: 1, 2, 4, 8 horas
                                                • -
                                                • traducciones: Noruego (gracias, Sander Danielsen), Chino (gracias, Zhang Fredrick)
                                                • +
                                                • traducciones: noruego (gracias, Sander Danielsen), chino (gracias, Zhang Fredrick)
                                                • correcciones de errores
                                                • optimizaciones

                                                1.0.7

                                                  -
                                                • fixed problem with signature verification of texts with trailing newline
                                                • -
                                                • more options for pass phrase cache time to live (20, 40, 60 mins)
                                                • +
                                                • corregido el problema con la verificación de firma de textos que arrastran a una nueva línea
                                                • +
                                                • más opciones para el tiempo de la caché de la frase de contraseña hasta ahora (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
                                                • +
                                                • corregido el problema al añadir cuentas en Froyo
                                                • +
                                                • borrado seguro de archivo
                                                • +
                                                • opción para borrar el archivo de la clave después de importarlo
                                                • +
                                                • flujo de cifrado/descifrado (galería, etc.)
                                                • +
                                                • nuevas opciones (idioma, forzar firmas v3)
                                                • +
                                                • cambios en la interfaz
                                                • correcciones de errores

                                                1.0.5

                                                  -
                                                • German and Italian translation
                                                • -
                                                • much smaller package, due to reduced BC sources
                                                • -
                                                • new preferences GUI
                                                • -
                                                • layout adjustment for localization
                                                • -
                                                • signature bugfix
                                                • +
                                                • traducciones a alemán e italiano
                                                • +
                                                • paquete de mucho menos tamaño, debido a fuentes BC reducidas
                                                • +
                                                • nuevas preferencias en la GUI
                                                • +
                                                • ajuste del diseño para localización
                                                • +
                                                • corrección de error en la firma

                                                1.0.4

                                                  -
                                                • fixed another crash caused by some SDK bug with query builder
                                                • +
                                                • corregido otro error causado por algún bug en el SDK con el constructor de consultas

                                                1.0.3

                                                  -
                                                • fixed crashes during encryption/signing and possibly key export
                                                • +
                                                • corregidos los errores durante el cifrado/firma y probablemente en la exportación de la clave

                                                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
                                                • +
                                                • listas de claves con filtro
                                                • +
                                                • preselección de claves de cifrado más inteligente
                                                • +
                                                • nuevo intento en el manejo para VER y ENVIAR, permite que los archivos sean cifrados/descifrados fuera de los gestores de archivos
                                                • +
                                                • corrige y añade características (preselección de clave) para K-9 Mail, nueva compilación disponible

                                                1.0.1

                                                  -
                                                • GMail account listing was broken in 1.0.0, fixed again
                                                • +
                                                • La enumeración de cuentas de GMail no funcionaba en 1.0.0, corregida de nuevo

                                                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
                                                • +
                                                • integración con K-9 Mail, APG compatible con la compilación beta de K-9 Mail
                                                • +
                                                • compatibilidad para más gestores de archivos (incluyendo ASTRO)
                                                • +
                                                • traducción al esloveno
                                                • +
                                                • nueva base de datos, más rápida, con menos demanda de memoria
                                                • +
                                                • definidos los intentos y el proveedor de contenido para otras aplicaciones
                                                • correcciones de errores
                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html index 88492731c..4a95680b5 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_nfc_beam.html @@ -1,12 +1,12 @@ -

                                                How to receive keys

                                                +

                                                Cómo recibir las claves

                                                  -
                                                1. Go to your partners contacts and open the contact you want to share.
                                                2. -
                                                3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                                4. -
                                                5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                                6. -
                                                7. Tap the card and the content will then load on the your device.
                                                8. +
                                                9. Vete a los contactos de tu compañero y abre el contacto con el que quieres compartir
                                                10. +
                                                11. Mantén los dos dispositivos de con ambos reversos juntos (tienen que estar casi en contacto) y notarás una vibración.
                                                12. +
                                                13. Después de que vibre, verás el contenido en el dispositivo de tu compañero convertirse en una especie de ficha con una animación de Star Trek de fondo.
                                                14. +
                                                15. Toca la ficha y el contenido se cargará en tu dispositivo.
                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html index 2f7a788e1..d0eee8adb 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_start.html @@ -1,19 +1,19 @@ -

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                Primeros pasos

                                                +

                                                Primero necesitas un par de claves personales. Crea una a través del menú "Mis claves" o importa un par de claves ya existentes a través de "Importar claves". Después, puedes descargar las claves de tus amigos o intercambiarlas a través de códigos QR o NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                Es recomendable que instales OI File Manager para una mejor selección de archivos y Barcode Scanner para escanear los códigos QR generados. Pulsando en los enlaces se abrirá Google Play o F-Droid.

                                                -

                                                I found a bug in OpenPGP Keychain!

                                                -

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                +

                                                ¡He encontrado un bug en OpenPGP Keychain!

                                                +

                                                Por favor, informa de errores usando el seguimiento de incidencias de OpenPGP Keychain.

                                                -

                                                Contribute

                                                -

                                                If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                +

                                                Aportar

                                                +

                                                Si quieres ayudarnos con el desarrollo de OpenPGP Keychain aportando código sigue nuestra pequeña guía en Github.

                                                -

                                                Translations

                                                -

                                                Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                +

                                                Traducciones

                                                +

                                                ¡Ayúdanos a traducir OpenPGP Keychain! Todo el mundo es bienvenido en Transifex - OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html index 083e055c7..b6c2a2278 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/nfc_beam_share.html @@ -2,10 +2,10 @@
                                                  -
                                                1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                                                2. -
                                                3. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                                                4. -
                                                5. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                                6. -
                                                7. Tap the card and the content will then load on the other person’s device.
                                                8. +
                                                9. Asegúrate de que NFC está encendido en Ajustes > Más > NFC, y asegúrate de que Android Beam está también activado en ese mismo apartado.
                                                10. +
                                                11. Mantén los dos dispositivos con ambos reversos juntos (deben estar casi en contacto) y notarás una vibración.
                                                12. +
                                                13. Después de la vibración verás el contenido de tu dispositivo convertirse en una especie de ficha con una animación de Star Trek de fondo.
                                                14. +
                                                15. Pulsa la ficha y el contenido será cargado en el dispositivo de la otra persona.
                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html index d45a27f55..4be071ec9 100644 --- a/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-fr/help_start.html @@ -2,18 +2,18 @@

                                                Commencer

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                Vous avez d'abord besoin d'une paire de clefs personelles. Créez-en une avec l'option du menu « Mes clefs » ou importez des paires de clefs existantes avec « Importer des clefs ». Ensuite vous pouvez télécharger les clefs de vos amis, ou les échanger par codes QR ou NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                Il vous est recommendé d'installer le gestionnaire de fichiers OI pour sa fonction améliorée de séléction des fichiers et le lecteur de codes à barres pour balayer les codes QR générés. Cliquer sur les liens ouvrira Google Play Store ou F-Droid pour l'installation.

                                                J'ai trouvé un bogue dans le Porte-clefs OpenPGP !

                                                -

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                +

                                                Veuillez rapporter le bogue en utilisant le gestionnaire de bogues du Porte-clefs OpenPGP.

                                                -

                                                Contribute

                                                -

                                                If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                +

                                                Contribuer

                                                +

                                                Si vous voulez nous aider à développer le Porte-clefs OpenPGP en y contribuant par du code, veuillez suivre notre petit guide sur Github.

                                                -

                                                Translations

                                                -

                                                Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                +

                                                Traductions

                                                +

                                                Aidez-nous à traduire le Porte-clefs OpenPGP ! Tout le monde peut y participer sur la page Transifex du Porte-clefs OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_changelog.html @@ -6,7 +6,7 @@
                                              • 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 key servers directly from the import screen
                                              • +
                                              • 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
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic key server support
                                              • +
                                              • basic keyserver support
                                              • app2sd
                                              • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                              • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-it-rIT/help_start.html @@ -2,9 +2,9 @@

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                I found a bug in OpenPGP Keychain!

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_changelog.html @@ -6,7 +6,7 @@
                                              • 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 key servers directly from the import screen
                                              • +
                                              • 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
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic key server support
                                              • +
                                              • basic keyserver support
                                              • app2sd
                                              • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                              • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-nl-rNL/help_start.html @@ -2,9 +2,9 @@

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                I found a bug in OpenPGP Keychain!

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_changelog.html @@ -6,7 +6,7 @@
                                              • 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 key servers directly from the import screen
                                              • +
                                              • 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
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic key server support
                                              • +
                                              • basic keyserver support
                                              • app2sd
                                              • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                              • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-pt-rBR/help_start.html @@ -2,9 +2,9 @@

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                I found a bug in OpenPGP Keychain!

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html index 68c054917..688f07be4 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html @@ -6,7 +6,7 @@
                                              • удален не требующийся экспорт публичного ключа при экспорте секретного ключа (спасибо, Ash Hughes)
                                              • исправлена ошибка срока годности ключей (спасибо, Ash Hughes)
                                              • исправления ошибок при изменении ключей (спасибо, Ash Hughes)
                                              • -
                                              • запрос ключа прямо из окна импорта ключей
                                              • +
                                              • querying keyservers directly from the import screen
                                              • исправление внешнего вида для Android 2.2-3.0
                                              • исправлено падение когда ключ не содержал имя пользователя
                                              • исправлено падение и пустой список при возвращении из окна подписания
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • поддержка серверов ключей
                                              • +
                                              • basic keyserver support
                                              • App2SD
                                              • больше вариантов сохранения кэша пароля: 1, 2, 4, 8 часов
                                              • переводы: норвежский (спасибо, Sander Danielsen), китайский (спасибо, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html index 4b5ea0a0b..b47f3c741 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html @@ -2,18 +2,18 @@

                                                Приступая

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                Я нашел ошибку в OpenPGP Keychain!

                                                -

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                +

                                                Пожалуйста, сообщайте о возникших проблемах и найденных ошибках в разделе Решение проблем OpenPGP Keychain.

                                                -

                                                Contribute

                                                -

                                                If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                +

                                                Вклад в развитие

                                                +

                                                Если Вы хотите помочь в разработке OpenPGP Keychain, обратитесь к инструкции на Github.

                                                -

                                                Translations

                                                -

                                                Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                +

                                                Перевод

                                                +

                                                Помогите переводить OpenPGP Keychain! Каждый может принять участие в переводе OpenPGP Keychain на Transifex.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_changelog.html @@ -6,7 +6,7 @@
                                              • 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 key servers directly from the import screen
                                              • +
                                              • 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
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic key server support
                                              • +
                                              • basic keyserver support
                                              • app2sd
                                              • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                              • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-sl-rSI/help_start.html @@ -2,9 +2,9 @@

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                I found a bug in OpenPGP Keychain!

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_changelog.html @@ -6,7 +6,7 @@
                                              • 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 key servers directly from the import screen
                                              • +
                                              • 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
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic key server support
                                              • +
                                              • basic keyserver support
                                              • app2sd
                                              • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                              • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-tr/help_start.html @@ -2,9 +2,9 @@

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                I found a bug in OpenPGP Keychain!

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html index c0dd0ae45..520224815 100644 --- a/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-uk/help_start.html @@ -2,18 +2,18 @@

                                                Приступаючи до роботи

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                Спершу вам потрібна персональна в'язка ключів. Створіть одну через меню параметрів у "Мої Ключі" або імпортуйте наявні в'язки ключів через "Імпорт ключів". Після цього ви зможете завантажувати ключі ваших друзів чи обміняти їх через штрих-коди або NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                Рекомендуємо вам встановити OI File Manager для поліпшеного виділення файлів та Barcode Scanner для сканування згенерованих штрих-кодів. Натискання посилань відкриє Google Play або F-Droid для встановлення.

                                                Я знайшов помилку в OpenPGP Keychain!

                                                -

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                +

                                                Будь ласка, повідомте про ваду за допомогою відстежувача проблем OpenPGP Keychain.

                                                -

                                                Contribute

                                                -

                                                If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                +

                                                Внесок

                                                +

                                                Якщо ви хочете допомогти нам у розробці OpenPGP Keychain через редагування коду програми підпишіться на наш невеличкий посібник у Github.

                                                -

                                                Translations

                                                -

                                                Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                +

                                                Переклади

                                                +

                                                Допоможіть перекласти OpenPGP Keychain! Кожний може взяти участь у OpenPGP Keychain на Transifex.

                                                diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html index 28d025a9f..abf660ba8 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_changelog.html @@ -6,7 +6,7 @@
                                              • 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 key servers directly from the import screen
                                              • +
                                              • 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
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic key server support
                                              • +
                                              • basic keyserver support
                                              • app2sd
                                              • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                              • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html b/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html index 2f7a788e1..198dfe64f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-zh/help_start.html @@ -2,9 +2,9 @@

                                                Getting started

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download keys of your friends or exchange them via QR Codes or NFC.

                                                +

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play or F-Droid for installation.

                                                +

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                I found a bug in OpenPGP Keychain!

                                                Please report the bug using the issue tracker of OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml index 9091936d5..d7b4ac89c 100644 --- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml @@ -12,7 +12,6 @@ Schlüssel bearbeiten Einstellungen Registrierte Anwendungen - Einstellung der Schlüsselserver Passwort ändern Passwort setzen E-Mail senden... @@ -22,8 +21,6 @@ Schlüssel exportieren Schlüssel exportieren Schlüssel nicht gefunden - Schlüssel-Server abfragen - Auf Schlüsselserver hochladen Unbekannter Signaturschlüssel Schlüssel beglaubigen Schlüsseldetails @@ -39,7 +36,6 @@ Aktionen Mit diesem Schlüssel beglaubigen Schlüssel hochladen - Schlüsselserver Verschlüsseln und/oder Signieren Entschlüsseln und Verifizieren @@ -57,7 +53,6 @@ Passwort ändern Passwort setzen Suchen - Auf Schlüsselserver hochladen Weiter Zurück Zwischenablage @@ -76,8 +71,6 @@ Schlüssel erstellen Schlüssel erstellen (Experte) Suchen - Schlüsselserver - Von einem Schlüsselserver aktualisieren Auf Schlüsselserver hochladen Teilen Teile Fingerabdruck… @@ -112,7 +105,6 @@ Nachrichten-Komprimierung Datei-Komprimierung OpenPGPv3-Signaturen erzwingen - Schlüsselserver Schlüssel-ID Erstellungsdatum Ablaufdatum @@ -122,7 +114,6 @@ Name Kommentar E-Mail - Schlüssel nach Beglaubigung auf ausgewählten Schlüsselserver hochladen Fingerabdruck Auswählen @@ -137,10 +128,6 @@ kann signieren abgelaufen zurückgezogen - - %d Schlüsselserver - %d Schlüsselserver - Fingerabdruck: Privater Schlüssel: @@ -371,7 +358,6 @@ existierende Schlüssel importierst. Für diesen Kontakt verschlüsseln - Schlüssel dieses Kontakts beglaubigen Kontakte Verschlüsseln diff --git a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml index 16217156e..587f884d0 100644 --- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml @@ -10,7 +10,6 @@ Editar clave Preferencias Aplicaciones registradas - Preferencias del servidor de claves Cambiar contraseña Establecer contraseña Enviar correo electrónico... @@ -20,7 +19,6 @@ Exportar clave Exportar claves Clave no encontrada - Solicitar al servidor de claves Clave de firma desconocida Ayuda @@ -55,7 +53,6 @@ Crear clave Crear clave (experto) Buscar - Importar desde servidor de claves Clave de firma Firmar @@ -75,7 +72,6 @@ Compresión de mensaje Compresión de archivo Forzar firmas V3 - Servidores de claves ID de clave Creación Expiración diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml index df870d9f0..cdcb44cd2 100644 --- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -15,7 +15,7 @@ Prioridad del servidor de claves Cambiar la frase de contraseña Establecer frase de contraseña - Enviar correo electrónico... + Enviar email... Cifrar hacia archivo Descifrar hacia archivo Importar claves @@ -77,7 +77,7 @@ Crear clave (experto) Buscar Importar desde servidor de claves - Actualizar desde el servidor de claves + Actualizar desde servidor de claves Cargar al servidor de claves Compartir Compartir la huella digital... @@ -121,8 +121,8 @@ ID del usuario principal Nombre Comentario - Correo electrónico - Cargar la clave al servidor de claves seleccionado después de la certificación + Email + Cargar clave al servidor de claves seleccionado después de la certificación Huella digital Seleccionar @@ -239,12 +239,12 @@ no se ha encontrado una clave secreta adecuada se ha encontrado un tipo de cifrado no conocido el almacenamiento externo no está preparado - correo electrónico incorrecto \'%s\' + email incorrecto \'%s\' el tamaño de clave debe ser de al menos 512bit la clave maestra no puede ser una clave ElGamal elegido algoritmo desconocido necesitas determinar un nombre - necesitas determinar una dirección de correo electrónica + tienes que determinar una dirección de email necesitas al menos una ID de usuario la ID del usuario principal no puede estar vacía necesitas al menos una clave maestra @@ -263,6 +263,8 @@ ¡NFC no está disponible en tu dispositivo! ¡Nada que importar! la fecha de caducidad debe ser posterior a la fecha de creación + no puedes eliminar este contacto porque eres tú mismo. ¡Por favor, bórralo desde la ventana \"Mis claves\"! + no puedes eliminar los siguientes contactos porque son tú mismo:\n%s¡Por favor, bórralos desde la ventana \"Mis claves\"! hecho. guardando... @@ -296,7 +298,7 @@ borrando \'%s\' de forma segura… consultando... - Buscar las claves públicas + Buscar claves públicas Buscar las claves secretas Compartir la clave con... @@ -364,14 +366,14 @@ 1 clave seleccionada. %d claves seleccionadas. - No hay claves disponibles todavía... + Aún no hay claves disponibles... Puedes empezar por o - creando tu propia clave - importando claves. + crear tu propia clave + importar claves Cifrar hacia este contacto - Certificar la ID de usuario de este contacto + Certificar la clave de este contacto Contactos Cifrar diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index dc7bc172c..dbf47375c 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -12,7 +12,7 @@ Modifier une clef Préférences Applications enregistrées - Serveurs de clefs préférés + Préférences du serveur de clefs Changer la phrase de passe Définir la phrase de passe Envoyer un courriel... @@ -25,6 +25,7 @@ Interroger le serveur de clefs Téléverser vers le serveur de clefs Clef de signature inconnue + Certifier la clef Détails sur la clef Aide @@ -36,12 +37,14 @@ Clef maîtresse ID utilisateur maître Actions + Votre clef utilisée pour la certification Téléverser la clef Serveur de clefs Chiffrer et/ou signer Déchiffrer et vérifier Signer + Certifier Déchiffrer Déchiffrer et vérifier Choisir les destinataires @@ -59,6 +62,7 @@ Retour Presse-papiers Partager avec... + Rechercher la clef Paramètres Aide @@ -118,6 +122,7 @@ Nom Commentaire Courriel + Téléverser la clef vers le serveur de clefs choisi après certification Empreinte Choisir @@ -131,9 +136,10 @@ peut chiffrer peut signer expiré + révoquée - %d serveur de clef - %d serveurs de clef + %d serveur de clefs + %d serveurs de clefs Empreinte : Clef secrète : @@ -212,10 +218,12 @@ %d clef trouvée. %d clefs trouvées. + Signature inconnue. Cliquer sur le bouton pour rechercher la clef manquante. %d mauvaise clef ignorée. Vous avez peut-être exporté avec l\'option\n --export-secret-subkeys\nAssurez-vous d\'exporter plutôt avec\n --export-secret-keys. %d mauvaises clefs ignorées. Vous avez peut-être exporté avec l\'option\n --export-secret-subkeys\nAssurez-vous d\'exporter plutôt avec\n --export-secret-keys. + Clef téléversée vers le serveur avec succès Clef signée avec succès Cette liste est vide ! Clef envoyée par NFC BEAM avec succès ! @@ -228,7 +236,7 @@ they will be put after "error_message", e.g. "Error: file not found"--> échec lors de la suppression de « %s » fichier introuvable - aucune clé secrète adéquate n\'a été trouvée + aucune clefs secrète adéquate n\'a été trouvée aucune sorte de chiffrement connu n\'a été trouvé le stockage externe n\'est pas prêt courriel « %s » invalide @@ -255,6 +263,8 @@ NFC n\'est pas disponible sur votre appareil ! Rien à importer ! la date d\'expiration doit venir après la date de création + vous ne pouvez pas supprimer ce contact car c\'est le vôtre. Veuillez le supprimer depuis l\'écran « Mes Clefs »! + vous ne pouvez pas supprimer les contacts suivants car c\'est les vôtres.\n%sVeuillez les supprimer depuis l\'écran « Mes Clefs »! fait. sauvegarde... @@ -363,6 +373,7 @@ Importer des clefs. Chiffrer vers ce contact + Certifier la clef de ce contact Contacts Chiffrer diff --git a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml index fdc7ce082..3f1cd3cd2 100644 --- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml @@ -10,7 +10,6 @@ Sleutel bewerken Instellingen Geregistreerde apps - Instellingen sleutelserver Wachtwoord wijzigen Wachtwoord instellen E-mail verzenden... @@ -20,7 +19,6 @@ Sleutels exporteren Sleutels exporteren Sleutel niet gevonden - Sleutelserver verzoek zenden Onbekende handtekeningssleutel Help @@ -55,7 +53,6 @@ Sleutel aanmaken Sleutel aanmaken (expert) Zoeken - Importeren uit sleutelserver Sleutel ondertekenen Beam-instellingen @@ -77,7 +74,6 @@ Berichtcompressie Bestandscompressie V3-handtekeningen afdwingen - Sleutelservers Sleutel-id Aanmaak Verlopen diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index eb4b248f4..ca9b9ec4d 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -12,7 +12,6 @@ Изменить ключ Настройки Связанные приложения - Настройки сервера ключей Изменить пароль Задать пароль Отправить... @@ -22,9 +21,8 @@ Экспортировать ключ Экспорт ключей Ключ не найден - Запросить сервер ключей - Загрузить на сервер ключей Неизвестная подпись + Сертифицировать ключ Сведения о ключе Помощь @@ -36,12 +34,13 @@ Основной ключ Владелец Действия + Ваш ключ для сертификации Загрузить ключ - Сервер ключей Зашифровать и/или Подписать Расшифровать и проверить Подписать + Сертифицировать Расшифровать Расшифровать и проверить Выбрать получателей @@ -54,11 +53,11 @@ Изменить пароль Задать пароль Поиск - Загрузить на сервер ключей Далее Назад Буфер обмена Поделиться... + Найти ключ Настройки Помощь @@ -72,8 +71,6 @@ Создать ключ Создать ключ (эксперт) Поиск - Импорт с сервера ключей - Обновить с сервера ключей Загрузить на сервер ключей Отправить... Отправить отпечаток... @@ -108,7 +105,6 @@ Сжатие сообщения Сжатие файла Использовать V3 подписи - Серверы ключей ID ключа Создан Годен до... @@ -132,11 +128,7 @@ шифрование подпись годен до - - %d сервер ключей - %d серверов ключей - %d серверов ключей - + отозван Отпечаток: Секретный ключ: @@ -219,11 +211,13 @@ Найдено %d ключей. Найдено %d ключей. + Неизвестная подпись. Нажмите кнопку, что бы найти ключ. %d плохой секретный ключ проигнорирован. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys %d плохих секретных ключей проигнорировано. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys\n %d плохих секретных ключей проигнорировано. Возможно, вы экспортируете с параметром\n--export-secret-subkeys\nВместо этого используйте\n--export-secret-keys\n + Ключ успешно загружен на сервер Ключ успешно подписан Список пуст! Ключ успешно передан через NFC! diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml index 587373301..8ec698bb0 100644 --- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml @@ -7,12 +7,10 @@ Anahtar oluştur Anahtarı düzenle Seçenekler - Anahtar Sunucusu Seçenekleri Anahtarları Al Anahtarı Ver Anahtarları Ver Anahtar Bulunamadı - Anahtar Sunucusunu Sorgula Bilinmeyen İmza Anahtarı Anahtar Detayları Yardım @@ -23,7 +21,6 @@ Varsayılanlar Gelişmiş Anahtar Yükle - Anahtar Sunucusu İmzala Alıcıları Seç @@ -32,7 +29,6 @@ Sil Tamam Ara - Sunucuya Anahtar Yükle İleri Geri @@ -47,7 +43,6 @@ Anahtar oluştur Anahtar oluştur (uzman) Ara - Anahtar sunucusundan al Panoya kopyala Anahtarı imzala İptal @@ -58,7 +53,6 @@ Tekrar Algoritma Açık Anahtar - Anahtar Sunucuları Oluşturma Kullanım Anahtar Boyutu diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml index 334dfca80..928c206c1 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml @@ -22,9 +22,10 @@ Експортувати ключ Експортувати ключі Ключ не знайдено - Сервер запиту ключа + Сервер ключа запиту Завантажити на сервер ключів Невідомий підпис ключа + Сертифікувати ключ Подробиці про ключ Довідка @@ -36,12 +37,14 @@ Основний ключ ІД основного ключа Дії + Ваш ключ використаний для сертифікації Завантажити ключ Сервер ключів Шифрувати і/або підписати Розшифрувати і Перевірити Підписати + Сертифікувати Розшифрувати Розшифрувати і Перевірити Вибрати одержувачів @@ -59,6 +62,7 @@ Назад Буфер обміну Поділитися через… + Шукати ключ Параметри Довідка @@ -118,6 +122,7 @@ Назва Коментар Ел. пошта + Завантажити ключ до вибраного сервера ключів після сертифікації Відбиток Вибрати @@ -132,6 +137,7 @@ можна зашифрувати можна підписати закінчився + скасовано %d сервер ключів %d сервери ключів @@ -219,11 +225,13 @@ Знайдено %d ключі. Знайдено %d ключів. + Невідомий підпис, натисніть кнопку для пошуку втраченого ключа. %d поганий секретний ключ проігнорований. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість. %d погані секретні ключі проігноровані. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість. %d поганих секретних ключів проігноровано. Можливо ви експортували з параметром\n --export-secret-subkeys\nЗробіть ваш експорт з \n --export-secret-keys\nнатомість. + Успішно завантажено ключ на сервер Успішно підписаний ключ Цей список - порожній! Успішно відправлений ключ з NFC променем! @@ -263,6 +271,8 @@ NFC недоступний на вашому пристрої! Нема що імпортувати! дата завершення дії має йти після дати створення + ви не можете вилучити цей контакт, тому що він ваш власний:\n Будь ласка, вилучіть його із екрану „Мої ключі“ + ви не можете вилучити наступні контакти, тому що вони - ваші власні:\n%s Будь ласка, вилучте їх із екрану „Мої ключі“ готово. збереження… @@ -374,6 +384,7 @@ імпортуюся ключі. Зашифрувати у цей контакт + Сертифікувати ключ цього контакту Контакти Зашифрувати diff --git a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml index 6bb115049..4ff02c7ed 100644 --- a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml @@ -1,26 +1,165 @@ + 加密 + 解密 + 密钥服务器偏好 + 查询密钥服务器 + 上传到密钥服务器 + 主密钥 + 密钥服务器 + 解密并验证 + 解密并验证 + 剪贴板 + 帮助 + 导入 + 删除密钥 + 创建密钥 + 创建密钥(专家) + 搜索 + 分享 + 复制到剪贴板 + 签署密钥 + 取消 + 加密到... + 签署 + 讯息 + 文件 + 没有密语 + 密语 + 算法 + 收件人 + 加密后删除 + 解密后删除 + 加密算法 + 哈希算法 + 公共密钥 + 密语 + 密语缓存 + 注解 + 电子邮件 + 指纹 + 可以加密 + 可以签署 + 过期了 + 没有 + 仅签署 + 仅加密 + 签署并加密 + 15秒 + 1分钟 + 3分钟 + 5分钟 + 10分钟 + 20分钟 + 40分钟 + 1小时 + 2小时 + 4小时 + 8小时 + 永远 + 打开... + 警告 + 错误 + 先设置密钥 + 安装了不匹配的文件管理器 + 密钥不匹配 + 不允许空的密钥 + 对称加密 + 删除成功 + 先选择一个文件 + 解密成功 + 加密成功 + 成功地加密到了剪贴板 + 输入两次密钥 + 选择至少一个加密密钥 + 选择至少一个加密密钥或者签名密钥 + 成功地导出了1个密钥 + 没有密钥被导出 + 成功地上传了密钥到服务器 + 这个列表是空的! + 没有找到文件 + 外置存储没有准备好 + 无效的email \'%s\' + 密钥的大小必须至少512位 + 位置的算法选择 + 你需要指定一个名字 + 你需要指定一个电子邮件地址 + 需要至少一个用户id + 主用户id不能是空的 + 需要至少一个主密钥 + 签名失败 + 没有提供密语 + 没有提供密钥 + 不是有效的加密数据 + 损坏的数据 + 错误的密语 + 完成。 + 保存... + 导入中... + 导出中... + 正在生成密钥,这可能需要一会 + 建立密钥 + 正在准备主密钥 + 正在验证签名... + 正在签名... + 正在读取数据 + 正在查找密钥 + 正在查询 + 512 + 1024 + 2048 + 4096 + + 非常慢 + 开始 + 更新日志 + 关于 + 版本: + 从剪贴板导入 + 二维码扫描完成! + 帮助 + OpenPGP: 解密文件 + OpenPGP: 导入密钥 + OpenPGP: 加密 + OpenPGP: 解密 + 显示高级设置 + 隐藏高级设置 + 选择密钥 + 保存 + 取消 + 撤销访问 + 允许访问 + 不允许访问 + 请选择一个密钥 + 请重审收件人列表 + 指纹: + 使用NFC分享 + 或者 + 加密 + 解密 + 导入密钥 + 我的密钥 -- cgit v1.2.3 From 754b2a6cb15a6af61150cd4b1ce472bebd4fec22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 9 Feb 2014 19:22:14 +0100 Subject: Restructuring for new API library --- .../org/openintents/openpgp/IOpenPgpCallback.aidl | 45 ----- .../openpgp/IOpenPgpKeyIdsCallback.aidl | 39 ---- .../org/openintents/openpgp/IOpenPgpService.aidl | 143 --------------- .../aidl/org/openintents/openpgp/OpenPgpData.aidl | 20 -- .../aidl/org/openintents/openpgp/OpenPgpError.aidl | 20 -- .../openpgp/OpenPgpSignatureResult.aidl | 20 -- .../service/remote/IExtendedApiCallback.aidl | 24 --- .../service/remote/IExtendedApiService.aidl | 48 ----- .../org/openintents/openpgp/OpenPgpConstants.java | 10 - .../java/org/openintents/openpgp/OpenPgpData.java | 127 ------------- .../java/org/openintents/openpgp/OpenPgpError.java | 81 --------- .../org/openintents/openpgp/OpenPgpHelper.java | 52 ------ .../openintents/openpgp/OpenPgpListPreference.java | 201 --------------------- .../openpgp/OpenPgpServiceConnection.java | 93 ---------- .../openpgp/OpenPgpSignatureResult.java | 110 ----------- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 +- 16 files changed, 1 insertion(+), 1034 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpCallback.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpKeyIdsCallback.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpData.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpError.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpSignatureResult.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiCallback.aidl delete mode 100644 OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiService.aidl delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpConstants.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpData.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpError.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpHelper.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpListPreference.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpServiceConnection.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpCallback.aidl b/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpCallback.aidl deleted file mode 100644 index ba41de1ba..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpCallback.aidl +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import org.openintents.openpgp.OpenPgpData; -import org.openintents.openpgp.OpenPgpSignatureResult; -import org.openintents.openpgp.OpenPgpError; - -interface IOpenPgpCallback { - - /** - * onSuccess returns on successful OpenPGP operations. - * - * @param output - * contains resulting output (decrypted content (when input was encrypted) - * or content without signature (when input was signed-only)) - * @param signatureResult - * signatureResult is only non-null if decryptAndVerify() was called and the content - * was encrypted or signed-and-encrypted. - */ - oneway void onSuccess(in OpenPgpData output, in OpenPgpSignatureResult signatureResult); - - /** - * onError returns on errors or when allowUserInteraction was set to false, but user interaction - * was required execute an OpenPGP operation. - * - * @param error - * See OpenPgpError class for more information. - */ - oneway void onError(in OpenPgpError error); -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpKeyIdsCallback.aidl b/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpKeyIdsCallback.aidl deleted file mode 100644 index 4ca356fad..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpKeyIdsCallback.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import org.openintents.openpgp.OpenPgpError; - -interface IOpenPgpKeyIdsCallback { - - /** - * onSuccess returns on successful getKeyIds operations. - * - * @param keyIds - * returned key ids - */ - oneway void onSuccess(in long[] keyIds); - - /** - * onError returns on errors or when allowUserInteraction was set to false, but user interaction - * was required execute an OpenPGP operation. - * - * @param error - * See OpenPgpError class for more information. - */ - oneway void onError(in OpenPgpError error); -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl b/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl deleted file mode 100644 index 8f9e8a0fd..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/IOpenPgpService.aidl +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import org.openintents.openpgp.OpenPgpData; -import org.openintents.openpgp.IOpenPgpCallback; -import org.openintents.openpgp.IOpenPgpKeyIdsCallback; - -/** - * All methods are oneway, which means they are asynchronous and non-blocking. - * Results are returned to the callback, which has to be implemented on client side. - */ -interface IOpenPgpService { - - /** - * Sign - * - * After successful signing, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param callback - * Callback where to return results - */ - oneway void sign(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback); - - /** - * Encrypt - * - * After successful encryption, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param keyIds - * Key Ids of recipients. Can be retrieved with getKeyIds() - * @param callback - * Callback where to return results - */ - oneway void encrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback); - - /** - * Sign then encrypt - * - * After successful signing and encryption, callback's onSuccess will contain the resulting output. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param keyIds - * Key Ids of recipients. Can be retrieved with getKeyIds() - * @param callback - * Callback where to return results - */ - oneway void signAndEncrypt(in OpenPgpData input, in OpenPgpData output, in long[] keyIds, in IOpenPgpCallback callback); - - /** - * Decrypts and verifies given input bytes. This methods handles encrypted-only, signed-and-encrypted, - * and also signed-only input. - * - * After successful decryption/verification, callback's onSuccess will contain the resulting output. - * The signatureResult in onSuccess is only non-null if signed-and-encrypted or signed-only inputBytes were given. - * - * @param input - * OpenPgpData object containing String, byte[], ParcelFileDescriptor, or Uri - * @param output - * Request output format by defining OpenPgpData object - * - * new OpenPgpData(OpenPgpData.TYPE_STRING) - * Returns as String - * (OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53) - * new OpenPgpData(OpenPgpData.TYPE_BYTE_ARRAY) - * Returns as byte[] - * new OpenPgpData(uri) - * Writes output to given Uri - * new OpenPgpData(fileDescriptor) - * Writes output to given ParcelFileDescriptor - * @param callback - * Callback where to return results - */ - oneway void decryptAndVerify(in OpenPgpData input, in OpenPgpData output, in IOpenPgpCallback callback); - - /** - * Get available key ids based on given user ids - * - * @param ids - * User Ids (emails) of recipients OR key ids - * @param allowUserInteraction - * Enable user interaction to lookup and import unknown keys - * @param callback - * Callback where to return results (different type than callback in other functions!) - */ - oneway void getKeyIds(in String[] ids, in boolean allowUserInteraction, in IOpenPgpKeyIdsCallback callback); - -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpData.aidl b/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpData.aidl deleted file mode 100644 index 3711e4fb4..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpData.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -// Declare OpenPgpData so AIDL can find it and knows that it implements the parcelable protocol. -parcelable OpenPgpData; \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpError.aidl b/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpError.aidl deleted file mode 100644 index 7a6bed1e6..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpError.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -// Declare OpenPgpError so AIDL can find it and knows that it implements the parcelable protocol. -parcelable OpenPgpError; \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpSignatureResult.aidl b/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpSignatureResult.aidl deleted file mode 100644 index e246792d0..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/openintents/openpgp/OpenPgpSignatureResult.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -// Declare OpenPgpSignatureResult so AIDL can find it and knows that it implements the parcelable protocol. -parcelable OpenPgpSignatureResult; \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiCallback.aidl b/OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiCallback.aidl deleted file mode 100644 index f69f66fd7..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiCallback.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.service.remote; - -interface IExtendedApiCallback { - - oneway void onSuccess(in byte[] outputBytes); - - oneway void onError(in String error); -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiService.aidl b/OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiService.aidl deleted file mode 100644 index 669bd31b5..000000000 --- a/OpenPGP-Keychain/src/main/aidl/org/sufficientlysecure/keychain/service/remote/IExtendedApiService.aidl +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.service.remote; - -import org.sufficientlysecure.keychain.service.remote.IExtendedApiCallback; - -/** - * All methods are oneway, which means they are asynchronous and non-blocking. - * Results are returned to the callback, which has to be implemented on client side. - */ -interface IExtendedApiService { - - /** - * Symmetric Encrypt - * - * @param inputBytes - * Byte array you want to encrypt - * @param passphrase - * symmetric passhprase - * @param callback - * Callback where to return results - */ - oneway void encrypt(in byte[] inputBytes, in String passphrase, in IExtendedApiCallback callback); - - /** - * Generates self signed X509 certificate signed by OpenPGP private key (from app settings) - * - * @param subjAltNameURI - * @param callback - * Callback where to return results - */ - oneway void selfSignedX509Cert(in String subjAltNameURI, in IExtendedApiCallback callback); - -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpConstants.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpConstants.java deleted file mode 100644 index b1ca1bfe6..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpConstants.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.openintents.openpgp; - -public class OpenPgpConstants { - - public static final String TAG = "OpenPgp API"; - - public static final int REQUIRED_API_VERSION = 1; - public static final String SERVICE_INTENT = "org.openintents.openpgp.IOpenPgpService"; - -} diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpData.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpData.java deleted file mode 100644 index 6615c2146..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpData.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import android.net.Uri; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.Parcelable; - -public class OpenPgpData implements Parcelable { - public static final int TYPE_STRING = 0; - public static final int TYPE_BYTE_ARRAY = 1; - public static final int TYPE_FILE_DESCRIPTOR = 2; - public static final int TYPE_URI = 3; - - int type; - - String string; - byte[] bytes = new byte[0]; - ParcelFileDescriptor fileDescriptor; - Uri uri; - - public int getType() { - return type; - } - - public String getString() { - return string; - } - - public byte[] getBytes() { - return bytes; - } - - public ParcelFileDescriptor getFileDescriptor() { - return fileDescriptor; - } - - public Uri getUri() { - return uri; - } - - public OpenPgpData() { - - } - - /** - * Not a real constructor. This can be used to define requested output type. - * - * @param type - */ - public OpenPgpData(int type) { - this.type = type; - } - - public OpenPgpData(String string) { - this.string = string; - this.type = TYPE_STRING; - } - - public OpenPgpData(byte[] bytes) { - this.bytes = bytes; - this.type = TYPE_BYTE_ARRAY; - } - - public OpenPgpData(ParcelFileDescriptor fileDescriptor) { - this.fileDescriptor = fileDescriptor; - this.type = TYPE_FILE_DESCRIPTOR; - } - - public OpenPgpData(Uri uri) { - this.uri = uri; - this.type = TYPE_URI; - } - - public OpenPgpData(OpenPgpData b) { - this.string = b.string; - this.bytes = b.bytes; - this.fileDescriptor = b.fileDescriptor; - this.uri = b.uri; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(type); - dest.writeString(string); - dest.writeInt(bytes.length); - dest.writeByteArray(bytes); - dest.writeParcelable(fileDescriptor, 0); - dest.writeParcelable(uri, 0); - } - - public static final Creator CREATOR = new Creator() { - public OpenPgpData createFromParcel(final Parcel source) { - OpenPgpData vr = new OpenPgpData(); - vr.type = source.readInt(); - vr.string = source.readString(); - vr.bytes = new byte[source.readInt()]; - source.readByteArray(vr.bytes); - vr.fileDescriptor = source.readParcelable(ParcelFileDescriptor.class.getClassLoader()); - vr.fileDescriptor = source.readParcelable(Uri.class.getClassLoader()); - return vr; - } - - public OpenPgpData[] newArray(final int size) { - return new OpenPgpData[size]; - } - }; - -} diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpError.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpError.java deleted file mode 100644 index f108d3169..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpError.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import android.os.Parcel; -import android.os.Parcelable; - -public class OpenPgpError implements Parcelable { - public static final int GENERIC_ERROR = 0; - public static final int NO_OR_WRONG_PASSPHRASE = 1; - public static final int NO_USER_IDS = 2; - public static final int USER_INTERACTION_REQUIRED = 3; - - int errorId; - String message; - - public OpenPgpError() { - } - - public OpenPgpError(int errorId, String message) { - this.errorId = errorId; - this.message = message; - } - - public OpenPgpError(OpenPgpError b) { - this.errorId = b.errorId; - this.message = b.message; - } - - public int getErrorId() { - return errorId; - } - - public void setErrorId(int errorId) { - this.errorId = errorId; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(errorId); - dest.writeString(message); - } - - public static final Creator CREATOR = new Creator() { - public OpenPgpError createFromParcel(final Parcel source) { - OpenPgpError error = new OpenPgpError(); - error.errorId = source.readInt(); - error.message = source.readString(); - return error; - } - - public OpenPgpError[] newArray(final int size) { - return new OpenPgpError[size]; - } - }; -} diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpHelper.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpHelper.java deleted file mode 100644 index 7305c47ce..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpHelper.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import java.util.List; -import java.util.regex.Pattern; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; - -public class OpenPgpHelper { - private Context context; - - public static Pattern PGP_MESSAGE = Pattern.compile( - ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL); - - public static Pattern PGP_SIGNED_MESSAGE = Pattern - .compile( - ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*", - Pattern.DOTALL); - - public OpenPgpHelper(Context context) { - super(); - this.context = context; - } - - public boolean isAvailable() { - Intent intent = new Intent(OpenPgpConstants.SERVICE_INTENT); - List resInfo = context.getPackageManager().queryIntentServices(intent, 0); - if (!resInfo.isEmpty()) { - return true; - } else { - return false; - } - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpListPreference.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpListPreference.java deleted file mode 100644 index 4ddd97485..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpListPreference.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import java.util.ArrayList; -import java.util.List; - -import android.app.AlertDialog.Builder; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.graphics.drawable.Drawable; -import android.preference.DialogPreference; -import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.ListAdapter; -import android.widget.TextView; - -public class OpenPgpListPreference extends DialogPreference { - ArrayList mProviderList = new ArrayList(); - private String mSelectedPackage; - - public OpenPgpListPreference(Context context, AttributeSet attrs) { - super(context, attrs); - - List resInfo = context.getPackageManager().queryIntentServices( - new Intent(OpenPgpConstants.SERVICE_INTENT), PackageManager.GET_META_DATA); - if (!resInfo.isEmpty()) { - for (ResolveInfo resolveInfo : resInfo) { - if (resolveInfo.serviceInfo == null) - continue; - - String packageName = resolveInfo.serviceInfo.packageName; - String simpleName = String.valueOf(resolveInfo.serviceInfo.loadLabel(context - .getPackageManager())); - Drawable icon = resolveInfo.serviceInfo.loadIcon(context.getPackageManager()); - - // get api version - ServiceInfo si = resolveInfo.serviceInfo; - int apiVersion = si.metaData.getInt("api_version"); - - mProviderList.add(new OpenPgpProviderEntry(packageName, simpleName, icon, - apiVersion)); - } - } - } - - public OpenPgpListPreference(Context context) { - this(context, null); - } - - /** - * Can be used to add "no selection" - * - * @param packageName - * @param simpleName - * @param icon - */ - public void addProvider(int position, String packageName, String simpleName, Drawable icon, - int apiVersion) { - mProviderList.add(position, new OpenPgpProviderEntry(packageName, simpleName, icon, - apiVersion)); - } - - @Override - protected void onPrepareDialogBuilder(Builder builder) { - // Init ArrayAdapter with OpenPGP Providers - ListAdapter adapter = new ArrayAdapter(getContext(), - android.R.layout.select_dialog_singlechoice, android.R.id.text1, mProviderList) { - public View getView(int position, View convertView, ViewGroup parent) { - // User super class to create the View - View v = super.getView(position, convertView, parent); - TextView tv = (TextView) v.findViewById(android.R.id.text1); - - // Put the image on the TextView - tv.setCompoundDrawablesWithIntrinsicBounds(mProviderList.get(position).icon, null, - null, null); - - // Add margin between image and text (support various screen densities) - int dp10 = (int) (10 * getContext().getResources().getDisplayMetrics().density + 0.5f); - tv.setCompoundDrawablePadding(dp10); - - // disable if it has the wrong api_version - if (mProviderList.get(position).apiVersion == OpenPgpConstants.REQUIRED_API_VERSION) { - tv.setEnabled(true); - } else { - tv.setEnabled(false); - tv.setText(tv.getText() + " (API v" + mProviderList.get(position).apiVersion - + ", needs v" + OpenPgpConstants.REQUIRED_API_VERSION + ")"); - } - - return v; - } - }; - - builder.setSingleChoiceItems(adapter, getIndexOfProviderList(getValue()), - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - mSelectedPackage = mProviderList.get(which).packageName; - - /* - * Clicking on an item simulates the positive button click, and dismisses - * the dialog. - */ - OpenPgpListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); - dialog.dismiss(); - } - }); - - /* - * The typical interaction for list-based dialogs is to have click-on-an-item dismiss the - * dialog instead of the user having to press 'Ok'. - */ - builder.setPositiveButton(null, null); - } - - @Override - protected void onDialogClosed(boolean positiveResult) { - super.onDialogClosed(positiveResult); - - if (positiveResult && (mSelectedPackage != null)) { - if (callChangeListener(mSelectedPackage)) { - setValue(mSelectedPackage); - } - } - } - - private int getIndexOfProviderList(String packageName) { - for (OpenPgpProviderEntry app : mProviderList) { - if (app.packageName.equals(packageName)) { - return mProviderList.indexOf(app); - } - } - - return -1; - } - - public void setValue(String packageName) { - mSelectedPackage = packageName; - persistString(packageName); - } - - public String getValue() { - return mSelectedPackage; - } - - public String getEntry() { - return getEntryByValue(mSelectedPackage); - } - - public String getEntryByValue(String packageName) { - for (OpenPgpProviderEntry app : mProviderList) { - if (app.packageName.equals(packageName)) { - return app.simpleName; - } - } - - return null; - } - - private static class OpenPgpProviderEntry { - private String packageName; - private String simpleName; - private Drawable icon; - private int apiVersion; - - public OpenPgpProviderEntry(String packageName, String simpleName, Drawable icon, - int apiVersion) { - this.packageName = packageName; - this.simpleName = simpleName; - this.icon = icon; - this.apiVersion = apiVersion; - } - - @Override - public String toString() { - return simpleName; - } - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpServiceConnection.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpServiceConnection.java deleted file mode 100644 index f7ba06aaf..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpServiceConnection.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import org.openintents.openpgp.IOpenPgpService; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; -import android.util.Log; - -public class OpenPgpServiceConnection { - private Context mApplicationContext; - - private IOpenPgpService mService; - private boolean mBound; - private String mCryptoProviderPackageName; - - public OpenPgpServiceConnection(Context context, String cryptoProviderPackageName) { - this.mApplicationContext = context.getApplicationContext(); - this.mCryptoProviderPackageName = cryptoProviderPackageName; - } - - public IOpenPgpService getService() { - return mService; - } - - public boolean isBound() { - return mBound; - } - - private ServiceConnection mCryptoServiceConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName name, IBinder service) { - mService = IOpenPgpService.Stub.asInterface(service); - Log.d(OpenPgpConstants.TAG, "connected to service"); - mBound = true; - } - - public void onServiceDisconnected(ComponentName name) { - mService = null; - Log.d(OpenPgpConstants.TAG, "disconnected from service"); - mBound = false; - } - }; - - /** - * If not already bound, bind! - * - * @return - */ - public boolean bindToService() { - if (mService == null && !mBound) { // if not already connected - try { - Log.d(OpenPgpConstants.TAG, "not bound yet"); - - Intent serviceIntent = new Intent(); - serviceIntent.setAction(IOpenPgpService.class.getName()); - serviceIntent.setPackage(mCryptoProviderPackageName); - mApplicationContext.bindService(serviceIntent, mCryptoServiceConnection, - Context.BIND_AUTO_CREATE); - - return true; - } catch (Exception e) { - Log.d(OpenPgpConstants.TAG, "Exception on binding", e); - return false; - } - } else { - Log.d(OpenPgpConstants.TAG, "already bound"); - return true; - } - } - - public void unbindFromService() { - mApplicationContext.unbindService(mCryptoServiceConnection); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java b/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java deleted file mode 100644 index 829f8f8cf..000000000 --- a/OpenPGP-Keychain/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2013 Dominik Schürmann - * - * 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.openintents.openpgp; - -import android.os.Parcel; -import android.os.Parcelable; - -public class OpenPgpSignatureResult implements Parcelable { - // generic error on signature verification - public static final int SIGNATURE_ERROR = 0; - // successfully verified signature, with trusted public key - public static final int SIGNATURE_SUCCESS_TRUSTED = 1; - // no public key was found for this signature verification - // you can retrieve the key with - // getKeys(new String[] {String.valueOf(signatureResult.getKeyId)}, true, callback) - public static final int SIGNATURE_UNKNOWN_PUB_KEY = 2; - // successfully verified signature, but with untrusted public key - public static final int SIGNATURE_SUCCESS_UNTRUSTED = 3; - - int status; - boolean signatureOnly; - String userId; - long keyId; - - public int getStatus() { - return status; - } - - public boolean isSignatureOnly() { - return signatureOnly; - } - - public String getUserId() { - return userId; - } - - public long getKeyId() { - return keyId; - } - - public OpenPgpSignatureResult() { - - } - - public OpenPgpSignatureResult(int signatureStatus, String signatureUserId, - boolean signatureOnly, long keyId) { - this.status = signatureStatus; - this.signatureOnly = signatureOnly; - this.userId = signatureUserId; - this.keyId = keyId; - } - - public OpenPgpSignatureResult(OpenPgpSignatureResult b) { - this.status = b.status; - this.userId = b.userId; - this.signatureOnly = b.signatureOnly; - this.keyId = b.keyId; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(status); - dest.writeByte((byte) (signatureOnly ? 1 : 0)); - dest.writeString(userId); - dest.writeLong(keyId); - } - - public static final Creator CREATOR = new Creator() { - public OpenPgpSignatureResult createFromParcel(final Parcel source) { - OpenPgpSignatureResult vr = new OpenPgpSignatureResult(); - vr.status = source.readInt(); - vr.signatureOnly = source.readByte() == 1; - vr.userId = source.readString(); - vr.keyId = source.readLong(); - return vr; - } - - public OpenPgpSignatureResult[] newArray(final int size) { - return new OpenPgpSignatureResult[size]; - } - }; - - @Override - public String toString() { - String out = new String(); - out += "\nstatus: " + status; - out += "\nuserId: " + userId; - out += "\nsignatureOnly: " + signatureOnly; - out += "\nkeyId: " + keyId; - return out; - } - -} diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index ddc3c9789..059b6ca9e 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -413,7 +413,7 @@ Encrypt to this contact - Certify this contact's key + Certify this contact\'s key Contacts -- cgit v1.2.3 From 0c4b809195f9219352d8ed7041fbeb678c9a0ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 9 Feb 2014 21:17:30 +0100 Subject: rework key view into fragments to later add certifications --- .../keychain/provider/ProviderHelper.java | 8 + .../keychain/ui/HelpAboutFragment.java | 76 +++++ .../keychain/ui/HelpActivity.java | 91 +----- .../keychain/ui/HelpFragmentAbout.java | 87 ------ .../keychain/ui/HelpFragmentHtml.java | 87 ------ .../keychain/ui/HelpHtmlFragment.java | 76 +++++ .../keychain/ui/ViewKeyActivity.java | 332 +++------------------ .../keychain/ui/ViewKeyActivityJB.java | 4 +- .../keychain/ui/ViewKeyCertsFragment.java | 92 ++++++ .../keychain/ui/ViewKeyMainFragment.java | 313 +++++++++++++++++++ .../keychain/ui/adapter/TabsAdapter.java | 84 ++++++ .../src/main/res/layout/view_key_activity.xml | 233 +-------------- .../main/res/layout/view_key_certs_fragment.xml | 31 ++ .../src/main/res/layout/view_key_keys_item.xml | 3 +- .../src/main/res/layout/view_key_main_fragment.xml | 222 ++++++++++++++ .../src/main/res/layout/view_key_userids_item.xml | 7 +- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 + 17 files changed, 971 insertions(+), 777 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java create mode 100644 OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml create mode 100644 OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 53ec4870c..9bee42973 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -30,6 +30,7 @@ import org.spongycastle.openpgp.PGPPublicKey; import org.spongycastle.openpgp.PGPPublicKeyRing; import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; @@ -212,6 +213,13 @@ public class ProviderHelper { ++userIdRank; } + for (PGPSignature certification : new IterableIterator(masterKey.getSignaturesOfType(PGPSignature.POSITIVE_CERTIFICATION))) { + //TODO: how to do this?? we need to verify the signatures again and again when they are displayed... +// if (certification.verify +// operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank)); + } + + try { context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations); } catch (RemoteException e) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java new file mode 100644 index 000000000..12d689274 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012-2013 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.ui; + +import org.sufficientlysecure.htmltextview.HtmlTextView; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.util.Log; + +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + + +public class HelpAboutFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.help_about_fragment, container, false); + + TextView versionText = (TextView) view.findViewById(R.id.help_about_version); + versionText.setText(getString(R.string.help_about_version) + " " + getVersion()); + + HtmlTextView aboutTextView = (HtmlTextView) view.findViewById(R.id.help_about_text); + + // load html from raw resource (Parsing handled by HtmlTextView library) + aboutTextView.setHtmlFromRawResource(getActivity(), R.raw.help_about); + + // no flickering when clicking textview for Android < 4 + aboutTextView.setTextColor(getResources().getColor(android.R.color.black)); + + return view; + } + + /** + * Get the current package version. + * + * @return The current version. + */ + private String getVersion() { + String result = ""; + try { + PackageManager manager = getActivity().getPackageManager(); + PackageInfo info = manager.getPackageInfo(getActivity().getPackageName(), 0); + + result = String.format("%s (%s)", info.versionName, info.versionCode); + } catch (NameNotFoundException e) { + Log.w(Constants.TAG, "Unable to get application version: " + e.getMessage()); + result = "Unable to get application version."; + } + + return result; + } + +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java index 2fe7c56e6..9ccd7e088 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java @@ -20,12 +20,13 @@ package org.sufficientlysecure.keychain.ui; import java.util.ArrayList; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; @@ -37,8 +38,6 @@ public class HelpActivity extends ActionBarActivity { ViewPager mViewPager; TabsAdapter mTabsAdapter; - TextView tabCenter; - TextView tabText; @Override public void onCreate(Bundle savedInstanceState) { @@ -63,93 +62,21 @@ public class HelpActivity extends ActionBarActivity { } Bundle startBundle = new Bundle(); - startBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_start); + startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start); mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)), - HelpFragmentHtml.class, startBundle, (selectedTab == 0 ? true : false)); + HelpHtmlFragment.class, startBundle, (selectedTab == 0 ? true : false)); Bundle nfcBundle = new Bundle(); - nfcBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_nfc_beam); + nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam); mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)), - HelpFragmentHtml.class, nfcBundle, (selectedTab == 1 ? true : false)); + HelpHtmlFragment.class, nfcBundle, (selectedTab == 1 ? true : false)); Bundle changelogBundle = new Bundle(); - changelogBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_changelog); + changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog); mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)), - HelpFragmentHtml.class, changelogBundle, (selectedTab == 2 ? true : false)); + HelpHtmlFragment.class, changelogBundle, (selectedTab == 2 ? true : false)); mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)), - HelpFragmentAbout.class, null, (selectedTab == 3 ? true : false)); - } - - public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, - ViewPager.OnPageChangeListener { - private final Context mContext; - private final ActionBar mActionBar; - private final ViewPager mViewPager; - private final ArrayList mTabs = new ArrayList(); - - static final class TabInfo { - private final Class clss; - private final Bundle args; - - TabInfo(Class _class, Bundle _args) { - clss = _class; - args = _args; - } - } - - public TabsAdapter(ActionBarActivity activity, ViewPager pager) { - super(activity.getSupportFragmentManager()); - mContext = activity; - mActionBar = activity.getSupportActionBar(); - mViewPager = pager; - mViewPager.setAdapter(this); - mViewPager.setOnPageChangeListener(this); - } - - public void addTab(ActionBar.Tab tab, Class clss, Bundle args, boolean selected) { - TabInfo info = new TabInfo(clss, args); - tab.setTag(info); - tab.setTabListener(this); - mTabs.add(info); - mActionBar.addTab(tab, selected); - notifyDataSetChanged(); - } - - @Override - public int getCount() { - return mTabs.size(); - } - - @Override - public Fragment getItem(int position) { - TabInfo info = mTabs.get(position); - return Fragment.instantiate(mContext, info.clss.getName(), info.args); - } - - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - } - - public void onPageSelected(int position) { - mActionBar.setSelectedNavigationItem(position); - } - - public void onPageScrollStateChanged(int state) { - } - - public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { - Object tag = tab.getTag(); - for (int i = 0; i < mTabs.size(); i++) { - if (mTabs.get(i) == tag) { - mViewPager.setCurrentItem(i); - } - } - } - - public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { - } - - public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { - } + HelpAboutFragment.class, null, (selectedTab == 3 ? true : false)); } } \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java deleted file mode 100644 index be7c50dbb..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2012-2013 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.ui; - -import org.sufficientlysecure.htmltextview.HtmlTextView; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.util.Log; - -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - - -public class HelpFragmentAbout extends Fragment { - - /** - * Workaround for Android Bug. See - * http://stackoverflow.com/questions/8748064/starting-activity-from - * -fragment-causes-nullpointerexception - */ - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - setUserVisibleHint(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.help_about_fragment, container, false); - - TextView versionText = (TextView) view.findViewById(R.id.help_about_version); - versionText.setText(getString(R.string.help_about_version) + " " + getVersion()); - - HtmlTextView aboutTextView = (HtmlTextView) view.findViewById(R.id.help_about_text); - - // load html from raw resource (Parsing handled by HtmlTextView library) - aboutTextView.setHtmlFromRawResource(getActivity(), R.raw.help_about); - - // no flickering when clicking textview for Android < 4 - aboutTextView.setTextColor(getResources().getColor(android.R.color.black)); - - return view; - } - - /** - * Get the current package version. - * - * @return The current version. - */ - private String getVersion() { - String result = ""; - try { - PackageManager manager = getActivity().getPackageManager(); - PackageInfo info = manager.getPackageInfo(getActivity().getPackageName(), 0); - - result = String.format("%s (%s)", info.versionName, info.versionCode); - } catch (NameNotFoundException e) { - Log.w(Constants.TAG, "Unable to get application version: " + e.getMessage()); - result = "Unable to get application version."; - } - - return result; - } - -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java deleted file mode 100644 index fb6747db0..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2012-2013 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.ui; - -import org.sufficientlysecure.htmltextview.HtmlTextView; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ScrollView; - -public class HelpFragmentHtml extends Fragment { - private Activity mActivity; - - private int htmlFile; - - public static final String ARG_HTML_FILE = "htmlFile"; - - /** - * Create a new instance of HelpFragmentHtml, providing "htmlFile" as an argument. - */ - static HelpFragmentHtml newInstance(int htmlFile) { - HelpFragmentHtml f = new HelpFragmentHtml(); - - // Supply html raw file input as an argument. - Bundle args = new Bundle(); - args.putInt(ARG_HTML_FILE, htmlFile); - f.setArguments(args); - - return f; - } - - /** - * Workaround for Android Bug. See - * http://stackoverflow.com/questions/8748064/starting-activity-from - * -fragment-causes-nullpointerexception - */ - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - setUserVisibleHint(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mActivity = getActivity(); - - htmlFile = getArguments().getInt(ARG_HTML_FILE); - - ScrollView scroller = new ScrollView(mActivity); - HtmlTextView text = new HtmlTextView(mActivity); - - // padding - int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, mActivity - .getResources().getDisplayMetrics()); - text.setPadding(padding, padding, padding, 0); - - scroller.addView(text); - - // load html from raw resource (Parsing handled by HtmlTextView library) - text.setHtmlFromRawResource(getActivity(), htmlFile); - - // no flickering when clicking textview for Android < 4 - text.setTextColor(getResources().getColor(android.R.color.black)); - - return scroller; - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java new file mode 100644 index 000000000..3afb5bbe0 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012-2013 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.ui; + +import org.sufficientlysecure.htmltextview.HtmlTextView; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ScrollView; + +public class HelpHtmlFragment extends Fragment { + private Activity mActivity; + + private int htmlFile; + + public static final String ARG_HTML_FILE = "htmlFile"; + + /** + * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument. + */ + static HelpHtmlFragment newInstance(int htmlFile) { + HelpHtmlFragment f = new HelpHtmlFragment(); + + // Supply html raw file input as an argument. + Bundle args = new Bundle(); + args.putInt(ARG_HTML_FILE, htmlFile); + f.setArguments(args); + + return f; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + mActivity = getActivity(); + + htmlFile = getArguments().getInt(ARG_HTML_FILE); + + ScrollView scroller = new ScrollView(mActivity); + HtmlTextView text = new HtmlTextView(mActivity); + + // padding + int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, mActivity + .getResources().getDisplayMetrics()); + text.setPadding(padding, padding, padding, 0); + + scroller.addView(text); + + // load html from raw resource (Parsing handled by HtmlTextView library) + text.setHtmlFromRawResource(getActivity(), htmlFile); + + // no flickering when clicking textview for Android < 4 + text.setTextColor(getResources().getColor(android.R.color.black)); + + return scroller; + } +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 14640480e..0a452bc8a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -18,8 +18,17 @@ package org.sufficientlysecure.keychain.ui; -import java.util.ArrayList; -import java.util.Date; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -27,64 +36,25 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter; -import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter; +import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment; import org.sufficientlysecure.keychain.util.Log; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.support.v4.app.LoaderManager; -import android.support.v4.content.CursorLoader; -import android.support.v4.content.Loader; -import android.support.v7.app.ActionBarActivity; -import android.text.format.DateFormat; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import com.beardedhen.androidbootstrap.BootstrapButton; +import java.util.ArrayList; -public class ViewKeyActivity extends ActionBarActivity implements - LoaderManager.LoaderCallbacks { +public class ViewKeyActivity extends ActionBarActivity { ExportHelper mExportHelper; protected Uri mDataUri; - private TextView mName; - private TextView mEmail; - private TextView mComment; - private TextView mAlgorithm; - private TextView mKeyId; - private TextView mExpiry; - private TextView mCreation; - private TextView mFingerprint; - private BootstrapButton mActionEncrypt; - private BootstrapButton mActionCertify; - - private ListView mUserIds; - private ListView mKeys; - - private static final int LOADER_ID_KEYRING = 0; - private static final int LOADER_ID_USER_IDS = 1; - private static final int LOADER_ID_KEYS = 2; - private ViewKeyUserIdsAdapter mUserIdsAdapter; - private ViewKeyKeysAdapter mKeysAdapter; + public static final String EXTRA_SELECTED_TAB = "selectedTab"; + + ViewPager mViewPager; + TabsAdapter mTabsAdapter; private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; @@ -95,26 +65,35 @@ public class ViewKeyActivity extends ActionBarActivity implements mExportHelper = new ExportHelper(this); // let the actionbar look like Android's contact app - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setIcon(android.R.color.transparent); - getSupportActionBar().setHomeButtonEnabled(true); + ActionBar actionBar = getSupportActionBar(); + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setIcon(android.R.color.transparent); + actionBar.setHomeButtonEnabled(true); + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); setContentView(R.layout.view_key_activity); - mName = (TextView) findViewById(R.id.name); - mEmail = (TextView) findViewById(R.id.email); - mComment = (TextView) findViewById(R.id.comment); - mKeyId = (TextView) findViewById(R.id.key_id); - mAlgorithm = (TextView) findViewById(R.id.algorithm); - mCreation = (TextView) findViewById(R.id.creation); - mExpiry = (TextView) findViewById(R.id.expiry); - mFingerprint = (TextView) findViewById(R.id.fingerprint); - mUserIds = (ListView) findViewById(R.id.user_ids); - mKeys = (ListView) findViewById(R.id.keys); - mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt); - mActionCertify = (BootstrapButton) findViewById(R.id.action_certify); - - loadData(getIntent()); + mViewPager = (ViewPager) findViewById(R.id.pager); + + mTabsAdapter = new TabsAdapter(this, mViewPager); + + int selectedTab = 0; + Intent intent = getIntent(); + if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) { + selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB); + } + + mDataUri = getIntent().getData(); + + Bundle mainBundle = new Bundle(); + mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri); + mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)), + ViewKeyMainFragment.class, mainBundle, (selectedTab == 0 ? true : false)); + + Bundle certBundle = new Bundle(); + certBundle.putParcelable(ViewKeyCertsFragment.ARG_DATA_URI, mDataUri); + mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)), + ViewKeyCertsFragment.class, certBundle, (selectedTab == 1 ? true : false)); } @Override @@ -168,210 +147,6 @@ public class ViewKeyActivity extends ActionBarActivity implements return super.onOptionsItemSelected(item); } - private void loadData(Intent intent) { - if (intent.getData().equals(mDataUri)) { - Log.d(Constants.TAG, "Same URI, no need to load the data again!"); - return; - } - - mDataUri = intent.getData(); - if (mDataUri == null) { - Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!"); - finish(); - return; - } - - Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); - - mActionEncrypt.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - encryptToContact(mDataUri); - } - }); - mActionCertify.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - certifyKey(mDataUri); - } - }); - - mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0); - mUserIds.setAdapter(mUserIdsAdapter); - // mUserIds.setEmptyView(findViewById(android.R.id.empty)); - // mUserIds.setClickable(true); - // mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() { - // @Override - // public void onItemClick(AdapterView arg0, View arg1, int position, long id) { - // } - // }); - - mKeysAdapter = new ViewKeyKeysAdapter(this, null, 0); - mKeys.setAdapter(mKeysAdapter); - - // Prepare the loaders. Either re-connect with an existing ones, - // or start new ones. - getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this); - getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); - getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this); - } - - static final String[] KEYRING_PROJECTION = new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID, - UserIds.USER_ID}; - static final int KEYRING_INDEX_ID = 0; - static final int KEYRING_INDEX_MASTER_KEY_ID = 1; - static final int KEYRING_INDEX_USER_ID = 2; - - static final String[] USER_IDS_PROJECTION = new String[]{UserIds._ID, UserIds.USER_ID, - UserIds.RANK,}; - // not the main user id - static final String USER_IDS_SELECTION = UserIds.RANK + " > 0 "; - static final String USER_IDS_SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC"; - - static final String[] KEYS_PROJECTION = new String[]{Keys._ID, Keys.KEY_ID, - Keys.IS_MASTER_KEY, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN, - Keys.CAN_ENCRYPT, Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT}; - static final String KEYS_SORT_ORDER = Keys.RANK + " ASC"; - static final int KEYS_INDEX_ID = 0; - static final int KEYS_INDEX_KEY_ID = 1; - static final int KEYS_INDEX_IS_MASTER_KEY = 2; - static final int KEYS_INDEX_ALGORITHM = 3; - static final int KEYS_INDEX_KEY_SIZE = 4; - static final int KEYS_INDEX_CAN_CERTIFY = 5; - static final int KEYS_INDEX_CAN_SIGN = 6; - static final int KEYS_INDEX_CAN_ENCRYPT = 7; - static final int KEYS_INDEX_CREATION = 8; - static final int KEYS_INDEX_EXPIRY = 9; - static final int KEYS_INDEX_FINGERPRINT = 10; - - public Loader onCreateLoader(int id, Bundle args) { - switch (id) { - case LOADER_ID_KEYRING: { - Uri baseUri = mDataUri; - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(this, baseUri, KEYRING_PROJECTION, null, null, null); - } - case LOADER_ID_USER_IDS: { - Uri baseUri = UserIds.buildUserIdsUri(mDataUri); - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null, - USER_IDS_SORT_ORDER); - } - case LOADER_ID_KEYS: { - Uri baseUri = Keys.buildKeysUri(mDataUri); - - // Now create and return a CursorLoader that will take care of - // creating a Cursor for the data being displayed. - return new CursorLoader(this, baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER); - } - - default: - return null; - } - } - - public void onLoadFinished(Loader loader, Cursor data) { - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - switch (loader.getId()) { - case LOADER_ID_KEYRING: - if (data.moveToFirst()) { - // get name, email, and comment from USER_ID - String[] mainUserId = PgpKeyHelper.splitUserId(data - .getString(KEYRING_INDEX_USER_ID)); - if (mainUserId[0] != null) { - setTitle(mainUserId[0]); - mName.setText(mainUserId[0]); - } else { - setTitle(R.string.user_id_no_name); - mName.setText(R.string.user_id_no_name); - } - mEmail.setText(mainUserId[1]); - mComment.setText(mainUserId[2]); - } - - break; - case LOADER_ID_USER_IDS: - mUserIdsAdapter.swapCursor(data); - break; - case LOADER_ID_KEYS: - // the first key here is our master key - if (data.moveToFirst()) { - // get key id from MASTER_KEY_ID - long keyId = data.getLong(KEYS_INDEX_KEY_ID); - - String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId); - mKeyId.setText(keyIdStr); - - // get creation date from CREATION - if (data.isNull(KEYS_INDEX_CREATION)) { - mCreation.setText(R.string.none); - } else { - Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000); - - mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format( - creationDate)); - } - - // get expiry date from EXPIRY - if (data.isNull(KEYS_INDEX_EXPIRY)) { - mExpiry.setText(R.string.none); - } else { - Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000); - - mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format( - expiryDate)); - } - - String algorithmStr = PgpKeyHelper.getAlgorithmInfo( - data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE)); - mAlgorithm.setText(algorithmStr); - - byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT); - if (fingerprintBlob == null) { - // FALLBACK for old database entries - fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri); - } - String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); - fingerprint = fingerprint.replace(" ", "\n"); - - mFingerprint.setText(fingerprint); - } - - mKeysAdapter.swapCursor(data); - break; - - default: - break; - } - } - - /** - * This is called when the last Cursor provided to onLoadFinished() above is about to be closed. - * We need to make sure we are no longer using it. - */ - public void onLoaderReset(Loader loader) { - switch (loader.getId()) { - case LOADER_ID_KEYRING: - // No resources need to be freed for this ID - break; - case LOADER_ID_USER_IDS: - mUserIdsAdapter.swapCursor(null); - break; - case LOADER_ID_KEYS: - mKeysAdapter.swapCursor(null); - break; - default: - break; - } - } - private void uploadToKeyserver(Uri dataUri) { Intent uploadIntent = new Intent(this, UploadKeyActivity.class); uploadIntent.setData(dataUri); @@ -394,25 +169,8 @@ public class ViewKeyActivity extends ActionBarActivity implements startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY); } - private void encryptToContact(Uri dataUri) { - long keyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri); - - long[] encryptionKeyIds = new long[]{keyId}; - Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class); - intent.setAction(EncryptActivity.ACTION_ENCRYPT); - intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); - // used instead of startActivity set actionbar based on callingPackage - startActivityForResult(intent, 0); - } - - private void certifyKey(Uri dataUri) { - Intent signIntent = new Intent(this, CertifyKeyActivity.class); - signIntent.setData(dataUri); - startActivity(signIntent); - } - private void shareKey(Uri dataUri, boolean fingerprintOnly) { - String content = null; + String content; if (fingerprintOnly) { byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri); String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java index a2e3e4339..59037d9ff 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java @@ -23,7 +23,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.ProviderHelper; import android.annotation.TargetApi; -import android.database.Cursor; import android.net.Uri; import android.nfc.NdefMessage; import android.nfc.NdefRecord; @@ -35,12 +34,11 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.support.v4.app.LoaderManager; import android.widget.Toast; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback, - OnNdefPushCompleteCallback, LoaderManager.LoaderCallbacks { + OnNdefPushCompleteCallback { // NFC private NfcAdapter mNfcAdapter; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java new file mode 100644 index 000000000..36d3e6ace --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2014 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.ui; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.util.Log; + + +public class ViewKeyCertsFragment extends Fragment { + + public static final String ARG_DATA_URI = "uri"; + + private BootstrapButton mActionCertify; + + private Uri mDataUri; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.view_key_certs_fragment, container, false); + + mActionCertify = (BootstrapButton) view.findViewById(R.id.action_certify); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + Uri dataUri = getArguments().getParcelable(ARG_DATA_URI); + if (dataUri == null) { + Log.e(Constants.TAG, "Data missing. Should be Uri of key!"); + getActivity().finish(); + return; + } + + loadData(dataUri); + } + + private void loadData(Uri dataUri) { + if (dataUri.equals(mDataUri)) { + Log.d(Constants.TAG, "Same URI, no need to load the data again!"); + return; + } + + mDataUri = dataUri; + + Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); + + mActionCertify.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + certifyKey(mDataUri); + } + }); + + } + + private void certifyKey(Uri dataUri) { + Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class); + signIntent.setData(dataUri); + startActivity(signIntent); + } + +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java new file mode 100644 index 000000000..495764eaf --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -0,0 +1,313 @@ +/* + * Copyright (C) 2014 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.ui; + +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +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.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import android.widget.TextView; + +import com.beardedhen.androidbootstrap.BootstrapButton; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter; +import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter; +import org.sufficientlysecure.keychain.util.Log; + +import java.util.Date; + + +public class ViewKeyMainFragment extends Fragment implements + LoaderManager.LoaderCallbacks{ + + public static final String ARG_DATA_URI = "uri"; + + private TextView mName; + private TextView mEmail; + private TextView mComment; + private TextView mAlgorithm; + private TextView mKeyId; + private TextView mExpiry; + private TextView mCreation; + private TextView mFingerprint; + private BootstrapButton mActionEncrypt; + + private ListView mUserIds; + private ListView mKeys; + + private static final int LOADER_ID_KEYRING = 0; + private static final int LOADER_ID_USER_IDS = 1; + private static final int LOADER_ID_KEYS = 2; + + private ViewKeyUserIdsAdapter mUserIdsAdapter; + private ViewKeyKeysAdapter mKeysAdapter; + + private Uri mDataUri; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.view_key_main_fragment, container, false); + + mName = (TextView) view.findViewById(R.id.name); + mEmail = (TextView) view.findViewById(R.id.email); + mComment = (TextView) view.findViewById(R.id.comment); + mKeyId = (TextView) view.findViewById(R.id.key_id); + mAlgorithm = (TextView) view.findViewById(R.id.algorithm); + mCreation = (TextView) view.findViewById(R.id.creation); + mExpiry = (TextView) view.findViewById(R.id.expiry); + mFingerprint = (TextView) view.findViewById(R.id.fingerprint); + mUserIds = (ListView) view.findViewById(R.id.user_ids); + mKeys = (ListView) view.findViewById(R.id.keys); + mActionEncrypt = (BootstrapButton) view.findViewById(R.id.action_encrypt); + + return view; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + Uri dataUri = getArguments().getParcelable(ARG_DATA_URI); + if (dataUri == null) { + Log.e(Constants.TAG, "Data missing. Should be Uri of key!"); + getActivity().finish(); + return; + } + + loadData(dataUri); + } + + private void loadData(Uri dataUri) { + if (dataUri.equals(mDataUri)) { + Log.d(Constants.TAG, "Same URI, no need to load the data again!"); + return; + } + + mDataUri = dataUri; + + Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); + + mActionEncrypt.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + encryptToContact(mDataUri); + } + }); + + mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0); + mUserIds.setAdapter(mUserIdsAdapter); + + mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0); + mKeys.setAdapter(mKeysAdapter); + + // Prepare the loaders. Either re-connect with an existing ones, + // or start new ones. + getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this); + getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); + getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this); + } + + static final String[] KEYRING_PROJECTION = new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.UserIds.USER_ID}; + static final int KEYRING_INDEX_ID = 0; + static final int KEYRING_INDEX_MASTER_KEY_ID = 1; + static final int KEYRING_INDEX_USER_ID = 2; + + static final String[] USER_IDS_PROJECTION = new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID, + KeychainContract.UserIds.RANK,}; + // not the main user id + static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 "; + static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC"; + + static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID, + KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN, + KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT}; + static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC"; + static final int KEYS_INDEX_ID = 0; + static final int KEYS_INDEX_KEY_ID = 1; + static final int KEYS_INDEX_IS_MASTER_KEY = 2; + static final int KEYS_INDEX_ALGORITHM = 3; + static final int KEYS_INDEX_KEY_SIZE = 4; + static final int KEYS_INDEX_CAN_CERTIFY = 5; + static final int KEYS_INDEX_CAN_SIGN = 6; + static final int KEYS_INDEX_CAN_ENCRYPT = 7; + static final int KEYS_INDEX_CREATION = 8; + static final int KEYS_INDEX_EXPIRY = 9; + static final int KEYS_INDEX_FINGERPRINT = 10; + + public Loader onCreateLoader(int id, Bundle args) { + switch (id) { + case LOADER_ID_KEYRING: { + Uri baseUri = mDataUri; + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, KEYRING_PROJECTION, null, null, null); + } + case LOADER_ID_USER_IDS: { + Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null, + USER_IDS_SORT_ORDER); + } + case LOADER_ID_KEYS: { + Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER); + } + + default: + return null; + } + } + + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + switch (loader.getId()) { + case LOADER_ID_KEYRING: + if (data.moveToFirst()) { + // get name, email, and comment from USER_ID + String[] mainUserId = PgpKeyHelper.splitUserId(data + .getString(KEYRING_INDEX_USER_ID)); + if (mainUserId[0] != null) { + getActivity().setTitle(mainUserId[0]); + mName.setText(mainUserId[0]); + } else { + getActivity().setTitle(R.string.user_id_no_name); + mName.setText(R.string.user_id_no_name); + } + mEmail.setText(mainUserId[1]); + mComment.setText(mainUserId[2]); + } + + break; + case LOADER_ID_USER_IDS: + mUserIdsAdapter.swapCursor(data); + break; + case LOADER_ID_KEYS: + // the first key here is our master key + if (data.moveToFirst()) { + // get key id from MASTER_KEY_ID + long keyId = data.getLong(KEYS_INDEX_KEY_ID); + + String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId); + mKeyId.setText(keyIdStr); + + // get creation date from CREATION + if (data.isNull(KEYS_INDEX_CREATION)) { + mCreation.setText(R.string.none); + } else { + Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000); + + mCreation.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format( + creationDate)); + } + + // get expiry date from EXPIRY + if (data.isNull(KEYS_INDEX_EXPIRY)) { + mExpiry.setText(R.string.none); + } else { + Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000); + + mExpiry.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format( + expiryDate)); + } + + String algorithmStr = PgpKeyHelper.getAlgorithmInfo( + data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE)); + mAlgorithm.setText(algorithmStr); + + byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT); + if (fingerprintBlob == null) { + // FALLBACK for old database entries + fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri); + } + String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true); + fingerprint = fingerprint.replace(" ", "\n"); + + mFingerprint.setText(fingerprint); + } + + mKeysAdapter.swapCursor(data); + break; + + default: + break; + } + } + + /** + * This is called when the last Cursor provided to onLoadFinished() above is about to be closed. + * We need to make sure we are no longer using it. + */ + public void onLoaderReset(Loader loader) { + switch (loader.getId()) { + case LOADER_ID_KEYRING: + // No resources need to be freed for this ID + break; + case LOADER_ID_USER_IDS: + mUserIdsAdapter.swapCursor(null); + break; + case LOADER_ID_KEYS: + mKeysAdapter.swapCursor(null); + break; + default: + break; + } + } + + + private void encryptToContact(Uri dataUri) { + long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri); + + long[] encryptionKeyIds = new long[]{keyId}; + Intent intent = new Intent(getActivity(), EncryptActivity.class); + intent.setAction(EncryptActivity.ACTION_ENCRYPT); + intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds); + // used instead of startActivity set actionbar based on callingPackage + startActivityForResult(intent, 0); + } + + private void certifyKey(Uri dataUri) { + Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class); + signIntent.setData(dataUri); + startActivity(signIntent); + } + + +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java new file mode 100644 index 000000000..924a70897 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java @@ -0,0 +1,84 @@ +package org.sufficientlysecure.keychain.ui.adapter; + +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; + +import java.util.ArrayList; + +public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener, + ViewPager.OnPageChangeListener { + private final Context mContext; + private final ActionBar mActionBar; + private final ViewPager mViewPager; + private final ArrayList mTabs = new ArrayList(); + + static final class TabInfo { + private final Class clss; + private final Bundle args; + + TabInfo(Class _class, Bundle _args) { + clss = _class; + args = _args; + } + } + + public TabsAdapter(ActionBarActivity activity, ViewPager pager) { + super(activity.getSupportFragmentManager()); + mContext = activity; + mActionBar = activity.getSupportActionBar(); + mViewPager = pager; + mViewPager.setAdapter(this); + mViewPager.setOnPageChangeListener(this); + } + + public void addTab(ActionBar.Tab tab, Class clss, Bundle args, boolean selected) { + TabInfo info = new TabInfo(clss, args); + tab.setTag(info); + tab.setTabListener(this); + mTabs.add(info); + mActionBar.addTab(tab, selected); + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mTabs.size(); + } + + @Override + public Fragment getItem(int position) { + TabInfo info = mTabs.get(position); + return Fragment.instantiate(mContext, info.clss.getName(), info.args); + } + + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + public void onPageSelected(int position) { + mActionBar.setSelectedNavigationItem(position); + } + + public void onPageScrollStateChanged(int state) { + } + + public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { + Object tag = tab.getTag(); + for (int i = 0; i < mTabs.size(); i++) { + if (mTabs.get(i) == tag) { + mViewPager.setCurrentItem(i); + } + } + } + + public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { + } + + public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { + } +} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml index 1c937430a..58e4919dc 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml @@ -1,229 +1,12 @@ - + + android:layout_height="match_parent" + android:orientation="vertical" > - + android:layout_height="match_parent" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml new file mode 100644 index 000000000..2a3dafc93 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml index b50253980..c44835bb0 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml @@ -1,8 +1,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml index 2d022ba13..508d080a6 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml @@ -1,16 +1,15 @@ + android:paddingRight="3dip" + android:singleLine="true"> diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 059b6ca9e..3a719afed 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -414,6 +414,8 @@ Encrypt to this contact Certify this contact\'s key + Info + Certifications Contacts -- cgit v1.2.3 From c744cad8db7ba0b9ea38907f0c7f61032792ef84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 9 Feb 2014 21:37:01 +0100 Subject: Allow import of full keys from qr codes --- .../keychain/ui/ImportKeysQrCodeFragment.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java index 27628dad4..ee91b2434 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java @@ -98,22 +98,29 @@ public class ImportKeysQrCodeFragment extends Fragment { IntentResult scanResult = IntentIntegratorSupportV4.parseActivityResult(requestCode, resultCode, data); if (scanResult != null && scanResult.getFormatName() != null) { + String scannedContent = scanResult.getContents(); - Log.d(Constants.TAG, "scanResult content: " + scanResult.getContents()); + Log.d(Constants.TAG, "scannedContent: " + scannedContent); // look if it's fingerprint only - if (scanResult.getContents().toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) { + if (scannedContent.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) { importFingerprint(Uri.parse(scanResult.getContents())); return; } // look if it is the whole key - String[] parts = scanResult.getContents().split(","); + String[] parts = scannedContent.split(","); if (parts.length == 3) { importParts(parts); return; } + // is this a full key encoded as qr code? + if (scannedContent.startsWith("-----BEGIN PGP")) { + mImportActivity.loadCallback(scannedContent.getBytes(), null, null, null); + return; + } + // fail... Toast.makeText(getActivity(), R.string.import_qr_code_wrong, Toast.LENGTH_LONG) .show(); -- cgit v1.2.3 From 7ba0d1012ce650bef68ec4d94d1e119be308097b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 9 Feb 2014 21:51:40 +0100 Subject: Pull from transifex --- .../src/main/res/raw-ru/help_changelog.html | 4 ++-- OpenPGP-Keychain/src/main/res/raw-ru/help_start.html | 4 ++-- OpenPGP-Keychain/src/main/res/values-de/strings.xml | 18 ++++++++++++++++++ OpenPGP-Keychain/src/main/res/values-es/strings.xml | 8 ++++++-- OpenPGP-Keychain/src/main/res/values-fr/strings.xml | 8 ++++++-- OpenPGP-Keychain/src/main/res/values-ru/strings.xml | 17 +++++++++++++++++ OpenPGP-Keychain/src/main/res/values-uk/strings.xml | 9 +++++++-- 7 files changed, 58 insertions(+), 10 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html index 688f07be4..2a324202f 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_changelog.html @@ -6,7 +6,7 @@
                                              • удален не требующийся экспорт публичного ключа при экспорте секретного ключа (спасибо, Ash Hughes)
                                              • исправлена ошибка срока годности ключей (спасибо, Ash Hughes)
                                              • исправления ошибок при изменении ключей (спасибо, Ash Hughes)
                                              • -
                                              • querying keyservers directly from the import screen
                                              • +
                                              • запрос ключа с сервера прямо из окна импорта ключей
                                              • исправление внешнего вида для Android 2.2-3.0
                                              • исправлено падение когда ключ не содержал имя пользователя
                                              • исправлено падение и пустой список при возвращении из окна подписания
                                              • @@ -46,7 +46,7 @@

                                              1.0.8

                                                -
                                              • basic keyserver support
                                              • +
                                              • поддержка серверов ключей
                                              • App2SD
                                              • больше вариантов сохранения кэша пароля: 1, 2, 4, 8 часов
                                              • переводы: норвежский (спасибо, Sander Danielsen), китайский (спасибо, Zhang Fredrick)
                                              • diff --git a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html index b47f3c741..99e6f263d 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-ru/help_start.html @@ -2,9 +2,9 @@

                                                Приступая

                                                -

                                                First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                +

                                                Для начала вам понадобится своя пара ключей. Воспользуйтесь меню в разделе "Мои ключи", что бы создать новую, или добавьте ранее созданную пару в разделе "Импорт ключей". После этого вы сможете скачать ключи ваших друзей или обменяться ключами посредством QR кодов или NFC.

                                                -

                                                It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                +

                                                Рекомендуется установить OI File Manager для удобного выбора файлов и Barcode Scanner для распознавания QR кодов. Перейдите по ссылкам на соответствующие страницы Google Play или F-Droid для дальнейшей установки.

                                                Я нашел ошибку в OpenPGP Keychain!

                                                Пожалуйста, сообщайте о возникших проблемах и найденных ошибках в разделе Решение проблем OpenPGP Keychain.

                                                diff --git a/OpenPGP-Keychain/src/main/res/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml index d7b4ac89c..29e60e788 100644 --- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml @@ -12,6 +12,7 @@ Schlüssel bearbeiten Einstellungen Registrierte Anwendungen + Schlüsselserver Passwort ändern Passwort setzen E-Mail senden... @@ -21,6 +22,8 @@ Schlüssel exportieren Schlüssel exportieren Schlüssel nicht gefunden + Schlüsselserver abfragen + Auf Schlüsselserver hochladen Unbekannter Signaturschlüssel Schlüssel beglaubigen Schlüsseldetails @@ -36,6 +39,7 @@ Aktionen Mit diesem Schlüssel beglaubigen Schlüssel hochladen + Schlüsselserver Verschlüsseln und/oder Signieren Entschlüsseln und Verifizieren @@ -53,6 +57,7 @@ Passwort ändern Passwort setzen Suchen + Auf Schlüsselserver hochladen Weiter Zurück Zwischenablage @@ -71,6 +76,8 @@ Schlüssel erstellen Schlüssel erstellen (Experte) Suchen + Schlüsselserver + Von einem Schlüsselserver aktualisieren Auf Schlüsselserver hochladen Teilen Teile Fingerabdruck… @@ -105,6 +112,7 @@ Nachrichten-Komprimierung Datei-Komprimierung OpenPGPv3-Signaturen erzwingen + Schlüsselserver Schlüssel-ID Erstellungsdatum Ablaufdatum @@ -114,6 +122,7 @@ Name Kommentar E-Mail + Schlüssel nach Beglaubigung auf ausgewählten Schlüsselserver hochladen Fingerabdruck Auswählen @@ -128,6 +137,10 @@ kann signieren abgelaufen zurückgezogen + + %d Schlüsselserver + %d Schlüsselserver + Fingerabdruck: Privater Schlüssel: @@ -250,6 +263,10 @@ NFC steht auf diesem Gerät nicht zur Verfügung! Nichts zu importieren! Ablaufdatum muss später sein als das Erstellungsdatum + + Bitte lösche ihn unter \'Meine Schlüssel\'! + Bitte lösche sie unter \'Meine Schlüssel\'! + fertig. speichern... @@ -358,6 +375,7 @@ existierende Schlüssel importierst. Für diesen Kontakt verschlüsseln + Schlüssel dieses Kontakts beglaubigen Kontakte Verschlüsseln diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml index cdcb44cd2..fe72d6106 100644 --- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -263,8 +263,12 @@ ¡NFC no está disponible en tu dispositivo! ¡Nada que importar! la fecha de caducidad debe ser posterior a la fecha de creación - no puedes eliminar este contacto porque eres tú mismo. ¡Por favor, bórralo desde la ventana \"Mis claves\"! - no puedes eliminar los siguientes contactos porque son tú mismo:\n%s¡Por favor, bórralos desde la ventana \"Mis claves\"! + no puedes eliminar este contacto porque eres tú mismo. + no puedes eliminar los siguientes contactos porque son tú mismo:\n%s + + Por favor, bórralo desde la pantalla \'Mis claves\'! + Por favor, bórralos desde la pantalla \'Mis claves\'! + hecho. guardando... diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index dbf47375c..cc0f17709 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -263,8 +263,12 @@ NFC n\'est pas disponible sur votre appareil ! Rien à importer ! la date d\'expiration doit venir après la date de création - vous ne pouvez pas supprimer ce contact car c\'est le vôtre. Veuillez le supprimer depuis l\'écran « Mes Clefs »! - vous ne pouvez pas supprimer les contacts suivants car c\'est les vôtres.\n%sVeuillez les supprimer depuis l\'écran « Mes Clefs »! + vous ne pouvez pas supprimer ce contact car c\'est le vôtre. + vous ne pouvez pas supprimer les contacts suivants car c\'est les vôtres.\n%s + + Veuillez le supprimer depuis l\'écran « Mes Clefs »! + Veuillez les supprimer depuis l\'écran « Mes Clefs »! + fait. sauvegarde... diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index ca9b9ec4d..b86db9d81 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -12,6 +12,7 @@ Изменить ключ Настройки Связанные приложения + Настройки сервера ключей Изменить пароль Задать пароль Отправить... @@ -21,6 +22,8 @@ Экспортировать ключ Экспорт ключей Ключ не найден + Запросить сервер ключей + Загрузить на сервер ключей Неизвестная подпись Сертифицировать ключ Сведения о ключе @@ -36,6 +39,7 @@ Действия Ваш ключ для сертификации Загрузить ключ + Сервер ключей Зашифровать и/или Подписать Расшифровать и проверить @@ -53,6 +57,7 @@ Изменить пароль Задать пароль Поиск + Загрузить на сервер ключей Далее Назад Буфер обмена @@ -71,6 +76,8 @@ Создать ключ Создать ключ (эксперт) Поиск + Импорт с сервера ключей + Обновить с сервера ключей Загрузить на сервер ключей Отправить... Отправить отпечаток... @@ -105,6 +112,7 @@ Сжатие сообщения Сжатие файла Использовать V3 подписи + Серверы ключей ID ключа Создан Годен до... @@ -114,6 +122,7 @@ Имя Комментарий Email + После сертификации загрузить ключ на сервер Отпечаток Выбрать @@ -129,6 +138,11 @@ подпись годен до отозван + + %d сервер ключей + %d серверов ключей + %d серверов ключей + Отпечаток: Секретный ключ: @@ -257,6 +271,8 @@ Ваше устройство не поддерживает NFC! Нет данных для импорта! срок годности не может быть раньше даты создания + нельзя удалить свой собственный контакт. Пожалуйста, удалите его в разделе \'Мои ключи\'! + это ваши собственные контакты, их нельзя удалить:\n%s готово. сохранение... @@ -368,6 +384,7 @@ Импортировать ключи Зашифровать для этого получателя + Сертифицировать ключ этого контакта Контакты Зашифровать diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml index 928c206c1..0a00f5658 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml @@ -271,8 +271,13 @@ NFC недоступний на вашому пристрої! Нема що імпортувати! дата завершення дії має йти після дати створення - ви не можете вилучити цей контакт, тому що він ваш власний:\n Будь ласка, вилучіть його із екрану „Мої ключі“ - ви не можете вилучити наступні контакти, тому що вони - ваші власні:\n%s Будь ласка, вилучте їх із екрану „Мої ключі“ + ви не можете вилучити цей контакт, тому що він ваш власний. + ви не можете вилучити наступні контакти, тому що вони - ваші власні:\n%s + + Будь ласка, вилучіть його з екрану „Мої ключі“! + Будь ласка, вилучіть їх з екрану „Мої ключі“! + Будь ласка, вилучіть їх з екрану „Мої ключі“! + готово. збереження… -- cgit v1.2.3 From 519209da6386f66df628dc426e260a5392209337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 13 Feb 2014 23:34:57 +0100 Subject: Layout fixes for registered apps --- .../service/remote/AppSettingsFragment.java | 11 +- .../service/remote/RemoteServiceActivity.java | 5 +- .../keychain/ui/CertifyKeyActivity.java | 4 +- .../main/res/layout/api_app_register_activity.xml | 44 +++-- .../main/res/layout/api_app_settings_activity.xml | 26 +-- .../main/res/layout/api_app_settings_fragment.xml | 216 ++++++++++----------- .../main/res/layout/api_apps_adapter_list_item.xml | 13 +- 7 files changed, 164 insertions(+), 155 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java index 025929cfa..64c4c5e96 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/AppSettingsFragment.java @@ -109,6 +109,15 @@ public class AppSettingsFragment extends Fragment implements return view; } + /** + * Set error String on key selection + * + * @param error + */ + public void setErrorOnSelectKeyFragment(String error) { + mSelectKeyFragment.setError(error); + } + private void initView(View view) { mSelectKeyFragment = (SelectSecretKeyLayoutFragment) getFragmentManager().findFragmentById( R.id.api_app_settings_select_key_fragment); @@ -182,7 +191,7 @@ public class AppSettingsFragment extends Fragment implements // TODO: Better: collapse/expand animation // final Animation animation2 = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, // Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f, - // Animation.RELATIVE_TO_SELF, 0.0f); + // Animation.RELATIVE_TO_SELF, 0.0f);u // animation2.setDuration(150); mAdvancedSettingsButton.setOnClickListener(new OnClickListener() { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index f1e203733..7ab39fce1 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -125,9 +125,8 @@ public class RemoteServiceActivity extends ActionBarActivity { // user needs to select a key! if (mSettingsFragment.getAppSettings().getKeyId() == Id.key.none) { - Toast.makeText(RemoteServiceActivity.this, - R.string.api_register_error_select_key, Toast.LENGTH_LONG) - .show(); + mSettingsFragment.setErrorOnSelectKeyFragment( + getString(R.string.api_register_error_select_key)); } else { ProviderHelper.insertApiApp(RemoteServiceActivity.this, mSettingsFragment.getAppSettings()); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index ba6d7aa49..aab6b81d9 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -164,8 +164,8 @@ public class CertifyKeyActivity extends ActionBarActivity implements passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly + Log.d(Constants.TAG, "No passphrase for this secret key!"); + // send message to handler to start certification directly returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); } } diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml index 79daef590..c60416494 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_register_activity.xml @@ -1,25 +1,29 @@ - + android:layout_width="match_parent" + android:layout_height="wrap_content"> - - - + android:layout_height="match_parent" + android:padding="16dp" + android:orientation="vertical"> + + + + - \ No newline at end of file + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml index e60ad50e3..d4fb5103a 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_activity.xml @@ -1,17 +1,21 @@ - + android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:padding="16dp" + android:orientation="vertical"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml index 0695e5922..a8b68859b 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_app_settings_fragment.xml @@ -1,129 +1,123 @@ - + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + + + + + + + + android:orientation="vertical" + android:visibility="gone"> + + + + - - - - - - - - + + + + + android:text="@string/label_message_compression" + android:textAppearance="?android:attr/textAppearanceMedium" /> - + + - - + + - - - - - - - - - - - - - - - - - - - - - - + android:text="com.example" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + - \ No newline at end of file + + + \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml b/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml index c89540291..e70a79589 100644 --- a/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml +++ b/OpenPGP-Keychain/src/main/res/layout/api_apps_adapter_list_item.xml @@ -1,6 +1,7 @@ @@ -8,20 +9,18 @@ android:id="@+id/api_apps_adapter_item_icon" android:layout_width="48dp" android:layout_height="48dp" - android:layout_alignParentTop="true" android:layout_marginLeft="8dp" - android:layout_marginRight="8dp" + android:layout_centerVertical="true" android:src="@drawable/icon" /> + android:textAppearance="?android:attr/textAppearanceMedium" + android:layout_centerVertical="true" + android:layout_toRightOf="@+id/api_apps_adapter_item_icon" /> \ No newline at end of file -- cgit v1.2.3 From 7b819e65de71a17827a3264a1a8663ca0d30b48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 13 Feb 2014 23:37:48 +0100 Subject: Transifex update --- .../src/main/res/raw-es/help_changelog.html | 2 +- .../src/main/res/raw-ja/help_about.html | 43 ++++++ .../src/main/res/raw-ja/help_changelog.html | 108 +++++++++++++++ .../src/main/res/raw-ja/help_nfc_beam.html | 12 ++ .../src/main/res/raw-ja/help_start.html | 19 +++ .../src/main/res/raw-ja/nfc_beam_share.html | 11 ++ .../src/main/res/values-es/strings.xml | 4 +- .../src/main/res/values-fr/strings.xml | 2 + .../src/main/res/values-ja/strings.xml | 149 +++++++++++++++++++++ .../src/main/res/values-ru/strings.xml | 9 +- .../src/main/res/values-uk/strings.xml | 2 + OpenPGP-Keychain/src/main/res/values/strings.xml | 4 +- 12 files changed, 360 insertions(+), 5 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/res/raw-ja/help_about.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-ja/help_start.html create mode 100644 OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html create mode 100644 OpenPGP-Keychain/src/main/res/values-ja/strings.xml (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html index 18b42a296..dfb51dc81 100644 --- a/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-es/help_changelog.html @@ -62,7 +62,7 @@
                                                • corregido el problema al añadir cuentas en Froyo
                                                • borrado seguro de archivo
                                                • -
                                                • opción para borrar el archivo de la clave después de importarlo
                                                • +
                                                • opción para borrar el archivo de clave después de importarlo
                                                • flujo de cifrado/descifrado (galería, etc.)
                                                • nuevas opciones (idioma, forzar firmas v3)
                                                • cambios en la interfaz
                                                • diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html new file mode 100644 index 000000000..773d11fa7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html @@ -0,0 +1,43 @@ + + + +

                                                  http://sufficientlysecure.org/keychain

                                                  +

                                                  OpenPGP Keychain is an OpenPGP implementation for Android. The development began as a fork of Android Privacy Guard (APG).

                                                  +

                                                  License: GPLv3+

                                                  + +

                                                  Developers OpenPGP Keychain

                                                  +
                                                    +
                                                  • Dominik Schürmann (Lead developer)
                                                  • +
                                                  • Ash Hughes (crypto patches)
                                                  • +
                                                  • Brian C. Barnes
                                                  • +
                                                  • Bahtiar 'kalkin' Gadimov (UI)
                                                  • + +
                                                  +

                                                  Developers APG 1.x

                                                  +
                                                    +
                                                  • 'Thialfihar' (Lead developer)
                                                  • +
                                                  • 'Senecaso' (QRCode, sign key, upload key)
                                                  • +
                                                  • Oliver Runge
                                                  • +
                                                  • Markus Doits
                                                  • +
                                                  +

                                                  Libraries

                                                  + + + diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html new file mode 100644 index 000000000..abf660ba8 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html @@ -0,0 +1,108 @@ + + + +

                                                  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 pass phrase 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 pass phrase 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
                                                  • +
                                                  + + diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html new file mode 100644 index 000000000..88492731c --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html @@ -0,0 +1,12 @@ + + + +

                                                  How to receive keys

                                                  +
                                                    +
                                                  1. Go to your partners contacts and open the contact you want to share.
                                                  2. +
                                                  3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                                  4. +
                                                  5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                                  6. +
                                                  7. Tap the card and the content will then load on the your device.
                                                  8. +
                                                  + + diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html new file mode 100644 index 000000000..198dfe64f --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html @@ -0,0 +1,19 @@ + + + +

                                                  Getting started

                                                  +

                                                  First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                  + +

                                                  It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                  + +

                                                  I found a bug in OpenPGP Keychain!

                                                  +

                                                  Please report the bug using the issue tracker of OpenPGP Keychain.

                                                  + +

                                                  Contribute

                                                  +

                                                  If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                  + +

                                                  Translations

                                                  +

                                                  Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                  + + + diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html new file mode 100644 index 000000000..083e055c7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html @@ -0,0 +1,11 @@ + + + +
                                                    +
                                                  1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                                                  2. +
                                                  3. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                                                  4. +
                                                  5. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                                  6. +
                                                  7. Tap the card and the content will then load on the other person’s device.
                                                  8. +
                                                  + + diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml index fe72d6106..0e22d4c4d 100644 --- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -303,7 +303,7 @@ consultando... Buscar claves públicas - Buscar las claves secretas + Buscar claves secretas Compartir la clave con... 512 @@ -378,6 +378,8 @@ Cifrar hacia este contacto Certificar la clave de este contacto + Información + Certificaciones Contactos Cifrar diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index cc0f17709..51ca32637 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -378,6 +378,8 @@ Chiffrer vers ce contact Certifier la clef de ce contact + Infos + Certifications Contacts Chiffrer diff --git a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml new file mode 100644 index 000000000..74af5c14b --- /dev/null +++ b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml @@ -0,0 +1,149 @@ + + + + 公開鍵の選択 + 秘密鍵の選択 + 暗号化 + 復号化 + パスフレーズ + 鍵の生成 + 鍵の編集 + 設定 + 登録済みのアプリケーション + パスフレーズの変更 + パスフレーズの設定 + メールの送信... + 暗号化してファイルに + 復号化してファイルに + 鍵のインポート + 鍵のエクスポート + 複数鍵のエクスポート + 鍵が見当りません + 不明な署名の鍵です + ヘルプ + + ユーザーID + + 一般 + デフォルト + 拡張 + + 署名 + 復号化 + 受信者の選択 + ファイル暗号化 + 保存 + キャンセル + 削除 + 無し + OK + パスフレーズの変更 + パスフレーズの設定 + 検索 + + 戻る + + 設定 + ファイルからインポート + QRコードからインポート + NFCからインポート + すべての鍵のエクスポート + ファイルへのエクスポート + 鍵の削除 + 鍵の生成 + 鍵の生成(上級) + 検索 + 鍵を署名 + Beamの設定 + + 署名 + メッセージ + ファイル + パスフレーズなし + パスフレーズ + もう一度 + アルゴリズム + アスキー形式 + 暗号化後に削除 + 復号化後に削除 + 暗号化アルゴリズム + ハッシュアルゴリズム + 公開鍵 + パスフレーズ + パスフレーズキャッシュ + メッセージの圧縮 + ファイルの圧縮 + 強制的にV3形式の署名にする + 鍵ID + 生成 + 満了 + 使い方 + 鍵サイズ + 主ユーザーID + 名前 + コメント + Eメール + <無し> + <鍵無し> + + 暗号化可能 + 署名可能 + 期限切れ + 指紋 + 秘密鍵: + + 無し + 署名のみ + 暗号化のみ + 署名と暗号化 + 15秒 + 1分 + 3分 + 5分 + 10分 + 20分 + 40分 + 1時間 + 2時間 + 4時間 + 8時間 + DSA + ElGamal + RSA + 開く... + 注意 + エラー + エラー: %s + + 良くないパスフレーズ + クリップボードの内容を使う。 + 最初にパスフレーズを設定してください。 + 互換性のないファイルマネージャがインストールされています。 + パスフレーズが一致しません。 + 空のパスフレーズは受け付けません。 + 対称暗号。 + \'%s\' にパスフレーズを入れてください。 + %s を削除してもかまいませんか? + 削除に成功しました。 + 最初にファイルを選択してください。 + 復号化に成功しました。 + 暗号化に成功しました。 + クリップボードの中身の暗号化に成功しました。 + もう一度パスフレーズを入れてください。 + 少なくとも1つの暗号鍵を選択して下さい。 + + + + + + + + + + + + + + diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index b86db9d81..131e5aeeb 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -136,7 +136,7 @@ шифрование подпись - годен до + просрочен отозван %d сервер ключей @@ -273,6 +273,11 @@ срок годности не может быть раньше даты создания нельзя удалить свой собственный контакт. Пожалуйста, удалите его в разделе \'Мои ключи\'! это ваши собственные контакты, их нельзя удалить:\n%s + + Пожалуйста, удалите его в разделе \'Мои ключи\'! + Пожалуйста, удалите их в разделе \'Мои ключи\'! + Пожалуйста, удалите их в разделе \'Мои ключи\'! + готово. сохранение... @@ -385,6 +390,8 @@ Зашифровать для этого получателя Сертифицировать ключ этого контакта + Информация + Сертификация Контакты Зашифровать diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml index 0a00f5658..344ca0966 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml @@ -390,6 +390,8 @@ Зашифрувати у цей контакт Сертифікувати ключ цього контакту + Інформація + Сертифікати Контакти Зашифрувати diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 3a719afed..88ad10a0a 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -373,7 +373,7 @@ OpenPGP: Decrypt - No registered applications! + No registered applications!\n\nThird-party applications can request access to OpenPGP Keychain. After granting access, they will be listed here. Show advanced settings Hide advanced settings No key selected @@ -383,7 +383,7 @@ Revoke access Package Name SHA-256 of Package Signature - The following application requests access to OpenPGP Keychain\'s API.\n\nAllow permanent access? + The following application requests access to OpenPGP Keychain.\n\nAllow permanent access? Allow access Disallow access Please select a key! -- cgit v1.2.3 From 7939aaaa440f84a0df5524f8a1a1c04dd569eedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 14 Feb 2014 02:33:21 +0100 Subject: Introducing new ParcelFileDescriptor pipes --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 2 +- .../keychain/service/remote/OpenPgpService.java | 280 +++++++++++++-------- .../keychain/service/remote/RemoteService.java | 4 - 3 files changed, 175 insertions(+), 111 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 6de35571f..45b034b97 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -30,7 +30,7 @@ --> Date: Fri, 14 Feb 2014 02:41:27 +0100 Subject: fix nullpointer --- .../keychain/service/remote/OpenPgpService.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 9cdb12eda..006754bae 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -522,9 +522,17 @@ public class OpenPgpService extends RemoteService { public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) { final AppSettings appSettings = getAppSettings(); - Bundle result = new Bundle(); + if (params == null) { + Bundle result = new Bundle(); + OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!"); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + return result; + } + if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) { // not compatible! + Bundle result = new Bundle(); OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error); result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); -- cgit v1.2.3 From acad2ba95723a940467e89a07e91498188a88745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 14 Feb 2014 13:40:24 +0100 Subject: PendingIntent to handle user input --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 7 +- .../keychain/service/KeychainIntentService.java | 2 +- .../keychain/service/remote/OpenPgpService.java | 79 +++++++++++++++------- .../service/remote/RemoteServiceActivity.java | 60 ++++++++-------- .../keychain/ui/DecryptActivity.java | 2 +- .../keychain/ui/EncryptActivity.java | 2 +- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 +- 7 files changed, 94 insertions(+), 60 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 45b034b97..ba2bd5571 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -362,10 +362,9 @@ + android:label="@string/app_name" /> + + Revoke access Package Name SHA-256 of Package Signature - The following application requests access to OpenPGP Keychain.\n\nAllow permanent access? + The following application requests access to OpenPGP Keychain.\n\nAllow access (you can revoke it later)? Allow access Disallow access Please select a key! -- cgit v1.2.3 From d6953745810bd4c6dee3bfefb538236b2b7bdbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 14 Feb 2014 17:01:17 +0100 Subject: conversion of other methods --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 26 +- .../service/exception/NoUserIdsException.java | 10 - .../UserInteractionRequiredException.java | 10 - .../exception/WrongPackageSignatureException.java | 10 - .../exception/WrongPassphraseException.java | 10 - .../keychain/service/remote/OpenPgpService.java | 715 +++++++-------------- .../keychain/service/remote/RemoteService.java | 1 - .../service/remote/RemoteServiceActivity.java | 77 +-- .../remote/WrongPackageSignatureException.java | 10 + 9 files changed, 292 insertions(+), 577 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index ba2bd5571..3b9cc1a8d 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -391,19 +391,19 @@ - - - - - - - + + + + + + + + + + + + + diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java deleted file mode 100644 index 555303238..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/NoUserIdsException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.sufficientlysecure.keychain.service.exception; - -public class NoUserIdsException extends Exception { - - private static final long serialVersionUID = 7009311527126696207L; - - public NoUserIdsException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java deleted file mode 100644 index 1152d6796..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/UserInteractionRequiredException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.sufficientlysecure.keychain.service.exception; - -public class UserInteractionRequiredException extends Exception { - - private static final long serialVersionUID = -60128148603511936L; - - public UserInteractionRequiredException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java deleted file mode 100644 index cef002265..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPackageSignatureException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.sufficientlysecure.keychain.service.exception; - -public class WrongPackageSignatureException extends Exception { - - private static final long serialVersionUID = -8294642703122196028L; - - public WrongPackageSignatureException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java deleted file mode 100644 index 14b774eb5..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/exception/WrongPassphraseException.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.sufficientlysecure.keychain.service.exception; - -public class WrongPassphraseException extends Exception { - - private static final long serialVersionUID = -5309689232853485740L; - - public WrongPassphraseException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 4bc5a90ac..b5b532f7a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2013-2014 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 @@ -17,106 +17,35 @@ package org.sufficientlysecure.keychain.service.remote; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.regex.Matcher; +import android.app.PendingIntent; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; -import org.openintents.openpgp.IOpenPgpCallback; -import org.openintents.openpgp.IOpenPgpKeyIdsCallback; import org.openintents.openpgp.IOpenPgpService; -import org.openintents.openpgp.OpenPgpData; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpConstants; import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.Preferences; -import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpOperation; -import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.service.exception.NoUserIdsException; -import org.sufficientlysecure.keychain.service.exception.UserInteractionRequiredException; -import org.sufficientlysecure.keychain.service.exception.WrongPassphraseException; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Message; -import android.os.ParcelFileDescriptor; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; public class OpenPgpService extends RemoteService { - private String getCachedPassphrase(long keyId, boolean allowUserInteraction) - throws UserInteractionRequiredException { - String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), keyId); - - if (passphrase == null) { - if (!allowUserInteraction) { - throw new UserInteractionRequiredException( - "Passphrase not found in cache, please enter your passphrase!"); - } - - Log.d(Constants.TAG, "No passphrase! Activity required!"); - - // start passphrase dialog - PassphraseActivityCallback callback = new PassphraseActivityCallback(); - Bundle extras = new Bundle(); - extras.putLong(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); - pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE, callback, - extras); - - if (callback.isSuccess()) { - Log.d(Constants.TAG, "New passphrase entered!"); - - // get again after it was entered - passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), keyId); - } else { - Log.d(Constants.TAG, "Passphrase dialog canceled!"); - - return null; - } - - } - - return passphrase; - } - - - public class PassphraseActivityCallback extends UserInputCallback { - - private boolean success = false; - - public boolean isSuccess() { - return success; - } - - @Override - public void handleUserInput(Message msg) { - if (msg.arg1 == OKAY) { - success = true; - } else { - success = false; - } - } - } - - ; /** * Search database for key ids based on emails. @@ -124,8 +53,7 @@ public class OpenPgpService extends RemoteService { * @param encryptionUserIds * @return */ - private long[] getKeyIdsFromEmails(String[] encryptionUserIds, boolean allowUserInteraction) - throws UserInteractionRequiredException { + private Bundle getKeyIdsFromEmails(String[] encryptionUserIds) { // find key ids to given emails in database ArrayList keyIds = new ArrayList(); @@ -159,98 +87,70 @@ public class OpenPgpService extends RemoteService { } // allow the user to verify pub key selection - if (allowUserInteraction && (missingUserIdsCheck || dublicateUserIdsCheck)) { - SelectPubKeysActivityCallback callback = new SelectPubKeysActivityCallback(); + if (missingUserIdsCheck || dublicateUserIdsCheck) { + // build PendingIntent for passphrase input + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS); + intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); + intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); + intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds); - Bundle extras = new Bundle(); - extras.putLongArray(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); - extras.putStringArrayList(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); - extras.putStringArrayList(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, - dublicateUserIds); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 42, intent, 0); - pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_SELECT_PUB_KEYS, callback, - extras); - - if (callback.isSuccess()) { - Log.d(Constants.TAG, "New selection of pub keys!"); - keyIdsArray = callback.getPubKeyIds(); - } else { - Log.d(Constants.TAG, "Pub key selection canceled!"); - return null; - } - } + // return PendingIntent to be executed by client + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); - // if no user interaction is allow throw exceptions on duplicate or missing pub keys - if (!allowUserInteraction) { - if (missingUserIdsCheck) - throw new UserInteractionRequiredException( - "Pub keys for these user ids are missing:" + missingUserIds.toString()); - if (dublicateUserIdsCheck) - throw new UserInteractionRequiredException( - "More than one pub key with these user ids exist:" - + dublicateUserIds.toString()); + return result; } if (keyIdsArray.length == 0) { return null; } - return keyIdsArray; - } - public class SelectPubKeysActivityCallback extends UserInputCallback { - public static final String PUB_KEY_IDS = "pub_key_ids"; + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS); + result.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, keyIdsArray); + return result; + } - private boolean success = false; - private long[] pubKeyIds; + private Bundle getPassphraseBundleIntent(long keyId) { + // build PendingIntent for passphrase input + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE); + intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 42, intent, 0); - public boolean isSuccess() { - return success; - } + // return PendingIntent to be executed by client + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); - public long[] getPubKeyIds() { - return pubKeyIds; - } - - @Override - public void handleUserInput(Message msg) { - if (msg.arg1 == OKAY) { - success = true; - pubKeyIds = msg.getData().getLongArray(PUB_KEY_IDS); - } else { - success = false; - } - } + return result; } - ; - - private synchronized void getKeyIdsSafe(String[] userIds, boolean allowUserInteraction, - IOpenPgpKeyIdsCallback callback, AppSettings appSettings) { + private Bundle encryptAndSignImpl(Bundle params, ParcelFileDescriptor input, + ParcelFileDescriptor output, AppSettings appSettings, + boolean sign) { try { - long[] keyIds = getKeyIdsFromEmails(userIds, allowUserInteraction); - if (keyIds == null) { - throw new NoUserIdsException("No user ids!"); - } + boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, false); - callback.onSuccess(keyIds); - } catch (UserInteractionRequiredException e) { -// callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); - } catch (NoUserIdsException e) { - callbackOpenPgpError(callback, OpenPgpError.NO_USER_IDS, e.getMessage()); - } catch (Exception e) { - callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage()); - } - } + long[] keyIds; + if (params.containsKey(OpenPgpConstants.PARAMS_KEY_IDS)) { + keyIds = params.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS); + } else { + // get key ids based on given user ids + String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS); + Bundle result = getKeyIdsFromEmails(userIds); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); - private synchronized void encryptAndSignSafe(OpenPgpData inputData, - final OpenPgpData outputData, long[] keyIds, boolean allowUserInteraction, - IOpenPgpCallback callback, AppSettings appSettings, boolean sign) { - try { - // TODO: other options of OpenPgpData! - byte[] inputBytes = getInput(inputData); - boolean asciiArmor = false; - if (outputData.getType() == OpenPgpData.TYPE_STRING) { - asciiArmor = true; + if (result.getInt(OpenPgpConstants.RESULT_CODE, 0) == OpenPgpConstants.RESULT_CODE_SUCCESS) { + keyIds = result.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS); + } else { + // non-unique result, we need user interaction! + return result; + } } // add own key for encryption @@ -258,48 +158,43 @@ public class OpenPgpService extends RemoteService { keyIds[keyIds.length - 1] = appSettings.getKeyId(); // build InputData and write into OutputStream - InputStream inputStream = new ByteArrayInputStream(inputBytes); - long inputLength = inputBytes.length; - InputData inputDt = new InputData(inputStream, inputLength); - - OutputStream outputStream = new ByteArrayOutputStream(); - - PgpOperation operation = new PgpOperation(getContext(), null, inputDt, outputStream); - if (sign) { - String passphrase = getCachedPassphrase(appSettings.getKeyId(), - allowUserInteraction); - if (passphrase == null) { - throw new WrongPassphraseException("No or wrong passphrase!"); - } - - operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, - appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(), - appSettings.getHashAlgorithm(), true, passphrase); - } else { - operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, - appSettings.getEncryptionAlgorithm(), Id.key.none, - appSettings.getHashAlgorithm(), true, null); - } - - outputStream.close(); + // Get Input- and OutputStream from ParcelFileDescriptor + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); + OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + try { + long inputLength = is.available(); + InputData inputData = new InputData(is, inputLength); - byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); + PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); + if (sign) { + String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), + appSettings.getKeyId()); + if (passphrase == null) { + return getPassphraseBundleIntent(appSettings.getKeyId()); + } - OpenPgpData output = null; - if (asciiArmor) { - output = new OpenPgpData(new String(outputBytes)); - } else { - output = new OpenPgpData(outputBytes); + operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, + appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(), + appSettings.getHashAlgorithm(), true, passphrase); + } else { + operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, + appSettings.getEncryptionAlgorithm(), Id.key.none, + appSettings.getHashAlgorithm(), true, null); + } + } finally { + is.close(); + os.close(); } - // return over handler on client side - callback.onSuccess(output, null); - } catch (UserInteractionRequiredException e) { -// callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); - } catch (WrongPassphraseException e) { - callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage()); + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS); + return result; } catch (Exception e) { - callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage()); + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + return result; } } @@ -309,28 +204,11 @@ public class OpenPgpService extends RemoteService { // get passphrase from cache, if key has "no" passphrase, this returns an empty String String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); if (passphrase == null) { - // TODO: we need to abort and return a passphrase Intent! - - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - // TODO: setComponent really needed for security? -// intent.setComponent(new ComponentName(Constants.PACKAGE_NAME, -// "org.sufficientlysecure.keychain.service.remote.RemoteServiceActivity")); -// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE); - intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, appSettings.getKeyId()); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 42, intent, 0); - - - Bundle result = new Bundle(); - result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); - result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); - - return result; + return getPassphraseBundleIntent(appSettings.getKeyId()); } - // INPUT + // Get Input- and OutputStream from ParcelFileDescriptor InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); - // OUTPUT OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); try { long inputLength = is.available(); @@ -339,22 +217,9 @@ public class OpenPgpService extends RemoteService { PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(), Preferences.getPreferences(this).getForceV3Signatures()); - + } finally { is.close(); os.close(); -// } catch (IOException e) { -// Log.e(Constants.TAG, "Fail", e); - } finally { -// try { - is.close(); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// try { - os.close(); -// } catch (IOException e) { -// e.printStackTrace(); -// } } Bundle result = new Bundle(); @@ -369,164 +234,159 @@ public class OpenPgpService extends RemoteService { } } - private synchronized void decryptAndVerifySafe(byte[] inputBytes, boolean allowUserInteraction, - IOpenPgpCallback callback, AppSettings appSettings) { + private Bundle decryptAndVerifyImpl(Bundle params, ParcelFileDescriptor input, + ParcelFileDescriptor output, AppSettings appSettings) { try { - // TODO: this is not really needed - // checked if it is text with BEGIN and END tags - String message = new String(inputBytes); - Log.d(Constants.TAG, "in: " + message); - boolean signedOnly = false; - Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message); - if (matcher.matches()) { - Log.d(Constants.TAG, "PGP_MESSAGE matched"); - message = matcher.group(1); - // replace non breakable spaces - message = message.replaceAll("\\xa0", " "); - - // overwrite inputBytes - inputBytes = message.getBytes(); - } else { - matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(message); - if (matcher.matches()) { - signedOnly = true; - Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched"); - message = matcher.group(1); - // replace non breakable spaces - message = message.replaceAll("\\xa0", " "); - - // overwrite inputBytes - inputBytes = message.getBytes(); - } else { - Log.d(Constants.TAG, "Nothing matched! Binary?"); - } - } - // END TODO - - Log.d(Constants.TAG, "in: " + new String(inputBytes)); - - // TODO: This allows to decrypt messages with ALL secret keys, not only the one for the - // app, Fix this? - - String passphrase = null; - if (!signedOnly) { - // BEGIN Get key - // TODO: this input stream is consumed after PgpMain.getDecryptionKeyId()... do it - // better! - InputStream inputStream2 = new ByteArrayInputStream(inputBytes); - - // TODO: duplicates functions from DecryptActivity! - long secretKeyId; - try { - if (inputStream2.markSupported()) { - // should probably set this to the max size of two - // pgpF objects, if it even needs to be anything other - // than 0. - inputStream2.mark(200); - } - secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2); - if (secretKeyId == Id.key.none) { - throw new PgpGeneralException(getString(R.string.error_no_secret_key_found)); - } - } catch (NoAsymmetricEncryptionException e) { - if (inputStream2.markSupported()) { - inputStream2.reset(); - } - secretKeyId = Id.key.symmetric; - if (!PgpOperation.hasSymmetricEncryption(this, inputStream2)) { - throw new PgpGeneralException( - getString(R.string.error_no_known_encryption_found)); - } - // we do not support symmetric decryption from the API! - throw new Exception("Symmetric decryption is not supported!"); - } + // Get Input- and OutputStream from ParcelFileDescriptor + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); + OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + OpenPgpSignatureResult sigResult = null; + try { - Log.d(Constants.TAG, "secretKeyId " + secretKeyId); - passphrase = getCachedPassphrase(secretKeyId, allowUserInteraction); - if (passphrase == null) { - throw new WrongPassphraseException("No or wrong passphrase!"); - } - } + // TODOs API 2.0: + // implement verify-only! + // fix the mess: http://stackoverflow.com/questions/148130/how-do-i-peek-at-the-first-two-bytes-in-an-inputstream + // should we allow to decrypt everything under every key id or only the one set? + // TODO: instead of trying to get the passphrase before + // pause stream when passphrase is missing and then resume + + + // TODO: this is not really needed + // checked if it is text with BEGIN and END tags +// String message = new String(inputBytes); +// Log.d(Constants.TAG, "in: " + message); + boolean signedOnly = false; +// Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message); +// if (matcher.matches()) { +// Log.d(Constants.TAG, "PGP_MESSAGE matched"); +// message = matcher.group(1); +// // replace non breakable spaces +// message = message.replaceAll("\\xa0", " "); +// +// // overwrite inputBytes +// inputBytes = message.getBytes(); +// } else { +// matcher = PgpHelper.PGP_SIGNED_MESSAGE.matcher(message); +// if (matcher.matches()) { +// signedOnly = true; +// Log.d(Constants.TAG, "PGP_SIGNED_MESSAGE matched"); +// message = matcher.group(1); +// // replace non breakable spaces +// message = message.replaceAll("\\xa0", " "); +// +// // overwrite inputBytes +// inputBytes = message.getBytes(); +// } else { +// Log.d(Constants.TAG, "Nothing matched! Binary?"); +// } +// } + // END TODO - // build InputData and write into OutputStream - InputStream inputStream = new ByteArrayInputStream(inputBytes); - long inputLength = inputBytes.length; - InputData inputData = new InputData(inputStream, inputLength); +// Log.d(Constants.TAG, "in: " + new String(inputBytes)); - OutputStream outputStream = new ByteArrayOutputStream(); + // TODO: This allows to decrypt messages with ALL secret keys, not only the one for the + // app, Fix this? - Bundle outputBundle; - PgpOperation operation = new PgpOperation(getContext(), null, inputData, outputStream); - if (signedOnly) { - outputBundle = operation.verifyText(); - } else { - outputBundle = operation.decryptAndVerify(passphrase, false); - } +// String passphrase = null; +// if (!signedOnly) { +// // BEGIN Get key +// // TODO: this input stream is consumed after PgpMain.getDecryptionKeyId()... do it +// // better! +// InputStream inputStream2 = new ByteArrayInputStream(inputBytes); +// +// // TODO: duplicates functions from DecryptActivity! +// long secretKeyId; +// try { +// if (inputStream2.markSupported()) { +// // should probably set this to the max size of two +// // pgpF objects, if it even needs to be anything other +// // than 0. +// inputStream2.mark(200); +// } +// secretKeyId = PgpHelper.getDecryptionKeyId(this, inputStream2); +// if (secretKeyId == Id.key.none) { +// throw new PgpGeneralException(getString(R.string.error_no_secret_key_found)); +// } +// } catch (NoAsymmetricEncryptionException e) { +// if (inputStream2.markSupported()) { +// inputStream2.reset(); +// } +// secretKeyId = Id.key.symmetric; +// if (!PgpOperation.hasSymmetricEncryption(this, inputStream2)) { +// throw new PgpGeneralException( +// getString(R.string.error_no_known_encryption_found)); +// } +// // we do not support symmetric decryption from the API! +// throw new Exception("Symmetric decryption is not supported!"); +// } +// +// Log.d(Constants.TAG, "secretKeyId " + secretKeyId); - outputStream.close(); + // NOTE: currently this only gets the passphrase for the saved key + String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + if (passphrase == null) { + return getPassphraseBundleIntent(appSettings.getKeyId()); + } +// } - byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); + // build InputData and write into OutputStream + long inputLength = is.available(); + InputData inputData = new InputData(is, inputLength); - // get signature informations from bundle - boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE); - OpenPgpSignatureResult sigResult = null; - if (signature) { - long signatureKeyId = outputBundle - .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID); - String signatureUserId = outputBundle - .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID); - boolean signatureSuccess = outputBundle - .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS); - boolean signatureUnknown = outputBundle - .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN); - - int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR; - if (signatureSuccess) { - signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_TRUSTED; - } else if (signatureUnknown) { - signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY; + Bundle outputBundle; + PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); + if (signedOnly) { + outputBundle = operation.verifyText(); + } else { + // BIG TODO: instead of trying to get the passphrase before + // pause stream when passphrase is missing and then resume + outputBundle = operation.decryptAndVerify(passphrase, false); } - sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, - signedOnly, signatureKeyId); - } - OpenPgpData output = new OpenPgpData(new String(outputBytes)); - - // return over handler on client side - callback.onSuccess(output, sigResult); - } catch (UserInteractionRequiredException e) { -// callbackOpenPgpError(callback, OpenPgpError.USER_INTERACTION_REQUIRED, e.getMessage()); - } catch (WrongPassphraseException e) { - callbackOpenPgpError(callback, OpenPgpError.NO_OR_WRONG_PASSPHRASE, e.getMessage()); - } catch (Exception e) { - callbackOpenPgpError(callback, OpenPgpError.GENERIC_ERROR, e.getMessage()); - } - } +// outputStream.close(); - /** - * Returns error to IOpenPgpCallback - * - * @param callback - * @param errorId - * @param message - */ - private void callbackOpenPgpError(IOpenPgpCallback callback, int errorId, String message) { - try { - callback.onError(new OpenPgpError(0, message)); - } catch (Exception t) { - Log.e(Constants.TAG, - "Exception while returning OpenPgpError to client via callback.onError()", t); - } - } +// byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); - private void callbackOpenPgpError(IOpenPgpKeyIdsCallback callback, int errorId, String message) { - try { - callback.onError(new OpenPgpError(0, message)); - } catch (Exception t) { - Log.e(Constants.TAG, - "Exception while returning OpenPgpError to client via callback.onError()", t); + // get signature informations from bundle + boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE); + + if (signature) { + long signatureKeyId = outputBundle + .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID); + String signatureUserId = outputBundle + .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID); + boolean signatureSuccess = outputBundle + .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS); + boolean signatureUnknown = outputBundle + .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN); + + int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR; + if (signatureSuccess) { + signatureStatus = OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED; + } else if (signatureUnknown) { + signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY; + } + + sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, + signedOnly, signatureKeyId); + } + } finally { + is.close(); + os.close(); + } + + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS); + result.putParcelable(OpenPgpConstants.RESULT_SIGNATURE, sigResult); + return result; + } catch (Exception e) { + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + return result; } } @@ -536,6 +396,7 @@ public class OpenPgpService extends RemoteService { * @param params * @return */ + private Bundle validateParamsAndVersion(Bundle params) { if (params == null) { Bundle result = new Bundle(); @@ -557,6 +418,7 @@ public class OpenPgpService extends RemoteService { return null; } + // TODO: enqueue in thread pool!!! private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() { @Override @@ -568,28 +430,31 @@ public class OpenPgpService extends RemoteService { return errorResult; } -// Runnable r = new Runnable() { -// @Override -// public void run() { return signImpl(input, output, appSettings); -// } -// }; - -// checkAndEnqueue(r); - -// return null; } @Override public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { + final AppSettings appSettings = getAppSettings(); - return null; + Bundle errorResult = validateParamsAndVersion(params); + if (errorResult != null) { + return errorResult; + } + + return encryptAndSignImpl(params, input, output, appSettings, false); } @Override public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { + final AppSettings appSettings = getAppSettings(); - return null; + Bundle errorResult = validateParamsAndVersion(params); + if (errorResult != null) { + return errorResult; + } + + return encryptAndSignImpl(params, input, output, appSettings, true); } @Override @@ -598,67 +463,6 @@ public class OpenPgpService extends RemoteService { return null; } -// @Override -// public void encrypt(final OpenPgpData input, final OpenPgpData output, final long[] keyIds, -// final IOpenPgpCallback callback) throws RemoteException { -// final AppSettings settings = getAppSettings(); -// -// Runnable r = new Runnable() { -// @Override -// public void run() { -// encryptAndSignSafe(input, output, keyIds, true, callback, settings, false); -// } -// }; -// -// checkAndEnqueue(r); -// } -// -// @Override -// public void signAndEncrypt(final OpenPgpData input, final OpenPgpData output, -// final long[] keyIds, final IOpenPgpCallback callback) throws RemoteException { -// final AppSettings settings = getAppSettings(); -// -// Runnable r = new Runnable() { -// @Override -// public void run() { -// encryptAndSignSafe(input, output, keyIds, true, callback, settings, true); -// } -// }; -// -// checkAndEnqueue(r); -// } -// -// @Override -// public void sign(final OpenPgpData input, final OpenPgpData output, -// final IOpenPgpCallback callback) throws RemoteException { -// final AppSettings settings = getAppSettings(); -// -// Runnable r = new Runnable() { -// @Override -// public void run() { -// signImpl(getInput(input), true, callback, settings); -// } -// }; -// -// checkAndEnqueue(r); -// } -// -// @Override -// public void decryptAndVerify(final OpenPgpData input, final OpenPgpData output, -// final IOpenPgpCallback callback) throws RemoteException { -// -// final AppSettings settings = getAppSettings(); -// -// Runnable r = new Runnable() { -// @Override -// public void run() { -// decryptAndVerifySafe(getInput(input), true, callback, settings); -// } -// }; -// -// checkAndEnqueue(r); -// } -// // @Override // public void getKeyIds(final String[] userIds, final boolean allowUserInteraction, // final IOpenPgpKeyIdsCallback callback) throws RemoteException { @@ -677,27 +481,6 @@ public class OpenPgpService extends RemoteService { }; - private static byte[] getInput(OpenPgpData data) { - // TODO: support Uri and ParcelFileDescriptor - - byte[] inBytes = null; - switch (data.getType()) { - case OpenPgpData.TYPE_STRING: - inBytes = data.getString().getBytes(); - break; - - case OpenPgpData.TYPE_BYTE_ARRAY: - inBytes = data.getBytes(); - break; - - default: - Log.e(Constants.TAG, "Uri and ParcelFileDescriptor not supported right now!"); - break; - } - - return inBytes; - } - @Override public IBinder onBind(Intent intent) { return mBinder; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java index ddc704c01..7e715e71d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java @@ -26,7 +26,6 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.exception.WrongPackageSignatureException; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 9852a2008..4ca713c1d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.service.remote; import java.util.ArrayList; +import org.openintents.openpgp.util.OpenPgpConstants; import org.sufficientlysecure.htmltextview.HtmlTextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -86,15 +87,15 @@ public class RemoteServiceActivity extends ActionBarActivity { protected void onStop() { super.onStop(); -// if (!finishHandled) { -// Message msg = Message.obtain(); -// msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL; -// try { -// mMessenger.send(msg); -// } catch (RemoteException e) { -// Log.e(Constants.TAG, "CryptoServiceActivity", e); -// } -// } + if (!finishHandled && mMessenger != null) { + Message msg = Message.obtain(); + msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL; + try { + mMessenger.send(msg); + } catch (RemoteException e) { + Log.e(Constants.TAG, "CryptoServiceActivity", e); + } + } } protected void handleActions(Intent intent, Bundle savedInstanceState) { @@ -212,39 +213,18 @@ public class RemoteServiceActivity extends ActionBarActivity { new View.OnClickListener() { @Override public void onClick(View v) { - // ok - - Message msg = Message.obtain(); - msg.arg1 = OpenPgpService.SelectPubKeysActivityCallback.OKAY; - Bundle data = new Bundle(); - data.putLongArray( - OpenPgpService.SelectPubKeysActivityCallback.PUB_KEY_IDS, + // return key ids to requesting activity + Intent finishIntent = new Intent(); + finishIntent.putExtra(OpenPgpConstants.PARAMS_KEY_IDS, mSelectFragment.getSelectedMasterKeyIds()); - msg.setData(data); - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.e(Constants.TAG, "CryptoServiceActivity", e); - } - - finishHandled = true; + setResult(RESULT_OK, finishIntent); finish(); } }, R.string.btn_do_not_save, new View.OnClickListener() { @Override public void onClick(View v) { // cancel - - Message msg = Message.obtain(); - msg.arg1 = OpenPgpService.SelectPubKeysActivityCallback.CANCEL; - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.e(Constants.TAG, "CryptoServiceActivity", e); - } - - finishHandled = true; + setResult(RESULT_CANCELED); finish(); } } @@ -287,6 +267,7 @@ public class RemoteServiceActivity extends ActionBarActivity { @Override public void onClick(View v) { + setResult(RESULT_OK); finish(); } }); @@ -298,6 +279,7 @@ public class RemoteServiceActivity extends ActionBarActivity { textView.setHtmlFromString(text); } else { Log.e(Constants.TAG, "Wrong action!"); + setResult(RESULT_CANCELED); finish(); } } @@ -313,31 +295,12 @@ public class RemoteServiceActivity extends ActionBarActivity { @Override public void handleMessage(Message message) { if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { -// Message msg = Message.obtain(); -// msg.arg1 = OpenPgpService.PassphraseActivityCallback.OKAY; -// try { -// mMessenger.send(msg); -// } catch (RemoteException e) { -// Log.e(Constants.TAG, "CryptoServiceActivity", e); -// } - RemoteServiceActivity.this.setResult(RESULT_OK); - RemoteServiceActivity.this.finish(); } else { -// Message msg = Message.obtain(); -// msg.arg1 = OpenPgpService.PassphraseActivityCallback.CANCEL; -// try { -// mMessenger.send(msg); -// } catch (RemoteException e) { -// Log.e(Constants.TAG, "CryptoServiceActivity", e); -// } - RemoteServiceActivity.this.setResult(RESULT_CANCELED); - RemoteServiceActivity.this.finish(); } -// finishHandled = true; -// finish(); + RemoteServiceActivity.this.finish(); } }; @@ -351,8 +314,8 @@ public class RemoteServiceActivity extends ActionBarActivity { passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); } catch (PgpGeneralException e) { Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly -// returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + RemoteServiceActivity.this.setResult(RESULT_OK); + RemoteServiceActivity.this.finish(); } } } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java new file mode 100644 index 000000000..cc08548e8 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/WrongPackageSignatureException.java @@ -0,0 +1,10 @@ +package org.sufficientlysecure.keychain.service.remote; + +public class WrongPackageSignatureException extends Exception { + + private static final long serialVersionUID = -8294642703122196028L; + + public WrongPackageSignatureException(String message) { + super(message); + } +} \ No newline at end of file -- cgit v1.2.3 From 581e6edb4cdfb6274f21e532ba60a610a3ce1fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 14 Feb 2014 17:19:54 +0100 Subject: cleanup --- .../service/remote/ExtendedApiService.java | 122 --------------------- 1 file changed, 122 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java deleted file mode 100644 index 427e6bb8f..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/ExtendedApiService.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2013 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.service.remote; - -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.security.cert.X509Certificate; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.PasswordCallback; - -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openssl.PEMWriter; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.pgp.PgpToX509; -import org.sufficientlysecure.keychain.util.Log; - -import android.content.Intent; -import android.os.IBinder; -import android.os.RemoteException; - -public class ExtendedApiService extends RemoteService { - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - private void selfSignedX509CertSafe(String subjAltNameURI, IExtendedApiCallback callback, - AppSettings appSettings) { - - // TODO: for pgp keyrings with password - CallbackHandler pgpPwdCallbackHandler = new PgpToX509.PredefinedPasswordCallbackHandler(""); - - try { - long keyId = appSettings.getKeyId(); - PGPSecretKey pgpSecretKey = PgpKeyHelper.getSigningKey(this, keyId); - - PasswordCallback pgpSecKeyPasswordCallBack = new PasswordCallback("pgp passphrase?", - false); - pgpPwdCallbackHandler.handle(new Callback[] { pgpSecKeyPasswordCallBack }); - PGPPrivateKey pgpPrivKey = pgpSecretKey.extractPrivateKey( - pgpSecKeyPasswordCallBack.getPassword(), Constants.BOUNCY_CASTLE_PROVIDER_NAME); - pgpSecKeyPasswordCallBack.clearPassword(); - - X509Certificate selfSignedCert = PgpToX509.createSelfSignedCert(pgpSecretKey, - pgpPrivKey, subjAltNameURI); - - // Write x509cert and privKey into files - // FileOutputStream fosCert = context.openFileOutput(CERT_FILENAME, - // Context.MODE_PRIVATE); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - PEMWriter pemWriterCert = new PEMWriter(new PrintWriter(outStream)); - pemWriterCert.writeObject(selfSignedCert); - pemWriterCert.close(); - - byte[] outputBytes = outStream.toByteArray(); - - callback.onSuccess(outputBytes); - } catch (Exception e) { - Log.e(Constants.TAG, "ExtendedApiService", e); - try { - callback.onError(e.getMessage()); - } catch (RemoteException e1) { - Log.e(Constants.TAG, "ExtendedApiService", e); - } - } - - // TODO: no private key at the moment! Don't give it to others - // PrivateKey privKey = pgpPrivKey.getKey(); - // FileOutputStream fosKey = context.openFileOutput(PRIV_KEY_FILENAME, - // Context.MODE_PRIVATE); - // PEMWriter pemWriterKey = new PEMWriter(new PrintWriter(fosKey)); - // pemWriterKey.writeObject(privKey); - // pemWriterKey.close(); - } - - private final IExtendedApiService.Stub mBinder = new IExtendedApiService.Stub() { - - @Override - public void encrypt(byte[] inputBytes, String passphrase, IExtendedApiCallback callback) - throws RemoteException { - // TODO : implement - - } - - @Override - public void selfSignedX509Cert(final String subjAltNameURI, - final IExtendedApiCallback callback) throws RemoteException { - final AppSettings settings = getAppSettings(); - - Runnable r = new Runnable() { - @Override - public void run() { - selfSignedX509CertSafe(subjAltNameURI, callback, settings); - } - }; - - checkAndEnqueue(r); - } - - }; - -} -- cgit v1.2.3 From 494a5fa414fe5962bdee0d50e761da9dc0cc1cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 01:06:03 +0100 Subject: private request codes, pass params through methods and pending intents, getKeyIds method --- .../keychain/service/remote/OpenPgpService.java | 138 +++++++++++++-------- 1 file changed, 89 insertions(+), 49 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index b5b532f7a..4c65f6b70 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -46,6 +46,9 @@ import java.util.ArrayList; public class OpenPgpService extends RemoteService { + private static final int PRIVATE_REQUEST_CODE_PASSPHRASE = 551; + private static final int PRIVATE_REQUEST_CODE_USER_IDS = 552; + /** * Search database for key ids based on emails. @@ -95,7 +98,7 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 42, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0); // return PendingIntent to be executed by client Bundle result = new Bundle(); @@ -120,7 +123,7 @@ public class OpenPgpService extends RemoteService { Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE); intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); - PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 42, intent, 0); + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0); // return PendingIntent to be executed by client Bundle result = new Bundle(); @@ -130,6 +133,46 @@ public class OpenPgpService extends RemoteService { return result; } + + // TODO: asciiArmor?! + private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings) { + try { + // get passphrase from cache, if key has "no" passphrase, this returns an empty String + String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + if (passphrase == null) { + // get PendingIntent for passphrase input, add it to given params and return to client + Bundle passphraseBundle = getPassphraseBundleIntent(appSettings.getKeyId()); + params.putAll(passphraseBundle); + return params; + } + + // Get Input- and OutputStream from ParcelFileDescriptor + InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); + OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); + try { + long inputLength = is.available(); + InputData inputData = new InputData(is, inputLength); + + PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); + operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(), + Preferences.getPreferences(this).getForceV3Signatures()); + } finally { + is.close(); + os.close(); + } + + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS); + return result; + } catch (Exception e) { + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + return result; + } + } + private Bundle encryptAndSignImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings, boolean sign) { @@ -143,13 +186,14 @@ public class OpenPgpService extends RemoteService { // get key ids based on given user ids String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS); Bundle result = getKeyIdsFromEmails(userIds); - result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); if (result.getInt(OpenPgpConstants.RESULT_CODE, 0) == OpenPgpConstants.RESULT_CODE_SUCCESS) { keyIds = result.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS); } else { - // non-unique result, we need user interaction! - return result; + // if not success -> result contains a PendingIntent for user interaction + // return all old params with the new PendingIntent to client! + params.putAll(result); + return params; } } @@ -170,7 +214,10 @@ public class OpenPgpService extends RemoteService { String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); if (passphrase == null) { - return getPassphraseBundleIntent(appSettings.getKeyId()); + // get PendingIntent for passphrase input, add it to given params and return to client + Bundle passphraseBundle = getPassphraseBundleIntent(appSettings.getKeyId()); + params.putAll(passphraseBundle); + return params; } operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, @@ -198,42 +245,6 @@ public class OpenPgpService extends RemoteService { } } - // TODO: asciiArmor?! - private Bundle signImpl(ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings) { - try { - // get passphrase from cache, if key has "no" passphrase, this returns an empty String - String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); - if (passphrase == null) { - return getPassphraseBundleIntent(appSettings.getKeyId()); - } - - // Get Input- and OutputStream from ParcelFileDescriptor - InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input); - OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output); - try { - long inputLength = is.available(); - InputData inputData = new InputData(is, inputLength); - - PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); - operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(), - Preferences.getPreferences(this).getForceV3Signatures()); - } finally { - is.close(); - os.close(); - } - - Bundle result = new Bundle(); - result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_SUCCESS); - return result; - } catch (Exception e) { - Bundle result = new Bundle(); - result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); - result.putParcelable(OpenPgpConstants.RESULT_ERRORS, - new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); - return result; - } - } - private Bundle decryptAndVerifyImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings) { try { @@ -323,11 +334,14 @@ public class OpenPgpService extends RemoteService { // // Log.d(Constants.TAG, "secretKeyId " + secretKeyId); - // NOTE: currently this only gets the passphrase for the saved key - String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); - if (passphrase == null) { - return getPassphraseBundleIntent(appSettings.getKeyId()); - } + // NOTE: currently this only gets the passphrase for the saved key + String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + if (passphrase == null) { + // get PendingIntent for passphrase input, add it to given params and return to client + Bundle passphraseBundle = getPassphraseBundleIntent(appSettings.getKeyId()); + params.putAll(passphraseBundle); + return params; + } // } // build InputData and write into OutputStream @@ -390,6 +404,15 @@ public class OpenPgpService extends RemoteService { } } + private Bundle getKeyIdsImpl(Bundle params) { + // get key ids based on given user ids + String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS); + Bundle result = getKeyIdsFromEmails(userIds); + + params.putAll(result); + return params; + } + /** * Checks that params != null and API version fits * @@ -430,7 +453,7 @@ public class OpenPgpService extends RemoteService { return errorResult; } - return signImpl(input, output, appSettings); + return signImpl(params, input, output, appSettings); } @Override @@ -459,10 +482,27 @@ public class OpenPgpService extends RemoteService { @Override public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { + final AppSettings appSettings = getAppSettings(); - return null; + Bundle errorResult = validateParamsAndVersion(params); + if (errorResult != null) { + return errorResult; + } + + return decryptAndVerifyImpl(params, input, output, appSettings); + } + + @Override + public Bundle getKeyIds(Bundle params) { + Bundle errorResult = validateParamsAndVersion(params); + if (errorResult != null) { + return errorResult; + } + + return getKeyIdsImpl(params); } + // TODO: old example for checkAndEnqueue! // @Override // public void getKeyIds(final String[] userIds, final boolean allowUserInteraction, // final IOpenPgpKeyIdsCallback callback) throws RemoteException { -- cgit v1.2.3 From 5f39cb3ec0d1d3f77d48fdbb428a2147dfe11d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 02:08:27 +0100 Subject: fix passtrough of params --- .../keychain/service/remote/OpenPgpService.java | 35 +++++++------- .../service/remote/RemoteServiceActivity.java | 53 ++++++++++++---------- 2 files changed, 45 insertions(+), 43 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 4c65f6b70..0f5aa9e3b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -56,7 +56,7 @@ public class OpenPgpService extends RemoteService { * @param encryptionUserIds * @return */ - private Bundle getKeyIdsFromEmails(String[] encryptionUserIds) { + private Bundle getKeyIdsFromEmails(Bundle params, String[] encryptionUserIds) { // find key ids to given emails in database ArrayList keyIds = new ArrayList(); @@ -97,6 +97,7 @@ public class OpenPgpService extends RemoteService { intent.putExtra(RemoteServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); intent.putExtra(RemoteServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds); intent.putExtra(RemoteServiceActivity.EXTRA_DUBLICATE_USER_IDS, dublicateUserIds); + intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_USER_IDS, intent, 0); @@ -118,11 +119,13 @@ public class OpenPgpService extends RemoteService { return result; } - private Bundle getPassphraseBundleIntent(long keyId) { + private Bundle getPassphraseBundleIntent(Bundle params, long keyId) { // build PendingIntent for passphrase input Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE); intent.putExtra(RemoteServiceActivity.EXTRA_SECRET_KEY_ID, keyId); + // pass params through to activity that it can be returned again later to repeat pgp operation + intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_PASSPHRASE, intent, 0); // return PendingIntent to be executed by client @@ -141,9 +144,8 @@ public class OpenPgpService extends RemoteService { String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Bundle passphraseBundle = getPassphraseBundleIntent(appSettings.getKeyId()); - params.putAll(passphraseBundle); - return params; + Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId()); + return passphraseBundle; } // Get Input- and OutputStream from ParcelFileDescriptor @@ -185,15 +187,14 @@ public class OpenPgpService extends RemoteService { } else { // get key ids based on given user ids String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS); - Bundle result = getKeyIdsFromEmails(userIds); + // give params through to activity... + Bundle result = getKeyIdsFromEmails(params, userIds); if (result.getInt(OpenPgpConstants.RESULT_CODE, 0) == OpenPgpConstants.RESULT_CODE_SUCCESS) { keyIds = result.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS); } else { // if not success -> result contains a PendingIntent for user interaction - // return all old params with the new PendingIntent to client! - params.putAll(result); - return params; + return result; } } @@ -215,9 +216,8 @@ public class OpenPgpService extends RemoteService { appSettings.getKeyId()); if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Bundle passphraseBundle = getPassphraseBundleIntent(appSettings.getKeyId()); - params.putAll(passphraseBundle); - return params; + Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId()); + return passphraseBundle; } operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, @@ -338,9 +338,8 @@ public class OpenPgpService extends RemoteService { String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - Bundle passphraseBundle = getPassphraseBundleIntent(appSettings.getKeyId()); - params.putAll(passphraseBundle); - return params; + Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId()); + return passphraseBundle; } // } @@ -407,10 +406,8 @@ public class OpenPgpService extends RemoteService { private Bundle getKeyIdsImpl(Bundle params) { // get key ids based on given user ids String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS); - Bundle result = getKeyIdsFromEmails(userIds); - - params.putAll(result); - return params; + Bundle result = getKeyIdsFromEmails(params, userIds); + return result; } /** diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 4ca713c1d..8f619f37e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2013-2014 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 @@ -17,7 +17,14 @@ package org.sufficientlysecure.keychain.service.remote; -import java.util.ArrayList; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.support.v7.app.ActionBarActivity; +import android.view.View; import org.openintents.openpgp.util.OpenPgpConstants; import org.sufficientlysecure.htmltextview.HtmlTextView; @@ -31,15 +38,7 @@ import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.support.v7.app.ActionBarActivity; -import android.view.View; -import android.widget.Toast; +import java.util.ArrayList; public class RemoteServiceActivity extends ActionBarActivity { @@ -102,11 +101,7 @@ public class RemoteServiceActivity extends ActionBarActivity { finishHandled = false; String action = intent.getAction(); - Bundle extras = intent.getExtras(); - - if (extras == null) { - extras = new Bundle(); - } + final Bundle extras = intent.getExtras(); mMessenger = extras.getParcelable(EXTRA_MESSENGER); @@ -176,8 +171,9 @@ public class RemoteServiceActivity extends ActionBarActivity { mSettingsFragment.setAppSettings(settings); } else if (ACTION_CACHE_PASSPHRASE.equals(action)) { long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID); + Bundle oldParams = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS); - showPassphraseDialog(secretKeyId); + showPassphraseDialog(oldParams, secretKeyId); } else if (ACTION_SELECT_PUB_KEYS.equals(action)) { long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); ArrayList missingUserIds = intent @@ -213,10 +209,13 @@ public class RemoteServiceActivity extends ActionBarActivity { new View.OnClickListener() { @Override public void onClick(View v) { - // return key ids to requesting activity - Intent finishIntent = new Intent(); - finishIntent.putExtra(OpenPgpConstants.PARAMS_KEY_IDS, + // sdd key ids to params Bundle for new request + Bundle params = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS); + params.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, mSelectFragment.getSelectedMasterKeyIds()); + + Intent finishIntent = new Intent(); + finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); setResult(RESULT_OK, finishIntent); finish(); } @@ -289,13 +288,16 @@ public class RemoteServiceActivity extends ActionBarActivity { * encryption. Based on mSecretKeyId it asks for a passphrase to open a private key or it asks * for a symmetric passphrase */ - private void showPassphraseDialog(long secretKeyId) { + private void showPassphraseDialog(final Bundle params, long secretKeyId) { // Message is received after passphrase is cached Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - RemoteServiceActivity.this.setResult(RESULT_OK); + // return given params again, for calling the service method again + Intent finishIntent = new Intent(); + finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); + RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent); } else { RemoteServiceActivity.this.setResult(RESULT_CANCELED); } @@ -314,8 +316,11 @@ public class RemoteServiceActivity extends ActionBarActivity { passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); } catch (PgpGeneralException e) { Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - RemoteServiceActivity.this.setResult(RESULT_OK); - RemoteServiceActivity.this.finish(); + // return given params again, for calling the service method again + Intent finishIntent = new Intent(); + finishIntent.putExtras(params); + setResult(RESULT_OK, finishIntent); + finish(); } } } -- cgit v1.2.3 From e0111c2ec40b35db94f06d89c8ca50529fbbb401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 02:30:31 +0100 Subject: code simplifications --- .../keychain/service/remote/RemoteServiceActivity.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 8f619f37e..669c5c28f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -181,6 +181,7 @@ public class RemoteServiceActivity extends ActionBarActivity { ArrayList dublicateUserIds = intent .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS); + // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids String text = new String(); text += "" + getString(R.string.api_select_pub_keys_text) + ""; text += "

                                                  "; @@ -209,7 +210,7 @@ public class RemoteServiceActivity extends ActionBarActivity { new View.OnClickListener() { @Override public void onClick(View v) { - // sdd key ids to params Bundle for new request + // add key ids to params Bundle for new request Bundle params = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS); params.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, mSelectFragment.getSelectedMasterKeyIds()); @@ -297,12 +298,12 @@ public class RemoteServiceActivity extends ActionBarActivity { // return given params again, for calling the service method again Intent finishIntent = new Intent(); finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); - RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent); + setResult(RESULT_OK, finishIntent); } else { - RemoteServiceActivity.this.setResult(RESULT_CANCELED); + setResult(RESULT_CANCELED); } - RemoteServiceActivity.this.finish(); + finish(); } }; @@ -318,7 +319,7 @@ public class RemoteServiceActivity extends ActionBarActivity { Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); // return given params again, for calling the service method again Intent finishIntent = new Intent(); - finishIntent.putExtras(params); + finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); setResult(RESULT_OK, finishIntent); finish(); } -- cgit v1.2.3 From 3b0f76bf60028603140c3fd8a956241b315a6b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 02:44:03 +0100 Subject: allow passphrase as parameter --- .../keychain/service/remote/OpenPgpService.java | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 0f5aa9e3b..b1635ec10 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -141,7 +141,12 @@ public class OpenPgpService extends RemoteService { private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings) { try { // get passphrase from cache, if key has "no" passphrase, this returns an empty String - String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + String passphrase; + if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) { + passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE); + } else { + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId()); @@ -212,8 +217,13 @@ public class OpenPgpService extends RemoteService { PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); if (sign) { - String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), - appSettings.getKeyId()); + String passphrase; + if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) { + passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE); + } else { + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), + appSettings.getKeyId()); + } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId()); @@ -335,7 +345,12 @@ public class OpenPgpService extends RemoteService { // Log.d(Constants.TAG, "secretKeyId " + secretKeyId); // NOTE: currently this only gets the passphrase for the saved key - String passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + String passphrase; + if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) { + passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE); + } else { + passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), appSettings.getKeyId()); + } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client Bundle passphraseBundle = getPassphraseBundleIntent(params, appSettings.getKeyId()); -- cgit v1.2.3 From 52f1c930ebe98251fb9d3b34b2725087f2917f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 13:00:47 +0100 Subject: parse string util method, better help text for access screen --- .../org/sufficientlysecure/keychain/service/remote/OpenPgpService.java | 3 ++- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index b1635ec10..5362aa603 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -138,7 +138,8 @@ public class OpenPgpService extends RemoteService { // TODO: asciiArmor?! - private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings) { + private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, + AppSettings appSettings) { try { // get passphrase from cache, if key has "no" passphrase, this returns an empty String String passphrase; diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 2a0b4b6f9..0608b108f 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -383,7 +383,7 @@ Revoke access Package Name SHA-256 of Package Signature - The following application requests access to OpenPGP Keychain.\n\nAllow access (you can revoke it later)? + The displayed application requests access to OpenPGP Keychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen. Allow access Disallow access Please select a key! -- cgit v1.2.3 From a76169c39e77e85c174707cad0f992b1920e0c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 16:08:43 +0100 Subject: fix regression bug with finish not called on activity but on fragment causing params to be not passed through --- .../keychain/service/remote/RemoteServiceActivity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 669c5c28f..7c8eaab62 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -298,12 +298,12 @@ public class RemoteServiceActivity extends ActionBarActivity { // return given params again, for calling the service method again Intent finishIntent = new Intent(); finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); - setResult(RESULT_OK, finishIntent); + RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent); } else { - setResult(RESULT_CANCELED); + RemoteServiceActivity.this.setResult(RESULT_CANCELED); } - finish(); + RemoteServiceActivity.this.finish(); } }; @@ -316,7 +316,7 @@ public class RemoteServiceActivity extends ActionBarActivity { passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); } catch (PgpGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + Log.d(Constants.TAG, "No passphrase for this secret key, do pgp operation directly!"); // return given params again, for calling the service method again Intent finishIntent = new Intent(); finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); -- cgit v1.2.3 From 2b98f2a0d7e37542a062886437c3f7b14599a4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 17:09:21 +0100 Subject: Restructure API lib folder to support Eclipse --- .../keychain/service/remote/RemoteServiceActivity.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 7c8eaab62..8f5b74650 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -182,8 +182,7 @@ public class RemoteServiceActivity extends ActionBarActivity { .getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS); // TODO: do this with spannable instead of HTML to prevent parsing failures with weird user ids - String text = new String(); - text += "" + getString(R.string.api_select_pub_keys_text) + ""; + String text = "" + getString(R.string.api_select_pub_keys_text) + ""; text += "

                                                  "; if (missingUserIds != null && missingUserIds.size() > 0) { text += getString(R.string.api_select_pub_keys_missing_text); @@ -258,8 +257,7 @@ public class RemoteServiceActivity extends ActionBarActivity { } else if (ACTION_ERROR_MESSAGE.equals(action)) { String errorMessage = intent.getStringExtra(EXTRA_ERROR_MESSAGE); - String text = new String(); - text += "" + errorMessage + ""; + String text = "" + errorMessage + ""; // Inflate a "Done" custom action bar view ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_okay, -- cgit v1.2.3 From b97a099598145d1461696b423ed2a49577090391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 17:09:55 +0100 Subject: warn that key generation takes looong --- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index 0608b108f..d34fe0105 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -295,7 +295,7 @@ saving… importing… exporting… - generating key, this can take a while… + generating key, this can take up to 3 minutes… building key… preparing master key… certifying master key… -- cgit v1.2.3 From 81b810e9f6cee2ac549758563fcd8987806828a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 15 Feb 2014 20:14:23 +0100 Subject: intent demo, fix some intents --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 42 ++++++++++++++++++--------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 3b9cc1a8d..0a9c9e638 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -153,12 +153,19 @@ android:windowSoftInputMode="stateHidden"> + + + + + - + + + @@ -176,12 +183,19 @@ android:windowSoftInputMode="stateHidden"> + + + + + - + + + @@ -293,7 +307,7 @@ - + @@ -392,17 +406,17 @@ - - - - - - - - - - - + + + + + + + + + + + -- cgit v1.2.3 From ec2ca61b65b881a9f5d3c572d85d770ba8a31abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 16 Feb 2014 00:40:10 +0100 Subject: fix some intents and demos --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 5 +++-- .../java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 0a9c9e638..58019cd4d 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -296,6 +296,7 @@ + @@ -303,11 +304,11 @@ - + - + diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index e0f25b632..1864e0d9d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -57,6 +57,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa + "IMPORT_KEY_FROM_QR_CODE"; public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEYSERVER"; + // TODO: implement: public static final String ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN = Constants.INTENT_PREFIX + "IMPORT_KEY_FROM_KEY_SERVER_AND_RETURN"; -- cgit v1.2.3 From 154849b5911cc2b99aa0f5c42eea53aaf55ba930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 16 Feb 2014 01:35:14 +0100 Subject: rename intent helper --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 58019cd4d..95f148686 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -304,6 +304,14 @@ + + + + + + + + -- cgit v1.2.3 From 37f280afbbb5a75a5f8c33b6c093884bcad67d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 17 Feb 2014 18:37:01 +0100 Subject: check if caller is allowed --- .../keychain/service/remote/OpenPgpService.java | 22 ++-- .../keychain/service/remote/RemoteService.java | 119 +++++++++++---------- 2 files changed, 76 insertions(+), 65 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 5362aa603..e676b6633 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -432,8 +432,8 @@ public class OpenPgpService extends RemoteService { * @param params * @return */ - - private Bundle validateParamsAndVersion(Bundle params) { + private Bundle checkRequirements(Bundle params) { + // params Bundle is required! if (params == null) { Bundle result = new Bundle(); OpenPgpError error = new OpenPgpError(OpenPgpError.GENERIC_ERROR, "params Bundle required!"); @@ -442,8 +442,8 @@ public class OpenPgpService extends RemoteService { return result; } + // version code is required and needs to correspond to version code of service! if (params.getInt(OpenPgpConstants.PARAMS_API_VERSION) != OpenPgpConstants.API_VERSION) { - // not compatible! Bundle result = new Bundle(); OpenPgpError error = new OpenPgpError(OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!"); result.putParcelable(OpenPgpConstants.RESULT_ERRORS, error); @@ -451,6 +451,12 @@ public class OpenPgpService extends RemoteService { return result; } + // check if caller is allowed to access openpgp keychain + Bundle result = isAllowed(params); + if (result != null) { + return result; + } + return null; } @@ -461,7 +467,7 @@ public class OpenPgpService extends RemoteService { public Bundle sign(Bundle params, final ParcelFileDescriptor input, final ParcelFileDescriptor output) { final AppSettings appSettings = getAppSettings(); - Bundle errorResult = validateParamsAndVersion(params); + Bundle errorResult = checkRequirements(params); if (errorResult != null) { return errorResult; } @@ -473,7 +479,7 @@ public class OpenPgpService extends RemoteService { public Bundle encrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { final AppSettings appSettings = getAppSettings(); - Bundle errorResult = validateParamsAndVersion(params); + Bundle errorResult = checkRequirements(params); if (errorResult != null) { return errorResult; } @@ -485,7 +491,7 @@ public class OpenPgpService extends RemoteService { public Bundle signAndEncrypt(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { final AppSettings appSettings = getAppSettings(); - Bundle errorResult = validateParamsAndVersion(params); + Bundle errorResult = checkRequirements(params); if (errorResult != null) { return errorResult; } @@ -497,7 +503,7 @@ public class OpenPgpService extends RemoteService { public Bundle decryptAndVerify(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output) { final AppSettings appSettings = getAppSettings(); - Bundle errorResult = validateParamsAndVersion(params); + Bundle errorResult = checkRequirements(params); if (errorResult != null) { return errorResult; } @@ -507,7 +513,7 @@ public class OpenPgpService extends RemoteService { @Override public Bundle getKeyIds(Bundle params) { - Bundle errorResult = validateParamsAndVersion(params); + Bundle errorResult = checkRequirements(params); if (errorResult != null) { return errorResult; } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java index 7e715e71d..bcfe37368 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java @@ -22,6 +22,8 @@ import java.util.Arrays; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; +import org.openintents.openpgp.OpenPgpError; +import org.openintents.openpgp.util.OpenPgpConstants; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; @@ -29,6 +31,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor; +import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -56,28 +59,9 @@ public abstract class RemoteService extends Service { private final Object userInputLock = new Object(); - /** - * Override handleUserInput() to handle OKAY (1) and CANCEL (0). After handling the waiting - * threads will be notified and the queue resumed - */ - protected class UserInputCallback extends BaseCallback { - - public void handleUserInput(Message msg) { - } - - @Override - public boolean handleMessage(Message msg) { - handleUserInput(msg); - - // resume - synchronized (userInputLock) { - userInputLock.notifyAll(); - } - mThreadPool.resume(); - return true; - } + private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; + private static final int PRIVATE_REQUEST_CODE_ERROR = 652; - } /** * Extends Handler.Callback with OKAY (1), CANCEL (0) variables @@ -97,18 +81,13 @@ public abstract class RemoteService extends Service { return mContext; } - /** - * Should be used from Stub implementations of AIDL interfaces to enqueue a runnable for - * execution - * - * @param r - */ - protected void checkAndEnqueue(Runnable r) { + protected Bundle isAllowed(Bundle params) { try { if (isCallerAllowed(false)) { - mThreadPool.execute(r); +// mThreadPool.execute(r); - Log.d(Constants.TAG, "Enqueued runnable…"); + return null; +// Log.d(Constants.TAG, "Enqueued runnable…"); } else { String[] callingPackages = getPackageManager().getPackagesForUid( Binder.getCallingUid()); @@ -120,32 +99,59 @@ public abstract class RemoteService extends Service { packageSignature = getPackageSignature(packageName); } catch (NameNotFoundException e) { Log.e(Constants.TAG, "Should not happen, returning!", e); - return; - } - Log.e(Constants.TAG, - "Not allowed to use service! Starting activity for registration!"); - Bundle extras = new Bundle(); - extras.putString(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); - extras.putByteArray(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature); - RegisterActivityCallback callback = new RegisterActivityCallback(); - - pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback, - extras); - - if (callback.isAllowed()) { - mThreadPool.execute(r); - Log.d(Constants.TAG, "Enqueued runnable…"); - } else { - Log.d(Constants.TAG, "User disallowed app!"); + // return error + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage())); + return result; } + Log.e(Constants.TAG, "Not allowed to use service! return PendingIntent for registration!"); + + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_REGISTER); + intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_NAME, packageName); + intent.putExtra(RemoteServiceActivity.EXTRA_PACKAGE_SIGNATURE, packageSignature); + intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_REGISTER, intent, 0); + + // return PendingIntent to be executed by client + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); + +// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback, +// extras); + return result; +// if (callback.isAllowed()) { +// mThreadPool.execute(r); +// Log.d(Constants.TAG, "Enqueued runnable…"); +// } else { +// Log.d(Constants.TAG, "User disallowed app!"); +// } } } catch (WrongPackageSignatureException e) { - Log.e(Constants.TAG, e.getMessage()); + Log.e(Constants.TAG, "wrong signature!", e); + + Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); + intent.setAction(RemoteServiceActivity.ACTION_ERROR_MESSAGE); + intent.putExtra(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, getString(R.string.api_error_wrong_signature)); + intent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); + + PendingIntent pi = PendingIntent.getActivity(getBaseContext(), PRIVATE_REQUEST_CODE_ERROR, intent, 0); + + // return PendingIntent to be executed by client + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); + result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); + + return result; - Bundle extras = new Bundle(); - extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, - getString(R.string.api_error_wrong_signature)); - pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras); +// Bundle extras = new Bundle(); +// extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, +// getString(R.string.api_error_wrong_signature)); +// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras); } } @@ -189,7 +195,7 @@ public abstract class RemoteService extends Service { /** * Retrieves AppSettings from database for the application calling this remote service - * + * * @return */ protected AppSettings getAppSettings() { @@ -267,9 +273,8 @@ public abstract class RemoteService extends Service { /** * Checks if process that binds to this service (i.e. the package name corresponding to the * process) is in the list of allowed package names. - * - * @param allowOnlySelf - * allow only Keychain app itself + * + * @param allowOnlySelf allow only Keychain app itself * @return true if process is allowed to use this service * @throws WrongPackageSignatureException */ @@ -303,7 +308,7 @@ public abstract class RemoteService extends Service { /** * Checks if packageName is a registered app for the API. Does not return true for own package! - * + * * @param packageName * @return * @throws WrongPackageSignatureException -- cgit v1.2.3 From f3bbd344823265f2b77cfc0af530a23211663e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 17 Feb 2014 19:06:29 +0100 Subject: Fix register activity --- .../keychain/service/remote/RemoteService.java | 154 ++++++++++----------- .../service/remote/RemoteServiceActivity.java | 75 +++------- 2 files changed, 93 insertions(+), 136 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java index bcfe37368..bfea70381 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java @@ -168,30 +168,30 @@ public abstract class RemoteService extends Service { /** * Locks current thread and pauses execution of runnables and starts activity for user input */ - protected void pauseAndStartUserInteraction(String action, BaseCallback callback, Bundle extras) { - synchronized (userInputLock) { - mThreadPool.pause(); - - Log.d(Constants.TAG, "starting activity..."); - Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.setAction(action); - - Messenger messenger = new Messenger(new Handler(getMainLooper(), callback)); - - extras.putParcelable(RemoteServiceActivity.EXTRA_MESSENGER, messenger); - intent.putExtras(extras); - - startActivity(intent); - - // lock current thread for user input - try { - userInputLock.wait(); - } catch (InterruptedException e) { - Log.e(Constants.TAG, "CryptoService", e); - } - } - } +// protected void pauseAndStartUserInteraction(String action, BaseCallback callback, Bundle extras) { +// synchronized (userInputLock) { +// mThreadPool.pause(); +// +// Log.d(Constants.TAG, "starting activity..."); +// Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); +// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// intent.setAction(action); +// +// Messenger messenger = new Messenger(new Handler(getMainLooper(), callback)); +// +// extras.putParcelable(RemoteServiceActivity.EXTRA_MESSENGER, messenger); +// intent.putExtras(extras); +// +// startActivity(intent); +// +// // lock current thread for user input +// try { +// userInputLock.wait(); +// } catch (InterruptedException e) { +// Log.e(Constants.TAG, "CryptoService", e); +// } +// } +// } /** * Retrieves AppSettings from database for the application calling this remote service @@ -216,59 +216,59 @@ public abstract class RemoteService extends Service { return null; } - class RegisterActivityCallback extends BaseCallback { - public static final String PACKAGE_NAME = "package_name"; - - private boolean allowed = false; - private String packageName; - - public boolean isAllowed() { - return allowed; - } - - public String getPackageName() { - return packageName; - } - - @Override - public boolean handleMessage(Message msg) { - if (msg.arg1 == OKAY) { - allowed = true; - packageName = msg.getData().getString(PACKAGE_NAME); - - // resume threads - try { - if (isPackageAllowed(packageName)) { - synchronized (userInputLock) { - userInputLock.notifyAll(); - } - mThreadPool.resume(); - } else { - // Should not happen! - Log.e(Constants.TAG, "Should not happen! Emergency shutdown!"); - mThreadPool.shutdownNow(); - } - } catch (WrongPackageSignatureException e) { - Log.e(Constants.TAG, e.getMessage()); - - Bundle extras = new Bundle(); - extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, - getString(R.string.api_error_wrong_signature)); - pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, - extras); - } - } else { - allowed = false; - - synchronized (userInputLock) { - userInputLock.notifyAll(); - } - mThreadPool.resume(); - } - return true; - } - - } +// class RegisterActivityCallback extends BaseCallback { +// public static final String PACKAGE_NAME = "package_name"; +// +// private boolean allowed = false; +// private String packageName; +// +// public boolean isAllowed() { +// return allowed; +// } +// +// public String getPackageName() { +// return packageName; +// } +// +// @Override +// public boolean handleMessage(Message msg) { +// if (msg.arg1 == OKAY) { +// allowed = true; +// packageName = msg.getData().getString(PACKAGE_NAME); +// +// // resume threads +// try { +// if (isPackageAllowed(packageName)) { +// synchronized (userInputLock) { +// userInputLock.notifyAll(); +// } +// mThreadPool.resume(); +// } else { +// // Should not happen! +// Log.e(Constants.TAG, "Should not happen! Emergency shutdown!"); +// mThreadPool.shutdownNow(); +// } +// } catch (WrongPackageSignatureException e) { +// Log.e(Constants.TAG, e.getMessage()); +// +// Bundle extras = new Bundle(); +// extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, +// getString(R.string.api_error_wrong_signature)); +// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, +// extras); +// } +// } else { +// allowed = false; +// +// synchronized (userInputLock) { +// userInputLock.notifyAll(); +// } +// mThreadPool.resume(); +// } +// return true; +// } +// +// } /** * Checks if process that binds to this service (i.e. the package name corresponding to the diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java index 8f5b74650..af8e3ade8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteServiceActivity.java @@ -22,7 +22,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; -import android.os.RemoteException; import android.support.v7.app.ActionBarActivity; import android.view.View; @@ -64,17 +63,11 @@ public class RemoteServiceActivity extends ActionBarActivity { // error message public static final String EXTRA_ERROR_MESSAGE = "error_message"; - private Messenger mMessenger; - // register view private AppSettingsFragment mSettingsFragment; // select pub keys view private SelectPublicKeyFragment mSelectFragment; - // has the user clicked one of the buttons - // or do we need to handle the callback in onStop() - private boolean finishHandled; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -82,32 +75,12 @@ public class RemoteServiceActivity extends ActionBarActivity { handleActions(getIntent(), savedInstanceState); } - @Override - protected void onStop() { - super.onStop(); - - if (!finishHandled && mMessenger != null) { - Message msg = Message.obtain(); - msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL; - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.e(Constants.TAG, "CryptoServiceActivity", e); - } - } - } - protected void handleActions(Intent intent, Bundle savedInstanceState) { - finishHandled = false; String action = intent.getAction(); final Bundle extras = intent.getExtras(); - mMessenger = extras.getParcelable(EXTRA_MESSENGER); - /** - * com.android.crypto actions - */ if (ACTION_REGISTER.equals(action)) { final String packageName = extras.getString(EXTRA_PACKAGE_NAME); final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE); @@ -127,37 +100,21 @@ public class RemoteServiceActivity extends ActionBarActivity { ProviderHelper.insertApiApp(RemoteServiceActivity.this, mSettingsFragment.getAppSettings()); - Message msg = Message.obtain(); - msg.arg1 = RemoteService.RegisterActivityCallback.OKAY; - Bundle data = new Bundle(); - data.putString(RemoteService.RegisterActivityCallback.PACKAGE_NAME, - packageName); - msg.setData(data); - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.e(Constants.TAG, "CryptoServiceActivity", e); - } - - finishHandled = true; - finish(); + // give params through for new service call + Bundle oldParams = extras.getBundle(OpenPgpConstants.PI_RESULT_PARAMS); + + Intent finishIntent = new Intent(); + finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, oldParams); + RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent); + RemoteServiceActivity.this.finish(); } } }, R.string.api_register_disallow, new View.OnClickListener() { @Override public void onClick(View v) { // Disallow - - Message msg = Message.obtain(); - msg.arg1 = RemoteService.RegisterActivityCallback.CANCEL; - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.e(Constants.TAG, "CryptoServiceActivity", e); - } - - finishHandled = true; - finish(); + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); } } ); @@ -216,15 +173,15 @@ public class RemoteServiceActivity extends ActionBarActivity { Intent finishIntent = new Intent(); finishIntent.putExtra(OpenPgpConstants.PI_RESULT_PARAMS, params); - setResult(RESULT_OK, finishIntent); - finish(); + RemoteServiceActivity.this.setResult(RESULT_OK, finishIntent); + RemoteServiceActivity.this.finish(); } }, R.string.btn_do_not_save, new View.OnClickListener() { @Override public void onClick(View v) { // cancel - setResult(RESULT_CANCELED); - finish(); + RemoteServiceActivity.this.setResult(RESULT_CANCELED); + RemoteServiceActivity.this.finish(); } } ); @@ -265,8 +222,8 @@ public class RemoteServiceActivity extends ActionBarActivity { @Override public void onClick(View v) { - setResult(RESULT_OK); - finish(); + RemoteServiceActivity.this.setResult(RESULT_OK); + RemoteServiceActivity.this.finish(); } }); @@ -276,7 +233,7 @@ public class RemoteServiceActivity extends ActionBarActivity { HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_app_error_message_text); textView.setHtmlFromString(text); } else { - Log.e(Constants.TAG, "Wrong action!"); + Log.e(Constants.TAG, "Action does not exist!"); setResult(RESULT_CANCELED); finish(); } -- cgit v1.2.3 From d5824e67402b31c0a00b8ab7bbb8f834c0899d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 17 Feb 2014 19:50:07 +0100 Subject: cleanup --- .../keychain/service/remote/OpenPgpService.java | 19 +--- .../keychain/service/remote/RemoteService.java | 123 +-------------------- 2 files changed, 2 insertions(+), 140 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index e676b6633..31c5662dc 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -460,7 +460,7 @@ public class OpenPgpService extends RemoteService { return null; } - // TODO: enqueue in thread pool!!! + // TODO: multi-threading private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() { @Override @@ -521,23 +521,6 @@ public class OpenPgpService extends RemoteService { return getKeyIdsImpl(params); } - // TODO: old example for checkAndEnqueue! -// @Override -// public void getKeyIds(final String[] userIds, final boolean allowUserInteraction, -// final IOpenPgpKeyIdsCallback callback) throws RemoteException { -// -// final AppSettings settings = getAppSettings(); -// -// Runnable r = new Runnable() { -// @Override -// public void run() { -// getKeyIdsSafe(userIds, allowUserInteraction, callback, settings); -// } -// }; -// -// checkAndEnqueue(r); -// } - }; @Override diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java index bfea70381..cfd2b9ec3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/RemoteService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Dominik Schürmann + * Copyright (C) 2013-2014 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 @@ -19,8 +19,6 @@ package org.sufficientlysecure.keychain.service.remote; import java.util.ArrayList; import java.util.Arrays; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.TimeUnit; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.util.OpenPgpConstants; @@ -29,7 +27,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.PausableThreadPoolExecutor; import android.app.PendingIntent; import android.app.Service; @@ -52,31 +49,10 @@ import android.os.Messenger; public abstract class RemoteService extends Service { Context mContext; - private final ArrayBlockingQueue mPoolQueue = new ArrayBlockingQueue(100); - // TODO: Are these parameters okay? - private PausableThreadPoolExecutor mThreadPool = new PausableThreadPoolExecutor(2, 4, 10, - TimeUnit.SECONDS, mPoolQueue); - - private final Object userInputLock = new Object(); - private static final int PRIVATE_REQUEST_CODE_REGISTER = 651; private static final int PRIVATE_REQUEST_CODE_ERROR = 652; - /** - * Extends Handler.Callback with OKAY (1), CANCEL (0) variables - */ - private class BaseCallback implements Handler.Callback { - public static final int OKAY = 1; - public static final int CANCEL = 0; - - @Override - public boolean handleMessage(Message msg) { - return false; - } - - } - public Context getContext() { return mContext; } @@ -84,10 +60,8 @@ public abstract class RemoteService extends Service { protected Bundle isAllowed(Bundle params) { try { if (isCallerAllowed(false)) { -// mThreadPool.execute(r); return null; -// Log.d(Constants.TAG, "Enqueued runnable…"); } else { String[] callingPackages = getPackageManager().getPackagesForUid( Binder.getCallingUid()); @@ -121,15 +95,7 @@ public abstract class RemoteService extends Service { result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED); result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); -// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_REGISTER, callback, -// extras); return result; -// if (callback.isAllowed()) { -// mThreadPool.execute(r); -// Log.d(Constants.TAG, "Enqueued runnable…"); -// } else { -// Log.d(Constants.TAG, "User disallowed app!"); -// } } } catch (WrongPackageSignatureException e) { Log.e(Constants.TAG, "wrong signature!", e); @@ -147,11 +113,6 @@ public abstract class RemoteService extends Service { result.putParcelable(OpenPgpConstants.RESULT_INTENT, pi); return result; - -// Bundle extras = new Bundle(); -// extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, -// getString(R.string.api_error_wrong_signature)); -// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, extras); } } @@ -165,34 +126,6 @@ public abstract class RemoteService extends Service { return packageSignature; } - /** - * Locks current thread and pauses execution of runnables and starts activity for user input - */ -// protected void pauseAndStartUserInteraction(String action, BaseCallback callback, Bundle extras) { -// synchronized (userInputLock) { -// mThreadPool.pause(); -// -// Log.d(Constants.TAG, "starting activity..."); -// Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class); -// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -// intent.setAction(action); -// -// Messenger messenger = new Messenger(new Handler(getMainLooper(), callback)); -// -// extras.putParcelable(RemoteServiceActivity.EXTRA_MESSENGER, messenger); -// intent.putExtras(extras); -// -// startActivity(intent); -// -// // lock current thread for user input -// try { -// userInputLock.wait(); -// } catch (InterruptedException e) { -// Log.e(Constants.TAG, "CryptoService", e); -// } -// } -// } - /** * Retrieves AppSettings from database for the application calling this remote service * @@ -216,60 +149,6 @@ public abstract class RemoteService extends Service { return null; } -// class RegisterActivityCallback extends BaseCallback { -// public static final String PACKAGE_NAME = "package_name"; -// -// private boolean allowed = false; -// private String packageName; -// -// public boolean isAllowed() { -// return allowed; -// } -// -// public String getPackageName() { -// return packageName; -// } -// -// @Override -// public boolean handleMessage(Message msg) { -// if (msg.arg1 == OKAY) { -// allowed = true; -// packageName = msg.getData().getString(PACKAGE_NAME); -// -// // resume threads -// try { -// if (isPackageAllowed(packageName)) { -// synchronized (userInputLock) { -// userInputLock.notifyAll(); -// } -// mThreadPool.resume(); -// } else { -// // Should not happen! -// Log.e(Constants.TAG, "Should not happen! Emergency shutdown!"); -// mThreadPool.shutdownNow(); -// } -// } catch (WrongPackageSignatureException e) { -// Log.e(Constants.TAG, e.getMessage()); -// -// Bundle extras = new Bundle(); -// extras.putString(RemoteServiceActivity.EXTRA_ERROR_MESSAGE, -// getString(R.string.api_error_wrong_signature)); -// pauseAndStartUserInteraction(RemoteServiceActivity.ACTION_ERROR_MESSAGE, null, -// extras); -// } -// } else { -// allowed = false; -// -// synchronized (userInputLock) { -// userInputLock.notifyAll(); -// } -// mThreadPool.resume(); -// } -// return true; -// } -// -// } - /** * Checks if process that binds to this service (i.e. the package name corresponding to the * process) is in the list of allowed package names. -- cgit v1.2.3 From 7a04dfe6bfc6bdfdbe75aebeef321464b87db155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 17 Feb 2014 20:16:58 +0100 Subject: prevent key view from scrolling, move encrypt button down again --- .../src/main/res/layout/view_key_main_fragment.xml | 38 ++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml index 3cbea3e9b..9a2b768a2 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml @@ -3,9 +3,13 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + @@ -76,23 +80,6 @@ - - - - + + + + \ No newline at end of file -- cgit v1.2.3 From 439c7a66f2bf22b822b6db219fee0334a3da9a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 17 Feb 2014 20:18:17 +0100 Subject: fix margins --- OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml index 9a2b768a2..055687183 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml @@ -201,8 +201,7 @@ + android:layout_height="wrap_content" /> -- cgit v1.2.3 From 0597b50258c4cfc9e0af6003b069dadff0d6203d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 17 Feb 2014 20:41:54 +0100 Subject: documentation --- .../sufficientlysecure/keychain/service/remote/OpenPgpService.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 31c5662dc..f6aaffbf6 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -427,10 +427,13 @@ public class OpenPgpService extends RemoteService { } /** - * Checks that params != null and API version fits + * Check requirements: + * - params != null + * - has supported API version + * - is allowed to call the service (access has been granted) * * @param params - * @return + * @return null if everything is okay, or a Bundle with an error/PendingIntent */ private Bundle checkRequirements(Bundle params) { // params Bundle is required! -- cgit v1.2.3 From 708d0c9a5ab76219c4ddff73324d814eda5d3873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 18 Feb 2014 13:19:41 +0100 Subject: better error check --- .../keychain/service/remote/OpenPgpService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index f6aaffbf6..d765f28cb 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -190,7 +190,7 @@ public class OpenPgpService extends RemoteService { long[] keyIds; if (params.containsKey(OpenPgpConstants.PARAMS_KEY_IDS)) { keyIds = params.getLongArray(OpenPgpConstants.PARAMS_KEY_IDS); - } else { + } else if (params.containsKey(OpenPgpConstants.PARAMS_USER_IDS)) { // get key ids based on given user ids String[] userIds = params.getStringArray(OpenPgpConstants.PARAMS_USER_IDS); // give params through to activity... @@ -202,6 +202,12 @@ public class OpenPgpService extends RemoteService { // if not success -> result contains a PendingIntent for user interaction return result; } + } else { + Bundle result = new Bundle(); + result.putInt(OpenPgpConstants.RESULT_CODE, OpenPgpConstants.RESULT_CODE_ERROR); + result.putParcelable(OpenPgpConstants.RESULT_ERRORS, + new OpenPgpError(OpenPgpError.GENERIC_ERROR, "Missing parameter user_ids or key_ids!")); + return result; } // add own key for encryption -- cgit v1.2.3 From 9b4245739e1d89265114c22208cf338e35bd95a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 18 Feb 2014 22:47:26 +0100 Subject: merge internal signText and signAndEncrypt methods --- .../keychain/pgp/PgpOperation.java | 409 +++++++++------------ .../keychain/service/remote/OpenPgpService.java | 13 +- OpenPGP-Keychain/src/main/res/values/strings.xml | 2 +- 3 files changed, 193 insertions(+), 231 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java index 1b08b65a1..5a3963f42 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java @@ -98,7 +98,7 @@ public class PgpOperation { private OutputStream mOutStream; public PgpOperation(Context context, ProgressDialogUpdater progress, InputData data, - OutputStream outStream) { + OutputStream outStream) { super(); this.mContext = context; this.mProgress = progress; @@ -118,9 +118,10 @@ public class PgpOperation { } } - public void signAndEncrypt(boolean useAsciiArmor, int compression, long[] encryptionKeyIds, - String encryptionPassphrase, int symmetricEncryptionAlgorithm, long signatureKeyId, - int signatureHashAlgorithm, boolean signatureForceV3, String signaturePassphrase) + public void signAndEncrypt(boolean enableAsciiArmor, int compressionId, long[] encryptionKeyIds, + String encryptionPassphrase, int symmetricEncryptionAlgorithm, + long signatureKeyId, int signatureHashAlgorithm, + boolean signatureForceV3, String signaturePassphrase) throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { @@ -128,26 +129,34 @@ public class PgpOperation { encryptionKeyIds = new long[0]; } + boolean enableSignature = signatureKeyId != Id.key.none; + boolean enableCompression = compressionId == Id.choice.compression.none; + boolean enableEncryption = encryptionKeyIds.length != 0 || encryptionPassphrase != null; + + int signatureType; + // TODO: disable when encrypting??? + if (enableAsciiArmor && enableSignature && !enableEncryption) { + signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; + } else { + signatureType = PGPSignature.BINARY_DOCUMENT; + } + ArmoredOutputStream armorOut = null; - OutputStream out = null; - OutputStream encryptOut = null; - if (useAsciiArmor) { + OutputStream out; + OutputStream encryptionOut = null; + if (enableAsciiArmor) { armorOut = new ArmoredOutputStream(mOutStream); armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); out = armorOut; } else { out = mOutStream; } + + PGPSecretKey signingKey = null; PGPSecretKeyRing signingKeyRing = null; PGPPrivateKey signaturePrivateKey = null; - - if (encryptionKeyIds.length == 0 && encryptionPassphrase == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_no_encryption_keys_or_passphrase)); - } - - if (signatureKeyId != Id.key.none) { + if (enableSignature) { signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, signatureKeyId); signingKey = PgpKeyHelper.getSigningKey(mContext, signatureKeyId); if (signingKey == null) { @@ -172,50 +181,51 @@ public class PgpOperation { updateProgress(R.string.progress_preparing_streams, 5, 100); // encrypt and compress input file content - JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder( - symmetricEncryptionAlgorithm).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) - .setWithIntegrityPacket(true); + if (enableEncryption) { + JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder( + symmetricEncryptionAlgorithm).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) + .setWithIntegrityPacket(true); - PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); - if (encryptionKeyIds.length == 0) { - // Symmetric encryption - Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); + if (encryptionKeyIds.length == 0) { + // Symmetric encryption + Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); - JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = new JcePBEKeyEncryptionMethodGenerator( - encryptionPassphrase.toCharArray()); - cPk.addMethod(symmetricEncryptionGenerator); - } else { - // Asymmetric encryption - for (long id : encryptionKeyIds) { - PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id); - if (key != null) { - - JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator( - key); - cPk.addMethod(pubKeyEncryptionGenerator); + JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = new JcePBEKeyEncryptionMethodGenerator( + encryptionPassphrase.toCharArray()); + cPk.addMethod(symmetricEncryptionGenerator); + } else { + // Asymmetric encryption + for (long id : encryptionKeyIds) { + PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id); + if (key != null) { + + JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator( + key); + cPk.addMethod(pubKeyEncryptionGenerator); + } } } + encryptionOut = cPk.open(out, new byte[1 << 16]); } - encryptOut = cPk.open(out, new byte[1 << 16]); PGPSignatureGenerator signatureGenerator = null; PGPV3SignatureGenerator signatureV3Generator = null; - - if (signatureKeyId != Id.key.none) { + if (enableSignature) { updateProgress(R.string.progress_preparing_signature, 10, 100); - // content signer based on signing key algorithm and choosen hash algorithm + // content signer based on signing key algorithm and chosen hash algorithm JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); if (signatureForceV3) { signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); - signatureV3Generator.init(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey); + signatureV3Generator.init(signatureType, signaturePrivateKey); } else { signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, signaturePrivateKey); + signatureGenerator.init(signatureType, signaturePrivateKey); String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper .getMasterKey(signingKeyRing)); @@ -226,200 +236,156 @@ public class PgpOperation { } PGPCompressedDataGenerator compressGen = null; - BCPGOutputStream bcpgOut = null; - if (compression == Id.choice.compression.none) { - bcpgOut = new BCPGOutputStream(encryptOut); - } else { - compressGen = new PGPCompressedDataGenerator(compression); - bcpgOut = new BCPGOutputStream(compressGen.open(encryptOut)); - } - if (signatureKeyId != Id.key.none) { - if (signatureForceV3) { - signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); + OutputStream pOut; + if (enableEncryption) { + BCPGOutputStream bcpgOut; + if (enableCompression) { + compressGen = new PGPCompressedDataGenerator(compressionId); + bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); } else { - signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); + bcpgOut = new BCPGOutputStream(encryptionOut); } - } - PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); - // file name not needed, so empty string - OutputStream pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), - new byte[1 << 16]); - updateProgress(R.string.progress_encrypting, 20, 100); - - long done = 0; - int n = 0; - byte[] buffer = new byte[1 << 16]; - InputStream in = mData.getInputStream(); - while ((n = in.read(buffer)) > 0) { - pOut.write(buffer, 0, n); - if (signatureKeyId != Id.key.none) { + if (enableSignature) { if (signatureForceV3) { - signatureV3Generator.update(buffer, 0, n); + signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); } else { - signatureGenerator.update(buffer, 0, n); + signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); } } - done += n; - if (mData.getSize() != 0) { - updateProgress((int) (20 + (95 - 20) * done / mData.getSize()), 100); - } - } - - literalGen.close(); - - if (signatureKeyId != Id.key.none) { - updateProgress(R.string.progress_generating_signature, 95, 100); - if (signatureForceV3) { - signatureV3Generator.generate().encode(pOut); - } else { - signatureGenerator.generate().encode(pOut); - } - } - if (compressGen != null) { - compressGen.close(); - } - encryptOut.close(); - if (useAsciiArmor) { - armorOut.close(); - } - - updateProgress(R.string.progress_done, 100, 100); - } - public void signText(long signatureKeyId, String signaturePassphrase, - int signatureHashAlgorithm, boolean forceV3Signature) throws PgpGeneralException, - PGPException, IOException, NoSuchAlgorithmException, SignatureException { + PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); + // file name not needed, so empty string + pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), + new byte[1 << 16]); + updateProgress(R.string.progress_encrypting, 20, 100); - ArmoredOutputStream armorOut = new ArmoredOutputStream(mOutStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); + long progress = 0; + int n; + byte[] buffer = new byte[1 << 16]; + InputStream in = mData.getInputStream(); + while ((n = in.read(buffer)) > 0) { + pOut.write(buffer, 0, n); + + // update signature buffer if signature is requested + if (enableSignature) { + if (signatureForceV3) { + signatureV3Generator.update(buffer, 0, n); + } else { + signatureGenerator.update(buffer, 0, n); + } + } - PGPSecretKey signingKey = null; - PGPSecretKeyRing signingKeyRing = null; - PGPPrivateKey signaturePrivateKey = null; + progress += n; + if (mData.getSize() != 0) { + updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100); + } + } - if (signatureKeyId == 0) { - armorOut.close(); - throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_key)); - } + literalGen.close(); + } else if (enableAsciiArmor && enableSignature && !enableEncryption && !enableCompression) { + /* sign-only of ascii text */ - signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, signatureKeyId); - signingKey = PgpKeyHelper.getSigningKey(mContext, signatureKeyId); - if (signingKey == null) { - armorOut.close(); - throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); - } + updateProgress(R.string.progress_signing, 40, 100); - if (signaturePassphrase == null) { - armorOut.close(); - throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_passphrase)); - } - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); - signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - armorOut.close(); - throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); - } - updateProgress(R.string.progress_preparing_streams, 0, 100); - - updateProgress(R.string.progress_preparing_signature, 30, 100); + // write directly on armor output stream + armorOut.beginClearText(signatureHashAlgorithm); - PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; + InputStream in = mData.getInputStream(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - // content signer based on signing key algorithm and choosen hash algorithm - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey - .getPublicKey().getAlgorithm(), signatureHashAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - if (forceV3Signature) { - signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); - signatureV3Generator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey); - } else { - signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, signaturePrivateKey); + final byte[] newline = "\r\n".getBytes("UTF-8"); - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); - spGen.setSignerUserID(false, userId); - signatureGenerator.setHashedSubpackets(spGen.generate()); - } + if (signatureForceV3) { + processLine(reader.readLine(), armorOut, signatureV3Generator); + } else { + processLine(reader.readLine(), armorOut, signatureGenerator); + } - updateProgress(R.string.progress_signing, 40, 100); + while (true) { + String line = reader.readLine(); - armorOut.beginClearText(signatureHashAlgorithm); + if (line == null) { + armorOut.write(newline); + break; + } - InputStream inStream = mData.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); + armorOut.write(newline); + if (signatureForceV3) { + signatureV3Generator.update(newline); + processLine(line, armorOut, signatureV3Generator); + } else { + signatureGenerator.update(newline); + processLine(line, armorOut, signatureGenerator); + } + } - final byte[] newline = "\r\n".getBytes("UTF-8"); + armorOut.endClearText(); - if (forceV3Signature) { - processLine(reader.readLine(), armorOut, signatureV3Generator); + pOut = new BCPGOutputStream(armorOut); } else { - processLine(reader.readLine(), armorOut, signatureGenerator); + // TODO: implement sign-only for files! + pOut = null; + Log.e(Constants.TAG, "not supported!"); } - while (true) { - final String line = reader.readLine(); - - if (line == null) { - armorOut.write(newline); - break; - } - - armorOut.write(newline); - if (forceV3Signature) { - signatureV3Generator.update(newline); - processLine(line, armorOut, signatureV3Generator); + if (enableSignature) { + updateProgress(R.string.progress_generating_signature, 95, 100); + if (signatureForceV3) { + signatureV3Generator.generate().encode(pOut); } else { - signatureGenerator.update(newline); - processLine(line, armorOut, signatureGenerator); + signatureGenerator.generate().encode(pOut); } } - armorOut.endClearText(); + // closing outputs... + if (enableEncryption) { + encryptionOut.close(); - BCPGOutputStream bOut = new BCPGOutputStream(armorOut); - if (forceV3Signature) { - signatureV3Generator.generate().encode(bOut); - } else { - signatureGenerator.generate().encode(bOut); + if (enableCompression) { + compressGen.close(); + } + } + if (enableAsciiArmor) { + armorOut.close(); } - armorOut.close(); updateProgress(R.string.progress_done, 100, 100); } - public void generateSignature(boolean armored, boolean binary, long signatureKeyId, - String signaturePassPhrase, int hashAlgorithm, boolean forceV3Signature) + public void signText(long signatureKeyId, String signaturePassphrase, + int signatureHashAlgorithm, boolean forceV3Signature) throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, SignatureException { - OutputStream out = null; + try { + signAndEncrypt(true, 0, null, null, 0, signatureKeyId, signatureHashAlgorithm, forceV3Signature, signaturePassphrase); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } + } - // Ascii Armor (Base64) - ArmoredOutputStream armorOut = null; + public void generateSignature(boolean armored, boolean binary, long signatureKeyId, + String signaturePassPhrase, int hashAlgorithm, boolean forceV3Signature) + throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, + SignatureException { + + OutputStream out; if (armored) { - armorOut = new ArmoredOutputStream(mOutStream); + // Ascii Armor (Radix-64) + ArmoredOutputStream armorOut = new ArmoredOutputStream(mOutStream); armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); out = armorOut; } else { out = mOutStream; } - PGPSecretKey signingKey = null; - PGPSecretKeyRing signingKeyRing = null; - PGPPrivateKey signaturePrivateKey = null; - if (signatureKeyId == 0) { throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_key)); } - signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, signatureKeyId); - signingKey = PgpKeyHelper.getSigningKey(mContext, signatureKeyId); + PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, signatureKeyId); + PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, signatureKeyId); if (signingKey == null) { throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); } @@ -430,7 +396,7 @@ public class PgpOperation { PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray()); - signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); + PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); if (signaturePrivateKey == null) { throw new PgpGeneralException( mContext.getString(R.string.error_could_not_extract_private_key)); @@ -439,19 +405,18 @@ public class PgpOperation { updateProgress(R.string.progress_preparing_signature, 30, 100); - PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; - int type = PGPSignature.CANONICAL_TEXT_DOCUMENT; if (binary) { type = PGPSignature.BINARY_DOCUMENT; } - // content signer based on signing key algorithm and choosen hash algorithm + // content signer based on signing key algorithm and chosen hash algorithm JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey .getPublicKey().getAlgorithm(), hashAlgorithm) .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureGenerator signatureGenerator = null; + PGPV3SignatureGenerator signatureV3Generator = null; if (forceV3Signature) { signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); signatureV3Generator.init(type, signaturePrivateKey); @@ -482,13 +447,8 @@ public class PgpOperation { final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); final byte[] newline = "\r\n".getBytes("UTF-8"); - while (true) { - final String line = reader.readLine(); - - if (line == null) { - break; - } - + String line; + while ((line = reader.readLine()) != null) { if (forceV3Signature) { processLine(line, null, signatureV3Generator); signatureV3Generator.update(newline); @@ -508,8 +468,7 @@ public class PgpOperation { out.close(); mOutStream.close(); - if (mProgress != null) - mProgress.setProgress(R.string.progress_done, 100, 100); + updateProgress(R.string.progress_done, 100, 100); } public static boolean hasSymmetricEncryption(Context context, InputStream inputStream) @@ -548,11 +507,11 @@ public class PgpOperation { } Bundle returnData = new Bundle(); + // automatically works with ascii armor input and binary InputStream in = PGPUtil.getDecoderStream(mData.getInputStream()); PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); - long signatureKeyId = 0; int currentProgress = 0; updateProgress(R.string.progress_reading_data, currentProgress, 100); @@ -669,6 +628,7 @@ public class PgpOperation { currentProgress += 10; } + long signatureKeyId = 0; if (dataChunk instanceof PGPOnePassSignatureList) { updateProgress(R.string.progress_processing_signature, currentProgress, 100); @@ -798,7 +758,7 @@ public class PgpOperation { updateProgress(R.string.progress_done, 0, 100); - // mostly taken from ClearSignedFileProcessor + // mostly taken from pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); int lookAhead = readInputLine(lineOut, aIn); byte[] lineSep = getLineSeparator(); @@ -895,8 +855,7 @@ public class PgpOperation { return returnData; } - public boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) - { + public boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { long signatureKeyId = signature.getKeyID(); boolean keyBinding_isok = false; String userId = null; @@ -914,8 +873,7 @@ public class PgpOperation { return keyBinding_isok; } - public boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) - { + public boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean subkeyBinding_isok = false; boolean tmp_subkeyBinding_isok = false; boolean primkeyBinding_isok = false; @@ -935,8 +893,8 @@ public class PgpOperation { if (sig.getKeyID() == masterPublicKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { //check and if ok, check primary key binding. try { - sig.init(contentVerifierBuilderProvider, masterPublicKey); - tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey); + sig.init(contentVerifierBuilderProvider, masterPublicKey); + tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey); } catch (PGPException e) { continue; } catch (SignatureException e) { @@ -958,42 +916,41 @@ public class PgpOperation { return (subkeyBinding_isok & primkeyBinding_isok); } - private boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) - { + private boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean primkeyBinding_isok = false; JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); PGPSignatureList eSigList; - if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { - try { - eSigList = Pkts.getEmbeddedSignatures(); - } catch (IOException e) { - return false; - } catch (PGPException e) { - return false; + if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { + try { + eSigList = Pkts.getEmbeddedSignatures(); + } catch (IOException e) { + return false; + } catch (PGPException e) { + return false; } - for (int j = 0; j < eSigList.size(); ++j) { - PGPSignature emSig = eSigList.get(j); - if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { + for (int j = 0; j < eSigList.size(); ++j) { + PGPSignature emSig = eSigList.get(j); + if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { try { - emSig.init(contentVerifierBuilderProvider, signingPublicKey); - primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; + emSig.init(contentVerifierBuilderProvider, signingPublicKey); + primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; } catch (PGPException e) { continue; } catch (SignatureException e) { continue; } - } - } + } + } } return primkeyBinding_isok; } private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException { + final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException { if (pLine == null) { return; @@ -1018,7 +975,7 @@ public class PgpOperation { } private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPV3SignatureGenerator pSignatureGenerator) throws IOException, + final PGPV3SignatureGenerator pSignatureGenerator) throws IOException, SignatureException { if (pLine == null) { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index d765f28cb..b13c8ac49 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -29,6 +29,7 @@ import org.openintents.openpgp.IOpenPgpService; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpConstants; +import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; @@ -237,10 +238,12 @@ public class OpenPgpService extends RemoteService { return passphraseBundle; } + // sign and encrypt operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(), appSettings.getHashAlgorithm(), true, passphrase); } else { + // encrypt only operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, appSettings.getEncryptionAlgorithm(), Id.key.none, appSettings.getHashAlgorithm(), true, null); @@ -271,7 +274,7 @@ public class OpenPgpService extends RemoteService { OpenPgpSignatureResult sigResult = null; try { - +// PGPUtil.getDecoderStream(is) // TODOs API 2.0: // implement verify-only! // fix the mess: http://stackoverflow.com/questions/148130/how-do-i-peek-at-the-first-two-bytes-in-an-inputstream @@ -351,7 +354,7 @@ public class OpenPgpService extends RemoteService { // // Log.d(Constants.TAG, "secretKeyId " + secretKeyId); - // NOTE: currently this only gets the passphrase for the saved key + // NOTE: currently this only gets the passphrase for the key set for this client String passphrase; if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) { passphrase = params.getString(OpenPgpConstants.PARAMS_PASSPHRASE); @@ -375,8 +378,10 @@ public class OpenPgpService extends RemoteService { if (signedOnly) { outputBundle = operation.verifyText(); } else { - // BIG TODO: instead of trying to get the passphrase before - // pause stream when passphrase is missing and then resume + // Do we want to do this: instead of trying to get the passphrase before + // pause stream when passphrase is missing and then resume??? + + // TODO: this also decrypts with other secret keys without passphrase!!! outputBundle = operation.decryptAndVerify(passphrase, false); } diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index d34fe0105..dcd9706ed 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -116,7 +116,7 @@ Passphrase Cache Message Compression File Compression - Force V3 Signatures + Force old OpenPGPv3 Signatures Keyservers Key ID Creation -- cgit v1.2.3 From d23950f7990da094019f82d4a6e1698a389d2f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 18 Feb 2014 22:59:00 +0100 Subject: add integrity check --- .../keychain/pgp/PgpOperation.java | 34 ++++++++++++---------- OpenPGP-Keychain/src/main/res/values/strings.xml | 1 + 2 files changed, 20 insertions(+), 15 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java index 5a3963f42..50db814e3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java @@ -118,7 +118,7 @@ public class PgpOperation { } } - public void signAndEncrypt(boolean enableAsciiArmor, int compressionId, long[] encryptionKeyIds, + public void signAndEncrypt(boolean enableAsciiArmorOutput, int compressionId, long[] encryptionKeyIds, String encryptionPassphrase, int symmetricEncryptionAlgorithm, long signatureKeyId, int signatureHashAlgorithm, boolean signatureForceV3, String signaturePassphrase) @@ -135,7 +135,7 @@ public class PgpOperation { int signatureType; // TODO: disable when encrypting??? - if (enableAsciiArmor && enableSignature && !enableEncryption) { + if (enableAsciiArmorOutput && enableSignature && !enableEncryption) { signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; } else { signatureType = PGPSignature.BINARY_DOCUMENT; @@ -144,7 +144,7 @@ public class PgpOperation { ArmoredOutputStream armorOut = null; OutputStream out; OutputStream encryptionOut = null; - if (enableAsciiArmor) { + if (enableAsciiArmorOutput) { armorOut = new ArmoredOutputStream(mOutStream); armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); out = armorOut; @@ -182,9 +182,11 @@ public class PgpOperation { // encrypt and compress input file content if (enableEncryption) { - JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder( - symmetricEncryptionAlgorithm).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) - .setWithIntegrityPacket(true); + // has Integrity packet enabled! + JcePGPDataEncryptorBuilder encryptorBuilder = + new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) + .setWithIntegrityPacket(true); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); @@ -192,8 +194,8 @@ public class PgpOperation { // Symmetric encryption Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); - JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = new JcePBEKeyEncryptionMethodGenerator( - encryptionPassphrase.toCharArray()); + JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = + new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); cPk.addMethod(symmetricEncryptionGenerator); } else { // Asymmetric encryption @@ -201,8 +203,8 @@ public class PgpOperation { PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id); if (key != null) { - JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator( - key); + JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = + new JcePublicKeyKeyEncryptionMethodGenerator(key); cPk.addMethod(pubKeyEncryptionGenerator); } } @@ -227,8 +229,7 @@ public class PgpOperation { signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); signatureGenerator.init(signatureType, signaturePrivateKey); - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper - .getMasterKey(signingKeyRing)); + String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, userId); signatureGenerator.setHashedSubpackets(spGen.generate()); @@ -283,7 +284,7 @@ public class PgpOperation { } literalGen.close(); - } else if (enableAsciiArmor && enableSignature && !enableEncryption && !enableCompression) { + } else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { /* sign-only of ascii text */ updateProgress(R.string.progress_signing, 40, 100); @@ -346,7 +347,7 @@ public class PgpOperation { compressGen.close(); } } - if (enableAsciiArmor) { + if (enableAsciiArmorOutput) { armorOut.close(); } @@ -365,6 +366,7 @@ public class PgpOperation { } } + // TODO: merge this into signAndEncrypt method! public void generateSignature(boolean armored, boolean binary, long signatureKeyId, String signaturePassPhrase, int hashAlgorithm, boolean forceV3Signature) throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, @@ -732,7 +734,7 @@ public class PgpOperation { } } - // TODO: add integrity somewhere + // TODO: test if this integrity really check works! if (encryptedData.isIntegrityProtected()) { updateProgress(R.string.progress_verifying_integrity, 95, 100); @@ -740,9 +742,11 @@ public class PgpOperation { // passed } else { // failed + throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed)); } } else { // no integrity check + Log.e(Constants.TAG, "No integrity check!"); } updateProgress(R.string.progress_done, 100, 100); diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index dcd9706ed..b8a03a82d 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -274,6 +274,7 @@ no signature key given not valid encryption data corrupt data + integrity check failed! Data has been modified! couldn\'t find a packet with symmetric encryption wrong passphrase error saving some keys -- cgit v1.2.3 From 1710f4416f8363a43fb7174c54b61c6c18248eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 00:18:52 +0100 Subject: Use builder pattern for sign and encrypt --- .../keychain/pgp/PgpOperation.java | 1105 -------------------- .../keychain/pgp/PgpOperationIncoming.java | 683 ++++++++++++ .../keychain/pgp/PgpOperationOutgoing.java | 584 +++++++++++ .../keychain/service/KeychainIntentService.java | 49 +- .../keychain/service/remote/OpenPgpService.java | 40 +- .../keychain/ui/DecryptActivity.java | 4 +- 6 files changed, 1326 insertions(+), 1139 deletions(-) delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java deleted file mode 100644 index 50db814e3..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperation.java +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * Copyright (C) 2012-2013 Dominik Schürmann - * Copyright (C) 2010 Thialfihar - * - * 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.pgp; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SignatureException; -import java.util.Date; -import java.util.Iterator; - -import org.spongycastle.bcpg.ArmoredInputStream; -import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.bcpg.BCPGInputStream; -import org.spongycastle.bcpg.BCPGOutputStream; - -import org.spongycastle.bcpg.SignaturePacket; - -import org.spongycastle.bcpg.SignatureSubpacket; -import org.spongycastle.bcpg.SignatureSubpacketTags; -import org.spongycastle.openpgp.PGPCompressedData; -import org.spongycastle.openpgp.PGPCompressedDataGenerator; -import org.spongycastle.openpgp.PGPEncryptedData; -import org.spongycastle.openpgp.PGPEncryptedDataGenerator; -import org.spongycastle.openpgp.PGPEncryptedDataList; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPLiteralData; -import org.spongycastle.openpgp.PGPLiteralDataGenerator; -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPOnePassSignature; -import org.spongycastle.openpgp.PGPOnePassSignatureList; -import org.spongycastle.openpgp.PGPPBEEncryptedData; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.PGPSignatureGenerator; -import org.spongycastle.openpgp.PGPSignatureList; -import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; -import org.spongycastle.openpgp.PGPSignatureSubpacketVector; -import org.spongycastle.openpgp.PGPUtil; -import org.spongycastle.openpgp.PGPV3SignatureGenerator; -import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; -import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; -import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; -import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; - -import android.content.Context; -import android.os.Bundle; - -public class PgpOperation { - private Context mContext; - private ProgressDialogUpdater mProgress; - private InputData mData; - private OutputStream mOutStream; - - public PgpOperation(Context context, ProgressDialogUpdater progress, InputData data, - OutputStream outStream) { - super(); - this.mContext = context; - this.mProgress = progress; - this.mData = data; - this.mOutStream = outStream; - } - - public void updateProgress(int message, int current, int total) { - if (mProgress != null) { - mProgress.setProgress(message, current, total); - } - } - - public void updateProgress(int current, int total) { - if (mProgress != null) { - mProgress.setProgress(current, total); - } - } - - public void signAndEncrypt(boolean enableAsciiArmorOutput, int compressionId, long[] encryptionKeyIds, - String encryptionPassphrase, int symmetricEncryptionAlgorithm, - long signatureKeyId, int signatureHashAlgorithm, - boolean signatureForceV3, String signaturePassphrase) - throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, - NoSuchAlgorithmException, SignatureException { - - if (encryptionKeyIds == null) { - encryptionKeyIds = new long[0]; - } - - boolean enableSignature = signatureKeyId != Id.key.none; - boolean enableCompression = compressionId == Id.choice.compression.none; - boolean enableEncryption = encryptionKeyIds.length != 0 || encryptionPassphrase != null; - - int signatureType; - // TODO: disable when encrypting??? - if (enableAsciiArmorOutput && enableSignature && !enableEncryption) { - signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; - } else { - signatureType = PGPSignature.BINARY_DOCUMENT; - } - - ArmoredOutputStream armorOut = null; - OutputStream out; - OutputStream encryptionOut = null; - if (enableAsciiArmorOutput) { - armorOut = new ArmoredOutputStream(mOutStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); - out = armorOut; - } else { - out = mOutStream; - } - - - PGPSecretKey signingKey = null; - PGPSecretKeyRing signingKeyRing = null; - PGPPrivateKey signaturePrivateKey = null; - if (enableSignature) { - signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, signatureKeyId); - signingKey = PgpKeyHelper.getSigningKey(mContext, signatureKeyId); - if (signingKey == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); - } - - if (signaturePassphrase == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_no_signature_passphrase)); - } - - updateProgress(R.string.progress_extracting_signature_key, 0, 100); - - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); - signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); - } - } - updateProgress(R.string.progress_preparing_streams, 5, 100); - - // encrypt and compress input file content - if (enableEncryption) { - // has Integrity packet enabled! - JcePGPDataEncryptorBuilder encryptorBuilder = - new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) - .setWithIntegrityPacket(true); - - PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); - - if (encryptionKeyIds.length == 0) { - // Symmetric encryption - Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); - - JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = - new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); - cPk.addMethod(symmetricEncryptionGenerator); - } else { - // Asymmetric encryption - for (long id : encryptionKeyIds) { - PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(mContext, id); - if (key != null) { - - JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = - new JcePublicKeyKeyEncryptionMethodGenerator(key); - cPk.addMethod(pubKeyEncryptionGenerator); - } - } - } - encryptionOut = cPk.open(out, new byte[1 << 16]); - } - - PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; - if (enableSignature) { - updateProgress(R.string.progress_preparing_signature, 10, 100); - - // content signer based on signing key algorithm and chosen hash algorithm - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( - signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - if (signatureForceV3) { - signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); - signatureV3Generator.init(signatureType, signaturePrivateKey); - } else { - signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(signatureType, signaturePrivateKey); - - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - spGen.setSignerUserID(false, userId); - signatureGenerator.setHashedSubpackets(spGen.generate()); - } - } - - PGPCompressedDataGenerator compressGen = null; - OutputStream pOut; - if (enableEncryption) { - BCPGOutputStream bcpgOut; - if (enableCompression) { - compressGen = new PGPCompressedDataGenerator(compressionId); - bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); - } else { - bcpgOut = new BCPGOutputStream(encryptionOut); - } - - if (enableSignature) { - if (signatureForceV3) { - signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); - } else { - signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); - } - } - - PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); - // file name not needed, so empty string - pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), - new byte[1 << 16]); - updateProgress(R.string.progress_encrypting, 20, 100); - - long progress = 0; - int n; - byte[] buffer = new byte[1 << 16]; - InputStream in = mData.getInputStream(); - while ((n = in.read(buffer)) > 0) { - pOut.write(buffer, 0, n); - - // update signature buffer if signature is requested - if (enableSignature) { - if (signatureForceV3) { - signatureV3Generator.update(buffer, 0, n); - } else { - signatureGenerator.update(buffer, 0, n); - } - } - - progress += n; - if (mData.getSize() != 0) { - updateProgress((int) (20 + (95 - 20) * progress / mData.getSize()), 100); - } - } - - literalGen.close(); - } else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { - /* sign-only of ascii text */ - - updateProgress(R.string.progress_signing, 40, 100); - - // write directly on armor output stream - armorOut.beginClearText(signatureHashAlgorithm); - - InputStream in = mData.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - - final byte[] newline = "\r\n".getBytes("UTF-8"); - - if (signatureForceV3) { - processLine(reader.readLine(), armorOut, signatureV3Generator); - } else { - processLine(reader.readLine(), armorOut, signatureGenerator); - } - - while (true) { - String line = reader.readLine(); - - if (line == null) { - armorOut.write(newline); - break; - } - - armorOut.write(newline); - if (signatureForceV3) { - signatureV3Generator.update(newline); - processLine(line, armorOut, signatureV3Generator); - } else { - signatureGenerator.update(newline); - processLine(line, armorOut, signatureGenerator); - } - } - - armorOut.endClearText(); - - pOut = new BCPGOutputStream(armorOut); - } else { - // TODO: implement sign-only for files! - pOut = null; - Log.e(Constants.TAG, "not supported!"); - } - - if (enableSignature) { - updateProgress(R.string.progress_generating_signature, 95, 100); - if (signatureForceV3) { - signatureV3Generator.generate().encode(pOut); - } else { - signatureGenerator.generate().encode(pOut); - } - } - - // closing outputs... - if (enableEncryption) { - encryptionOut.close(); - - if (enableCompression) { - compressGen.close(); - } - } - if (enableAsciiArmorOutput) { - armorOut.close(); - } - - updateProgress(R.string.progress_done, 100, 100); - } - - public void signText(long signatureKeyId, String signaturePassphrase, - int signatureHashAlgorithm, boolean forceV3Signature) - throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, - SignatureException { - - try { - signAndEncrypt(true, 0, null, null, 0, signatureKeyId, signatureHashAlgorithm, forceV3Signature, signaturePassphrase); - } catch (NoSuchProviderException e) { - e.printStackTrace(); - } - } - - // TODO: merge this into signAndEncrypt method! - public void generateSignature(boolean armored, boolean binary, long signatureKeyId, - String signaturePassPhrase, int hashAlgorithm, boolean forceV3Signature) - throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, - SignatureException { - - OutputStream out; - if (armored) { - // Ascii Armor (Radix-64) - ArmoredOutputStream armorOut = new ArmoredOutputStream(mOutStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(mContext)); - out = armorOut; - } else { - out = mOutStream; - } - - if (signatureKeyId == 0) { - throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_key)); - } - - PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(mContext, signatureKeyId); - PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(mContext, signatureKeyId); - if (signingKey == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_signature_failed)); - } - - if (signaturePassPhrase == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_no_signature_passphrase)); - } - - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassPhrase.toCharArray()); - PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); - } - updateProgress(R.string.progress_preparing_streams, 0, 100); - - updateProgress(R.string.progress_preparing_signature, 30, 100); - - int type = PGPSignature.CANONICAL_TEXT_DOCUMENT; - if (binary) { - type = PGPSignature.BINARY_DOCUMENT; - } - - // content signer based on signing key algorithm and chosen hash algorithm - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey - .getPublicKey().getAlgorithm(), hashAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; - if (forceV3Signature) { - signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); - signatureV3Generator.init(type, signaturePrivateKey); - } else { - signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(type, signaturePrivateKey); - - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); - spGen.setSignerUserID(false, userId); - signatureGenerator.setHashedSubpackets(spGen.generate()); - } - - updateProgress(R.string.progress_signing, 40, 100); - - InputStream inStream = mData.getInputStream(); - if (binary) { - byte[] buffer = new byte[1 << 16]; - int n = 0; - while ((n = inStream.read(buffer)) > 0) { - if (forceV3Signature) { - signatureV3Generator.update(buffer, 0, n); - } else { - signatureGenerator.update(buffer, 0, n); - } - } - } else { - final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); - final byte[] newline = "\r\n".getBytes("UTF-8"); - - String line; - while ((line = reader.readLine()) != null) { - if (forceV3Signature) { - processLine(line, null, signatureV3Generator); - signatureV3Generator.update(newline); - } else { - processLine(line, null, signatureGenerator); - signatureGenerator.update(newline); - } - } - } - - BCPGOutputStream bOut = new BCPGOutputStream(out); - if (forceV3Signature) { - signatureV3Generator.generate().encode(bOut); - } else { - signatureGenerator.generate().encode(bOut); - } - out.close(); - mOutStream.close(); - - updateProgress(R.string.progress_done, 100, 100); - } - - public static boolean hasSymmetricEncryption(Context context, InputStream inputStream) - throws PgpGeneralException, IOException { - InputStream in = PGPUtil.getDecoderStream(inputStream); - PGPObjectFactory pgpF = new PGPObjectFactory(in); - PGPEncryptedDataList enc; - Object o = pgpF.nextObject(); - - // the first object might be a PGP marker packet. - if (o instanceof PGPEncryptedDataList) { - enc = (PGPEncryptedDataList) o; - } else { - enc = (PGPEncryptedDataList) pgpF.nextObject(); - } - - if (enc == null) { - throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); - } - - Iterator it = enc.getEncryptedDataObjects(); - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPBEEncryptedData) { - return true; - } - } - - return false; - } - - public Bundle decryptAndVerify(String passphrase, boolean assumeSymmetric) throws IOException, - PgpGeneralException, PGPException, SignatureException { - if (passphrase == null) { - passphrase = ""; - } - - Bundle returnData = new Bundle(); - // automatically works with ascii armor input and binary - InputStream in = PGPUtil.getDecoderStream(mData.getInputStream()); - PGPObjectFactory pgpF = new PGPObjectFactory(in); - PGPEncryptedDataList enc; - Object o = pgpF.nextObject(); - - int currentProgress = 0; - updateProgress(R.string.progress_reading_data, currentProgress, 100); - - if (o instanceof PGPEncryptedDataList) { - enc = (PGPEncryptedDataList) o; - } else { - enc = (PGPEncryptedDataList) pgpF.nextObject(); - } - - if (enc == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_invalid_data)); - } - - InputStream clear = null; - PGPEncryptedData encryptedData = null; - - currentProgress += 5; - - // TODO: currently we always only look at the first known key or symmetric encryption, - // there might be more... - if (assumeSymmetric) { - PGPPBEEncryptedData pbe = null; - Iterator it = enc.getEncryptedDataObjects(); - // find secret key - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPBEEncryptedData) { - pbe = (PGPPBEEncryptedData) obj; - break; - } - } - - if (pbe == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_no_symmetric_encryption_packet)); - } - - updateProgress(R.string.progress_preparing_streams, currentProgress, 100); - - PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); - PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( - digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); - - clear = pbe.getDataStream(decryptorFactory); - - encryptedData = pbe; - currentProgress += 5; - } else { - updateProgress(R.string.progress_finding_key, currentProgress, 100); - - PGPPublicKeyEncryptedData pbe = null; - PGPSecretKey secretKey = null; - Iterator it = enc.getEncryptedDataObjects(); - // find secret key - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPublicKeyEncryptedData) { - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; - secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); - if (secretKey != null) { - pbe = encData; - break; - } - } - } - - if (secretKey == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found)); - } - - currentProgress += 5; - updateProgress(R.string.progress_extracting_key, currentProgress, 100); - PGPPrivateKey privateKey = null; - try { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); - privateKey = secretKey.extractPrivateKey(keyDecryptor); - } catch (PGPException e) { - throw new PGPException(mContext.getString(R.string.error_wrong_passphrase)); - } - if (privateKey == null) { - throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); - } - currentProgress += 5; - updateProgress(R.string.progress_preparing_streams, currentProgress, 100); - - PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(privateKey); - - clear = pbe.getDataStream(decryptorFactory); - - encryptedData = pbe; - currentProgress += 5; - } - - PGPObjectFactory plainFact = new PGPObjectFactory(clear); - Object dataChunk = plainFact.nextObject(); - PGPOnePassSignature signature = null; - PGPPublicKey signatureKey = null; - int signatureIndex = -1; - - if (dataChunk instanceof PGPCompressedData) { - updateProgress(R.string.progress_decompressing_data, currentProgress, 100); - - PGPObjectFactory fact = new PGPObjectFactory( - ((PGPCompressedData) dataChunk).getDataStream()); - dataChunk = fact.nextObject(); - plainFact = fact; - currentProgress += 10; - } - - long signatureKeyId = 0; - if (dataChunk instanceof PGPOnePassSignatureList) { - updateProgress(R.string.progress_processing_signature, currentProgress, 100); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); - PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; - for (int i = 0; i < sigList.size(); ++i) { - signature = sigList.get(i); - signatureKey = ProviderHelper - .getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); - if (signatureKeyId == 0) { - signatureKeyId = signature.getKeyID(); - } - if (signatureKey == null) { - signature = null; - } else { - signatureIndex = i; - signatureKeyId = signature.getKeyID(); - String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( - mContext, signatureKeyId); - if (signKeyRing != null) { - userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); - } - returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); - break; - } - } - - returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); - - if (signature != null) { - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - signature.init(contentVerifierBuilderProvider, signatureKey); - } else { - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); - } - - dataChunk = plainFact.nextObject(); - currentProgress += 10; - } - - if (dataChunk instanceof PGPSignatureList) { - dataChunk = plainFact.nextObject(); - } - - if (dataChunk instanceof PGPLiteralData) { - updateProgress(R.string.progress_decrypting, currentProgress, 100); - - PGPLiteralData literalData = (PGPLiteralData) dataChunk; - OutputStream out = mOutStream; - - byte[] buffer = new byte[1 << 16]; - InputStream dataIn = literalData.getInputStream(); - - int startProgress = currentProgress; - int endProgress = 100; - if (signature != null) { - endProgress = 90; - } else if (encryptedData.isIntegrityProtected()) { - endProgress = 95; - } - int n = 0; - int done = 0; - long startPos = mData.getStreamPosition(); - while ((n = dataIn.read(buffer)) > 0) { - out.write(buffer, 0, n); - done += n; - if (signature != null) { - try { - signature.update(buffer, 0, n); - } catch (SignatureException e) { - returnData - .putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false); - signature = null; - } - } - // unknown size, but try to at least have a moving, slowing down progress bar - currentProgress = startProgress + (endProgress - startProgress) * done - / (done + 100000); - if (mData.getSize() - startPos == 0) { - currentProgress = endProgress; - } else { - currentProgress = (int) (startProgress + (endProgress - startProgress) - * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos)); - } - updateProgress(currentProgress, 100); - } - - if (signature != null) { - updateProgress(R.string.progress_verifying_signature, 90, 100); - - PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); - PGPSignature messageSignature = signatureList.get(signatureIndex); - - //Now check binding signatures - boolean keyBinding_isok = verifyKeyBinding(mContext, messageSignature, signatureKey); - boolean sig_isok = signature.verify(messageSignature); - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok); - } - } - - // TODO: test if this integrity really check works! - if (encryptedData.isIntegrityProtected()) { - updateProgress(R.string.progress_verifying_integrity, 95, 100); - - if (encryptedData.verify()) { - // passed - } else { - // failed - throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed)); - } - } else { - // no integrity check - Log.e(Constants.TAG, "No integrity check!"); - } - - updateProgress(R.string.progress_done, 100, 100); - return returnData; - } - - public Bundle verifyText() throws IOException, PgpGeneralException, - PGPException, SignatureException { - Bundle returnData = new Bundle(); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ArmoredInputStream aIn = new ArmoredInputStream(mData.getInputStream()); - - updateProgress(R.string.progress_done, 0, 100); - - // mostly taken from pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java - ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); - int lookAhead = readInputLine(lineOut, aIn); - byte[] lineSep = getLineSeparator(); - - byte[] line = lineOut.toByteArray(); - out.write(line, 0, getLengthWithoutSeparator(line)); - out.write(lineSep); - - while (lookAhead != -1 && aIn.isClearText()) { - lookAhead = readInputLine(lineOut, lookAhead, aIn); - line = lineOut.toByteArray(); - out.write(line, 0, getLengthWithoutSeparator(line)); - out.write(lineSep); - } - - out.close(); - - byte[] clearText = out.toByteArray(); - mOutStream.write(clearText); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); - - updateProgress(R.string.progress_processing_signature, 60, 100); - PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); - - PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); - if (sigList == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_corrupt_data)); - } - PGPSignature signature = null; - long signatureKeyId = 0; - PGPPublicKey signatureKey = null; - for (int i = 0; i < sigList.size(); ++i) { - signature = sigList.get(i); - signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); - if (signatureKeyId == 0) { - signatureKeyId = signature.getKeyID(); - } - - if (signatureKey == null) { - signature = null; - } else { - signatureKeyId = signature.getKeyID(); - String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, - signatureKeyId); - if (signKeyRing != null) { - userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); - } - returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); - break; - } - } - - returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); - - if (signature == null) { - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); - if (mProgress != null) - mProgress.setProgress(R.string.progress_done, 100, 100); - return returnData; - } - - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - signature.init(contentVerifierBuilderProvider, signatureKey); - - InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText)); - - lookAhead = readInputLine(lineOut, sigIn); - - processLine(signature, lineOut.toByteArray()); - - if (lookAhead != -1) { - do { - lookAhead = readInputLine(lineOut, lookAhead, sigIn); - - signature.update((byte) '\r'); - signature.update((byte) '\n'); - - processLine(signature, lineOut.toByteArray()); - } while (lookAhead != -1); - } - - boolean sig_isok = signature.verify(); - - //Now check binding signatures - boolean keyBinding_isok = verifyKeyBinding(mContext, signature, signatureKey); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok); - - updateProgress(R.string.progress_done, 100, 100); - return returnData; - } - - public boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { - long signatureKeyId = signature.getKeyID(); - boolean keyBinding_isok = false; - String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, - signatureKeyId); - PGPPublicKey mKey = null; - if (signKeyRing != null) { - mKey = PgpKeyHelper.getMasterKey(signKeyRing); - } - if (signature.getKeyID() != mKey.getKeyID()) { - keyBinding_isok = verifyKeyBinding(mKey, signatureKey); - } else { //if the key used to make the signature was the master key, no need to check binding sigs - keyBinding_isok = true; - } - return keyBinding_isok; - } - - public boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { - boolean subkeyBinding_isok = false; - boolean tmp_subkeyBinding_isok = false; - boolean primkeyBinding_isok = false; - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - Iterator itr = signingPublicKey.getSignatures(); - - subkeyBinding_isok = false; - tmp_subkeyBinding_isok = false; - primkeyBinding_isok = false; - while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong? - //gpg has an invalid subkey binding error on key import I think, but doesn't shout - //about keys without subkey signing. Can't get it to import a slightly broken one - //either, so we will err on bad subkey binding here. - PGPSignature sig = itr.next(); - if (sig.getKeyID() == masterPublicKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { - //check and if ok, check primary key binding. - try { - sig.init(contentVerifierBuilderProvider, masterPublicKey); - tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey); - } catch (PGPException e) { - continue; - } catch (SignatureException e) { - continue; - } - - if (tmp_subkeyBinding_isok) - subkeyBinding_isok = true; - if (tmp_subkeyBinding_isok) { - primkeyBinding_isok = verifyPrimaryBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; - primkeyBinding_isok = verifyPrimaryBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; - } - } - } - return (subkeyBinding_isok & primkeyBinding_isok); - } - - private boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { - boolean primkeyBinding_isok = false; - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureList eSigList; - - if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { - try { - eSigList = Pkts.getEmbeddedSignatures(); - } catch (IOException e) { - return false; - } catch (PGPException e) { - return false; - } - for (int j = 0; j < eSigList.size(); ++j) { - PGPSignature emSig = eSigList.get(j); - if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { - try { - emSig.init(contentVerifierBuilderProvider, signingPublicKey); - primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; - } catch (PGPException e) { - continue; - } catch (SignatureException e) { - continue; - } - } - } - } - return primkeyBinding_isok; - } - - private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException { - - if (pLine == null) { - return; - } - - final char[] chars = pLine.toCharArray(); - int len = chars.length; - - while (len > 0) { - if (!Character.isWhitespace(chars[len - 1])) { - break; - } - len--; - } - - final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); - - if (pArmoredOutput != null) { - pArmoredOutput.write(data); - } - pSignatureGenerator.update(data); - } - - private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPV3SignatureGenerator pSignatureGenerator) throws IOException, - SignatureException { - - if (pLine == null) { - return; - } - - final char[] chars = pLine.toCharArray(); - int len = chars.length; - - while (len > 0) { - if (!Character.isWhitespace(chars[len - 1])) { - break; - } - len--; - } - - final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); - - if (pArmoredOutput != null) { - pArmoredOutput.write(data); - } - pSignatureGenerator.update(data); - } - - // taken from ClearSignedFileProcessor in BC - private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, - IOException { - int length = getLengthWithoutWhiteSpace(line); - if (length > 0) { - sig.update(line, 0, length); - } - } - - private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) - throws IOException { - bOut.reset(); - - int lookAhead = -1; - int ch; - - while ((ch = fIn.read()) >= 0) { - bOut.write(ch); - if (ch == '\r' || ch == '\n') { - lookAhead = readPassedEOL(bOut, ch, fIn); - break; - } - } - - return lookAhead; - } - - private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) - throws IOException { - bOut.reset(); - - int ch = lookAhead; - - do { - bOut.write(ch); - if (ch == '\r' || ch == '\n') { - lookAhead = readPassedEOL(bOut, ch, fIn); - break; - } - } while ((ch = fIn.read()) >= 0); - - if (ch < 0) { - lookAhead = -1; - } - - return lookAhead; - } - - private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) - throws IOException { - int lookAhead = fIn.read(); - - if (lastCh == '\r' && lookAhead == '\n') { - bOut.write(lookAhead); - lookAhead = fIn.read(); - } - - return lookAhead; - } - - private static int getLengthWithoutSeparator(byte[] line) { - int end = line.length - 1; - - while (end >= 0 && isLineEnding(line[end])) { - end--; - } - - return end + 1; - } - - private static boolean isLineEnding(byte b) { - return b == '\r' || b == '\n'; - } - - private static int getLengthWithoutWhiteSpace(byte[] line) { - int end = line.length - 1; - - while (end >= 0 && isWhiteSpace(line[end])) { - end--; - } - - return end + 1; - } - - private static boolean isWhiteSpace(byte b) { - return b == '\r' || b == '\n' || b == '\t' || b == ' '; - } - - private static byte[] getLineSeparator() { - String nl = System.getProperty("line.separator"); - byte[] nlBytes = new byte[nl.length()]; - - for (int i = 0; i != nlBytes.length; i++) { - nlBytes[i] = (byte) nl.charAt(i); - } - - return nlBytes; - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java new file mode 100644 index 000000000..c57691f8d --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java @@ -0,0 +1,683 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * 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.pgp; + +import android.content.Context; +import android.os.Bundle; + +import org.spongycastle.bcpg.ArmoredInputStream; +import org.spongycastle.bcpg.SignatureSubpacketTags; +import org.spongycastle.openpgp.PGPCompressedData; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.spongycastle.openpgp.PGPEncryptedDataList; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPOnePassSignature; +import org.spongycastle.openpgp.PGPOnePassSignatureList; +import org.spongycastle.openpgp.PGPPBEEncryptedData; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureList; +import org.spongycastle.openpgp.PGPSignatureSubpacketVector; +import org.spongycastle.openpgp.PGPUtil; +import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.util.InputData; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.SignatureException; +import java.util.Iterator; + +/** + * TODO: make builder pattern like in PgpOperationOutgoing + */ +public class PgpOperationIncoming { + private Context mContext; + private ProgressDialogUpdater mProgress; + private InputData mData; + private OutputStream mOutStream; + + public PgpOperationIncoming(Context context, ProgressDialogUpdater progress, InputData data, + OutputStream outStream) { + super(); + this.mContext = context; + this.mProgress = progress; + this.mData = data; + this.mOutStream = outStream; + } + + public void updateProgress(int message, int current, int total) { + if (mProgress != null) { + mProgress.setProgress(message, current, total); + } + } + + public void updateProgress(int current, int total) { + if (mProgress != null) { + mProgress.setProgress(current, total); + } + } + + public static boolean hasSymmetricEncryption(Context context, InputStream inputStream) + throws PgpGeneralException, IOException { + InputStream in = PGPUtil.getDecoderStream(inputStream); + PGPObjectFactory pgpF = new PGPObjectFactory(in); + PGPEncryptedDataList enc; + Object o = pgpF.nextObject(); + + // the first object might be a PGP marker packet. + if (o instanceof PGPEncryptedDataList) { + enc = (PGPEncryptedDataList) o; + } else { + enc = (PGPEncryptedDataList) pgpF.nextObject(); + } + + if (enc == null) { + throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); + } + + Iterator it = enc.getEncryptedDataObjects(); + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPBEEncryptedData) { + return true; + } + } + + return false; + } + + public Bundle decryptAndVerify(String passphrase, boolean assumeSymmetric) throws IOException, + PgpGeneralException, PGPException, SignatureException { + if (passphrase == null) { + passphrase = ""; + } + + Bundle returnData = new Bundle(); + // automatically works with ascii armor input and binary + InputStream in = PGPUtil.getDecoderStream(mData.getInputStream()); + PGPObjectFactory pgpF = new PGPObjectFactory(in); + PGPEncryptedDataList enc; + Object o = pgpF.nextObject(); + + int currentProgress = 0; + updateProgress(R.string.progress_reading_data, currentProgress, 100); + + if (o instanceof PGPEncryptedDataList) { + enc = (PGPEncryptedDataList) o; + } else { + enc = (PGPEncryptedDataList) pgpF.nextObject(); + } + + if (enc == null) { + throw new PgpGeneralException(mContext.getString(R.string.error_invalid_data)); + } + + InputStream clear; + PGPEncryptedData encryptedData; + + currentProgress += 5; + + // TODO: currently we always only look at the first known key or symmetric encryption, + // there might be more... + if (assumeSymmetric) { + PGPPBEEncryptedData pbe = null; + Iterator it = enc.getEncryptedDataObjects(); + // find secret key + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPBEEncryptedData) { + pbe = (PGPPBEEncryptedData) obj; + break; + } + } + + if (pbe == null) { + throw new PgpGeneralException( + mContext.getString(R.string.error_no_symmetric_encryption_packet)); + } + + updateProgress(R.string.progress_preparing_streams, currentProgress, 100); + + PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); + PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( + digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + passphrase.toCharArray()); + + clear = pbe.getDataStream(decryptorFactory); + + encryptedData = pbe; + currentProgress += 5; + } else { + updateProgress(R.string.progress_finding_key, currentProgress, 100); + + PGPPublicKeyEncryptedData pbe = null; + PGPSecretKey secretKey = null; + Iterator it = enc.getEncryptedDataObjects(); + // find secret key + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPublicKeyEncryptedData) { + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; + secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); + if (secretKey != null) { + pbe = encData; + break; + } + } + } + + if (secretKey == null) { + throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found)); + } + + currentProgress += 5; + updateProgress(R.string.progress_extracting_key, currentProgress, 100); + PGPPrivateKey privateKey = null; + try { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + passphrase.toCharArray()); + privateKey = secretKey.extractPrivateKey(keyDecryptor); + } catch (PGPException e) { + throw new PGPException(mContext.getString(R.string.error_wrong_passphrase)); + } + if (privateKey == null) { + throw new PgpGeneralException( + mContext.getString(R.string.error_could_not_extract_private_key)); + } + currentProgress += 5; + updateProgress(R.string.progress_preparing_streams, currentProgress, 100); + + PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(privateKey); + + clear = pbe.getDataStream(decryptorFactory); + + encryptedData = pbe; + currentProgress += 5; + } + + PGPObjectFactory plainFact = new PGPObjectFactory(clear); + Object dataChunk = plainFact.nextObject(); + PGPOnePassSignature signature = null; + PGPPublicKey signatureKey = null; + int signatureIndex = -1; + + if (dataChunk instanceof PGPCompressedData) { + updateProgress(R.string.progress_decompressing_data, currentProgress, 100); + + PGPObjectFactory fact = new PGPObjectFactory( + ((PGPCompressedData) dataChunk).getDataStream()); + dataChunk = fact.nextObject(); + plainFact = fact; + currentProgress += 10; + } + + long signatureKeyId = 0; + if (dataChunk instanceof PGPOnePassSignatureList) { + updateProgress(R.string.progress_processing_signature, currentProgress, 100); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); + PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; + for (int i = 0; i < sigList.size(); ++i) { + signature = sigList.get(i); + signatureKey = ProviderHelper + .getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); + if (signatureKeyId == 0) { + signatureKeyId = signature.getKeyID(); + } + if (signatureKey == null) { + signature = null; + } else { + signatureIndex = i; + signatureKeyId = signature.getKeyID(); + String userId = null; + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( + mContext, signatureKeyId); + if (signKeyRing != null) { + userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); + } + returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); + break; + } + } + + returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); + + if (signature != null) { + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + signature.init(contentVerifierBuilderProvider, signatureKey); + } else { + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); + } + + dataChunk = plainFact.nextObject(); + currentProgress += 10; + } + + if (dataChunk instanceof PGPSignatureList) { + dataChunk = plainFact.nextObject(); + } + + if (dataChunk instanceof PGPLiteralData) { + updateProgress(R.string.progress_decrypting, currentProgress, 100); + + PGPLiteralData literalData = (PGPLiteralData) dataChunk; + OutputStream out = mOutStream; + + byte[] buffer = new byte[1 << 16]; + InputStream dataIn = literalData.getInputStream(); + + int startProgress = currentProgress; + int endProgress = 100; + if (signature != null) { + endProgress = 90; + } else if (encryptedData.isIntegrityProtected()) { + endProgress = 95; + } + + int n; +// int progress = 0; + long startPos = mData.getStreamPosition(); + while ((n = dataIn.read(buffer)) > 0) { + out.write(buffer, 0, n); +// progress += n; + if (signature != null) { + try { + signature.update(buffer, 0, n); + } catch (SignatureException e) { + returnData + .putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false); + signature = null; + } + } + // TODO: dead code?! + // unknown size, but try to at least have a moving, slowing down progress bar +// currentProgress = startProgress + (endProgress - startProgress) * progress +// / (progress + 100000); + if (mData.getSize() - startPos == 0) { + currentProgress = endProgress; + } else { + currentProgress = (int) (startProgress + (endProgress - startProgress) + * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos)); + } + updateProgress(currentProgress, 100); + } + + if (signature != null) { + updateProgress(R.string.progress_verifying_signature, 90, 100); + + PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); + PGPSignature messageSignature = signatureList.get(signatureIndex); + + //Now check binding signatures + boolean keyBinding_isok = verifyKeyBinding(mContext, messageSignature, signatureKey); + boolean sig_isok = signature.verify(messageSignature); + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok); + } + } + + // TODO: test if this integrity really check works! + if (encryptedData.isIntegrityProtected()) { + updateProgress(R.string.progress_verifying_integrity, 95, 100); + + if (encryptedData.verify()) { + // passed + Log.d(Constants.TAG, "Integrity verification: success!"); + } else { + // failed + Log.d(Constants.TAG, "Integrity verification: failed!"); + throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed)); + } + } else { + // no integrity check + Log.e(Constants.TAG, "Encrypted data was not integrity protected!"); + } + + updateProgress(R.string.progress_done, 100, 100); + return returnData; + } + + public Bundle verifyText() throws IOException, PgpGeneralException, + PGPException, SignatureException { + Bundle returnData = new Bundle(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ArmoredInputStream aIn = new ArmoredInputStream(mData.getInputStream()); + + updateProgress(R.string.progress_done, 0, 100); + + // mostly taken from pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java + ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); + int lookAhead = readInputLine(lineOut, aIn); + byte[] lineSep = getLineSeparator(); + + byte[] line = lineOut.toByteArray(); + out.write(line, 0, getLengthWithoutSeparator(line)); + out.write(lineSep); + + while (lookAhead != -1 && aIn.isClearText()) { + lookAhead = readInputLine(lineOut, lookAhead, aIn); + line = lineOut.toByteArray(); + out.write(line, 0, getLengthWithoutSeparator(line)); + out.write(lineSep); + } + + out.close(); + + byte[] clearText = out.toByteArray(); + mOutStream.write(clearText); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); + + updateProgress(R.string.progress_processing_signature, 60, 100); + PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); + + PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); + if (sigList == null) { + throw new PgpGeneralException(mContext.getString(R.string.error_corrupt_data)); + } + PGPSignature signature = null; + long signatureKeyId = 0; + PGPPublicKey signatureKey = null; + for (int i = 0; i < sigList.size(); ++i) { + signature = sigList.get(i); + signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); + if (signatureKeyId == 0) { + signatureKeyId = signature.getKeyID(); + } + + if (signatureKey == null) { + signature = null; + } else { + signatureKeyId = signature.getKeyID(); + String userId = null; + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, + signatureKeyId); + if (signKeyRing != null) { + userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); + } + returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); + break; + } + } + + returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); + + if (signature == null) { + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); + if (mProgress != null) + mProgress.setProgress(R.string.progress_done, 100, 100); + return returnData; + } + + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + signature.init(contentVerifierBuilderProvider, signatureKey); + + InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText)); + + lookAhead = readInputLine(lineOut, sigIn); + + processLine(signature, lineOut.toByteArray()); + + if (lookAhead != -1) { + do { + lookAhead = readInputLine(lineOut, lookAhead, sigIn); + + signature.update((byte) '\r'); + signature.update((byte) '\n'); + + processLine(signature, lineOut.toByteArray()); + } while (lookAhead != -1); + } + + boolean sig_isok = signature.verify(); + + //Now check binding signatures + boolean keyBinding_isok = verifyKeyBinding(mContext, signature, signatureKey); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok); + + updateProgress(R.string.progress_done, 100, 100); + return returnData; + } + + public boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { + long signatureKeyId = signature.getKeyID(); + boolean keyBinding_isok = false; + String userId = null; + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, + signatureKeyId); + PGPPublicKey mKey = null; + if (signKeyRing != null) { + mKey = PgpKeyHelper.getMasterKey(signKeyRing); + } + if (signature.getKeyID() != mKey.getKeyID()) { + keyBinding_isok = verifyKeyBinding(mKey, signatureKey); + } else { //if the key used to make the signature was the master key, no need to check binding sigs + keyBinding_isok = true; + } + return keyBinding_isok; + } + + public boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + boolean subkeyBinding_isok = false; + boolean tmp_subkeyBinding_isok = false; + boolean primkeyBinding_isok = false; + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + Iterator itr = signingPublicKey.getSignatures(); + + subkeyBinding_isok = false; + tmp_subkeyBinding_isok = false; + primkeyBinding_isok = false; + while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong? + //gpg has an invalid subkey binding error on key import I think, but doesn't shout + //about keys without subkey signing. Can't get it to import a slightly broken one + //either, so we will err on bad subkey binding here. + PGPSignature sig = itr.next(); + if (sig.getKeyID() == masterPublicKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { + //check and if ok, check primary key binding. + try { + sig.init(contentVerifierBuilderProvider, masterPublicKey); + tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey); + } catch (PGPException e) { + continue; + } catch (SignatureException e) { + continue; + } + + if (tmp_subkeyBinding_isok) + subkeyBinding_isok = true; + if (tmp_subkeyBinding_isok) { + primkeyBinding_isok = verifyPrimaryBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; + primkeyBinding_isok = verifyPrimaryBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; + } + } + } + return (subkeyBinding_isok & primkeyBinding_isok); + } + + private boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + boolean primkeyBinding_isok = false; + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureList eSigList; + + if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { + try { + eSigList = Pkts.getEmbeddedSignatures(); + } catch (IOException e) { + return false; + } catch (PGPException e) { + return false; + } + for (int j = 0; j < eSigList.size(); ++j) { + PGPSignature emSig = eSigList.get(j); + if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { + try { + emSig.init(contentVerifierBuilderProvider, signingPublicKey); + primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; + } catch (PGPException e) { + continue; + } catch (SignatureException e) { + continue; + } + } + } + } + return primkeyBinding_isok; + } + + + // taken from ClearSignedFileProcessor in BC + private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, + IOException { + int length = getLengthWithoutWhiteSpace(line); + if (length > 0) { + sig.update(line, 0, length); + } + } + + private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) + throws IOException { + bOut.reset(); + + int lookAhead = -1; + int ch; + + while ((ch = fIn.read()) >= 0) { + bOut.write(ch); + if (ch == '\r' || ch == '\n') { + lookAhead = readPassedEOL(bOut, ch, fIn); + break; + } + } + + return lookAhead; + } + + private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) + throws IOException { + bOut.reset(); + + int ch = lookAhead; + + do { + bOut.write(ch); + if (ch == '\r' || ch == '\n') { + lookAhead = readPassedEOL(bOut, ch, fIn); + break; + } + } while ((ch = fIn.read()) >= 0); + + if (ch < 0) { + lookAhead = -1; + } + + return lookAhead; + } + + private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) + throws IOException { + int lookAhead = fIn.read(); + + if (lastCh == '\r' && lookAhead == '\n') { + bOut.write(lookAhead); + lookAhead = fIn.read(); + } + + return lookAhead; + } + + private static int getLengthWithoutSeparator(byte[] line) { + int end = line.length - 1; + + while (end >= 0 && isLineEnding(line[end])) { + end--; + } + + return end + 1; + } + + private static boolean isLineEnding(byte b) { + return b == '\r' || b == '\n'; + } + + private static int getLengthWithoutWhiteSpace(byte[] line) { + int end = line.length - 1; + + while (end >= 0 && isWhiteSpace(line[end])) { + end--; + } + + return end + 1; + } + + private static boolean isWhiteSpace(byte b) { + return b == '\r' || b == '\n' || b == '\t' || b == ' '; + } + + private static byte[] getLineSeparator() { + String nl = System.getProperty("line.separator"); + byte[] nlBytes = new byte[nl.length()]; + + for (int i = 0; i != nlBytes.length; i++) { + nlBytes[i] = (byte) nl.charAt(i); + } + + return nlBytes; + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java new file mode 100644 index 000000000..346638fa7 --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java @@ -0,0 +1,584 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * 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.pgp; + +import android.content.Context; + +import org.spongycastle.bcpg.ArmoredOutputStream; +import org.spongycastle.bcpg.BCPGOutputStream; +import org.spongycastle.openpgp.PGPCompressedDataGenerator; +import org.spongycastle.openpgp.PGPEncryptedDataGenerator; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPLiteralDataGenerator; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureGenerator; +import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.spongycastle.openpgp.PGPV3SignatureGenerator; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.util.InputData; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.util.Date; + +/** + * This class uses a Builder pattern! + */ +public class PgpOperationOutgoing { + private Context context; + private InputData data; + private OutputStream outStream; + + private ProgressDialogUpdater progress; + private boolean enableAsciiArmorOutput; + private int compressionId; + private long[] encryptionKeyIds; + private String encryptionPassphrase; + private int symmetricEncryptionAlgorithm; + private long signatureKeyId; + private int signatureHashAlgorithm; + private boolean signatureForceV3; + private String signaturePassphrase; + + private PgpOperationOutgoing(Builder builder) { + // private Constructor can only be called from Builder + this.context = builder.context; + this.data = builder.data; + this.outStream = builder.outStream; + + this.progress = builder.progress; + this.enableAsciiArmorOutput = builder.enableAsciiArmorOutput; + this.compressionId = builder.compressionId; + this.encryptionKeyIds = builder.encryptionKeyIds; + this.encryptionPassphrase = builder.encryptionPassphrase; + this.symmetricEncryptionAlgorithm = builder.symmetricEncryptionAlgorithm; + this.signatureKeyId = builder.signatureKeyId; + this.signatureHashAlgorithm = builder.signatureHashAlgorithm; + this.signatureForceV3 = builder.signatureForceV3; + this.signaturePassphrase = builder.signaturePassphrase; + } + + public static class Builder { + // mandatory parameter + private Context context; + private InputData data; + private OutputStream outStream; + + // optional + private ProgressDialogUpdater progress = null; + private boolean enableAsciiArmorOutput = false; + private int compressionId = Id.choice.compression.none; + private long[] encryptionKeyIds = new long[0]; + private String encryptionPassphrase = null; + private int symmetricEncryptionAlgorithm = 0; + private long signatureKeyId = Id.key.none; + private int signatureHashAlgorithm = 0; + private boolean signatureForceV3 = false; + private String signaturePassphrase = null; + + public Builder(Context context, InputData data, OutputStream outStream) { + this.context = context; + this.data = data; + this.outStream = outStream; + } + + public Builder progress(ProgressDialogUpdater progress) { + this.progress = progress; + return this; + } + + public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) { + this.enableAsciiArmorOutput = enableAsciiArmorOutput; + return this; + } + + public Builder compressionId(int compressionId) { + this.compressionId = compressionId; + return this; + } + + public Builder encryptionKeyIds(long[] encryptionKeyIds) { + this.encryptionKeyIds = encryptionKeyIds; + return this; + } + + public Builder encryptionPassphrase(String encryptionPassphrase) { + this.encryptionPassphrase = encryptionPassphrase; + return this; + } + + public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { + this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; + return this; + } + + public Builder signatureKeyId(long signatureKeyId) { + this.signatureKeyId = signatureKeyId; + return this; + } + + public Builder signatureHashAlgorithm(int signatureHashAlgorithm) { + this.signatureHashAlgorithm = signatureHashAlgorithm; + return this; + } + + public Builder signatureForceV3(boolean signatureForceV3) { + this.signatureForceV3 = signatureForceV3; + return this; + } + + public Builder signaturePassphrase(String signaturePassphrase) { + this.signaturePassphrase = signaturePassphrase; + return this; + } + + public PgpOperationOutgoing build() { + return new PgpOperationOutgoing(this); + } + } + + public void updateProgress(int message, int current, int total) { + if (progress != null) { + progress.setProgress(message, current, total); + } + } + + public void updateProgress(int current, int total) { + if (progress != null) { + progress.setProgress(current, total); + } + } + + public void signAndEncrypt() + throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, + NoSuchAlgorithmException, SignatureException { + + if (encryptionKeyIds == null) { + encryptionKeyIds = new long[0]; + } + + boolean enableSignature = signatureKeyId != Id.key.none; + boolean enableCompression = compressionId != Id.choice.compression.none; + boolean enableEncryption = encryptionKeyIds.length != 0 || encryptionPassphrase != null; + + int signatureType; + if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; + } else { + signatureType = PGPSignature.BINARY_DOCUMENT; + } + + ArmoredOutputStream armorOut = null; + OutputStream out; + OutputStream encryptionOut = null; + if (enableAsciiArmorOutput) { + armorOut = new ArmoredOutputStream(outStream); + armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); + out = armorOut; + } else { + out = outStream; + } + + + PGPSecretKey signingKey = null; + PGPSecretKeyRing signingKeyRing = null; + PGPPrivateKey signaturePrivateKey = null; + if (enableSignature) { + signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); + signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); + if (signingKey == null) { + throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); + } + + if (signaturePassphrase == null) { + throw new PgpGeneralException( + context.getString(R.string.error_no_signature_passphrase)); + } + + updateProgress(R.string.progress_extracting_signature_key, 0, 100); + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); + signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); + if (signaturePrivateKey == null) { + throw new PgpGeneralException( + context.getString(R.string.error_could_not_extract_private_key)); + } + } + updateProgress(R.string.progress_preparing_streams, 5, 100); + + // encrypt and compress input file content + if (enableEncryption) { + // has Integrity packet enabled! + JcePGPDataEncryptorBuilder encryptorBuilder = + new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) + .setWithIntegrityPacket(true); + + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); + + if (encryptionKeyIds.length == 0) { + // Symmetric encryption + Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); + + JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = + new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); + cPk.addMethod(symmetricEncryptionGenerator); + } else { + // Asymmetric encryption + for (long id : encryptionKeyIds) { + PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(context, id); + if (key != null) { + + JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = + new JcePublicKeyKeyEncryptionMethodGenerator(key); + cPk.addMethod(pubKeyEncryptionGenerator); + } + } + } + encryptionOut = cPk.open(out, new byte[1 << 16]); + } + + PGPSignatureGenerator signatureGenerator = null; + PGPV3SignatureGenerator signatureV3Generator = null; + if (enableSignature) { + updateProgress(R.string.progress_preparing_signature, 10, 100); + + // content signer based on signing key algorithm and chosen hash algorithm + JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( + signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + if (signatureForceV3) { + signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); + signatureV3Generator.init(signatureType, signaturePrivateKey); + } else { + signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); + signatureGenerator.init(signatureType, signaturePrivateKey); + + String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + spGen.setSignerUserID(false, userId); + signatureGenerator.setHashedSubpackets(spGen.generate()); + } + } + + PGPCompressedDataGenerator compressGen = null; + OutputStream pOut; + if (enableEncryption) { + BCPGOutputStream bcpgOut; + if (enableCompression) { + compressGen = new PGPCompressedDataGenerator(compressionId); + bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); + } else { + bcpgOut = new BCPGOutputStream(encryptionOut); + } + + if (enableSignature) { + if (signatureForceV3) { + signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); + } else { + signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); + } + } + + PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); + // file name not needed, so empty string + pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), + new byte[1 << 16]); + updateProgress(R.string.progress_encrypting, 20, 100); + + long progress = 0; + int n; + byte[] buffer = new byte[1 << 16]; + InputStream in = data.getInputStream(); + while ((n = in.read(buffer)) > 0) { + pOut.write(buffer, 0, n); + + // update signature buffer if signature is requested + if (enableSignature) { + if (signatureForceV3) { + signatureV3Generator.update(buffer, 0, n); + } else { + signatureGenerator.update(buffer, 0, n); + } + } + + progress += n; + if (data.getSize() != 0) { + updateProgress((int) (20 + (95 - 20) * progress / data.getSize()), 100); + } + } + + literalGen.close(); + } else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + /* sign-only of ascii text */ + + updateProgress(R.string.progress_signing, 40, 100); + + // write directly on armor output stream + armorOut.beginClearText(signatureHashAlgorithm); + + InputStream in = data.getInputStream(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + + final byte[] newline = "\r\n".getBytes("UTF-8"); + + if (signatureForceV3) { + processLine(reader.readLine(), armorOut, signatureV3Generator); + } else { + processLine(reader.readLine(), armorOut, signatureGenerator); + } + + while (true) { + String line = reader.readLine(); + + if (line == null) { + armorOut.write(newline); + break; + } + + armorOut.write(newline); + if (signatureForceV3) { + signatureV3Generator.update(newline); + processLine(line, armorOut, signatureV3Generator); + } else { + signatureGenerator.update(newline); + processLine(line, armorOut, signatureGenerator); + } + } + + armorOut.endClearText(); + + pOut = new BCPGOutputStream(armorOut); + } else { + // TODO: implement sign-only for files! + pOut = null; + Log.e(Constants.TAG, "not supported!"); + } + + if (enableSignature) { + updateProgress(R.string.progress_generating_signature, 95, 100); + if (signatureForceV3) { + signatureV3Generator.generate().encode(pOut); + } else { + signatureGenerator.generate().encode(pOut); + } + } + + // closing outputs... + if (enableEncryption) { + encryptionOut.close(); + + if (enableCompression) { + compressGen.close(); + } + } + if (enableAsciiArmorOutput) { + armorOut.close(); + } + + updateProgress(R.string.progress_done, 100, 100); + } + + // TODO: merge this into signAndEncrypt method! + public void generateSignature() + throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, + SignatureException { + + OutputStream out; + if (enableAsciiArmorOutput) { + // Ascii Armor (Radix-64) + ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream); + armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); + out = armorOut; + } else { + out = outStream; + } + + if (signatureKeyId == 0) { + throw new PgpGeneralException(context.getString(R.string.error_no_signature_key)); + } + + PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); + PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); + if (signingKey == null) { + throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); + } + + if (signaturePassphrase == null) { + throw new PgpGeneralException(context.getString(R.string.error_no_signature_passphrase)); + } + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); + PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); + if (signaturePrivateKey == null) { + throw new PgpGeneralException( + context.getString(R.string.error_could_not_extract_private_key)); + } + updateProgress(R.string.progress_preparing_streams, 0, 100); + + updateProgress(R.string.progress_preparing_signature, 30, 100); + + int type = PGPSignature.CANONICAL_TEXT_DOCUMENT; +// if (binary) { +// type = PGPSignature.BINARY_DOCUMENT; +// } + + // content signer based on signing key algorithm and chosen hash algorithm + JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey + .getPublicKey().getAlgorithm(), signatureHashAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + PGPSignatureGenerator signatureGenerator = null; + PGPV3SignatureGenerator signatureV3Generator = null; + if (signatureForceV3) { + signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); + signatureV3Generator.init(type, signaturePrivateKey); + } else { + signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); + signatureGenerator.init(type, signaturePrivateKey); + + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); + spGen.setSignerUserID(false, userId); + signatureGenerator.setHashedSubpackets(spGen.generate()); + } + + updateProgress(R.string.progress_signing, 40, 100); + + InputStream inStream = data.getInputStream(); +// if (binary) { +// byte[] buffer = new byte[1 << 16]; +// int n = 0; +// while ((n = inStream.read(buffer)) > 0) { +// if (signatureForceV3) { +// signatureV3Generator.update(buffer, 0, n); +// } else { +// signatureGenerator.update(buffer, 0, n); +// } +// } +// } else { + final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); + final byte[] newline = "\r\n".getBytes("UTF-8"); + + String line; + while ((line = reader.readLine()) != null) { + if (signatureForceV3) { + processLine(line, null, signatureV3Generator); + signatureV3Generator.update(newline); + } else { + processLine(line, null, signatureGenerator); + signatureGenerator.update(newline); + } + } +// } + + BCPGOutputStream bOut = new BCPGOutputStream(out); + if (signatureForceV3) { + signatureV3Generator.generate().encode(bOut); + } else { + signatureGenerator.generate().encode(bOut); + } + out.close(); + outStream.close(); + + updateProgress(R.string.progress_done, 100, 100); + } + + + private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, + final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException { + + if (pLine == null) { + return; + } + + final char[] chars = pLine.toCharArray(); + int len = chars.length; + + while (len > 0) { + if (!Character.isWhitespace(chars[len - 1])) { + break; + } + len--; + } + + final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); + + if (pArmoredOutput != null) { + pArmoredOutput.write(data); + } + pSignatureGenerator.update(data); + } + + private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, + final PGPV3SignatureGenerator pSignatureGenerator) throws IOException, + SignatureException { + + if (pLine == null) { + return; + } + + final char[] chars = pLine.toCharArray(); + int len = chars.length; + + while (len > 0) { + if (!Character.isWhitespace(chars[len - 1])) { + break; + } + len--; + } + + final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); + + if (pArmoredOutput != null) { + pArmoredOutput.write(data); + } + pSignatureGenerator.update(data); + } + + private static boolean isWhiteSpace(byte b) { + return b == '\r' || b == '\n' || b == '\t' || b == ' '; + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 1de9ab985..8d8f4e796 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -46,7 +46,8 @@ import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpImportExport; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; -import org.sufficientlysecure.keychain.pgp.PgpOperation; +import org.sufficientlysecure.keychain.pgp.PgpOperationIncoming; +import org.sufficientlysecure.keychain.pgp.PgpOperationOutgoing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -316,27 +317,41 @@ public class KeychainIntentService extends IntentService implements ProgressDial } /* Operation */ - PgpOperation operation = new PgpOperation(this, this, inputData, outStream); + PgpOperationOutgoing.Builder builder = + new PgpOperationOutgoing.Builder(this, inputData, outStream); + builder.progress(this); + if (generateSignature) { Log.d(Constants.TAG, "generating signature..."); - operation.generateSignature(useAsciiArmor, false, secretKeyId, - PassphraseCacheService.getCachedPassphrase(this, secretKeyId), - Preferences.getPreferences(this).getDefaultHashAlgorithm(), Preferences - .getPreferences(this).getForceV3Signatures()); + builder.enableAsciiArmorOutput(useAsciiArmor) + .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) + .signatureKeyId(secretKeyId) + .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) + .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + + builder.build().generateSignature(); } else if (signOnly) { Log.d(Constants.TAG, "sign only..."); - operation.signText(secretKeyId, PassphraseCacheService.getCachedPassphrase( - this, secretKeyId), Preferences.getPreferences(this) - .getDefaultHashAlgorithm(), Preferences.getPreferences(this) - .getForceV3Signatures()); + builder.enableAsciiArmorOutput(useAsciiArmor) + .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) + .signatureKeyId(secretKeyId) + .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) + .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + + builder.build().signAndEncrypt(); } else { Log.d(Constants.TAG, "encrypt..."); - operation.signAndEncrypt(useAsciiArmor, compressionId, encryptionKeyIds, - encryptionPassphrase, Preferences.getPreferences(this) - .getDefaultEncryptionAlgorithm(), secretKeyId, Preferences - .getPreferences(this).getDefaultHashAlgorithm(), Preferences - .getPreferences(this).getForceV3Signatures(), - PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + builder.enableAsciiArmorOutput(useAsciiArmor) + .compressionId(compressionId) + .symmetricEncryptionAlgorithm(Preferences.getPreferences(this).getDefaultEncryptionAlgorithm()) + .signatureForceV3(Preferences.getPreferences(this).getForceV3Signatures()) + .encryptionKeyIds(encryptionKeyIds) + .encryptionPassphrase(encryptionPassphrase) + .signatureKeyId(secretKeyId) + .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) + .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + + builder.build().signAndEncrypt(); } outStream.close(); @@ -466,7 +481,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial // verifyText and decrypt returning additional resultData values for the // verification of signatures - PgpOperation operation = new PgpOperation(this, this, inputData, outStream); + PgpOperationIncoming operation = new PgpOperationIncoming(this, this, inputData, outStream); if (signedOnly) { resultData = operation.verifyText(); } else { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index b13c8ac49..da42be2e2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -29,12 +29,11 @@ import org.openintents.openpgp.IOpenPgpService; import org.openintents.openpgp.OpenPgpError; import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpConstants; -import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.helper.Preferences; -import org.sufficientlysecure.keychain.pgp.PgpOperation; +import org.sufficientlysecure.keychain.pgp.PgpOperationOutgoing; +import org.sufficientlysecure.keychain.pgp.PgpOperationIncoming; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -162,9 +161,14 @@ public class OpenPgpService extends RemoteService { long inputLength = is.available(); InputData inputData = new InputData(is, inputLength); - PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); - operation.signText(appSettings.getKeyId(), passphrase, appSettings.getHashAlgorithm(), - Preferences.getPreferences(this).getForceV3Signatures()); + // sign-only + PgpOperationOutgoing.Builder builder = new PgpOperationOutgoing.Builder(getContext(), inputData, os); + builder.enableAsciiArmorOutput(true) + .signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureForceV3(false) + .signatureKeyId(appSettings.getKeyId()) + .signaturePassphrase(passphrase); + builder.build().signAndEncrypt(); } finally { is.close(); os.close(); @@ -223,7 +227,14 @@ public class OpenPgpService extends RemoteService { long inputLength = is.available(); InputData inputData = new InputData(is, inputLength); - PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); + PgpOperationOutgoing.Builder builder = new PgpOperationOutgoing.Builder(getContext(), inputData, os); + builder.enableAsciiArmorOutput(asciiArmor) + .compressionId(appSettings.getCompression()) + .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) + .signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureForceV3(false) + .encryptionKeyIds(keyIds); + if (sign) { String passphrase; if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) { @@ -239,15 +250,14 @@ public class OpenPgpService extends RemoteService { } // sign and encrypt - operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, - appSettings.getEncryptionAlgorithm(), appSettings.getKeyId(), - appSettings.getHashAlgorithm(), true, passphrase); + builder.signatureKeyId(appSettings.getKeyId()) + .signaturePassphrase(passphrase); } else { // encrypt only - operation.signAndEncrypt(asciiArmor, appSettings.getCompression(), keyIds, null, - appSettings.getEncryptionAlgorithm(), Id.key.none, - appSettings.getHashAlgorithm(), true, null); + builder.signatureKeyId(Id.key.none); } + // execute PGP operation! + builder.build().signAndEncrypt(); } finally { is.close(); os.close(); @@ -344,7 +354,7 @@ public class OpenPgpService extends RemoteService { // inputStream2.reset(); // } // secretKeyId = Id.key.symmetric; -// if (!PgpOperation.hasSymmetricEncryption(this, inputStream2)) { +// if (!PgpOperationIncoming.hasSymmetricEncryption(this, inputStream2)) { // throw new PgpGeneralException( // getString(R.string.error_no_known_encryption_found)); // } @@ -374,7 +384,7 @@ public class OpenPgpService extends RemoteService { Bundle outputBundle; - PgpOperation operation = new PgpOperation(getContext(), null, inputData, os); + PgpOperationIncoming operation = new PgpOperationIncoming(getContext(), null, inputData, os); if (signedOnly) { outputBundle = operation.verifyText(); } else { diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index b8eed83c9..1f3280af3 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -34,7 +34,7 @@ import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.pgp.PgpOperation; +import org.sufficientlysecure.keychain.pgp.PgpOperationIncoming; import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -546,7 +546,7 @@ public class DecryptActivity extends DrawerActivity { inStream.reset(); } mSecretKeyId = Id.key.symmetric; - if (!PgpOperation.hasSymmetricEncryption(this, inStream)) { + if (!PgpOperationIncoming.hasSymmetricEncryption(this, inStream)) { throw new PgpGeneralException( getString(R.string.error_no_known_encryption_found)); } -- cgit v1.2.3 From a5e33097a6cb3d8240ea475bfd32f0dbda02b4a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 10:47:13 +0100 Subject: cleanup --- .../keychain/pgp/PgpOperationOutgoing.java | 22 ++++++++++------------ .../keychain/service/remote/OpenPgpService.java | 14 +++++++------- 2 files changed, 17 insertions(+), 19 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java index 346638fa7..f86d83547 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java @@ -191,13 +191,9 @@ public class PgpOperationOutgoing { throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { - if (encryptionKeyIds == null) { - encryptionKeyIds = new long[0]; - } - boolean enableSignature = signatureKeyId != Id.key.none; - boolean enableCompression = compressionId != Id.choice.compression.none; - boolean enableEncryption = encryptionKeyIds.length != 0 || encryptionPassphrase != null; + boolean enableEncryption = (encryptionKeyIds.length != 0 || encryptionPassphrase != null); + boolean enableCompression = (enableEncryption && compressionId != Id.choice.compression.none); int signatureType; if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { @@ -208,7 +204,6 @@ public class PgpOperationOutgoing { ArmoredOutputStream armorOut = null; OutputStream out; - OutputStream encryptionOut = null; if (enableAsciiArmorOutput) { armorOut = new ArmoredOutputStream(outStream); armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); @@ -217,7 +212,7 @@ public class PgpOperationOutgoing { out = outStream; } - + /* Get keys for signature generation for later usage */ PGPSecretKey signingKey = null; PGPSecretKeyRing signingKeyRing = null; PGPPrivateKey signaturePrivateKey = null; @@ -245,7 +240,8 @@ public class PgpOperationOutgoing { } updateProgress(R.string.progress_preparing_streams, 5, 100); - // encrypt and compress input file content + /* Initialize PGPEncryptedDataGenerator for later usage */ + PGPEncryptedDataGenerator cPk = null; if (enableEncryption) { // has Integrity packet enabled! JcePGPDataEncryptorBuilder encryptorBuilder = @@ -253,7 +249,7 @@ public class PgpOperationOutgoing { .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) .setWithIntegrityPacket(true); - PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(encryptorBuilder); + cPk = new PGPEncryptedDataGenerator(encryptorBuilder); if (encryptionKeyIds.length == 0) { // Symmetric encryption @@ -267,16 +263,15 @@ public class PgpOperationOutgoing { for (long id : encryptionKeyIds) { PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(context, id); if (key != null) { - JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = new JcePublicKeyKeyEncryptionMethodGenerator(key); cPk.addMethod(pubKeyEncryptionGenerator); } } } - encryptionOut = cPk.open(out, new byte[1 << 16]); } + /* Initialize signature generator object for later usage */ PGPSignatureGenerator signatureGenerator = null; PGPV3SignatureGenerator signatureV3Generator = null; if (enableSignature) { @@ -303,7 +298,10 @@ public class PgpOperationOutgoing { PGPCompressedDataGenerator compressGen = null; OutputStream pOut; + OutputStream encryptionOut = null; if (enableEncryption) { + encryptionOut = cPk.open(out, new byte[1 << 16]); + BCPGOutputStream bcpgOut; if (enableCompression) { compressGen = new PGPCompressedDataGenerator(compressionId); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index da42be2e2..ec3f40d23 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -136,11 +136,11 @@ public class OpenPgpService extends RemoteService { return result; } - - // TODO: asciiArmor?! private Bundle signImpl(Bundle params, ParcelFileDescriptor input, ParcelFileDescriptor output, AppSettings appSettings) { try { + boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true); + // get passphrase from cache, if key has "no" passphrase, this returns an empty String String passphrase; if (params.containsKey(OpenPgpConstants.PARAMS_PASSPHRASE)) { @@ -163,7 +163,7 @@ public class OpenPgpService extends RemoteService { // sign-only PgpOperationOutgoing.Builder builder = new PgpOperationOutgoing.Builder(getContext(), inputData, os); - builder.enableAsciiArmorOutput(true) + builder.enableAsciiArmorOutput(asciiArmor) .signatureHashAlgorithm(appSettings.getHashAlgorithm()) .signatureForceV3(false) .signatureKeyId(appSettings.getKeyId()) @@ -190,7 +190,7 @@ public class OpenPgpService extends RemoteService { ParcelFileDescriptor output, AppSettings appSettings, boolean sign) { try { - boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, false); + boolean asciiArmor = params.getBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true); long[] keyIds; if (params.containsKey(OpenPgpConstants.PARAMS_KEY_IDS)) { @@ -231,8 +231,6 @@ public class OpenPgpService extends RemoteService { builder.enableAsciiArmorOutput(asciiArmor) .compressionId(appSettings.getCompression()) .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) - .signatureHashAlgorithm(appSettings.getHashAlgorithm()) - .signatureForceV3(false) .encryptionKeyIds(keyIds); if (sign) { @@ -250,7 +248,9 @@ public class OpenPgpService extends RemoteService { } // sign and encrypt - builder.signatureKeyId(appSettings.getKeyId()) + builder.signatureHashAlgorithm(appSettings.getHashAlgorithm()) + .signatureForceV3(false) + .signatureKeyId(appSettings.getKeyId()) .signaturePassphrase(passphrase); } else { // encrypt only -- cgit v1.2.3 From c5688889a70d9d8a8fa17e548faa0049ed0368dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 12:07:07 +0100 Subject: fixes encryption --- .../keychain/pgp/PgpOperationOutgoing.java | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java index f86d83547..8431aa165 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java @@ -33,6 +33,7 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPV3SignatureGenerator; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; @@ -195,8 +196,14 @@ public class PgpOperationOutgoing { boolean enableEncryption = (encryptionKeyIds.length != 0 || encryptionPassphrase != null); boolean enableCompression = (enableEncryption && compressionId != Id.choice.compression.none); + Log.d(Constants.TAG, "enableSignature:" + enableSignature + + "\nenableEncryption:" + enableEncryption + + "\nenableCompression:" + enableCompression + + "\nenableAsciiArmorOutput:" + enableAsciiArmorOutput); + int signatureType; if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + // for sign-only ascii text signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; } else { signatureType = PGPSignature.BINARY_DOCUMENT; @@ -299,10 +306,10 @@ public class PgpOperationOutgoing { PGPCompressedDataGenerator compressGen = null; OutputStream pOut; OutputStream encryptionOut = null; + BCPGOutputStream bcpgOut; if (enableEncryption) { encryptionOut = cPk.open(out, new byte[1 << 16]); - BCPGOutputStream bcpgOut; if (enableCompression) { compressGen = new PGPCompressedDataGenerator(compressionId); bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); @@ -402,18 +409,23 @@ public class PgpOperationOutgoing { } } - // closing outputs... + // closing outputs + // NOTE: closing need to be done in the correct order! + // TODO: closing bcpgOut and pOut??? if (enableEncryption) { - encryptionOut.close(); - if (enableCompression) { compressGen.close(); } + + encryptionOut.close(); } if (enableAsciiArmorOutput) { armorOut.close(); } + out.close(); + outStream.close(); + updateProgress(R.string.progress_done, 100, 100); } -- cgit v1.2.3 From b074293168810aff8b93fd4a19dd88d2f456d627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 12:43:56 +0100 Subject: certifications text --- .../org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java | 6 ++++-- OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java index 8431aa165..52e41306f 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java @@ -33,7 +33,6 @@ import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSignature; import org.spongycastle.openpgp.PGPSignatureGenerator; import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; -import org.spongycastle.openpgp.PGPUtil; import org.spongycastle.openpgp.PGPV3SignatureGenerator; import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; @@ -308,6 +307,8 @@ public class PgpOperationOutgoing { OutputStream encryptionOut = null; BCPGOutputStream bcpgOut; if (enableEncryption) { + /* actual encryption */ + encryptionOut = cPk.open(out, new byte[1 << 16]); if (enableCompression) { @@ -410,7 +411,7 @@ public class PgpOperationOutgoing { } // closing outputs - // NOTE: closing need to be done in the correct order! + // NOTE: closing needs to be done in the correct order! // TODO: closing bcpgOut and pOut??? if (enableEncryption) { if (enableCompression) { @@ -430,6 +431,7 @@ public class PgpOperationOutgoing { } // TODO: merge this into signAndEncrypt method! + // TODO: allow binary input for this class public void generateSignature() throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, SignatureException { diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml index 2a3dafc93..299471c66 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml @@ -10,6 +10,13 @@ android:paddingLeft="16dp" android:paddingRight="16dp"> + + Date: Wed, 19 Feb 2014 12:44:35 +0100 Subject: Update from transifex --- .../src/main/res/raw-ja/help_about.html | 20 +- .../src/main/res/raw-ja/help_changelog.html | 122 +++++------ .../src/main/res/raw-ja/help_nfc_beam.html | 10 +- .../src/main/res/raw-ja/help_start.html | 18 +- .../src/main/res/raw-ja/nfc_beam_share.html | 8 +- .../src/main/res/values-de/strings.xml | 6 +- .../src/main/res/values-es-rCO/strings.xml | 1 - .../src/main/res/values-es/strings.xml | 9 +- .../src/main/res/values-fr/strings.xml | 7 +- .../src/main/res/values-ja/strings.xml | 244 ++++++++++++++++++++- .../src/main/res/values-nl-rNL/strings.xml | 4 - .../src/main/res/values-ru/strings.xml | 7 +- .../src/main/res/values-tr/strings.xml | 1 - .../src/main/res/values-uk/strings.xml | 9 +- .../src/main/res/values-zh/strings.xml | 1 - 15 files changed, 344 insertions(+), 123 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html index 773d11fa7..51e0b8c25 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_about.html @@ -2,25 +2,25 @@

                                                  http://sufficientlysecure.org/keychain

                                                  -

                                                  OpenPGP Keychain is an OpenPGP implementation for Android. The development began as a fork of Android Privacy Guard (APG).

                                                  -

                                                  License: GPLv3+

                                                  +

                                                  OpenPGP Keychain は AndroidにおけるOpenPGP実装の一つです。開発はAndroid Privacy Guard (APG)から分岐して始まりました。

                                                  +

                                                  ライセンス: GPLv3以降

                                                  -

                                                  Developers OpenPGP Keychain

                                                  +

                                                  OpenPGP Keychain開発者

                                                    -
                                                  • Dominik Schürmann (Lead developer)
                                                  • -
                                                  • Ash Hughes (crypto patches)
                                                  • +
                                                  • Dominik Schürmann (主任開発者)
                                                  • +
                                                  • Ash Hughes (暗号関係パッチ提供)
                                                  • Brian C. Barnes
                                                  • Bahtiar 'kalkin' Gadimov (UI)
                                                  -

                                                  Developers APG 1.x

                                                  +

                                                  APG 1.xの開発者達

                                                    -
                                                  • 'Thialfihar' (Lead developer)
                                                  • -
                                                  • 'Senecaso' (QRCode, sign key, upload key)
                                                  • +
                                                  • 'Thialfihar' (主任開発者)
                                                  • +
                                                  • 'Senecaso' (QRコード, 鍵署名, 鍵アップロード関係)
                                                  • Oliver Runge
                                                  • Markus Doits
                                                  -

                                                  Libraries

                                                  +

                                                  ライブラリ

                                                  diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html index abf660ba8..4878a3b55 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_changelog.html @@ -3,106 +3,106 @@

                                                  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
                                                  • +
                                                  • 秘密鍵のエクスポート時における必要でない公開鍵のエクスポートの削除 (thanks to Ash Hughes)
                                                  • +
                                                  • 鍵の期限日時設定の修正 (thanks to Ash Hughes)
                                                  • +
                                                  • 鍵編集時のさらなる内部修正 (thanks to Ash Hughes)
                                                  • +
                                                  • インポート画面から直接鍵サーバへ要求するようにした
                                                  • +
                                                  • Android 2.2から3.0でのレイアウトとダイアログスタイルの修正
                                                  • +
                                                  • 空ユーザIDの鍵でのクラッシュ修正
                                                  • +
                                                  • 署名画面から戻ってきたときにリストが空だとクラッシュするのを修正
                                                  • +
                                                  • Bouncy Castle (cryptography library) を1.47 から 1.50アップデートおよびソースからのビルド
                                                  • +
                                                  • 署名画面からの鍵のアップロード修正

                                                  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
                                                  • +
                                                  • ナビゲーションドロワーの新しいデザイン
                                                  • +
                                                  • 新しい公開鍵リストデザイン
                                                  • +
                                                  • 新しい公開鍵ビュー
                                                  • +
                                                  • 鍵のインポート時のバグ修正
                                                  • +
                                                  • 鍵のクロス証明 (thanks to Ash Hughes)
                                                  • +
                                                  • 適切な UTF-8 パスワード処理 (thanks to Ash Hughes)
                                                  • +
                                                  • 新しい言語での最初のバージョン (thanks to the contributors on Transifex)
                                                  • +
                                                  • QRコードによる鍵共有の修正と改善
                                                  • +
                                                  • APIでのパッケージ署名検証

                                                  2.1.1

                                                    -
                                                  • API Updates, preparation for K-9 Mail integration
                                                  • +
                                                  • APIアップデート、K-9 Mail統合準備

                                                  2.1

                                                    -
                                                  • lots of bug fixes
                                                  • -
                                                  • new API for developers
                                                  • -
                                                  • PRNG bug fix by Google
                                                  • +
                                                  • たくさんのバグ修正
                                                  • +
                                                  • 開発者向け新API
                                                  • +
                                                  • 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
                                                  • +
                                                  • 再デザイン完了
                                                  • +
                                                  • QRコード、NFCビームでの公開鍵共有
                                                  • +
                                                  • 鍵への署名
                                                  • +
                                                  • 鍵サーバへアップロード
                                                  • +
                                                  • インポート問題修正
                                                  • +
                                                  • 新しいAIDL API

                                                  1.0.8

                                                    -
                                                  • basic keyserver support
                                                  • -
                                                  • app2sd
                                                  • -
                                                  • more choices for pass phrase cache: 1, 2, 4, 8, hours
                                                  • -
                                                  • translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)
                                                  • -
                                                  • bugfixes
                                                  • -
                                                  • optimizations
                                                  • +
                                                  • 鍵サーバの基本サポート
                                                  • +
                                                  • App2SD
                                                  • +
                                                  • パスフレーズのキャッシュ時間について1,2,4,8時間の選択肢追加
                                                  • +
                                                  • 翻訳: ノルウェー語 (thanks, Sander Danielsen), 中国語 (thanks, Zhang Fredrick) 追加
                                                  • +
                                                  • バグ修正
                                                  • +
                                                  • 最適化

                                                  1.0.7

                                                    -
                                                  • fixed problem with signature verification of texts with trailing newline
                                                  • -
                                                  • more options for pass phrase cache time to live (20, 40, 60 mins)
                                                  • +
                                                  • 改行を含まないテキストの署名検証問題の修正
                                                  • +
                                                  • パスフレーズのキャッシュ時間 (20,40,60分) のオプション追加

                                                  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
                                                  • +
                                                  • Froyo でのアカウント追加時クラッシュの修正
                                                  • +
                                                  • セキュアファイル削除
                                                  • +
                                                  • 鍵ファイルインポート後の削除オプション
                                                  • +
                                                  • ストリーム暗号化/復号化 (ギャラリーなど)
                                                  • +
                                                  • 新しいオプション (言語、強制V3署名)
                                                  • +
                                                  • インタフェース変更
                                                  • +
                                                  • バグ修正

                                                  1.0.5

                                                    -
                                                  • German and Italian translation
                                                  • -
                                                  • much smaller package, due to reduced BC sources
                                                  • -
                                                  • new preferences GUI
                                                  • -
                                                  • layout adjustment for localization
                                                  • -
                                                  • signature bugfix
                                                  • +
                                                  • ドイツ語およびイタリア語翻訳追加
                                                  • +
                                                  • BCソースが重複してしまっていたことによる、より小さいパッケージ化
                                                  • +
                                                  • 新しい設定GUI
                                                  • +
                                                  • ローカライズでのレイアウトを適合化
                                                  • +
                                                  • 署名バグ修正

                                                  1.0.4

                                                    -
                                                  • fixed another crash caused by some SDK bug with query builder
                                                  • +
                                                  • クエリービルダーによるSDKのいくつかのバグによるクラッシュの修正

                                                  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
                                                  • +
                                                  • 鍵リストのフィルタ可能化
                                                  • +
                                                  • 暗号化鍵の事前選択のよりスマートな実装
                                                  • +
                                                  • VIEWおよびSENDについて新しいインテントのハンドリング、ファイルマネージャ外のファイルを暗号化/復号化するのを受け付けるようになる。
                                                  • +
                                                  • K-9 Mailにおける修正と追加機能 (鍵事前選択)、新しいベータビルド提供

                                                  1.0.1

                                                    -
                                                  • GMail account listing was broken in 1.0.0, fixed again
                                                  • +
                                                  • 1.0.0で壊れたGmailアカウントリストアップを再度修正

                                                  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
                                                  • +
                                                  • K-9 Mail 統合、K-9 MailでのAPG サポートのベータビルド
                                                  • +
                                                  • (ASTROを含む)ファイルマネージャのさらなるサポート
                                                  • +
                                                  • スロベニア語翻訳追加
                                                  • +
                                                  • より早くてメモリ使用量の少ない新しいデータベース
                                                  • +
                                                  • 他のアプリでのインテントおよびコンテンツプロバイダの定義
                                                  • +
                                                  • バグ修正
                                                  diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html index 88492731c..c19280fd1 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_nfc_beam.html @@ -1,12 +1,12 @@ -

                                                  How to receive keys

                                                  +

                                                  鍵の受信方法

                                                    -
                                                  1. Go to your partners contacts and open the contact you want to share.
                                                  2. -
                                                  3. Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.
                                                  4. -
                                                  5. After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                                  6. -
                                                  7. Tap the card and the content will then load on the your device.
                                                  8. +
                                                  9. パートナーの連絡先に行き、共有したい連絡先を開きます。
                                                  10. +
                                                  11. 2つのデバイスを背中合せ(ほとんどすべてのタッチ方法)にしてバイブを感じるまで保持しておいてください。
                                                  12. +
                                                  13. バイブの後、相手のデバイスでスタートレック風のバックグラウンドアニメーションしているカード風のコンテンツを見ると思います。
                                                  14. +
                                                  15. カードをタップしコンテンツをあなたのデバイスにロードします。
                                                  diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html index 198dfe64f..5c78a1273 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/help_start.html @@ -1,19 +1,19 @@ -

                                                  Getting started

                                                  -

                                                  First you need a personal key pair. Create one via the option menus in "My Keys" or import existing key pairs via "Import Keys". Afterwards, you can download your friends' keys or exchange them via QR Codes or NFC.

                                                  +

                                                  入門

                                                  +

                                                  最初にあなたの個人用鍵ペアが必要になります。オプションメニューの"自分の鍵"で生成するか、"鍵のインポート"から既存の鍵ペアをインポートします。その後、あなたの友人の鍵をダウンロード、もしくはQRコードやNFCで交換します。

                                                  -

                                                  It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                  +

                                                  ファイルの選択を拡張するにはOI File ManagerBarcode Scannerを生成したQRコードのスキャンのため、それぞれのインストールを必要とします。 リンクをクリックして、Google Play Store上かF-Droidからインストールしてください。

                                                  -

                                                  I found a bug in OpenPGP Keychain!

                                                  -

                                                  Please report the bug using the issue tracker of OpenPGP Keychain.

                                                  +

                                                  OpenPGP Keychainにバグを発見した!

                                                  +

                                                  OpenPGP KeychainのIssueトラッカーを使ってバグレポートを送ってください。

                                                  -

                                                  Contribute

                                                  -

                                                  If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                  +

                                                  寄贈

                                                  +

                                                  もし、あなたが OpenPGP Keychain の開発を助け、コードを寄贈するというなら、Githubの寄贈ガイドを確認して下さい。

                                                  -

                                                  Translations

                                                  -

                                                  Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                  +

                                                  翻訳

                                                  +

                                                  OpenPGP Keychainの翻訳を補助してください! だれでも、TransifexでのOpenPGP Keychainプロジェクトに参加できます。

                                                  diff --git a/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html b/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html index 083e055c7..422423a5d 100644 --- a/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html +++ b/OpenPGP-Keychain/src/main/res/raw-ja/nfc_beam_share.html @@ -2,10 +2,10 @@
                                                    -
                                                  1. Make sure that NFC is turned on in Settings > More > NFC and make sure that Android Beam is also on in the same section.
                                                  2. -
                                                  3. Hold the two devices back to back (they have to be almost touching) and you'll feel a vibration.
                                                  4. -
                                                  5. After it vibrates you'll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.
                                                  6. -
                                                  7. Tap the card and the content will then load on the other person’s device.
                                                  8. +
                                                  9. 設定 > その他 > NFC からNFCを有効にしてください、そしてAndroid Beamもまた選択してください。
                                                  10. +
                                                  11. 2つのデバイスを背中合せ(ほとんどすべてのタッチ方法)にしてバイブを感じるまで保持しておいてください。
                                                  12. +
                                                  13. バイブの後、相手のデバイスでスタートレック風のバックグラウンドアニメーションしているカード風のコンテンツを見ると思います。
                                                  14. +
                                                  15. カードをタップしコンテンツを他のデバイスに読み込ませてください。
                                                  diff --git a/OpenPGP-Keychain/src/main/res/values-de/strings.xml b/OpenPGP-Keychain/src/main/res/values-de/strings.xml index 29e60e788..d421fd141 100644 --- a/OpenPGP-Keychain/src/main/res/values-de/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-de/strings.xml @@ -111,7 +111,6 @@ Passwort-Cache Nachrichten-Komprimierung Datei-Komprimierung - OpenPGPv3-Signaturen erzwingen Schlüsselserver Schlüssel-ID Erstellungsdatum @@ -272,7 +271,6 @@ speichern... importieren... exportieren... - erstelle Schlüssel, dies kann eine Weile dauern... erstelle Schlüssel... Hauptschlüssel wird vorbereitet... Hauptschlüssel wird beglaubigt... @@ -339,17 +337,15 @@ OpenPGP: Verschlüsseln OpenPGP: Entschlüsseln - Keine registrierten Anwendungen vorhanden! Erweiterte Einstellungen anzeigen Erweiterte Einstellungen ausblenden Kein Schlüssel ausgewählt Schlüssel auswählen Speichern Abbrechen - Zugang widerufen + Zugriff widerufen Paketname SHA-256 der Paketsignatur - Folgende Anwendung beantragt Zugriff zur API von OpenPGP Keychain.\n\nZugriff dauerhaft erlauben? Zugriff erlauben Zugriff verbieten Bitte einen Schlüssel auswählen! diff --git a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml index 587f884d0..6efe9548d 100644 --- a/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es-rCO/strings.xml @@ -71,7 +71,6 @@ Contraseña Compresión de mensaje Compresión de archivo - Forzar firmas V3 ID de clave Creación Expiración diff --git a/OpenPGP-Keychain/src/main/res/values-es/strings.xml b/OpenPGP-Keychain/src/main/res/values-es/strings.xml index 0e22d4c4d..d6b0f9562 100644 --- a/OpenPGP-Keychain/src/main/res/values-es/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-es/strings.xml @@ -111,7 +111,7 @@ Caché de frase de contraseña Compresión de mensaje Compresión de archivo - Forzar firmas V3 + Forzar firmas OpenPGPv3 antiguas Servidores de claves ID de clave Creación @@ -254,6 +254,7 @@ no has proporcionado una clave de firma cifrado de datos no válido datos corrompidos + ¡ha fallado la comprobación de integridad! ¡Los datos han sido modificados! no se ha podido encontrar un paquete con cifrado simétrico frase de contraseña incorrecta error al guardar algunas claves @@ -274,7 +275,7 @@ guardando... importando... exportando... - generando la clave, esto puede tardar un rato... + generando la clave, esto puede tardar más de 3 minutos... construyendo la clave... preparando la clave maestra... certificando la clave maestra... @@ -341,7 +342,7 @@ OpenPGP: Cifrar OpenPGP: Descifrar - ¡No hay aplicaciones registradas! + ¡No hay aplicaciones registradas¡\n\nLas aplicaciones de terceros pueden pedir acceso a OpenPGP Keychain. Después de recibir permiso, se mostrarán aquí. Mostrar la configuración avanzada Ocultar la configuración avanzada No se ha seleccionado ninguna clave @@ -351,7 +352,7 @@ Revocar acceso Nombre de paquete SHA-256 de firma de paquete - La siguiente aplicación solicita acceso a la API de OpenPGP Keychain.\n\n¿Permitir el acceso permanentemente? + La aplicación mostrada pide acceso a OpenPGP Keychain.\n¿Permitir acceso?\n\nAVISO: Si no sabes por qué ha aparecido esta pantalla, ¡deniega el acceso! Puedes revocar el acceso más tarde usando la ventana \'Aplicaciones Registradas\'. Permitir el acceso Denegar el acceso ¡Por favor, selecciona una clave! diff --git a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml index 51ca32637..016090d61 100644 --- a/OpenPGP-Keychain/src/main/res/values-fr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-fr/strings.xml @@ -111,7 +111,6 @@ Cache de la phrase de passe Compression des messages Compression des fichiers - Forcer les signatures V3 Serveurs de clefs ID de le clef Création @@ -274,7 +273,7 @@ sauvegarde... importation... exportation... - génération de la clef, ceci peut prendre un moment... + génération de la clef, ceci peut prendre jusqu\'à 3 minutes... assemblage de la clef... préparation de la clef maîtresse... certification de la clef maîtresse... @@ -341,7 +340,7 @@ OpenPGP : chiffrer OpenPGP : déchiffrer - Aucune application enregistrée ! + Aucune application enregistrée !\n\nLes applications tierces peuvent demander l\'accès au Porte-clefs OpenPGP. Après avoir autoriser l\'accès, elles seront listées ici. Afficher les paramètres avancés Masquer les paramètres avancés Aucune clef choisie @@ -351,7 +350,7 @@ Révoquer l\'accès Nom du paquet SHA-256 de la signature du paquet - L\'application suivante demande l\'accès à l\'API du Porte-clefs OpenPGP.\n\nPermettre l\'accès permanent ? + L\'application affichée demande l\'accès au Porte-clefs OpenPGP.\nPermettre l\'accès ?\n\nAvertissement : si vous ne savez pas pourquoi cet écran est apparu, refusé l\'accès ! Vous pourrez révoquer l\'accès plus tard en utilisant l\'écran « Applications enregistrées ». Permettre l\'accès Enlever l\'accès Veuillez choisir une clef ! diff --git a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml index 74af5c14b..15043c93a 100644 --- a/OpenPGP-Keychain/src/main/res/values-ja/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ja/strings.xml @@ -1,6 +1,8 @@ + 連絡先 + 秘密鍵 公開鍵の選択 秘密鍵の選択 暗号化 @@ -10,6 +12,7 @@ 鍵の編集 設定 登録済みのアプリケーション + 鍵サーバ設定 パスフレーズの変更 パスフレーズの設定 メールの送信... @@ -19,17 +22,31 @@ 鍵のエクスポート 複数鍵のエクスポート 鍵が見当りません + 鍵サーバへの要求 + 鍵サーバへアップロード 不明な署名の鍵です + 鍵検証 + 鍵の概要 ヘルプ - ユーザーID + ユーザID 一般 デフォルト 拡張 + 主鍵 + 主ユーザID + アクション + あなたの鍵を証明に利用します + 鍵のアップロード + 鍵サーバ + 暗号化と/もしくは署名 + 復号化と検証 署名 + 検証 復号化 + 復号化と検証 受信者の選択 ファイル暗号化 保存 @@ -40,12 +57,18 @@ パスフレーズの変更 パスフレーズの設定 検索 + 鍵サーバへアップロード 戻る + クリップボード + 共有... + 鍵検出 設定 + ヘルプ ファイルからインポート QRコードからインポート + インポート NFCからインポート すべての鍵のエクスポート ファイルへのエクスポート @@ -53,8 +76,22 @@ 鍵の生成 鍵の生成(上級) 検索 + 鍵サーバからのインポート + 鍵サーバからの更新 + 鍵サーバへのアップロード + 共有 + 指紋の共有... + すべての鍵の共有... + ...(指紋) + ...(鍵) + QRコードで共有(鍵) + QRコードで共有(指紋) + NFCで共有 + クリップボードへコピー 鍵を署名 Beamの設定 + キャンセル + 暗号化... 署名 メッセージ @@ -64,6 +101,7 @@ もう一度 アルゴリズム アスキー形式 + 受信者 暗号化後に削除 復号化後に削除 暗号化アルゴリズム @@ -73,23 +111,35 @@ パスフレーズキャッシュ メッセージの圧縮 ファイルの圧縮 - 強制的にV3形式の署名にする + 強制的に古いOpenPGPV3形式の署名にする + 鍵サーバ 鍵ID 生成 満了 使い方 鍵サイズ - 主ユーザーID + 主ユーザID 名前 コメント - Eメール + Eメールアドレス + 証明後選択した鍵サーバに鍵をアップロード + 指紋 + 選択 + + %d を選択 + + <名前なし> <無し> <鍵無し> 暗号化可能 署名可能 期限切れ - 指紋 + 破棄 + + %d の鍵サーバ + + 指紋: 秘密鍵: 無し @@ -107,6 +157,7 @@ 2時間 4時間 8時間 + 永遠 DSA ElGamal RSA @@ -130,20 +181,201 @@ 暗号化に成功しました。 クリップボードの中身の暗号化に成功しました。 もう一度パスフレーズを入れてください。 - 少なくとも1つの暗号鍵を選択して下さい。 + 少なくとも1つの暗号化鍵を選択して下さい。 + 少なくとも1つの暗号化鍵か署名鍵を選択して下さい。 + どのファイルを暗号化するか決めてください。\n注意: 既存のファイルがあると上書きされます。 + どのファイルを復号化するか決めてください。\n注意: 既存のファイルがあると上書きされます。 + どのファイルをエクスポートするか決めてください。\n注意: 既存のファイルがあると上書きされます。 + どのファイルをエクスポートするか決めてください。\n注意: 秘密鍵をエクスポートしています。\n注意: 既存のファイルがあると上書きされます。 + 鍵\'%s\'を本当に削除してもよいですか?\nこれは元に戻せません! + 選択したすべての鍵を本当に削除してよいですか?\nこれは元に戻せません。 + 秘密鍵\'%s\'を本当に削除してもよいですか?\nこれは元に戻せません! + + %d の鍵を追加しました + + + そして %d の鍵をアップロードしました。 + + + %d の鍵を追加しました。 + + + %d の鍵をアップロードしました。 + + 鍵の追加もしくは更新はありませんでした。 + 1つの鍵をエクスポートしました。 + %d の鍵をエクスポートしました。 + 鍵をエクスポートしていません。 + 備考: 副鍵として ElGamalだけがサポートされ, ElGamal は鍵サイズとして1536, 2048, 3072, 4096, 8192 だけが使えます。 + 鍵 %08X は見付かりませんでした。 + + %d の鍵を発見。 + + 不明な署名、ボタンを押して見付からない鍵を検出してください。 + + %d の問題ある鍵を無視しました。 おそらく次のオプションでエクスポートしています\n --export-secret-subkeys\n代りに次のオプションでエクスポートしてください。\n --export-secret-keys + + 鍵を鍵サーバにアップロードしました + 鍵に署名しました。 + このリストは空です! + NFCビームで鍵を送信しました! + 鍵はクリプボードにコピーされました! + 鍵はすでに署名されています! + 署名に使う鍵を選択して下さい! + この共有方法では鍵が大きすぎます! + \'%s\' の削除に失敗 + ファイルが見付かりません + 組になっている秘密鍵が見付かりません + 暗号化法が既知の種類内から見付かりません + 外部ストレージが準備できていません + \'%s\' は不正なEメールアドレスです + 鍵サイズは最低でも512bit必要です + 主鍵を ElGamal にすることはできません + 未知のアルゴリズムを選択しています + 名前を特定する必要があります + Eメールアドレスを特定する必要があります + 最低でも1つのユーザIDが必要です + 主ユーザIDは空にすることはできません + 主鍵が最低でも1つ必要です + 鍵が暗号化されていないかパスフレーズが与えられていません + 署名に失敗 + パスフレーズが与えられていません + 署名鍵を与えられていません + 暗号化データが不正です + 壊れたデータ + 完全性チェックが失敗しました! データに変更があります! + 対称鍵暗号のパケットが見付かりませんでした + 正しくないパスフレーズです + 鍵の保存エラー + 秘密鍵を取り出すことができません + ファイルシステムに存在するファイルではないバイナリデータはサポートされません。 ACTION_ENCRYPT_STREAM_AND_RETURN でのみサポートされます。 + Android NFC Beam機能を使うにはAndroid 4.1 (Jelly Bean) が必要です! + あなたのデバイスにはNFCが存在しません! + インポートするものがありません! + 期限日時は生成日時より後である必要があります + この連絡先はあなたなので削除できません。 + この連絡先はあなたなので削除できません。:\n%s + + \'自分の鍵\'画面から削除してください! + + 完了。 + 保存... + インポート... + エクスポート... + 鍵の生成、3分ほどかかります... + 鍵の構築中... + 主鍵の準備中... + 主鍵の検証中... + 主鍵輪の構築中... + 副鍵の追加中... + 鍵の保存... + + 鍵のエクスポート... + + 署名鍵の取り出し中... + 鍵の取り出し中... + ストリームの準備中... + データの暗号化中... + データの復号化中... + 署名の準備中... + 署名の生成中... + 署名処理中... + 署名の検証中... + 署名中... + データ読み込み中... + 鍵検索中... + データの展開中... + 完全性の検証中... + \'%s\' を完全に削除中… + 要求中... + 公開鍵の検索 + 秘密鍵の検索 + 鍵の共有... + 512 + 1024 + 2048 + 4096 + 早い + とても遅い + 開始 + NFC Beam + Changelog + これについて + バージョン: + 選択した鍵のインポート + 選択した鍵のインポート、署名、そしてアップロード + クリップボードからインポート + + ID %s のQRコードがありません + + QRコードをID 1で始めてください + 不適QRコード! もう一度! + QRコードの読み取り完了! + QRコードに含まれる指紋が短かすぎます (< 16 文字) + \'バーコードスキャナー\'でQRコードをスキャンする + NFCで鍵を受信しました、デバイスのロックを解除する必要があります。 + ヘルプ + クリップボードから鍵を取得 + OpenPGP: ファイル復号 + OpenPGP: 鍵のインポート + OpenPGP: 暗号化 + OpenPGP: 復号化 + 登録されていないアプリケーション!\n\nサードパーティアプリケーションはOpenPGP Keychainにアクセスを要求できます。アクセスを与えた後、それらはここにリストされます。 + 拡張設定を表示 + 拡張設定を非表示 + 鍵が選択されていない + 鍵の選択 + 保存 + キャンセル + 破棄されたアクセス + パッケージ名 + パッケージの署名 SHA-256 + 表示されているアプリケーションはOpenPGP Keychainへのアクセスを要求しています。\nアクセスを許可しますか?\n\n注意: もしなぜスクリーンに表れたかわからないなら、アクセスを許可しないでください! あなたは\'登録済みアプリケーション\'スクリーンを使って、以降のアクセスを破棄するこもできます。 + 許可されたアクセス + 許可されないアクセス + 鍵を選択してください! + このユーザIDについて公開鍵が見付かりません: + このユーザIDについて1つ以上の公開鍵が存在します: + 受信者リストを確認してください! + 署名チェックが失敗! 違うところからこのアプリをインストールしましたか? もし攻撃されてでなくそうであるなら、OpenPGP Keychainにあるこのアプリの登録を破棄し、再度アプリを登録してください。 + QRコードで共有 + すべてのQRコードを見る場合、\'次\' を押して一つ一つスキャンしてください。 + 指紋: + %2$d の ID %1$d のQRコード + NFCで共有 + + %d の鍵を選択。 + + すでにその鍵は存在しません... + で始める + もしくは + あなた所有の鍵を作る + 鍵のインポート。 + この連絡先を暗号化 + この連絡先の鍵を検証 + 情報 + 証明 + 連絡先 + 暗号化 + 復号化 + 鍵のインポート + 自分の鍵 + 登録済みのアプリ + ナビゲーションドロワーを開く + ナビゲーションドロワーを閉める diff --git a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml index 3f1cd3cd2..72a8fdea8 100644 --- a/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-nl-rNL/strings.xml @@ -73,7 +73,6 @@ Wachtwoordcache Berichtcompressie Bestandscompressie - V3-handtekeningen afdwingen Sleutel-id Aanmaak Verlopen @@ -176,7 +175,6 @@ opslaan... importeren... exporteren... - sleutel genereren, een ogenblik geduld... sleutel maken... hoofdsleutel voorbereiden... hoofdsleutel certificeren... @@ -227,13 +225,11 @@ OpenPGP: versleutelen OpenPGP: ontsleutelen - Geen geregistreerde apps Geen sleutel geselecteerd Sleutel selecteren Opslaan Annuleren Toegang herroepen - De volgende app vraagt toegang to de KeyChain-API van OpenPGP\n\nAltijd toestaan? Toegang toestaan Toegang weigeren Selecteert u a.u.b. een sleutel diff --git a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml index 131e5aeeb..cbc394766 100644 --- a/OpenPGP-Keychain/src/main/res/values-ru/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-ru/strings.xml @@ -111,7 +111,6 @@ Помнить пароль Сжатие сообщения Сжатие файла - Использовать V3 подписи Серверы ключей ID ключа Создан @@ -283,7 +282,7 @@ сохранение... импорт... экспорт... - создание ключа... на это нужно время... + создание ключа. это может занять до 3 минут... создание ключа... подготовка основного ключа... сертификация основного ключа... @@ -352,7 +351,7 @@ OpenPGP: Зашифровать OpenPGP: Расшифровать - Нет связанных приложений! + Нет связанных программ!\n\nСторонние программы могут запросить доступ к OpenPGP Keychain, после чего они будут отражаться здесь. Показать расширенные настройки Скрыть расширенные настройки Ключ не выбран @@ -362,7 +361,7 @@ Отозвать доступ Наименование пакета SHA-256 подписи пакета - Приложение запрашивает доступ к OpenPGP Keychain API.\nРазрешить доступ? + Данное приложение запрашивает доступ к OpenPGP Keychain.\nРазрешить доступ?\n\nВНИМАНИЕ: Если вы не знаете почему возник этот запрос, откажите в доступе!\nПозже вы можете отозвать право доступа в разделе \"Зарегистрированные программы\". Разрешить доступ Запретить доступ Пожалуйста, выберите ключ! diff --git a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml index 8ec698bb0..5bb5225b5 100644 --- a/OpenPGP-Keychain/src/main/res/values-tr/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-tr/strings.xml @@ -99,7 +99,6 @@ kaydediliyor... alıyor... veriyor... - anahtar üretiliyor, bu biraz süre alabilir... anahtar oluşturuluyor... imza hazırlanıyor... imza oluşturuluyor... diff --git a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml index 344ca0966..47cbb38b3 100644 --- a/OpenPGP-Keychain/src/main/res/values-uk/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-uk/strings.xml @@ -111,7 +111,7 @@ Кеш парольної фрази Стиснення повідомлення Стиснення файлу - Примусові підписи V3 + Примусово старі підписи OpenPGPv3 Сервери ключів ІД ключа Створення @@ -262,6 +262,7 @@ не подано ключ підпису недійсні дані шифрування пошкодити дані + Невдала перевірка цілісності! Дані вже змінено! не знайдено пакунок з симетричним шифруванням помилкова парольна фраза помилка збереження деяких ключів @@ -283,7 +284,7 @@ збереження… імпортується… експортується… - генерується ключ, зачекайте… + генерується ключ, вона може тривати до 3 хвилин… будується ключ… підготовка основного ключа… сертифікація основного ключа… @@ -352,7 +353,7 @@ OpenPGP: зашифрувати OpenPGP: розшифрувати - Немає зареєстрованих програм! + Нема зареєстрованих програм!\n\nСтороні програми можуть вимагати доступ до OpenPGP Keychain. Після надання доступу вони будуть наведені тут. Показати додаткові налаштування Приховати додаткові налаштування Не вибрано ключа @@ -362,7 +363,7 @@ Відкликати доступ Назва пакунку SHA-256 підписку пакунку - Наступна програм запитала доступ до OpenPGP Keychain API.\n\nДозволити постійний доступ? + Показана програма запитує доступ до OpenPGP Keychain.\nДозволити доступ?\n\nУВАГА: якщо ви не знаєте, чому цей екран появився, не дозволяйте доступ! Ви можете відкликати доступ пізніше, використовуючи екран \'Зареєстровані програми\'. Дозволити доступ Не дозволити доступ Будь ласка, виберіть ключ! diff --git a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml index 4ff02c7ed..30d6a3518 100644 --- a/OpenPGP-Keychain/src/main/res/values-zh/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values-zh/strings.xml @@ -109,7 +109,6 @@ 保存... 导入中... 导出中... - 正在生成密钥,这可能需要一会 建立密钥 正在准备主密钥 正在验证签名... -- cgit v1.2.3 From b952af90e6b5a3007f4d1230e1ec78a0d90cbc29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 13:04:29 +0100 Subject: Builder pattern for PgpOperationIncoming --- .../keychain/pgp/PgpOperationIncoming.java | 135 ++++++++++++++------- .../keychain/service/KeychainIntentService.java | 13 +- .../keychain/service/remote/OpenPgpService.java | 10 +- 3 files changed, 103 insertions(+), 55 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java index c57691f8d..b018f35d8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java @@ -50,6 +50,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilde import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -68,32 +69,74 @@ import java.security.SignatureException; import java.util.Iterator; /** - * TODO: make builder pattern like in PgpOperationOutgoing + * This class uses a Builder pattern! */ public class PgpOperationIncoming { - private Context mContext; - private ProgressDialogUpdater mProgress; - private InputData mData; - private OutputStream mOutStream; - - public PgpOperationIncoming(Context context, ProgressDialogUpdater progress, InputData data, - OutputStream outStream) { - super(); - this.mContext = context; - this.mProgress = progress; - this.mData = data; - this.mOutStream = outStream; + private Context context; + private InputData data; + private OutputStream outStream; + + private ProgressDialogUpdater progress; + boolean assumeSymmetric; + String passphrase; + + private PgpOperationIncoming(Builder builder) { + // private Constructor can only be called from Builder + this.context = builder.context; + this.data = builder.data; + this.outStream = builder.outStream; + + this.progress = builder.progress; + this.assumeSymmetric = builder.assumeSymmetric; + this.passphrase = builder.passphrase; + } + + public static class Builder { + // mandatory parameter + private Context context; + private InputData data; + private OutputStream outStream; + + // optional + private ProgressDialogUpdater progress = null; + private boolean assumeSymmetric = false; + private String passphrase = ""; + + public Builder(Context context, InputData data, OutputStream outStream) { + this.context = context; + this.data = data; + this.outStream = outStream; + } + + public Builder progress(ProgressDialogUpdater progress) { + this.progress = progress; + return this; + } + + public Builder assumeSymmetric(boolean assumeSymmetric) { + this.assumeSymmetric = assumeSymmetric; + return this; + } + + public Builder passphrase(String passphrase) { + this.passphrase = passphrase; + return this; + } + + public PgpOperationIncoming build() { + return new PgpOperationIncoming(this); + } } public void updateProgress(int message, int current, int total) { - if (mProgress != null) { - mProgress.setProgress(message, current, total); + if (progress != null) { + progress.setProgress(message, current, total); } } public void updateProgress(int current, int total) { - if (mProgress != null) { - mProgress.setProgress(current, total); + if (progress != null) { + progress.setProgress(current, total); } } @@ -126,15 +169,12 @@ public class PgpOperationIncoming { return false; } - public Bundle decryptAndVerify(String passphrase, boolean assumeSymmetric) throws IOException, - PgpGeneralException, PGPException, SignatureException { - if (passphrase == null) { - passphrase = ""; - } + public Bundle decryptAndVerify() + throws IOException, PgpGeneralException, PGPException, SignatureException { Bundle returnData = new Bundle(); // automatically works with ascii armor input and binary - InputStream in = PGPUtil.getDecoderStream(mData.getInputStream()); + InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); @@ -149,7 +189,7 @@ public class PgpOperationIncoming { } if (enc == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_invalid_data)); + throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); } InputStream clear; @@ -173,7 +213,7 @@ public class PgpOperationIncoming { if (pbe == null) { throw new PgpGeneralException( - mContext.getString(R.string.error_no_symmetric_encryption_packet)); + context.getString(R.string.error_no_symmetric_encryption_packet)); } updateProgress(R.string.progress_preparing_streams, currentProgress, 100); @@ -199,7 +239,7 @@ public class PgpOperationIncoming { Object obj = it.next(); if (obj instanceof PGPPublicKeyEncryptedData) { PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; - secretKey = ProviderHelper.getPGPSecretKeyByKeyId(mContext, encData.getKeyID()); + secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID()); if (secretKey != null) { pbe = encData; break; @@ -208,7 +248,7 @@ public class PgpOperationIncoming { } if (secretKey == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_no_secret_key_found)); + throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); } currentProgress += 5; @@ -220,11 +260,11 @@ public class PgpOperationIncoming { passphrase.toCharArray()); privateKey = secretKey.extractPrivateKey(keyDecryptor); } catch (PGPException e) { - throw new PGPException(mContext.getString(R.string.error_wrong_passphrase)); + throw new PGPException(context.getString(R.string.error_wrong_passphrase)); } if (privateKey == null) { throw new PgpGeneralException( - mContext.getString(R.string.error_could_not_extract_private_key)); + context.getString(R.string.error_could_not_extract_private_key)); } currentProgress += 5; updateProgress(R.string.progress_preparing_streams, currentProgress, 100); @@ -263,7 +303,7 @@ public class PgpOperationIncoming { for (int i = 0; i < sigList.size(); ++i) { signature = sigList.get(i); signatureKey = ProviderHelper - .getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); + .getPGPPublicKeyByKeyId(context, signature.getKeyID()); if (signatureKeyId == 0) { signatureKeyId = signature.getKeyID(); } @@ -274,7 +314,7 @@ public class PgpOperationIncoming { signatureKeyId = signature.getKeyID(); String userId = null; PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( - mContext, signatureKeyId); + context, signatureKeyId); if (signKeyRing != null) { userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); } @@ -306,7 +346,7 @@ public class PgpOperationIncoming { updateProgress(R.string.progress_decrypting, currentProgress, 100); PGPLiteralData literalData = (PGPLiteralData) dataChunk; - OutputStream out = mOutStream; + OutputStream out = outStream; byte[] buffer = new byte[1 << 16]; InputStream dataIn = literalData.getInputStream(); @@ -321,7 +361,7 @@ public class PgpOperationIncoming { int n; // int progress = 0; - long startPos = mData.getStreamPosition(); + long startPos = data.getStreamPosition(); while ((n = dataIn.read(buffer)) > 0) { out.write(buffer, 0, n); // progress += n; @@ -338,11 +378,11 @@ public class PgpOperationIncoming { // unknown size, but try to at least have a moving, slowing down progress bar // currentProgress = startProgress + (endProgress - startProgress) * progress // / (progress + 100000); - if (mData.getSize() - startPos == 0) { + if (data.getSize() - startPos == 0) { currentProgress = endProgress; } else { currentProgress = (int) (startProgress + (endProgress - startProgress) - * (mData.getStreamPosition() - startPos) / (mData.getSize() - startPos)); + * (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); } updateProgress(currentProgress, 100); } @@ -354,7 +394,7 @@ public class PgpOperationIncoming { PGPSignature messageSignature = signatureList.get(signatureIndex); //Now check binding signatures - boolean keyBinding_isok = verifyKeyBinding(mContext, messageSignature, signatureKey); + boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey); boolean sig_isok = signature.verify(messageSignature); returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok); } @@ -370,7 +410,7 @@ public class PgpOperationIncoming { } else { // failed Log.d(Constants.TAG, "Integrity verification: failed!"); - throw new PgpGeneralException(mContext.getString(R.string.error_integrity_check_failed)); + throw new PgpGeneralException(context.getString(R.string.error_integrity_check_failed)); } } else { // no integrity check @@ -381,12 +421,13 @@ public class PgpOperationIncoming { return returnData; } + // TODO: merge into decryptAndVerify by checking what the input is public Bundle verifyText() throws IOException, PgpGeneralException, PGPException, SignatureException { Bundle returnData = new Bundle(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - ArmoredInputStream aIn = new ArmoredInputStream(mData.getInputStream()); + ArmoredInputStream aIn = new ArmoredInputStream(data.getInputStream()); updateProgress(R.string.progress_done, 0, 100); @@ -409,7 +450,7 @@ public class PgpOperationIncoming { out.close(); byte[] clearText = out.toByteArray(); - mOutStream.write(clearText); + outStream.write(clearText); returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); @@ -418,14 +459,14 @@ public class PgpOperationIncoming { PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); if (sigList == null) { - throw new PgpGeneralException(mContext.getString(R.string.error_corrupt_data)); + throw new PgpGeneralException(context.getString(R.string.error_corrupt_data)); } PGPSignature signature = null; long signatureKeyId = 0; PGPPublicKey signatureKey = null; for (int i = 0; i < sigList.size(); ++i) { signature = sigList.get(i); - signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(mContext, signature.getKeyID()); + signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(context, signature.getKeyID()); if (signatureKeyId == 0) { signatureKeyId = signature.getKeyID(); } @@ -435,7 +476,7 @@ public class PgpOperationIncoming { } else { signatureKeyId = signature.getKeyID(); String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, signatureKeyId); if (signKeyRing != null) { userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); @@ -449,8 +490,8 @@ public class PgpOperationIncoming { if (signature == null) { returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); - if (mProgress != null) - mProgress.setProgress(R.string.progress_done, 100, 100); + if (progress != null) + progress.setProgress(R.string.progress_done, 100, 100); return returnData; } @@ -479,7 +520,7 @@ public class PgpOperationIncoming { boolean sig_isok = signature.verify(); //Now check binding signatures - boolean keyBinding_isok = verifyKeyBinding(mContext, signature, signatureKey); + boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey); returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok); @@ -487,7 +528,7 @@ public class PgpOperationIncoming { return returnData; } - public boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { + private boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { long signatureKeyId = signature.getKeyID(); boolean keyBinding_isok = false; String userId = null; @@ -505,7 +546,7 @@ public class PgpOperationIncoming { return keyBinding_isok; } - public boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + private boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean subkeyBinding_isok = false; boolean tmp_subkeyBinding_isok = false; boolean primkeyBinding_isok = false; diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 8d8f4e796..422ce010c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -481,13 +481,16 @@ public class KeychainIntentService extends IntentService implements ProgressDial // verifyText and decrypt returning additional resultData values for the // verification of signatures - PgpOperationIncoming operation = new PgpOperationIncoming(this, this, inputData, outStream); + PgpOperationIncoming.Builder builder = new PgpOperationIncoming.Builder(this, inputData, outStream); + builder.progress(this); + if (signedOnly) { - resultData = operation.verifyText(); + resultData = builder.build().verifyText(); } else { - resultData = operation.decryptAndVerify( - PassphraseCacheService.getCachedPassphrase(this, secretKeyId), - assumeSymmetricEncryption); + builder.assumeSymmetric(assumeSymmetricEncryption) + .passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + + resultData = builder.build().decryptAndVerify(); } outStream.close(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index ec3f40d23..74e311294 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -384,15 +384,19 @@ public class OpenPgpService extends RemoteService { Bundle outputBundle; - PgpOperationIncoming operation = new PgpOperationIncoming(getContext(), null, inputData, os); + PgpOperationIncoming.Builder builder = new PgpOperationIncoming.Builder(this, inputData, os); + if (signedOnly) { - outputBundle = operation.verifyText(); + outputBundle = builder.build().verifyText(); } else { + builder.assumeSymmetric(false) + .passphrase(passphrase); + // Do we want to do this: instead of trying to get the passphrase before // pause stream when passphrase is missing and then resume??? // TODO: this also decrypts with other secret keys without passphrase!!! - outputBundle = operation.decryptAndVerify(passphrase, false); + outputBundle = builder.build().decryptAndVerify(); } // outputStream.close(); -- cgit v1.2.3 From 7436bf578c23dc012dd90a60f82d9afe3ee891e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 13:06:57 +0100 Subject: cleanup --- .../sufficientlysecure/keychain/pgp/PgpOperationIncoming.java | 4 ++-- .../sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java index b018f35d8..b6d7433be 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java @@ -624,8 +624,8 @@ public class PgpOperationIncoming { // taken from ClearSignedFileProcessor in BC - private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, - IOException { + private static void processLine(PGPSignature sig, byte[] line) + throws SignatureException, IOException { int length = getLengthWithoutWhiteSpace(line); if (length > 0) { sig.update(line, 0, length); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java index 52e41306f..044fe5aad 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java @@ -539,7 +539,8 @@ public class PgpOperationOutgoing { private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPSignatureGenerator pSignatureGenerator) throws IOException, SignatureException { + final PGPSignatureGenerator pSignatureGenerator) + throws IOException, SignatureException { if (pLine == null) { return; @@ -564,8 +565,8 @@ public class PgpOperationOutgoing { } private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPV3SignatureGenerator pSignatureGenerator) throws IOException, - SignatureException { + final PGPV3SignatureGenerator pSignatureGenerator) + throws IOException, SignatureException { if (pLine == null) { return; @@ -589,8 +590,4 @@ public class PgpOperationOutgoing { pSignatureGenerator.update(data); } - private static boolean isWhiteSpace(byte b) { - return b == '\r' || b == '\n' || b == '\t' || b == ' '; - } - } -- cgit v1.2.3 From e75fd5a156acf3e2012dd8ea5eeff416e08773e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 19 Feb 2014 13:12:08 +0100 Subject: cleanup --- .../org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java index b6d7433be..51e93935d 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java @@ -528,7 +528,7 @@ public class PgpOperationIncoming { return returnData; } - private boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { + private static boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { long signatureKeyId = signature.getKeyID(); boolean keyBinding_isok = false; String userId = null; @@ -546,7 +546,7 @@ public class PgpOperationIncoming { return keyBinding_isok; } - private boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + private static boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean subkeyBinding_isok = false; boolean tmp_subkeyBinding_isok = false; boolean primkeyBinding_isok = false; @@ -589,7 +589,7 @@ public class PgpOperationIncoming { return (subkeyBinding_isok & primkeyBinding_isok); } - private boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + private static boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { boolean primkeyBinding_isok = false; JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); @@ -622,7 +622,6 @@ public class PgpOperationIncoming { return primkeyBinding_isok; } - // taken from ClearSignedFileProcessor in BC private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, IOException { -- cgit v1.2.3 From b9ad95b93d707759c6b83ee66060f688541869cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ha=C3=9F?= Date: Thu, 20 Feb 2014 17:50:53 +0100 Subject: Replaced Toasts with AppMsg-Library notifys --- .../org/sufficientlysecure/keychain/ui/ImportKeysActivity.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 1864e0d9d..85c162d2a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -50,6 +50,7 @@ import android.widget.ArrayAdapter; import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; +import com.devspark.appmsg.AppMsg; public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNavigationListener { public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY"; @@ -282,8 +283,8 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa Log.d(Constants.TAG, "fingerprint: " + fingerprint); if (fingerprint.length() < 16) { - Toast.makeText(this, R.string.import_qr_code_too_short_fingerprint, - Toast.LENGTH_LONG).show(); + AppMsg.makeText(this, R.string.import_qr_code_too_short_fingerprint, + AppMsg.STYLE_ALERT).show(); return; } @@ -392,7 +393,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa } else { toastMessage = getString(R.string.no_keys_added_or_updated); } - Toast.makeText(ImportKeysActivity.this, toastMessage, Toast.LENGTH_SHORT) + AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO) .show(); if (bad > 0) { AlertDialog.Builder alert = new AlertDialog.Builder( @@ -474,7 +475,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa // start service with intent startService(intent); } else { - Toast.makeText(this, R.string.error_nothing_import, Toast.LENGTH_LONG).show(); + AppMsg.makeText(this, R.string.error_nothing_import, AppMsg.STYLE_ALERT).show(); } } -- cgit v1.2.3 From f6c9fd97076e6c71c02491426730409e8a191f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ha=C3=9F?= Date: Thu, 20 Feb 2014 17:51:33 +0100 Subject: Deleted Toast import --- .../main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 85c162d2a..a5027ac1c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -47,7 +47,6 @@ import android.support.v7.app.ActionBar; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; -import android.widget.Toast; import com.beardedhen.androidbootstrap.BootstrapButton; import com.devspark.appmsg.AppMsg; -- cgit v1.2.3 From 77c635ea120957a22528d3d943a09f15c9230412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 20 Feb 2014 20:13:36 +0100 Subject: rename in README --- .../java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java index 51e93935d..3f0cb0d1a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java @@ -50,7 +50,6 @@ import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilde import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; -- cgit v1.2.3 From 836ef8b7abe92056e714dfa7f392990d53dd2b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ha=C3=9F?= Date: Thu, 20 Feb 2014 21:07:59 +0100 Subject: Updated library section (AppMsg library) --- OpenPGP-Keychain/src/main/res/raw/help_about.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw/help_about.html b/OpenPGP-Keychain/src/main/res/raw/help_about.html index 85130965c..882049c49 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_about.html @@ -34,8 +34,9 @@ And don't add newlines before or after p tags because of transifex -->
                                                • ZXing (Apache License v2)
                                                • SpongyCastle (MIT X11 License)
                                                • HtmlTextView (Apache License v2)
                                                • +
                                                • Android AppMsg Library (Apache License v2)
                                                • Icons from RRZE Icon Set (Creative Commons Attribution Share-Alike licence 3.0)
                                                • Icons from Tango Icon Set (Public Domain)
                                                - \ No newline at end of file + -- cgit v1.2.3 From b4f977673f32278e6a5c2ef5abd071e2d934adaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2014 01:03:20 +0100 Subject: rename to OpenKeychain --- OpenPGP-Keychain/src/main/res/values/static_strings.xml | 2 +- OpenPGP-Keychain/src/main/res/values/strings.xml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/values/static_strings.xml b/OpenPGP-Keychain/src/main/res/values/static_strings.xml index 3c9cf6673..faf1e687a 100644 --- a/OpenPGP-Keychain/src/main/res/values/static_strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/static_strings.xml @@ -1,6 +1,6 @@ - OpenPGP Keychain + OpenKeychain \ No newline at end of file diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml index b8a03a82d..178ef8f17 100644 --- a/OpenPGP-Keychain/src/main/res/values/strings.xml +++ b/OpenPGP-Keychain/src/main/res/values/strings.xml @@ -368,13 +368,13 @@ Get key from clipboard - OpenPGP: Decrypt File - OpenPGP: Import Key - OpenPGP: Encrypt - OpenPGP: Decrypt + OpenKeychain: Decrypt File + OpenKeychain: Import Key + OpenKeychain: Encrypt + OpenKeychain: Decrypt - No registered applications!\n\nThird-party applications can request access to OpenPGP Keychain. After granting access, they will be listed here. + No registered applications!\n\nThird-party applications can request access to OpenKeychain. After granting access, they will be listed here. Show advanced settings Hide advanced settings No key selected @@ -384,14 +384,14 @@ Revoke access Package Name SHA-256 of Package Signature - The displayed application requests access to OpenPGP Keychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen. + The displayed application requests access to OpenKeychain.\nAllow access?\n\nWARNING: If you do not know why this screen appeared, disallow access! You can revoke access later using the \'Registered Applications\' screen. Allow access Disallow access Please select a key! No public keys were found for these user ids: More than one public key exist for these user ids: Please review the list of recipients! - Signature check failed! Have you installed this app from a different source? If you are sure that this is not an attack, revoke this app\'s registration in OpenPGP Keychain and then register the app again. + Signature check failed! Have you installed this app from a different source? If you are sure that this is not an attack, revoke this app\'s registration in OpenKeychain and then register the app again. Share with QR Code -- cgit v1.2.3 From aaddd26b51a9d3a8e230a704cb33de8e9a5bcbef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2014 02:31:30 +0100 Subject: verification of cleartext signatures works --- .../keychain/pgp/PgpOperationIncoming.java | 77 +++++++++++++++++----- .../keychain/pgp/PgpOperationOutgoing.java | 16 ++++- .../keychain/service/KeychainIntentService.java | 17 ++--- .../keychain/service/remote/OpenPgpService.java | 39 ++++++----- .../keychain/ui/DecryptActivity.java | 6 +- 5 files changed, 106 insertions(+), 49 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java index 3f0cb0d1a..7f78f6b07 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java @@ -168,15 +168,37 @@ public class PgpOperationIncoming { return false; } - public Bundle decryptAndVerify() + /** + * Decrypts and/or verifies data based on parameters of class + * + * @return + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws SignatureException + */ + public Bundle decryptVerify() throws IOException, PgpGeneralException, PGPException, SignatureException { - Bundle returnData = new Bundle(); + // automatically works with ascii armor input and binary InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); + if (in instanceof ArmoredInputStream) { + ArmoredInputStream aIn = (ArmoredInputStream) in; + // it is ascii armored + Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine()); + + if (aIn.isClearText()) { + // a cleartext signature, verify it with the other method + return verifyCleartextSignature(aIn); + } else { + // go on... + } + } PGPObjectFactory pgpF = new PGPObjectFactory(in); PGPEncryptedDataList enc; Object o = pgpF.nextObject(); + Log.d(Constants.TAG, "o: " + o.getClass().getName()); int currentProgress = 0; updateProgress(R.string.progress_reading_data, currentProgress, 100); @@ -345,7 +367,6 @@ public class PgpOperationIncoming { updateProgress(R.string.progress_decrypting, currentProgress, 100); PGPLiteralData literalData = (PGPLiteralData) dataChunk; - OutputStream out = outStream; byte[] buffer = new byte[1 << 16]; InputStream dataIn = literalData.getInputStream(); @@ -359,10 +380,11 @@ public class PgpOperationIncoming { } int n; + // TODO: progress calculation is broken here! Try to rework it based on commented code! // int progress = 0; long startPos = data.getStreamPosition(); while ((n = dataIn.read(buffer)) > 0) { - out.write(buffer, 0, n); + outStream.write(buffer, 0, n); // progress += n; if (signature != null) { try { @@ -392,9 +414,13 @@ public class PgpOperationIncoming { PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); PGPSignature messageSignature = signatureList.get(signatureIndex); + // these are not cleartext signatures! + returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false); + //Now check binding signatures boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey); boolean sig_isok = signature.verify(messageSignature); + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok); } } @@ -420,17 +446,29 @@ public class PgpOperationIncoming { return returnData; } - // TODO: merge into decryptAndVerify by checking what the input is - public Bundle verifyText() throws IOException, PgpGeneralException, - PGPException, SignatureException { + /** + * This method verifies cleartext signatures + * as defined in http://tools.ietf.org/html/rfc4880#section-7 + *

                                                + * The method is heavily based on + * pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java + * + * @return + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws SignatureException + */ + private Bundle verifyCleartextSignature(ArmoredInputStream aIn) + throws IOException, PgpGeneralException, PGPException, SignatureException { Bundle returnData = new Bundle(); + // cleartext signatures are never encrypted ;) + returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, true); ByteArrayOutputStream out = new ByteArrayOutputStream(); - ArmoredInputStream aIn = new ArmoredInputStream(data.getInputStream()); updateProgress(R.string.progress_done, 0, 100); - // mostly taken from pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); int lookAhead = readInputLine(lineOut, aIn); byte[] lineSep = getLineSeparator(); @@ -489,13 +527,13 @@ public class PgpOperationIncoming { if (signature == null) { returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); - if (progress != null) - progress.setProgress(R.string.progress_done, 100, 100); + updateProgress(R.string.progress_done, 100, 100); return returnData; } - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = + new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); signature.init(contentVerifierBuilderProvider, signatureKey); @@ -527,11 +565,11 @@ public class PgpOperationIncoming { return returnData; } - private static boolean verifyKeyBinding(Context mContext, PGPSignature signature, PGPPublicKey signatureKey) { + private static boolean verifyKeyBinding(Context context, PGPSignature signature, PGPPublicKey signatureKey) { long signatureKeyId = signature.getKeyID(); boolean keyBinding_isok = false; String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(mContext, + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, signatureKeyId); PGPPublicKey mKey = null; if (signKeyRing != null) { @@ -621,7 +659,14 @@ public class PgpOperationIncoming { return primkeyBinding_isok; } - // taken from ClearSignedFileProcessor in BC + /** + * Mostly taken from ClearSignedFileProcessor in Bouncy Castle + * + * @param sig + * @param line + * @throws SignatureException + * @throws IOException + */ private static void processLine(PGPSignature sig, byte[] line) throws SignatureException, IOException { int length = getLengthWithoutWhiteSpace(line); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java index 044fe5aad..fd859fd5a 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java @@ -187,7 +187,17 @@ public class PgpOperationOutgoing { } } - public void signAndEncrypt() + /** + * Signs and/or encrypts data based on parameters of class + * + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws NoSuchProviderException + * @throws NoSuchAlgorithmException + * @throws SignatureException + */ + public void signEncrypt() throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, NoSuchAlgorithmException, SignatureException { @@ -383,6 +393,8 @@ public class PgpOperationOutgoing { } armorOut.write(newline); + + // update signature buffer with input line if (signatureForceV3) { signatureV3Generator.update(newline); processLine(line, armorOut, signatureV3Generator); @@ -430,7 +442,7 @@ public class PgpOperationOutgoing { updateProgress(R.string.progress_done, 100, 100); } - // TODO: merge this into signAndEncrypt method! + // TODO: merge this into signEncrypt method! // TODO: allow binary input for this class public void generateSignature() throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 422ce010c..4ce1569f0 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -120,7 +120,6 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String ENCRYPT_PROVIDER_URI = "provider_uri"; // decrypt/verify - public static final String DECRYPT_SIGNED_ONLY = "signed_only"; public static final String DECRYPT_RETURN_BYTES = "return_binary"; public static final String DECRYPT_CIPHERTEXT_BYTES = "ciphertext_bytes"; public static final String DECRYPT_ASSUME_SYMMETRIC = "assume_symmetric"; @@ -185,6 +184,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial public static final String RESULT_SIGNATURE = "signature"; public static final String RESULT_SIGNATURE_KEY_ID = "signature_key_id"; public static final String RESULT_SIGNATURE_USER_ID = "signature_user_id"; + public static final String RESULT_CLEARTEXT_SIGNATURE_ONLY = "signature_only"; public static final String RESULT_SIGNATURE_SUCCESS = "signature_success"; public static final String RESULT_SIGNATURE_UNKNOWN = "signature_unknown"; @@ -338,7 +338,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - builder.build().signAndEncrypt(); + builder.build().signEncrypt(); } else { Log.d(Constants.TAG, "encrypt..."); builder.enableAsciiArmorOutput(useAsciiArmor) @@ -351,7 +351,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - builder.build().signAndEncrypt(); + builder.build().signEncrypt(); } outStream.close(); @@ -404,7 +404,6 @@ public class KeychainIntentService extends IntentService implements ProgressDial long secretKeyId = data.getLong(ENCRYPT_SECRET_KEY_ID); byte[] bytes = data.getByteArray(DECRYPT_CIPHERTEXT_BYTES); - boolean signedOnly = data.getBoolean(DECRYPT_SIGNED_ONLY); boolean returnBytes = data.getBoolean(DECRYPT_RETURN_BYTES); boolean assumeSymmetricEncryption = data.getBoolean(DECRYPT_ASSUME_SYMMETRIC); @@ -484,14 +483,10 @@ public class KeychainIntentService extends IntentService implements ProgressDial PgpOperationIncoming.Builder builder = new PgpOperationIncoming.Builder(this, inputData, outStream); builder.progress(this); - if (signedOnly) { - resultData = builder.build().verifyText(); - } else { - builder.assumeSymmetric(assumeSymmetricEncryption) - .passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); + builder.assumeSymmetric(assumeSymmetricEncryption) + .passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - resultData = builder.build().decryptAndVerify(); - } + resultData = builder.build().decryptVerify(); outStream.close(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 74e311294..688537be5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -168,7 +168,7 @@ public class OpenPgpService extends RemoteService { .signatureForceV3(false) .signatureKeyId(appSettings.getKeyId()) .signaturePassphrase(passphrase); - builder.build().signAndEncrypt(); + builder.build().signEncrypt(); } finally { is.close(); os.close(); @@ -257,7 +257,7 @@ public class OpenPgpService extends RemoteService { builder.signatureKeyId(Id.key.none); } // execute PGP operation! - builder.build().signAndEncrypt(); + builder.build().signEncrypt(); } finally { is.close(); os.close(); @@ -297,7 +297,7 @@ public class OpenPgpService extends RemoteService { // checked if it is text with BEGIN and END tags // String message = new String(inputBytes); // Log.d(Constants.TAG, "in: " + message); - boolean signedOnly = false; +// boolean signedOnly = false; // Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(message); // if (matcher.matches()) { // Log.d(Constants.TAG, "PGP_MESSAGE matched"); @@ -386,35 +386,37 @@ public class OpenPgpService extends RemoteService { Bundle outputBundle; PgpOperationIncoming.Builder builder = new PgpOperationIncoming.Builder(this, inputData, os); - if (signedOnly) { - outputBundle = builder.build().verifyText(); - } else { - builder.assumeSymmetric(false) - .passphrase(passphrase); +// if (signedOnly) { +// outputBundle = builder.build().verifyText(); +// } else { + builder.assumeSymmetric(false) + .passphrase(passphrase); - // Do we want to do this: instead of trying to get the passphrase before - // pause stream when passphrase is missing and then resume??? + // Do we want to do this: instead of trying to get the passphrase before + // pause stream when passphrase is missing and then resume??? - // TODO: this also decrypts with other secret keys without passphrase!!! - outputBundle = builder.build().decryptAndVerify(); - } + // TODO: this also decrypts with other secret keys without passphrase!!! + outputBundle = builder.build().decryptVerify(); +// } // outputStream.close(); // byte[] outputBytes = ((ByteArrayOutputStream) outputStream).toByteArray(); // get signature informations from bundle - boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE); + boolean signature = outputBundle.getBoolean(KeychainIntentService.RESULT_SIGNATURE, false); if (signature) { long signatureKeyId = outputBundle - .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID); + .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, 0); String signatureUserId = outputBundle .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID); boolean signatureSuccess = outputBundle - .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS); + .getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false); boolean signatureUnknown = outputBundle - .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN); + .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, false); + boolean signatureOnly = outputBundle + .getBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false); int signatureStatus = OpenPgpSignatureResult.SIGNATURE_ERROR; if (signatureSuccess) { @@ -423,8 +425,9 @@ public class OpenPgpService extends RemoteService { signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY; } + // TODO: signed only?!?!?! sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, - signedOnly, signatureKeyId); + signatureOnly, signatureKeyId); } } finally { is.close(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 1f3280af3..7df416417 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -83,6 +83,9 @@ public class DecryptActivity extends DrawerActivity { private long mSignatureKeyId = 0; private boolean mReturnResult = false; + + // TODO: replace signed only checks with something more intelligent + // PgpOperationIncoming should handle all automatically!!! private boolean mSignedOnly = false; private boolean mAssumeSymmetricEncryption = false; @@ -456,7 +459,7 @@ public class DecryptActivity extends DrawerActivity { } else { if (mDecryptTarget == Id.target.file) { askForOutputFilename(); - } else { + } else { // mDecryptTarget == Id.target.message decryptStart(); } } @@ -633,7 +636,6 @@ public class DecryptActivity extends DrawerActivity { data.putLong(KeychainIntentService.ENCRYPT_SECRET_KEY_ID, mSecretKeyId); - data.putBoolean(KeychainIntentService.DECRYPT_SIGNED_ONLY, mSignedOnly); data.putBoolean(KeychainIntentService.DECRYPT_RETURN_BYTES, mReturnBinary); data.putBoolean(KeychainIntentService.DECRYPT_ASSUME_SYMMETRIC, mAssumeSymmetricEncryption); -- cgit v1.2.3 From fb0816c1267de978a3be51a7bd9c640dfce7ad80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2014 02:40:44 +0100 Subject: internal renaming, cleanup --- .../keychain/pgp/PgpDecryptVerify.java | 782 +++++++++++++++++++++ .../keychain/pgp/PgpOperationIncoming.java | 767 -------------------- .../keychain/pgp/PgpOperationOutgoing.java | 605 ---------------- .../keychain/pgp/PgpSignEncrypt.java | 605 ++++++++++++++++ .../keychain/service/KeychainIntentService.java | 16 +- .../keychain/service/remote/OpenPgpService.java | 19 +- .../keychain/ui/DecryptActivity.java | 6 +- 7 files changed, 1407 insertions(+), 1393 deletions(-) create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java delete mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java create mode 100644 OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java new file mode 100644 index 000000000..fb97f3a5c --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerify.java @@ -0,0 +1,782 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * 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.pgp; + +import android.content.Context; +import android.os.Bundle; + +import org.spongycastle.bcpg.ArmoredInputStream; +import org.spongycastle.bcpg.SignatureSubpacketTags; +import org.spongycastle.openpgp.PGPCompressedData; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.spongycastle.openpgp.PGPEncryptedDataList; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPObjectFactory; +import org.spongycastle.openpgp.PGPOnePassSignature; +import org.spongycastle.openpgp.PGPOnePassSignatureList; +import org.spongycastle.openpgp.PGPPBEEncryptedData; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureList; +import org.spongycastle.openpgp.PGPSignatureSubpacketVector; +import org.spongycastle.openpgp.PGPUtil; +import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; +import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.util.InputData; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.SignatureException; +import java.util.Iterator; + +/** + * This class uses a Builder pattern! + */ +public class PgpDecryptVerify { + private Context context; + private InputData data; + private OutputStream outStream; + + private ProgressDialogUpdater progress; + boolean assumeSymmetric; + String passphrase; + + private PgpDecryptVerify(Builder builder) { + // private Constructor can only be called from Builder + this.context = builder.context; + this.data = builder.data; + this.outStream = builder.outStream; + + this.progress = builder.progress; + this.assumeSymmetric = builder.assumeSymmetric; + this.passphrase = builder.passphrase; + } + + public static class Builder { + // mandatory parameter + private Context context; + private InputData data; + private OutputStream outStream; + + // optional + private ProgressDialogUpdater progress = null; + private boolean assumeSymmetric = false; + private String passphrase = ""; + + public Builder(Context context, InputData data, OutputStream outStream) { + this.context = context; + this.data = data; + this.outStream = outStream; + } + + public Builder progress(ProgressDialogUpdater progress) { + this.progress = progress; + return this; + } + + public Builder assumeSymmetric(boolean assumeSymmetric) { + this.assumeSymmetric = assumeSymmetric; + return this; + } + + public Builder passphrase(String passphrase) { + this.passphrase = passphrase; + return this; + } + + public PgpDecryptVerify build() { + return new PgpDecryptVerify(this); + } + } + + public void updateProgress(int message, int current, int total) { + if (progress != null) { + progress.setProgress(message, current, total); + } + } + + public void updateProgress(int current, int total) { + if (progress != null) { + progress.setProgress(current, total); + } + } + + public static boolean hasSymmetricEncryption(Context context, InputStream inputStream) + throws PgpGeneralException, IOException { + InputStream in = PGPUtil.getDecoderStream(inputStream); + PGPObjectFactory pgpF = new PGPObjectFactory(in); + PGPEncryptedDataList enc; + Object o = pgpF.nextObject(); + + // the first object might be a PGP marker packet. + if (o instanceof PGPEncryptedDataList) { + enc = (PGPEncryptedDataList) o; + } else { + enc = (PGPEncryptedDataList) pgpF.nextObject(); + } + + if (enc == null) { + throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); + } + + Iterator it = enc.getEncryptedDataObjects(); + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPBEEncryptedData) { + return true; + } + } + + return false; + } + + /** + * Decrypts and/or verifies data based on parameters of class + * + * @return + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws SignatureException + */ + public Bundle execute() + throws IOException, PgpGeneralException, PGPException, SignatureException { + + // automatically works with ascii armor input and binary + InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); + if (in instanceof ArmoredInputStream) { + ArmoredInputStream aIn = (ArmoredInputStream) in; + // it is ascii armored + Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine()); + + if (aIn.isClearText()) { + // a cleartext signature, verify it with the other method + return verifyCleartextSignature(aIn); + } + // else: ascii armored encryption! go on... + } + + return decryptVerify(in); + } + + /** + * Decrypt and/or verifies binary or ascii armored pgp + * + * @param in + * @return + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws SignatureException + */ + private Bundle decryptVerify(InputStream in) + throws IOException, PgpGeneralException, PGPException, SignatureException { + Bundle returnData = new Bundle(); + + PGPObjectFactory pgpF = new PGPObjectFactory(in); + PGPEncryptedDataList enc; + Object o = pgpF.nextObject(); + + int currentProgress = 0; + updateProgress(R.string.progress_reading_data, currentProgress, 100); + + if (o instanceof PGPEncryptedDataList) { + enc = (PGPEncryptedDataList) o; + } else { + enc = (PGPEncryptedDataList) pgpF.nextObject(); + } + + if (enc == null) { + throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); + } + + InputStream clear; + PGPEncryptedData encryptedData; + + currentProgress += 5; + + // TODO: currently we always only look at the first known key or symmetric encryption, + // there might be more... + if (assumeSymmetric) { + PGPPBEEncryptedData pbe = null; + Iterator it = enc.getEncryptedDataObjects(); + // find secret key + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPBEEncryptedData) { + pbe = (PGPPBEEncryptedData) obj; + break; + } + } + + if (pbe == null) { + throw new PgpGeneralException( + context.getString(R.string.error_no_symmetric_encryption_packet)); + } + + updateProgress(R.string.progress_preparing_streams, currentProgress, 100); + + PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); + PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( + digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + passphrase.toCharArray()); + + clear = pbe.getDataStream(decryptorFactory); + + encryptedData = pbe; + currentProgress += 5; + } else { + updateProgress(R.string.progress_finding_key, currentProgress, 100); + + PGPPublicKeyEncryptedData pbe = null; + PGPSecretKey secretKey = null; + Iterator it = enc.getEncryptedDataObjects(); + // find secret key + while (it.hasNext()) { + Object obj = it.next(); + if (obj instanceof PGPPublicKeyEncryptedData) { + PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; + secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID()); + if (secretKey != null) { + pbe = encData; + break; + } + } + } + + if (secretKey == null) { + throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); + } + + currentProgress += 5; + updateProgress(R.string.progress_extracting_key, currentProgress, 100); + PGPPrivateKey privateKey = null; + try { + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( + passphrase.toCharArray()); + privateKey = secretKey.extractPrivateKey(keyDecryptor); + } catch (PGPException e) { + throw new PGPException(context.getString(R.string.error_wrong_passphrase)); + } + if (privateKey == null) { + throw new PgpGeneralException( + context.getString(R.string.error_could_not_extract_private_key)); + } + currentProgress += 5; + updateProgress(R.string.progress_preparing_streams, currentProgress, 100); + + PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(privateKey); + + clear = pbe.getDataStream(decryptorFactory); + + encryptedData = pbe; + currentProgress += 5; + } + + PGPObjectFactory plainFact = new PGPObjectFactory(clear); + Object dataChunk = plainFact.nextObject(); + PGPOnePassSignature signature = null; + PGPPublicKey signatureKey = null; + int signatureIndex = -1; + + if (dataChunk instanceof PGPCompressedData) { + updateProgress(R.string.progress_decompressing_data, currentProgress, 100); + + PGPObjectFactory fact = new PGPObjectFactory( + ((PGPCompressedData) dataChunk).getDataStream()); + dataChunk = fact.nextObject(); + plainFact = fact; + currentProgress += 10; + } + + long signatureKeyId = 0; + if (dataChunk instanceof PGPOnePassSignatureList) { + updateProgress(R.string.progress_processing_signature, currentProgress, 100); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); + PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; + for (int i = 0; i < sigList.size(); ++i) { + signature = sigList.get(i); + signatureKey = ProviderHelper + .getPGPPublicKeyByKeyId(context, signature.getKeyID()); + if (signatureKeyId == 0) { + signatureKeyId = signature.getKeyID(); + } + if (signatureKey == null) { + signature = null; + } else { + signatureIndex = i; + signatureKeyId = signature.getKeyID(); + String userId = null; + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( + context, signatureKeyId); + if (signKeyRing != null) { + userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); + } + returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); + break; + } + } + + returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); + + if (signature != null) { + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + signature.init(contentVerifierBuilderProvider, signatureKey); + } else { + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); + } + + dataChunk = plainFact.nextObject(); + currentProgress += 10; + } + + if (dataChunk instanceof PGPSignatureList) { + dataChunk = plainFact.nextObject(); + } + + if (dataChunk instanceof PGPLiteralData) { + updateProgress(R.string.progress_decrypting, currentProgress, 100); + + PGPLiteralData literalData = (PGPLiteralData) dataChunk; + + byte[] buffer = new byte[1 << 16]; + InputStream dataIn = literalData.getInputStream(); + + int startProgress = currentProgress; + int endProgress = 100; + if (signature != null) { + endProgress = 90; + } else if (encryptedData.isIntegrityProtected()) { + endProgress = 95; + } + + int n; + // TODO: progress calculation is broken here! Try to rework it based on commented code! +// int progress = 0; + long startPos = data.getStreamPosition(); + while ((n = dataIn.read(buffer)) > 0) { + outStream.write(buffer, 0, n); +// progress += n; + if (signature != null) { + try { + signature.update(buffer, 0, n); + } catch (SignatureException e) { + returnData + .putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false); + signature = null; + } + } + // TODO: dead code?! + // unknown size, but try to at least have a moving, slowing down progress bar +// currentProgress = startProgress + (endProgress - startProgress) * progress +// / (progress + 100000); + if (data.getSize() - startPos == 0) { + currentProgress = endProgress; + } else { + currentProgress = (int) (startProgress + (endProgress - startProgress) + * (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); + } + updateProgress(currentProgress, 100); + } + + if (signature != null) { + updateProgress(R.string.progress_verifying_signature, 90, 100); + + PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); + PGPSignature messageSignature = signatureList.get(signatureIndex); + + // these are not cleartext signatures! + returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false); + + //Now check binding signatures + boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey); + boolean sig_isok = signature.verify(messageSignature); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok); + } + } + + // TODO: test if this integrity really check works! + if (encryptedData.isIntegrityProtected()) { + updateProgress(R.string.progress_verifying_integrity, 95, 100); + + if (encryptedData.verify()) { + // passed + Log.d(Constants.TAG, "Integrity verification: success!"); + } else { + // failed + Log.d(Constants.TAG, "Integrity verification: failed!"); + throw new PgpGeneralException(context.getString(R.string.error_integrity_check_failed)); + } + } else { + // no integrity check + Log.e(Constants.TAG, "Encrypted data was not integrity protected!"); + } + + updateProgress(R.string.progress_done, 100, 100); + return returnData; + } + + /** + * This method verifies cleartext signatures + * as defined in http://tools.ietf.org/html/rfc4880#section-7 + *

                                                + * The method is heavily based on + * pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java + * + * @return + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws SignatureException + */ + private Bundle verifyCleartextSignature(ArmoredInputStream aIn) + throws IOException, PgpGeneralException, PGPException, SignatureException { + Bundle returnData = new Bundle(); + // cleartext signatures are never encrypted ;) + returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, true); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + updateProgress(R.string.progress_done, 0, 100); + + ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); + int lookAhead = readInputLine(lineOut, aIn); + byte[] lineSep = getLineSeparator(); + + byte[] line = lineOut.toByteArray(); + out.write(line, 0, getLengthWithoutSeparator(line)); + out.write(lineSep); + + while (lookAhead != -1 && aIn.isClearText()) { + lookAhead = readInputLine(lineOut, lookAhead, aIn); + line = lineOut.toByteArray(); + out.write(line, 0, getLengthWithoutSeparator(line)); + out.write(lineSep); + } + + out.close(); + + byte[] clearText = out.toByteArray(); + outStream.write(clearText); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); + + updateProgress(R.string.progress_processing_signature, 60, 100); + PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); + + PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); + if (sigList == null) { + throw new PgpGeneralException(context.getString(R.string.error_corrupt_data)); + } + PGPSignature signature = null; + long signatureKeyId = 0; + PGPPublicKey signatureKey = null; + for (int i = 0; i < sigList.size(); ++i) { + signature = sigList.get(i); + signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(context, signature.getKeyID()); + if (signatureKeyId == 0) { + signatureKeyId = signature.getKeyID(); + } + + if (signatureKey == null) { + signature = null; + } else { + signatureKeyId = signature.getKeyID(); + String userId = null; + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, + signatureKeyId); + if (signKeyRing != null) { + userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); + } + returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); + break; + } + } + + returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); + + if (signature == null) { + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); + updateProgress(R.string.progress_done, 100, 100); + return returnData; + } + + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = + new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + signature.init(contentVerifierBuilderProvider, signatureKey); + + InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText)); + + lookAhead = readInputLine(lineOut, sigIn); + + processLine(signature, lineOut.toByteArray()); + + if (lookAhead != -1) { + do { + lookAhead = readInputLine(lineOut, lookAhead, sigIn); + + signature.update((byte) '\r'); + signature.update((byte) '\n'); + + processLine(signature, lineOut.toByteArray()); + } while (lookAhead != -1); + } + + boolean sig_isok = signature.verify(); + + //Now check binding signatures + boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey); + + returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok); + + updateProgress(R.string.progress_done, 100, 100); + return returnData; + } + + private static boolean verifyKeyBinding(Context context, PGPSignature signature, PGPPublicKey signatureKey) { + long signatureKeyId = signature.getKeyID(); + boolean keyBinding_isok = false; + String userId = null; + PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, + signatureKeyId); + PGPPublicKey mKey = null; + if (signKeyRing != null) { + mKey = PgpKeyHelper.getMasterKey(signKeyRing); + } + if (signature.getKeyID() != mKey.getKeyID()) { + keyBinding_isok = verifyKeyBinding(mKey, signatureKey); + } else { //if the key used to make the signature was the master key, no need to check binding sigs + keyBinding_isok = true; + } + return keyBinding_isok; + } + + private static boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + boolean subkeyBinding_isok = false; + boolean tmp_subkeyBinding_isok = false; + boolean primkeyBinding_isok = false; + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + Iterator itr = signingPublicKey.getSignatures(); + + subkeyBinding_isok = false; + tmp_subkeyBinding_isok = false; + primkeyBinding_isok = false; + while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong? + //gpg has an invalid subkey binding error on key import I think, but doesn't shout + //about keys without subkey signing. Can't get it to import a slightly broken one + //either, so we will err on bad subkey binding here. + PGPSignature sig = itr.next(); + if (sig.getKeyID() == masterPublicKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { + //check and if ok, check primary key binding. + try { + sig.init(contentVerifierBuilderProvider, masterPublicKey); + tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey); + } catch (PGPException e) { + continue; + } catch (SignatureException e) { + continue; + } + + if (tmp_subkeyBinding_isok) + subkeyBinding_isok = true; + if (tmp_subkeyBinding_isok) { + primkeyBinding_isok = verifyPrimaryBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; + primkeyBinding_isok = verifyPrimaryBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; + } + } + } + return (subkeyBinding_isok & primkeyBinding_isok); + } + + private static boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { + boolean primkeyBinding_isok = false; + JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + PGPSignatureList eSigList; + + if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { + try { + eSigList = Pkts.getEmbeddedSignatures(); + } catch (IOException e) { + return false; + } catch (PGPException e) { + return false; + } + for (int j = 0; j < eSigList.size(); ++j) { + PGPSignature emSig = eSigList.get(j); + if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { + try { + emSig.init(contentVerifierBuilderProvider, signingPublicKey); + primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey); + if (primkeyBinding_isok) + break; + } catch (PGPException e) { + continue; + } catch (SignatureException e) { + continue; + } + } + } + } + return primkeyBinding_isok; + } + + /** + * Mostly taken from ClearSignedFileProcessor in Bouncy Castle + * + * @param sig + * @param line + * @throws SignatureException + * @throws IOException + */ + private static void processLine(PGPSignature sig, byte[] line) + throws SignatureException, IOException { + int length = getLengthWithoutWhiteSpace(line); + if (length > 0) { + sig.update(line, 0, length); + } + } + + private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) + throws IOException { + bOut.reset(); + + int lookAhead = -1; + int ch; + + while ((ch = fIn.read()) >= 0) { + bOut.write(ch); + if (ch == '\r' || ch == '\n') { + lookAhead = readPassedEOL(bOut, ch, fIn); + break; + } + } + + return lookAhead; + } + + private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) + throws IOException { + bOut.reset(); + + int ch = lookAhead; + + do { + bOut.write(ch); + if (ch == '\r' || ch == '\n') { + lookAhead = readPassedEOL(bOut, ch, fIn); + break; + } + } while ((ch = fIn.read()) >= 0); + + if (ch < 0) { + lookAhead = -1; + } + + return lookAhead; + } + + private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) + throws IOException { + int lookAhead = fIn.read(); + + if (lastCh == '\r' && lookAhead == '\n') { + bOut.write(lookAhead); + lookAhead = fIn.read(); + } + + return lookAhead; + } + + private static int getLengthWithoutSeparator(byte[] line) { + int end = line.length - 1; + + while (end >= 0 && isLineEnding(line[end])) { + end--; + } + + return end + 1; + } + + private static boolean isLineEnding(byte b) { + return b == '\r' || b == '\n'; + } + + private static int getLengthWithoutWhiteSpace(byte[] line) { + int end = line.length - 1; + + while (end >= 0 && isWhiteSpace(line[end])) { + end--; + } + + return end + 1; + } + + private static boolean isWhiteSpace(byte b) { + return b == '\r' || b == '\n' || b == '\t' || b == ' '; + } + + private static byte[] getLineSeparator() { + String nl = System.getProperty("line.separator"); + byte[] nlBytes = new byte[nl.length()]; + + for (int i = 0; i != nlBytes.length; i++) { + nlBytes[i] = (byte) nl.charAt(i); + } + + return nlBytes; + } +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java deleted file mode 100644 index 7f78f6b07..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationIncoming.java +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010 Thialfihar - * - * 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.pgp; - -import android.content.Context; -import android.os.Bundle; - -import org.spongycastle.bcpg.ArmoredInputStream; -import org.spongycastle.bcpg.SignatureSubpacketTags; -import org.spongycastle.openpgp.PGPCompressedData; -import org.spongycastle.openpgp.PGPEncryptedData; -import org.spongycastle.openpgp.PGPEncryptedDataList; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPLiteralData; -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPOnePassSignature; -import org.spongycastle.openpgp.PGPOnePassSignatureList; -import org.spongycastle.openpgp.PGPPBEEncryptedData; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.PGPSignatureList; -import org.spongycastle.openpgp.PGPSignatureSubpacketVector; -import org.spongycastle.openpgp.PGPUtil; -import org.spongycastle.openpgp.operator.PBEDataDecryptorFactory; -import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider; -import org.spongycastle.openpgp.operator.PublicKeyDataDecryptorFactory; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.SignatureException; -import java.util.Iterator; - -/** - * This class uses a Builder pattern! - */ -public class PgpOperationIncoming { - private Context context; - private InputData data; - private OutputStream outStream; - - private ProgressDialogUpdater progress; - boolean assumeSymmetric; - String passphrase; - - private PgpOperationIncoming(Builder builder) { - // private Constructor can only be called from Builder - this.context = builder.context; - this.data = builder.data; - this.outStream = builder.outStream; - - this.progress = builder.progress; - this.assumeSymmetric = builder.assumeSymmetric; - this.passphrase = builder.passphrase; - } - - public static class Builder { - // mandatory parameter - private Context context; - private InputData data; - private OutputStream outStream; - - // optional - private ProgressDialogUpdater progress = null; - private boolean assumeSymmetric = false; - private String passphrase = ""; - - public Builder(Context context, InputData data, OutputStream outStream) { - this.context = context; - this.data = data; - this.outStream = outStream; - } - - public Builder progress(ProgressDialogUpdater progress) { - this.progress = progress; - return this; - } - - public Builder assumeSymmetric(boolean assumeSymmetric) { - this.assumeSymmetric = assumeSymmetric; - return this; - } - - public Builder passphrase(String passphrase) { - this.passphrase = passphrase; - return this; - } - - public PgpOperationIncoming build() { - return new PgpOperationIncoming(this); - } - } - - public void updateProgress(int message, int current, int total) { - if (progress != null) { - progress.setProgress(message, current, total); - } - } - - public void updateProgress(int current, int total) { - if (progress != null) { - progress.setProgress(current, total); - } - } - - public static boolean hasSymmetricEncryption(Context context, InputStream inputStream) - throws PgpGeneralException, IOException { - InputStream in = PGPUtil.getDecoderStream(inputStream); - PGPObjectFactory pgpF = new PGPObjectFactory(in); - PGPEncryptedDataList enc; - Object o = pgpF.nextObject(); - - // the first object might be a PGP marker packet. - if (o instanceof PGPEncryptedDataList) { - enc = (PGPEncryptedDataList) o; - } else { - enc = (PGPEncryptedDataList) pgpF.nextObject(); - } - - if (enc == null) { - throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); - } - - Iterator it = enc.getEncryptedDataObjects(); - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPBEEncryptedData) { - return true; - } - } - - return false; - } - - /** - * Decrypts and/or verifies data based on parameters of class - * - * @return - * @throws IOException - * @throws PgpGeneralException - * @throws PGPException - * @throws SignatureException - */ - public Bundle decryptVerify() - throws IOException, PgpGeneralException, PGPException, SignatureException { - Bundle returnData = new Bundle(); - - // automatically works with ascii armor input and binary - InputStream in = PGPUtil.getDecoderStream(data.getInputStream()); - if (in instanceof ArmoredInputStream) { - ArmoredInputStream aIn = (ArmoredInputStream) in; - // it is ascii armored - Log.d(Constants.TAG, "ASCII Armor Header Line: " + aIn.getArmorHeaderLine()); - - if (aIn.isClearText()) { - // a cleartext signature, verify it with the other method - return verifyCleartextSignature(aIn); - } else { - // go on... - } - } - PGPObjectFactory pgpF = new PGPObjectFactory(in); - PGPEncryptedDataList enc; - Object o = pgpF.nextObject(); - Log.d(Constants.TAG, "o: " + o.getClass().getName()); - - int currentProgress = 0; - updateProgress(R.string.progress_reading_data, currentProgress, 100); - - if (o instanceof PGPEncryptedDataList) { - enc = (PGPEncryptedDataList) o; - } else { - enc = (PGPEncryptedDataList) pgpF.nextObject(); - } - - if (enc == null) { - throw new PgpGeneralException(context.getString(R.string.error_invalid_data)); - } - - InputStream clear; - PGPEncryptedData encryptedData; - - currentProgress += 5; - - // TODO: currently we always only look at the first known key or symmetric encryption, - // there might be more... - if (assumeSymmetric) { - PGPPBEEncryptedData pbe = null; - Iterator it = enc.getEncryptedDataObjects(); - // find secret key - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPBEEncryptedData) { - pbe = (PGPPBEEncryptedData) obj; - break; - } - } - - if (pbe == null) { - throw new PgpGeneralException( - context.getString(R.string.error_no_symmetric_encryption_packet)); - } - - updateProgress(R.string.progress_preparing_streams, currentProgress, 100); - - PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(); - PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder( - digestCalcProvider).setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); - - clear = pbe.getDataStream(decryptorFactory); - - encryptedData = pbe; - currentProgress += 5; - } else { - updateProgress(R.string.progress_finding_key, currentProgress, 100); - - PGPPublicKeyEncryptedData pbe = null; - PGPSecretKey secretKey = null; - Iterator it = enc.getEncryptedDataObjects(); - // find secret key - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof PGPPublicKeyEncryptedData) { - PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj; - secretKey = ProviderHelper.getPGPSecretKeyByKeyId(context, encData.getKeyID()); - if (secretKey != null) { - pbe = encData; - break; - } - } - } - - if (secretKey == null) { - throw new PgpGeneralException(context.getString(R.string.error_no_secret_key_found)); - } - - currentProgress += 5; - updateProgress(R.string.progress_extracting_key, currentProgress, 100); - PGPPrivateKey privateKey = null; - try { - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build( - passphrase.toCharArray()); - privateKey = secretKey.extractPrivateKey(keyDecryptor); - } catch (PGPException e) { - throw new PGPException(context.getString(R.string.error_wrong_passphrase)); - } - if (privateKey == null) { - throw new PgpGeneralException( - context.getString(R.string.error_could_not_extract_private_key)); - } - currentProgress += 5; - updateProgress(R.string.progress_preparing_streams, currentProgress, 100); - - PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(privateKey); - - clear = pbe.getDataStream(decryptorFactory); - - encryptedData = pbe; - currentProgress += 5; - } - - PGPObjectFactory plainFact = new PGPObjectFactory(clear); - Object dataChunk = plainFact.nextObject(); - PGPOnePassSignature signature = null; - PGPPublicKey signatureKey = null; - int signatureIndex = -1; - - if (dataChunk instanceof PGPCompressedData) { - updateProgress(R.string.progress_decompressing_data, currentProgress, 100); - - PGPObjectFactory fact = new PGPObjectFactory( - ((PGPCompressedData) dataChunk).getDataStream()); - dataChunk = fact.nextObject(); - plainFact = fact; - currentProgress += 10; - } - - long signatureKeyId = 0; - if (dataChunk instanceof PGPOnePassSignatureList) { - updateProgress(R.string.progress_processing_signature, currentProgress, 100); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); - PGPOnePassSignatureList sigList = (PGPOnePassSignatureList) dataChunk; - for (int i = 0; i < sigList.size(); ++i) { - signature = sigList.get(i); - signatureKey = ProviderHelper - .getPGPPublicKeyByKeyId(context, signature.getKeyID()); - if (signatureKeyId == 0) { - signatureKeyId = signature.getKeyID(); - } - if (signatureKey == null) { - signature = null; - } else { - signatureIndex = i; - signatureKeyId = signature.getKeyID(); - String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId( - context, signatureKeyId); - if (signKeyRing != null) { - userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); - } - returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); - break; - } - } - - returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); - - if (signature != null) { - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - signature.init(contentVerifierBuilderProvider, signatureKey); - } else { - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); - } - - dataChunk = plainFact.nextObject(); - currentProgress += 10; - } - - if (dataChunk instanceof PGPSignatureList) { - dataChunk = plainFact.nextObject(); - } - - if (dataChunk instanceof PGPLiteralData) { - updateProgress(R.string.progress_decrypting, currentProgress, 100); - - PGPLiteralData literalData = (PGPLiteralData) dataChunk; - - byte[] buffer = new byte[1 << 16]; - InputStream dataIn = literalData.getInputStream(); - - int startProgress = currentProgress; - int endProgress = 100; - if (signature != null) { - endProgress = 90; - } else if (encryptedData.isIntegrityProtected()) { - endProgress = 95; - } - - int n; - // TODO: progress calculation is broken here! Try to rework it based on commented code! -// int progress = 0; - long startPos = data.getStreamPosition(); - while ((n = dataIn.read(buffer)) > 0) { - outStream.write(buffer, 0, n); -// progress += n; - if (signature != null) { - try { - signature.update(buffer, 0, n); - } catch (SignatureException e) { - returnData - .putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, false); - signature = null; - } - } - // TODO: dead code?! - // unknown size, but try to at least have a moving, slowing down progress bar -// currentProgress = startProgress + (endProgress - startProgress) * progress -// / (progress + 100000); - if (data.getSize() - startPos == 0) { - currentProgress = endProgress; - } else { - currentProgress = (int) (startProgress + (endProgress - startProgress) - * (data.getStreamPosition() - startPos) / (data.getSize() - startPos)); - } - updateProgress(currentProgress, 100); - } - - if (signature != null) { - updateProgress(R.string.progress_verifying_signature, 90, 100); - - PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); - PGPSignature messageSignature = signatureList.get(signatureIndex); - - // these are not cleartext signatures! - returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, false); - - //Now check binding signatures - boolean keyBinding_isok = verifyKeyBinding(context, messageSignature, signatureKey); - boolean sig_isok = signature.verify(messageSignature); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, keyBinding_isok & sig_isok); - } - } - - // TODO: test if this integrity really check works! - if (encryptedData.isIntegrityProtected()) { - updateProgress(R.string.progress_verifying_integrity, 95, 100); - - if (encryptedData.verify()) { - // passed - Log.d(Constants.TAG, "Integrity verification: success!"); - } else { - // failed - Log.d(Constants.TAG, "Integrity verification: failed!"); - throw new PgpGeneralException(context.getString(R.string.error_integrity_check_failed)); - } - } else { - // no integrity check - Log.e(Constants.TAG, "Encrypted data was not integrity protected!"); - } - - updateProgress(R.string.progress_done, 100, 100); - return returnData; - } - - /** - * This method verifies cleartext signatures - * as defined in http://tools.ietf.org/html/rfc4880#section-7 - *

                                                - * The method is heavily based on - * pg/src/main/java/org/spongycastle/openpgp/examples/ClearSignedFileProcessor.java - * - * @return - * @throws IOException - * @throws PgpGeneralException - * @throws PGPException - * @throws SignatureException - */ - private Bundle verifyCleartextSignature(ArmoredInputStream aIn) - throws IOException, PgpGeneralException, PGPException, SignatureException { - Bundle returnData = new Bundle(); - // cleartext signatures are never encrypted ;) - returnData.putBoolean(KeychainIntentService.RESULT_CLEARTEXT_SIGNATURE_ONLY, true); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - updateProgress(R.string.progress_done, 0, 100); - - ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); - int lookAhead = readInputLine(lineOut, aIn); - byte[] lineSep = getLineSeparator(); - - byte[] line = lineOut.toByteArray(); - out.write(line, 0, getLengthWithoutSeparator(line)); - out.write(lineSep); - - while (lookAhead != -1 && aIn.isClearText()) { - lookAhead = readInputLine(lineOut, lookAhead, aIn); - line = lineOut.toByteArray(); - out.write(line, 0, getLengthWithoutSeparator(line)); - out.write(lineSep); - } - - out.close(); - - byte[] clearText = out.toByteArray(); - outStream.write(clearText); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE, true); - - updateProgress(R.string.progress_processing_signature, 60, 100); - PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); - - PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); - if (sigList == null) { - throw new PgpGeneralException(context.getString(R.string.error_corrupt_data)); - } - PGPSignature signature = null; - long signatureKeyId = 0; - PGPPublicKey signatureKey = null; - for (int i = 0; i < sigList.size(); ++i) { - signature = sigList.get(i); - signatureKey = ProviderHelper.getPGPPublicKeyByKeyId(context, signature.getKeyID()); - if (signatureKeyId == 0) { - signatureKeyId = signature.getKeyID(); - } - - if (signatureKey == null) { - signature = null; - } else { - signatureKeyId = signature.getKeyID(); - String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, - signatureKeyId); - if (signKeyRing != null) { - userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signKeyRing)); - } - returnData.putString(KeychainIntentService.RESULT_SIGNATURE_USER_ID, userId); - break; - } - } - - returnData.putLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID, signatureKeyId); - - if (signature == null) { - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN, true); - updateProgress(R.string.progress_done, 100, 100); - return returnData; - } - - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = - new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - signature.init(contentVerifierBuilderProvider, signatureKey); - - InputStream sigIn = new BufferedInputStream(new ByteArrayInputStream(clearText)); - - lookAhead = readInputLine(lineOut, sigIn); - - processLine(signature, lineOut.toByteArray()); - - if (lookAhead != -1) { - do { - lookAhead = readInputLine(lineOut, lookAhead, sigIn); - - signature.update((byte) '\r'); - signature.update((byte) '\n'); - - processLine(signature, lineOut.toByteArray()); - } while (lookAhead != -1); - } - - boolean sig_isok = signature.verify(); - - //Now check binding signatures - boolean keyBinding_isok = verifyKeyBinding(context, signature, signatureKey); - - returnData.putBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS, sig_isok & keyBinding_isok); - - updateProgress(R.string.progress_done, 100, 100); - return returnData; - } - - private static boolean verifyKeyBinding(Context context, PGPSignature signature, PGPPublicKey signatureKey) { - long signatureKeyId = signature.getKeyID(); - boolean keyBinding_isok = false; - String userId = null; - PGPPublicKeyRing signKeyRing = ProviderHelper.getPGPPublicKeyRingByKeyId(context, - signatureKeyId); - PGPPublicKey mKey = null; - if (signKeyRing != null) { - mKey = PgpKeyHelper.getMasterKey(signKeyRing); - } - if (signature.getKeyID() != mKey.getKeyID()) { - keyBinding_isok = verifyKeyBinding(mKey, signatureKey); - } else { //if the key used to make the signature was the master key, no need to check binding sigs - keyBinding_isok = true; - } - return keyBinding_isok; - } - - private static boolean verifyKeyBinding(PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { - boolean subkeyBinding_isok = false; - boolean tmp_subkeyBinding_isok = false; - boolean primkeyBinding_isok = false; - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - Iterator itr = signingPublicKey.getSignatures(); - - subkeyBinding_isok = false; - tmp_subkeyBinding_isok = false; - primkeyBinding_isok = false; - while (itr.hasNext()) { //what does gpg do if the subkey binding is wrong? - //gpg has an invalid subkey binding error on key import I think, but doesn't shout - //about keys without subkey signing. Can't get it to import a slightly broken one - //either, so we will err on bad subkey binding here. - PGPSignature sig = itr.next(); - if (sig.getKeyID() == masterPublicKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { - //check and if ok, check primary key binding. - try { - sig.init(contentVerifierBuilderProvider, masterPublicKey); - tmp_subkeyBinding_isok = sig.verifyCertification(masterPublicKey, signingPublicKey); - } catch (PGPException e) { - continue; - } catch (SignatureException e) { - continue; - } - - if (tmp_subkeyBinding_isok) - subkeyBinding_isok = true; - if (tmp_subkeyBinding_isok) { - primkeyBinding_isok = verifyPrimaryBinding(sig.getUnhashedSubPackets(), masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; - primkeyBinding_isok = verifyPrimaryBinding(sig.getHashedSubPackets(), masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; - } - } - } - return (subkeyBinding_isok & primkeyBinding_isok); - } - - private static boolean verifyPrimaryBinding(PGPSignatureSubpacketVector Pkts, PGPPublicKey masterPublicKey, PGPPublicKey signingPublicKey) { - boolean primkeyBinding_isok = false; - JcaPGPContentVerifierBuilderProvider contentVerifierBuilderProvider = new JcaPGPContentVerifierBuilderProvider() - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - PGPSignatureList eSigList; - - if (Pkts.hasSubpacket(SignatureSubpacketTags.EMBEDDED_SIGNATURE)) { - try { - eSigList = Pkts.getEmbeddedSignatures(); - } catch (IOException e) { - return false; - } catch (PGPException e) { - return false; - } - for (int j = 0; j < eSigList.size(); ++j) { - PGPSignature emSig = eSigList.get(j); - if (emSig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { - try { - emSig.init(contentVerifierBuilderProvider, signingPublicKey); - primkeyBinding_isok = emSig.verifyCertification(masterPublicKey, signingPublicKey); - if (primkeyBinding_isok) - break; - } catch (PGPException e) { - continue; - } catch (SignatureException e) { - continue; - } - } - } - } - return primkeyBinding_isok; - } - - /** - * Mostly taken from ClearSignedFileProcessor in Bouncy Castle - * - * @param sig - * @param line - * @throws SignatureException - * @throws IOException - */ - private static void processLine(PGPSignature sig, byte[] line) - throws SignatureException, IOException { - int length = getLengthWithoutWhiteSpace(line); - if (length > 0) { - sig.update(line, 0, length); - } - } - - private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn) - throws IOException { - bOut.reset(); - - int lookAhead = -1; - int ch; - - while ((ch = fIn.read()) >= 0) { - bOut.write(ch); - if (ch == '\r' || ch == '\n') { - lookAhead = readPassedEOL(bOut, ch, fIn); - break; - } - } - - return lookAhead; - } - - private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn) - throws IOException { - bOut.reset(); - - int ch = lookAhead; - - do { - bOut.write(ch); - if (ch == '\r' || ch == '\n') { - lookAhead = readPassedEOL(bOut, ch, fIn); - break; - } - } while ((ch = fIn.read()) >= 0); - - if (ch < 0) { - lookAhead = -1; - } - - return lookAhead; - } - - private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn) - throws IOException { - int lookAhead = fIn.read(); - - if (lastCh == '\r' && lookAhead == '\n') { - bOut.write(lookAhead); - lookAhead = fIn.read(); - } - - return lookAhead; - } - - private static int getLengthWithoutSeparator(byte[] line) { - int end = line.length - 1; - - while (end >= 0 && isLineEnding(line[end])) { - end--; - } - - return end + 1; - } - - private static boolean isLineEnding(byte b) { - return b == '\r' || b == '\n'; - } - - private static int getLengthWithoutWhiteSpace(byte[] line) { - int end = line.length - 1; - - while (end >= 0 && isWhiteSpace(line[end])) { - end--; - } - - return end + 1; - } - - private static boolean isWhiteSpace(byte b) { - return b == '\r' || b == '\n' || b == '\t' || b == ' '; - } - - private static byte[] getLineSeparator() { - String nl = System.getProperty("line.separator"); - byte[] nlBytes = new byte[nl.length()]; - - for (int i = 0; i != nlBytes.length; i++) { - nlBytes[i] = (byte) nl.charAt(i); - } - - return nlBytes; - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java deleted file mode 100644 index fd859fd5a..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpOperationOutgoing.java +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * Copyright (C) 2010 Thialfihar - * - * 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.pgp; - -import android.content.Context; - -import org.spongycastle.bcpg.ArmoredOutputStream; -import org.spongycastle.bcpg.BCPGOutputStream; -import org.spongycastle.openpgp.PGPCompressedDataGenerator; -import org.spongycastle.openpgp.PGPEncryptedDataGenerator; -import org.spongycastle.openpgp.PGPException; -import org.spongycastle.openpgp.PGPLiteralData; -import org.spongycastle.openpgp.PGPLiteralDataGenerator; -import org.spongycastle.openpgp.PGPPrivateKey; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.spongycastle.openpgp.PGPSignature; -import org.spongycastle.openpgp.PGPSignatureGenerator; -import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; -import org.spongycastle.openpgp.PGPV3SignatureGenerator; -import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; -import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; -import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; -import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.util.InputData; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SignatureException; -import java.util.Date; - -/** - * This class uses a Builder pattern! - */ -public class PgpOperationOutgoing { - private Context context; - private InputData data; - private OutputStream outStream; - - private ProgressDialogUpdater progress; - private boolean enableAsciiArmorOutput; - private int compressionId; - private long[] encryptionKeyIds; - private String encryptionPassphrase; - private int symmetricEncryptionAlgorithm; - private long signatureKeyId; - private int signatureHashAlgorithm; - private boolean signatureForceV3; - private String signaturePassphrase; - - private PgpOperationOutgoing(Builder builder) { - // private Constructor can only be called from Builder - this.context = builder.context; - this.data = builder.data; - this.outStream = builder.outStream; - - this.progress = builder.progress; - this.enableAsciiArmorOutput = builder.enableAsciiArmorOutput; - this.compressionId = builder.compressionId; - this.encryptionKeyIds = builder.encryptionKeyIds; - this.encryptionPassphrase = builder.encryptionPassphrase; - this.symmetricEncryptionAlgorithm = builder.symmetricEncryptionAlgorithm; - this.signatureKeyId = builder.signatureKeyId; - this.signatureHashAlgorithm = builder.signatureHashAlgorithm; - this.signatureForceV3 = builder.signatureForceV3; - this.signaturePassphrase = builder.signaturePassphrase; - } - - public static class Builder { - // mandatory parameter - private Context context; - private InputData data; - private OutputStream outStream; - - // optional - private ProgressDialogUpdater progress = null; - private boolean enableAsciiArmorOutput = false; - private int compressionId = Id.choice.compression.none; - private long[] encryptionKeyIds = new long[0]; - private String encryptionPassphrase = null; - private int symmetricEncryptionAlgorithm = 0; - private long signatureKeyId = Id.key.none; - private int signatureHashAlgorithm = 0; - private boolean signatureForceV3 = false; - private String signaturePassphrase = null; - - public Builder(Context context, InputData data, OutputStream outStream) { - this.context = context; - this.data = data; - this.outStream = outStream; - } - - public Builder progress(ProgressDialogUpdater progress) { - this.progress = progress; - return this; - } - - public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) { - this.enableAsciiArmorOutput = enableAsciiArmorOutput; - return this; - } - - public Builder compressionId(int compressionId) { - this.compressionId = compressionId; - return this; - } - - public Builder encryptionKeyIds(long[] encryptionKeyIds) { - this.encryptionKeyIds = encryptionKeyIds; - return this; - } - - public Builder encryptionPassphrase(String encryptionPassphrase) { - this.encryptionPassphrase = encryptionPassphrase; - return this; - } - - public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { - this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; - return this; - } - - public Builder signatureKeyId(long signatureKeyId) { - this.signatureKeyId = signatureKeyId; - return this; - } - - public Builder signatureHashAlgorithm(int signatureHashAlgorithm) { - this.signatureHashAlgorithm = signatureHashAlgorithm; - return this; - } - - public Builder signatureForceV3(boolean signatureForceV3) { - this.signatureForceV3 = signatureForceV3; - return this; - } - - public Builder signaturePassphrase(String signaturePassphrase) { - this.signaturePassphrase = signaturePassphrase; - return this; - } - - public PgpOperationOutgoing build() { - return new PgpOperationOutgoing(this); - } - } - - public void updateProgress(int message, int current, int total) { - if (progress != null) { - progress.setProgress(message, current, total); - } - } - - public void updateProgress(int current, int total) { - if (progress != null) { - progress.setProgress(current, total); - } - } - - /** - * Signs and/or encrypts data based on parameters of class - * - * @throws IOException - * @throws PgpGeneralException - * @throws PGPException - * @throws NoSuchProviderException - * @throws NoSuchAlgorithmException - * @throws SignatureException - */ - public void signEncrypt() - throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, - NoSuchAlgorithmException, SignatureException { - - boolean enableSignature = signatureKeyId != Id.key.none; - boolean enableEncryption = (encryptionKeyIds.length != 0 || encryptionPassphrase != null); - boolean enableCompression = (enableEncryption && compressionId != Id.choice.compression.none); - - Log.d(Constants.TAG, "enableSignature:" + enableSignature - + "\nenableEncryption:" + enableEncryption - + "\nenableCompression:" + enableCompression - + "\nenableAsciiArmorOutput:" + enableAsciiArmorOutput); - - int signatureType; - if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { - // for sign-only ascii text - signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; - } else { - signatureType = PGPSignature.BINARY_DOCUMENT; - } - - ArmoredOutputStream armorOut = null; - OutputStream out; - if (enableAsciiArmorOutput) { - armorOut = new ArmoredOutputStream(outStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); - out = armorOut; - } else { - out = outStream; - } - - /* Get keys for signature generation for later usage */ - PGPSecretKey signingKey = null; - PGPSecretKeyRing signingKeyRing = null; - PGPPrivateKey signaturePrivateKey = null; - if (enableSignature) { - signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); - signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); - if (signingKey == null) { - throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); - } - - if (signaturePassphrase == null) { - throw new PgpGeneralException( - context.getString(R.string.error_no_signature_passphrase)); - } - - updateProgress(R.string.progress_extracting_signature_key, 0, 100); - - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); - signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - throw new PgpGeneralException( - context.getString(R.string.error_could_not_extract_private_key)); - } - } - updateProgress(R.string.progress_preparing_streams, 5, 100); - - /* Initialize PGPEncryptedDataGenerator for later usage */ - PGPEncryptedDataGenerator cPk = null; - if (enableEncryption) { - // has Integrity packet enabled! - JcePGPDataEncryptorBuilder encryptorBuilder = - new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) - .setWithIntegrityPacket(true); - - cPk = new PGPEncryptedDataGenerator(encryptorBuilder); - - if (encryptionKeyIds.length == 0) { - // Symmetric encryption - Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); - - JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = - new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); - cPk.addMethod(symmetricEncryptionGenerator); - } else { - // Asymmetric encryption - for (long id : encryptionKeyIds) { - PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(context, id); - if (key != null) { - JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = - new JcePublicKeyKeyEncryptionMethodGenerator(key); - cPk.addMethod(pubKeyEncryptionGenerator); - } - } - } - } - - /* Initialize signature generator object for later usage */ - PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; - if (enableSignature) { - updateProgress(R.string.progress_preparing_signature, 10, 100); - - // content signer based on signing key algorithm and chosen hash algorithm - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( - signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - if (signatureForceV3) { - signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); - signatureV3Generator.init(signatureType, signaturePrivateKey); - } else { - signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(signatureType, signaturePrivateKey); - - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - spGen.setSignerUserID(false, userId); - signatureGenerator.setHashedSubpackets(spGen.generate()); - } - } - - PGPCompressedDataGenerator compressGen = null; - OutputStream pOut; - OutputStream encryptionOut = null; - BCPGOutputStream bcpgOut; - if (enableEncryption) { - /* actual encryption */ - - encryptionOut = cPk.open(out, new byte[1 << 16]); - - if (enableCompression) { - compressGen = new PGPCompressedDataGenerator(compressionId); - bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); - } else { - bcpgOut = new BCPGOutputStream(encryptionOut); - } - - if (enableSignature) { - if (signatureForceV3) { - signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); - } else { - signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); - } - } - - PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); - // file name not needed, so empty string - pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), - new byte[1 << 16]); - updateProgress(R.string.progress_encrypting, 20, 100); - - long progress = 0; - int n; - byte[] buffer = new byte[1 << 16]; - InputStream in = data.getInputStream(); - while ((n = in.read(buffer)) > 0) { - pOut.write(buffer, 0, n); - - // update signature buffer if signature is requested - if (enableSignature) { - if (signatureForceV3) { - signatureV3Generator.update(buffer, 0, n); - } else { - signatureGenerator.update(buffer, 0, n); - } - } - - progress += n; - if (data.getSize() != 0) { - updateProgress((int) (20 + (95 - 20) * progress / data.getSize()), 100); - } - } - - literalGen.close(); - } else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { - /* sign-only of ascii text */ - - updateProgress(R.string.progress_signing, 40, 100); - - // write directly on armor output stream - armorOut.beginClearText(signatureHashAlgorithm); - - InputStream in = data.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - - final byte[] newline = "\r\n".getBytes("UTF-8"); - - if (signatureForceV3) { - processLine(reader.readLine(), armorOut, signatureV3Generator); - } else { - processLine(reader.readLine(), armorOut, signatureGenerator); - } - - while (true) { - String line = reader.readLine(); - - if (line == null) { - armorOut.write(newline); - break; - } - - armorOut.write(newline); - - // update signature buffer with input line - if (signatureForceV3) { - signatureV3Generator.update(newline); - processLine(line, armorOut, signatureV3Generator); - } else { - signatureGenerator.update(newline); - processLine(line, armorOut, signatureGenerator); - } - } - - armorOut.endClearText(); - - pOut = new BCPGOutputStream(armorOut); - } else { - // TODO: implement sign-only for files! - pOut = null; - Log.e(Constants.TAG, "not supported!"); - } - - if (enableSignature) { - updateProgress(R.string.progress_generating_signature, 95, 100); - if (signatureForceV3) { - signatureV3Generator.generate().encode(pOut); - } else { - signatureGenerator.generate().encode(pOut); - } - } - - // closing outputs - // NOTE: closing needs to be done in the correct order! - // TODO: closing bcpgOut and pOut??? - if (enableEncryption) { - if (enableCompression) { - compressGen.close(); - } - - encryptionOut.close(); - } - if (enableAsciiArmorOutput) { - armorOut.close(); - } - - out.close(); - outStream.close(); - - updateProgress(R.string.progress_done, 100, 100); - } - - // TODO: merge this into signEncrypt method! - // TODO: allow binary input for this class - public void generateSignature() - throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, - SignatureException { - - OutputStream out; - if (enableAsciiArmorOutput) { - // Ascii Armor (Radix-64) - ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream); - armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); - out = armorOut; - } else { - out = outStream; - } - - if (signatureKeyId == 0) { - throw new PgpGeneralException(context.getString(R.string.error_no_signature_key)); - } - - PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); - PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); - if (signingKey == null) { - throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); - } - - if (signaturePassphrase == null) { - throw new PgpGeneralException(context.getString(R.string.error_no_signature_passphrase)); - } - - PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( - Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); - PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); - if (signaturePrivateKey == null) { - throw new PgpGeneralException( - context.getString(R.string.error_could_not_extract_private_key)); - } - updateProgress(R.string.progress_preparing_streams, 0, 100); - - updateProgress(R.string.progress_preparing_signature, 30, 100); - - int type = PGPSignature.CANONICAL_TEXT_DOCUMENT; -// if (binary) { -// type = PGPSignature.BINARY_DOCUMENT; -// } - - // content signer based on signing key algorithm and chosen hash algorithm - JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey - .getPublicKey().getAlgorithm(), signatureHashAlgorithm) - .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); - - PGPSignatureGenerator signatureGenerator = null; - PGPV3SignatureGenerator signatureV3Generator = null; - if (signatureForceV3) { - signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); - signatureV3Generator.init(type, signaturePrivateKey); - } else { - signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); - signatureGenerator.init(type, signaturePrivateKey); - - PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); - String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); - spGen.setSignerUserID(false, userId); - signatureGenerator.setHashedSubpackets(spGen.generate()); - } - - updateProgress(R.string.progress_signing, 40, 100); - - InputStream inStream = data.getInputStream(); -// if (binary) { -// byte[] buffer = new byte[1 << 16]; -// int n = 0; -// while ((n = inStream.read(buffer)) > 0) { -// if (signatureForceV3) { -// signatureV3Generator.update(buffer, 0, n); -// } else { -// signatureGenerator.update(buffer, 0, n); -// } -// } -// } else { - final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); - final byte[] newline = "\r\n".getBytes("UTF-8"); - - String line; - while ((line = reader.readLine()) != null) { - if (signatureForceV3) { - processLine(line, null, signatureV3Generator); - signatureV3Generator.update(newline); - } else { - processLine(line, null, signatureGenerator); - signatureGenerator.update(newline); - } - } -// } - - BCPGOutputStream bOut = new BCPGOutputStream(out); - if (signatureForceV3) { - signatureV3Generator.generate().encode(bOut); - } else { - signatureGenerator.generate().encode(bOut); - } - out.close(); - outStream.close(); - - updateProgress(R.string.progress_done, 100, 100); - } - - - private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPSignatureGenerator pSignatureGenerator) - throws IOException, SignatureException { - - if (pLine == null) { - return; - } - - final char[] chars = pLine.toCharArray(); - int len = chars.length; - - while (len > 0) { - if (!Character.isWhitespace(chars[len - 1])) { - break; - } - len--; - } - - final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); - - if (pArmoredOutput != null) { - pArmoredOutput.write(data); - } - pSignatureGenerator.update(data); - } - - private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, - final PGPV3SignatureGenerator pSignatureGenerator) - throws IOException, SignatureException { - - if (pLine == null) { - return; - } - - final char[] chars = pLine.toCharArray(); - int len = chars.length; - - while (len > 0) { - if (!Character.isWhitespace(chars[len - 1])) { - break; - } - len--; - } - - final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); - - if (pArmoredOutput != null) { - pArmoredOutput.write(data); - } - pSignatureGenerator.update(data); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java new file mode 100644 index 000000000..ba1182c1b --- /dev/null +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java @@ -0,0 +1,605 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * 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.pgp; + +import android.content.Context; + +import org.spongycastle.bcpg.ArmoredOutputStream; +import org.spongycastle.bcpg.BCPGOutputStream; +import org.spongycastle.openpgp.PGPCompressedDataGenerator; +import org.spongycastle.openpgp.PGPEncryptedDataGenerator; +import org.spongycastle.openpgp.PGPException; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPLiteralDataGenerator; +import org.spongycastle.openpgp.PGPPrivateKey; +import org.spongycastle.openpgp.PGPPublicKey; +import org.spongycastle.openpgp.PGPSecretKey; +import org.spongycastle.openpgp.PGPSecretKeyRing; +import org.spongycastle.openpgp.PGPSignature; +import org.spongycastle.openpgp.PGPSignatureGenerator; +import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.spongycastle.openpgp.PGPV3SignatureGenerator; +import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; +import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; +import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.Id; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.util.InputData; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.ProgressDialogUpdater; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SignatureException; +import java.util.Date; + +/** + * This class uses a Builder pattern! + */ +public class PgpSignEncrypt { + private Context context; + private InputData data; + private OutputStream outStream; + + private ProgressDialogUpdater progress; + private boolean enableAsciiArmorOutput; + private int compressionId; + private long[] encryptionKeyIds; + private String encryptionPassphrase; + private int symmetricEncryptionAlgorithm; + private long signatureKeyId; + private int signatureHashAlgorithm; + private boolean signatureForceV3; + private String signaturePassphrase; + + private PgpSignEncrypt(Builder builder) { + // private Constructor can only be called from Builder + this.context = builder.context; + this.data = builder.data; + this.outStream = builder.outStream; + + this.progress = builder.progress; + this.enableAsciiArmorOutput = builder.enableAsciiArmorOutput; + this.compressionId = builder.compressionId; + this.encryptionKeyIds = builder.encryptionKeyIds; + this.encryptionPassphrase = builder.encryptionPassphrase; + this.symmetricEncryptionAlgorithm = builder.symmetricEncryptionAlgorithm; + this.signatureKeyId = builder.signatureKeyId; + this.signatureHashAlgorithm = builder.signatureHashAlgorithm; + this.signatureForceV3 = builder.signatureForceV3; + this.signaturePassphrase = builder.signaturePassphrase; + } + + public static class Builder { + // mandatory parameter + private Context context; + private InputData data; + private OutputStream outStream; + + // optional + private ProgressDialogUpdater progress = null; + private boolean enableAsciiArmorOutput = false; + private int compressionId = Id.choice.compression.none; + private long[] encryptionKeyIds = new long[0]; + private String encryptionPassphrase = null; + private int symmetricEncryptionAlgorithm = 0; + private long signatureKeyId = Id.key.none; + private int signatureHashAlgorithm = 0; + private boolean signatureForceV3 = false; + private String signaturePassphrase = null; + + public Builder(Context context, InputData data, OutputStream outStream) { + this.context = context; + this.data = data; + this.outStream = outStream; + } + + public Builder progress(ProgressDialogUpdater progress) { + this.progress = progress; + return this; + } + + public Builder enableAsciiArmorOutput(boolean enableAsciiArmorOutput) { + this.enableAsciiArmorOutput = enableAsciiArmorOutput; + return this; + } + + public Builder compressionId(int compressionId) { + this.compressionId = compressionId; + return this; + } + + public Builder encryptionKeyIds(long[] encryptionKeyIds) { + this.encryptionKeyIds = encryptionKeyIds; + return this; + } + + public Builder encryptionPassphrase(String encryptionPassphrase) { + this.encryptionPassphrase = encryptionPassphrase; + return this; + } + + public Builder symmetricEncryptionAlgorithm(int symmetricEncryptionAlgorithm) { + this.symmetricEncryptionAlgorithm = symmetricEncryptionAlgorithm; + return this; + } + + public Builder signatureKeyId(long signatureKeyId) { + this.signatureKeyId = signatureKeyId; + return this; + } + + public Builder signatureHashAlgorithm(int signatureHashAlgorithm) { + this.signatureHashAlgorithm = signatureHashAlgorithm; + return this; + } + + public Builder signatureForceV3(boolean signatureForceV3) { + this.signatureForceV3 = signatureForceV3; + return this; + } + + public Builder signaturePassphrase(String signaturePassphrase) { + this.signaturePassphrase = signaturePassphrase; + return this; + } + + public PgpSignEncrypt build() { + return new PgpSignEncrypt(this); + } + } + + public void updateProgress(int message, int current, int total) { + if (progress != null) { + progress.setProgress(message, current, total); + } + } + + public void updateProgress(int current, int total) { + if (progress != null) { + progress.setProgress(current, total); + } + } + + /** + * Signs and/or encrypts data based on parameters of class + * + * @throws IOException + * @throws PgpGeneralException + * @throws PGPException + * @throws NoSuchProviderException + * @throws NoSuchAlgorithmException + * @throws SignatureException + */ + public void execute() + throws IOException, PgpGeneralException, PGPException, NoSuchProviderException, + NoSuchAlgorithmException, SignatureException { + + boolean enableSignature = signatureKeyId != Id.key.none; + boolean enableEncryption = (encryptionKeyIds.length != 0 || encryptionPassphrase != null); + boolean enableCompression = (enableEncryption && compressionId != Id.choice.compression.none); + + Log.d(Constants.TAG, "enableSignature:" + enableSignature + + "\nenableEncryption:" + enableEncryption + + "\nenableCompression:" + enableCompression + + "\nenableAsciiArmorOutput:" + enableAsciiArmorOutput); + + int signatureType; + if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + // for sign-only ascii text + signatureType = PGPSignature.CANONICAL_TEXT_DOCUMENT; + } else { + signatureType = PGPSignature.BINARY_DOCUMENT; + } + + ArmoredOutputStream armorOut = null; + OutputStream out; + if (enableAsciiArmorOutput) { + armorOut = new ArmoredOutputStream(outStream); + armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); + out = armorOut; + } else { + out = outStream; + } + + /* Get keys for signature generation for later usage */ + PGPSecretKey signingKey = null; + PGPSecretKeyRing signingKeyRing = null; + PGPPrivateKey signaturePrivateKey = null; + if (enableSignature) { + signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); + signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); + if (signingKey == null) { + throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); + } + + if (signaturePassphrase == null) { + throw new PgpGeneralException( + context.getString(R.string.error_no_signature_passphrase)); + } + + updateProgress(R.string.progress_extracting_signature_key, 0, 100); + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); + signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); + if (signaturePrivateKey == null) { + throw new PgpGeneralException( + context.getString(R.string.error_could_not_extract_private_key)); + } + } + updateProgress(R.string.progress_preparing_streams, 5, 100); + + /* Initialize PGPEncryptedDataGenerator for later usage */ + PGPEncryptedDataGenerator cPk = null; + if (enableEncryption) { + // has Integrity packet enabled! + JcePGPDataEncryptorBuilder encryptorBuilder = + new JcePGPDataEncryptorBuilder(symmetricEncryptionAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME) + .setWithIntegrityPacket(true); + + cPk = new PGPEncryptedDataGenerator(encryptorBuilder); + + if (encryptionKeyIds.length == 0) { + // Symmetric encryption + Log.d(Constants.TAG, "encryptionKeyIds length is 0 -> symmetric encryption"); + + JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = + new JcePBEKeyEncryptionMethodGenerator(encryptionPassphrase.toCharArray()); + cPk.addMethod(symmetricEncryptionGenerator); + } else { + // Asymmetric encryption + for (long id : encryptionKeyIds) { + PGPPublicKey key = PgpKeyHelper.getEncryptPublicKey(context, id); + if (key != null) { + JcePublicKeyKeyEncryptionMethodGenerator pubKeyEncryptionGenerator = + new JcePublicKeyKeyEncryptionMethodGenerator(key); + cPk.addMethod(pubKeyEncryptionGenerator); + } + } + } + } + + /* Initialize signature generator object for later usage */ + PGPSignatureGenerator signatureGenerator = null; + PGPV3SignatureGenerator signatureV3Generator = null; + if (enableSignature) { + updateProgress(R.string.progress_preparing_signature, 10, 100); + + // content signer based on signing key algorithm and chosen hash algorithm + JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder( + signingKey.getPublicKey().getAlgorithm(), signatureHashAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + if (signatureForceV3) { + signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); + signatureV3Generator.init(signatureType, signaturePrivateKey); + } else { + signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); + signatureGenerator.init(signatureType, signaturePrivateKey); + + String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + spGen.setSignerUserID(false, userId); + signatureGenerator.setHashedSubpackets(spGen.generate()); + } + } + + PGPCompressedDataGenerator compressGen = null; + OutputStream pOut; + OutputStream encryptionOut = null; + BCPGOutputStream bcpgOut; + if (enableEncryption) { + /* actual encryption */ + + encryptionOut = cPk.open(out, new byte[1 << 16]); + + if (enableCompression) { + compressGen = new PGPCompressedDataGenerator(compressionId); + bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut)); + } else { + bcpgOut = new BCPGOutputStream(encryptionOut); + } + + if (enableSignature) { + if (signatureForceV3) { + signatureV3Generator.generateOnePassVersion(false).encode(bcpgOut); + } else { + signatureGenerator.generateOnePassVersion(false).encode(bcpgOut); + } + } + + PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); + // file name not needed, so empty string + pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, "", new Date(), + new byte[1 << 16]); + updateProgress(R.string.progress_encrypting, 20, 100); + + long progress = 0; + int n; + byte[] buffer = new byte[1 << 16]; + InputStream in = data.getInputStream(); + while ((n = in.read(buffer)) > 0) { + pOut.write(buffer, 0, n); + + // update signature buffer if signature is requested + if (enableSignature) { + if (signatureForceV3) { + signatureV3Generator.update(buffer, 0, n); + } else { + signatureGenerator.update(buffer, 0, n); + } + } + + progress += n; + if (data.getSize() != 0) { + updateProgress((int) (20 + (95 - 20) * progress / data.getSize()), 100); + } + } + + literalGen.close(); + } else if (enableAsciiArmorOutput && enableSignature && !enableEncryption && !enableCompression) { + /* sign-only of ascii text */ + + updateProgress(R.string.progress_signing, 40, 100); + + // write directly on armor output stream + armorOut.beginClearText(signatureHashAlgorithm); + + InputStream in = data.getInputStream(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + + final byte[] newline = "\r\n".getBytes("UTF-8"); + + if (signatureForceV3) { + processLine(reader.readLine(), armorOut, signatureV3Generator); + } else { + processLine(reader.readLine(), armorOut, signatureGenerator); + } + + while (true) { + String line = reader.readLine(); + + if (line == null) { + armorOut.write(newline); + break; + } + + armorOut.write(newline); + + // update signature buffer with input line + if (signatureForceV3) { + signatureV3Generator.update(newline); + processLine(line, armorOut, signatureV3Generator); + } else { + signatureGenerator.update(newline); + processLine(line, armorOut, signatureGenerator); + } + } + + armorOut.endClearText(); + + pOut = new BCPGOutputStream(armorOut); + } else { + // TODO: implement sign-only for files! + pOut = null; + Log.e(Constants.TAG, "not supported!"); + } + + if (enableSignature) { + updateProgress(R.string.progress_generating_signature, 95, 100); + if (signatureForceV3) { + signatureV3Generator.generate().encode(pOut); + } else { + signatureGenerator.generate().encode(pOut); + } + } + + // closing outputs + // NOTE: closing needs to be done in the correct order! + // TODO: closing bcpgOut and pOut??? + if (enableEncryption) { + if (enableCompression) { + compressGen.close(); + } + + encryptionOut.close(); + } + if (enableAsciiArmorOutput) { + armorOut.close(); + } + + out.close(); + outStream.close(); + + updateProgress(R.string.progress_done, 100, 100); + } + + // TODO: merge this into execute method! + // TODO: allow binary input for this class + public void generateSignature() + throws PgpGeneralException, PGPException, IOException, NoSuchAlgorithmException, + SignatureException { + + OutputStream out; + if (enableAsciiArmorOutput) { + // Ascii Armor (Radix-64) + ArmoredOutputStream armorOut = new ArmoredOutputStream(outStream); + armorOut.setHeader("Version", PgpHelper.getFullVersion(context)); + out = armorOut; + } else { + out = outStream; + } + + if (signatureKeyId == 0) { + throw new PgpGeneralException(context.getString(R.string.error_no_signature_key)); + } + + PGPSecretKeyRing signingKeyRing = ProviderHelper.getPGPSecretKeyRingByKeyId(context, signatureKeyId); + PGPSecretKey signingKey = PgpKeyHelper.getSigningKey(context, signatureKeyId); + if (signingKey == null) { + throw new PgpGeneralException(context.getString(R.string.error_signature_failed)); + } + + if (signaturePassphrase == null) { + throw new PgpGeneralException(context.getString(R.string.error_no_signature_passphrase)); + } + + PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider( + Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(signaturePassphrase.toCharArray()); + PGPPrivateKey signaturePrivateKey = signingKey.extractPrivateKey(keyDecryptor); + if (signaturePrivateKey == null) { + throw new PgpGeneralException( + context.getString(R.string.error_could_not_extract_private_key)); + } + updateProgress(R.string.progress_preparing_streams, 0, 100); + + updateProgress(R.string.progress_preparing_signature, 30, 100); + + int type = PGPSignature.CANONICAL_TEXT_DOCUMENT; +// if (binary) { +// type = PGPSignature.BINARY_DOCUMENT; +// } + + // content signer based on signing key algorithm and chosen hash algorithm + JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(signingKey + .getPublicKey().getAlgorithm(), signatureHashAlgorithm) + .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME); + + PGPSignatureGenerator signatureGenerator = null; + PGPV3SignatureGenerator signatureV3Generator = null; + if (signatureForceV3) { + signatureV3Generator = new PGPV3SignatureGenerator(contentSignerBuilder); + signatureV3Generator.init(type, signaturePrivateKey); + } else { + signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder); + signatureGenerator.init(type, signaturePrivateKey); + + PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); + String userId = PgpKeyHelper.getMainUserId(PgpKeyHelper.getMasterKey(signingKeyRing)); + spGen.setSignerUserID(false, userId); + signatureGenerator.setHashedSubpackets(spGen.generate()); + } + + updateProgress(R.string.progress_signing, 40, 100); + + InputStream inStream = data.getInputStream(); +// if (binary) { +// byte[] buffer = new byte[1 << 16]; +// int n = 0; +// while ((n = inStream.read(buffer)) > 0) { +// if (signatureForceV3) { +// signatureV3Generator.update(buffer, 0, n); +// } else { +// signatureGenerator.update(buffer, 0, n); +// } +// } +// } else { + final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); + final byte[] newline = "\r\n".getBytes("UTF-8"); + + String line; + while ((line = reader.readLine()) != null) { + if (signatureForceV3) { + processLine(line, null, signatureV3Generator); + signatureV3Generator.update(newline); + } else { + processLine(line, null, signatureGenerator); + signatureGenerator.update(newline); + } + } +// } + + BCPGOutputStream bOut = new BCPGOutputStream(out); + if (signatureForceV3) { + signatureV3Generator.generate().encode(bOut); + } else { + signatureGenerator.generate().encode(bOut); + } + out.close(); + outStream.close(); + + updateProgress(R.string.progress_done, 100, 100); + } + + + private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, + final PGPSignatureGenerator pSignatureGenerator) + throws IOException, SignatureException { + + if (pLine == null) { + return; + } + + final char[] chars = pLine.toCharArray(); + int len = chars.length; + + while (len > 0) { + if (!Character.isWhitespace(chars[len - 1])) { + break; + } + len--; + } + + final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); + + if (pArmoredOutput != null) { + pArmoredOutput.write(data); + } + pSignatureGenerator.update(data); + } + + private static void processLine(final String pLine, final ArmoredOutputStream pArmoredOutput, + final PGPV3SignatureGenerator pSignatureGenerator) + throws IOException, SignatureException { + + if (pLine == null) { + return; + } + + final char[] chars = pLine.toCharArray(); + int len = chars.length; + + while (len > 0) { + if (!Character.isWhitespace(chars[len - 1])) { + break; + } + len--; + } + + final byte[] data = pLine.substring(0, len).getBytes("UTF-8"); + + if (pArmoredOutput != null) { + pArmoredOutput.write(data); + } + pSignatureGenerator.update(data); + } + +} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index 4ce1569f0..3904a91d8 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -43,11 +43,11 @@ import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.helper.OtherHelper; import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpImportExport; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; -import org.sufficientlysecure.keychain.pgp.PgpOperationIncoming; -import org.sufficientlysecure.keychain.pgp.PgpOperationOutgoing; +import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.KeychainContract.DataStream; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -317,8 +317,8 @@ public class KeychainIntentService extends IntentService implements ProgressDial } /* Operation */ - PgpOperationOutgoing.Builder builder = - new PgpOperationOutgoing.Builder(this, inputData, outStream); + PgpSignEncrypt.Builder builder = + new PgpSignEncrypt.Builder(this, inputData, outStream); builder.progress(this); if (generateSignature) { @@ -338,7 +338,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - builder.build().signEncrypt(); + builder.build().execute(); } else { Log.d(Constants.TAG, "encrypt..."); builder.enableAsciiArmorOutput(useAsciiArmor) @@ -351,7 +351,7 @@ public class KeychainIntentService extends IntentService implements ProgressDial .signatureHashAlgorithm(Preferences.getPreferences(this).getDefaultHashAlgorithm()) .signaturePassphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - builder.build().signEncrypt(); + builder.build().execute(); } outStream.close(); @@ -480,13 +480,13 @@ public class KeychainIntentService extends IntentService implements ProgressDial // verifyText and decrypt returning additional resultData values for the // verification of signatures - PgpOperationIncoming.Builder builder = new PgpOperationIncoming.Builder(this, inputData, outStream); + PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, outStream); builder.progress(this); builder.assumeSymmetric(assumeSymmetricEncryption) .passphrase(PassphraseCacheService.getCachedPassphrase(this, secretKeyId)); - resultData = builder.build().decryptVerify(); + resultData = builder.build().execute(); outStream.close(); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java index 688537be5..34213bd3b 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/service/remote/OpenPgpService.java @@ -32,8 +32,8 @@ import org.openintents.openpgp.util.OpenPgpConstants; import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.pgp.PgpOperationOutgoing; -import org.sufficientlysecure.keychain.pgp.PgpOperationIncoming; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; +import org.sufficientlysecure.keychain.pgp.PgpSignEncrypt; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.PassphraseCacheService; @@ -162,13 +162,13 @@ public class OpenPgpService extends RemoteService { InputData inputData = new InputData(is, inputLength); // sign-only - PgpOperationOutgoing.Builder builder = new PgpOperationOutgoing.Builder(getContext(), inputData, os); + PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); builder.enableAsciiArmorOutput(asciiArmor) .signatureHashAlgorithm(appSettings.getHashAlgorithm()) .signatureForceV3(false) .signatureKeyId(appSettings.getKeyId()) .signaturePassphrase(passphrase); - builder.build().signEncrypt(); + builder.build().execute(); } finally { is.close(); os.close(); @@ -227,7 +227,7 @@ public class OpenPgpService extends RemoteService { long inputLength = is.available(); InputData inputData = new InputData(is, inputLength); - PgpOperationOutgoing.Builder builder = new PgpOperationOutgoing.Builder(getContext(), inputData, os); + PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(getContext(), inputData, os); builder.enableAsciiArmorOutput(asciiArmor) .compressionId(appSettings.getCompression()) .symmetricEncryptionAlgorithm(appSettings.getEncryptionAlgorithm()) @@ -257,7 +257,7 @@ public class OpenPgpService extends RemoteService { builder.signatureKeyId(Id.key.none); } // execute PGP operation! - builder.build().signEncrypt(); + builder.build().execute(); } finally { is.close(); os.close(); @@ -354,7 +354,7 @@ public class OpenPgpService extends RemoteService { // inputStream2.reset(); // } // secretKeyId = Id.key.symmetric; -// if (!PgpOperationIncoming.hasSymmetricEncryption(this, inputStream2)) { +// if (!PgpDecryptVerify.hasSymmetricEncryption(this, inputStream2)) { // throw new PgpGeneralException( // getString(R.string.error_no_known_encryption_found)); // } @@ -384,7 +384,7 @@ public class OpenPgpService extends RemoteService { Bundle outputBundle; - PgpOperationIncoming.Builder builder = new PgpOperationIncoming.Builder(this, inputData, os); + PgpDecryptVerify.Builder builder = new PgpDecryptVerify.Builder(this, inputData, os); // if (signedOnly) { // outputBundle = builder.build().verifyText(); @@ -396,7 +396,7 @@ public class OpenPgpService extends RemoteService { // pause stream when passphrase is missing and then resume??? // TODO: this also decrypts with other secret keys without passphrase!!! - outputBundle = builder.build().decryptVerify(); + outputBundle = builder.build().execute(); // } // outputStream.close(); @@ -425,7 +425,6 @@ public class OpenPgpService extends RemoteService { signatureStatus = OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY; } - // TODO: signed only?!?!?! sigResult = new OpenPgpSignatureResult(signatureStatus, signatureUserId, signatureOnly, signatureKeyId); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 7df416417..2e467aa21 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -34,7 +34,7 @@ import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.pgp.PgpOperationIncoming; +import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify; import org.sufficientlysecure.keychain.pgp.exception.NoAsymmetricEncryptionException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.ProviderHelper; @@ -85,7 +85,7 @@ public class DecryptActivity extends DrawerActivity { private boolean mReturnResult = false; // TODO: replace signed only checks with something more intelligent - // PgpOperationIncoming should handle all automatically!!! + // PgpDecryptVerify should handle all automatically!!! private boolean mSignedOnly = false; private boolean mAssumeSymmetricEncryption = false; @@ -549,7 +549,7 @@ public class DecryptActivity extends DrawerActivity { inStream.reset(); } mSecretKeyId = Id.key.symmetric; - if (!PgpOperationIncoming.hasSymmetricEncryption(this, inStream)) { + if (!PgpDecryptVerify.hasSymmetricEncryption(this, inStream)) { throw new PgpGeneralException( getString(R.string.error_no_known_encryption_found)); } -- cgit v1.2.3 From f29d3015b8ca067986f588481242a6cc9061dbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2014 15:45:10 +0100 Subject: rename --- OpenPGP-Keychain/src/main/res/raw/help_about.html | 6 +++--- OpenPGP-Keychain/src/main/res/raw/help_start.html | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/res/raw/help_about.html b/OpenPGP-Keychain/src/main/res/raw/help_about.html index 882049c49..51e3f1325 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_about.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_about.html @@ -5,11 +5,11 @@ And don't add newlines before or after p tags because of transifex --> -

                                                http://sufficientlysecure.org/keychain

                                                -

                                                OpenPGP Keychain is an OpenPGP implementation for Android. The development began as a fork of Android Privacy Guard (APG).

                                                +

                                                http://www.openkeychain.org

                                                +

                                                OpenKeychain is an OpenPGP implementation for Android.

                                                License: GPLv3+

                                                -

                                                Developers OpenPGP Keychain

                                                +

                                                Developers OpenKeychain

                                                • Dominik Schürmann (Lead developer)
                                                • Ash Hughes (crypto patches)
                                                • diff --git a/OpenPGP-Keychain/src/main/res/raw/help_start.html b/OpenPGP-Keychain/src/main/res/raw/help_start.html index f2041b066..6c8c49846 100644 --- a/OpenPGP-Keychain/src/main/res/raw/help_start.html +++ b/OpenPGP-Keychain/src/main/res/raw/help_start.html @@ -10,14 +10,14 @@ And don't add newlines before or after p tags because of transifex -->

                                                  It is recommended that you install OI File Manager for enhanced file selection and Barcode Scanner to scan generated QR Codes. Clicking on the links will open Google Play Store or F-Droid for installation.

                                                  -

                                                  I found a bug in OpenPGP Keychain!

                                                  -

                                                  Please report the bug using the issue tracker of OpenPGP Keychain.

                                                  +

                                                  I found a bug in OpenKeychain!

                                                  +

                                                  Please report the bug using the issue tracker of OpenKeychain.

                                                  Contribute

                                                  -

                                                  If you want to help us developing OpenPGP Keychain by contributing code follow our small guide on Github.

                                                  +

                                                  If you want to help us developing OpenKeychain by contributing code follow our small guide on Github.

                                                  Translations

                                                  -

                                                  Help translating OpenPGP Keychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                  +

                                                  Help translating OpenKeychain! Everybody can participate at OpenPGP Keychain on Transifex.

                                                  -- cgit v1.2.3 From c2013c9ca88e44a8a6a1eb110a331eba9811a1f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2014 15:47:15 +0100 Subject: precompile user id pattern --- .../main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java index 3fc63cda1..b3e21685e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyHelper.java @@ -42,6 +42,8 @@ import android.content.Context; public class PgpKeyHelper { + private static final Pattern USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$"); + public static Date getCreationDate(PGPPublicKey key) { return key.getCreationTime(); } @@ -540,8 +542,7 @@ public class PgpKeyHelper { * "Max Mustermann (this is a comment)" * "Max Mustermann [this is nothing]" */ - Pattern withComment = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$"); - Matcher matcher = withComment.matcher(userId); + Matcher matcher = USER_ID_PATTERN.matcher(userId); if (matcher.matches()) { result[0] = matcher.group(1); result[1] = matcher.group(3); -- cgit v1.2.3 From 5b0c82b58f0f0348024477c0ae62099c4831c5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Fri, 21 Feb 2014 16:21:06 +0100 Subject: import key from email app directly --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 62 ++++++++++++++++----------- 1 file changed, 37 insertions(+), 25 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 95f148686..205b3c044 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -273,8 +273,9 @@ android:launchMode="singleTop" android:windowSoftInputMode="stateHidden"> - - + + @@ -287,40 +288,25 @@ - - - - - - - - - - + - + + - + + - + - + - - - - - - - - - + @@ -341,6 +327,7 @@ + @@ -362,6 +349,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Date: Fri, 21 Feb 2014 16:28:48 +0100 Subject: AndroidManfiest code for later... --- OpenPGP-Keychain/src/main/AndroidManifest.xml | 24 ++++++++++++++++++++-- .../keychain/ui/DecryptActivity.java | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'OpenPGP-Keychain/src') diff --git a/OpenPGP-Keychain/src/main/AndroidManifest.xml b/OpenPGP-Keychain/src/main/AndroidManifest.xml index 205b3c044..480acdbd8 100644 --- a/OpenPGP-Keychain/src/main/AndroidManifest.xml +++ b/OpenPGP-Keychain/src/main/AndroidManifest.xml @@ -182,6 +182,26 @@ android:label="@string/title_decrypt" android:windowSoftInputMode="stateHidden"> + + + + + + + + + + + + + + + + + + + + @@ -295,7 +315,7 @@ - + @@ -303,7 +323,7 @@ - + diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 2e467aa21..652310cd2 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -297,7 +297,7 @@ public class DecryptActivity extends DrawerActivity { * Android's Action */ if (Intent.ACTION_SEND.equals(action) && type != null) { - // When sending to Keychain Encrypt via share menu + // When sending to Keychain Decrypt via share menu if ("text/plain".equals(type)) { // Plain text String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); -- cgit v1.2.3