aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-08-14 13:31:01 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2014-08-14 13:31:01 +0200
commit6da17ef6bbe9569e53268b446e59dcc69aaa2da4 (patch)
tree0747b0f06b974f032573f48c08930498050ab9ce /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote
parent881a50207af0a9f9f5aa69f451110de786779b54 (diff)
parent37edd0f390064e725d1b5c1c866a76c9922b0f64 (diff)
downloadopen-keychain-6da17ef6bbe9569e53268b446e59dcc69aaa2da4.tar.gz
open-keychain-6da17ef6bbe9569e53268b446e59dcc69aaa2da4.tar.bz2
open-keychain-6da17ef6bbe9569e53268b446e59dcc69aaa2da4.zip
Merge branch 'master' into yubikey
Conflicts: OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncrypt.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java84
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java80
3 files changed, 124 insertions, 42 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index eae217e16..6bc623b85 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -25,6 +25,7 @@ import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import org.openintents.openpgp.IOpenPgpService;
+import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
@@ -184,7 +185,13 @@ public class OpenPgpService extends RemoteService {
if (data.hasExtra(OpenPgpApi.EXTRA_PASSPHRASE)) {
passphrase = data.getStringExtra(OpenPgpApi.EXTRA_PASSPHRASE);
} else {
- passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId());
+ try {
+ passphrase = PassphraseCacheService.getCachedPassphrase(getContext(), accSettings.getKeyId());
+ } catch (PassphraseCacheService.KeyNotFoundException e) {
+ // secret key that is set for this account is deleted?
+ // show account config again!
+ return getCreateAccountIntent(data, data.getStringExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME));
+ }
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
@@ -204,9 +211,9 @@ public class OpenPgpService extends RemoteService {
// sign-only
PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
new ProviderHelper(getContext()),
- PgpHelper.getFullVersion(getContext()),
inputData, os);
builder.setEnableAsciiArmorOutput(asciiArmor)
+ .setVersionHeader(PgpHelper.getVersionForHeader(this))
.setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
.setSignatureMasterKeyId(accSettings.getKeyId())
.setSignaturePassphrase(passphrase)
@@ -257,6 +264,10 @@ public class OpenPgpService extends RemoteService {
boolean sign) {
try {
boolean asciiArmor = data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
+ String originalFilename = data.getStringExtra(OpenPgpApi.EXTRA_ORIGINAL_FILENAME);
+ if (originalFilename == null) {
+ originalFilename = "";
+ }
long[] keyIds;
if (data.hasExtra(OpenPgpApi.EXTRA_KEY_IDS)) {
@@ -297,12 +308,13 @@ public class OpenPgpService extends RemoteService {
PgpSignEncrypt.Builder builder = new PgpSignEncrypt.Builder(
new ProviderHelper(getContext()),
- PgpHelper.getFullVersion(getContext()),
inputData, os);
builder.setEnableAsciiArmorOutput(asciiArmor)
+ .setVersionHeader(PgpHelper.getVersionForHeader(this))
.setCompressionId(accSettings.getCompression())
.setSymmetricEncryptionAlgorithm(accSettings.getEncryptionAlgorithm())
- .setEncryptionMasterKeyIds(keyIds);
+ .setEncryptionMasterKeyIds(keyIds)
+ .setOriginalFilename(originalFilename);
if (sign) {
String passphrase;
@@ -359,11 +371,18 @@ public class OpenPgpService extends RemoteService {
}
private Intent decryptAndVerifyImpl(Intent data, ParcelFileDescriptor input,
- ParcelFileDescriptor output, Set<Long> allowedKeyIds) {
+ ParcelFileDescriptor output, Set<Long> allowedKeyIds,
+ boolean decryptMetadataOnly) {
try {
// Get Input- and OutputStream from ParcelFileDescriptor
InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
- OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+
+ OutputStream os;
+ if (decryptMetadataOnly) {
+ os = null;
+ } else {
+ os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
+ }
Intent result = new Intent();
try {
@@ -376,17 +395,24 @@ public class OpenPgpService extends RemoteService {
new ProviderHelper(this),
new PgpDecryptVerify.PassphraseCache() {
@Override
- public String getCachedPassphrase(long masterKeyId) {
- return PassphraseCacheService.getCachedPassphrase(
- OpenPgpService.this, masterKeyId);
+ public String getCachedPassphrase(long masterKeyId) throws PgpDecryptVerify.NoSecretKeyException {
+ try {
+ return PassphraseCacheService.getCachedPassphrase(
+ OpenPgpService.this, masterKeyId);
+ } catch (PassphraseCacheService.KeyNotFoundException e) {
+ throw new PgpDecryptVerify.NoSecretKeyException();
+ }
}
},
inputData, os
);
- builder.setAllowSymmetricDecryption(false) // no support for symmetric encryption
- .setAllowedKeyIds(allowedKeyIds) // allow only private keys associated with
- // accounts of this app
- .setPassphrase(passphrase);
+
+ // allow only private keys associated with accounts of this app
+ // no support for symmetric encryption
+ builder.setPassphrase(passphrase)
+ .setAllowSymmetricDecryption(false)
+ .setAllowedKeyIds(allowedKeyIds)
+ .setDecryptMetadataOnly(decryptMetadataOnly);
PgpDecryptVerifyResult decryptVerifyResult;
try {
@@ -409,8 +435,7 @@ public class OpenPgpService extends RemoteService {
if (PgpDecryptVerifyResult.KEY_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
// get PendingIntent for passphrase input, add it to given params and return to client
return getPassphraseIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
- } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
- decryptVerifyResult.getStatus()) {
+ } else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED == decryptVerifyResult.getStatus()) {
throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
}
@@ -434,9 +459,18 @@ public class OpenPgpService extends RemoteService {
}
}
+ if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 4) {
+ OpenPgpMetadata metadata = decryptVerifyResult.getDecryptMetadata();
+ if (metadata != null) {
+ result.putExtra(OpenPgpApi.RESULT_METADATA, metadata);
+ }
+ }
+
} finally {
is.close();
- os.close();
+ if (os != null) {
+ os.close();
+ }
}
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
@@ -492,6 +526,7 @@ public class OpenPgpService extends RemoteService {
return result;
}
} catch (Exception e) {
+ Log.d(Constants.TAG, "getKeyImpl", e);
Intent result = new Intent();
result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
@@ -537,10 +572,15 @@ public class OpenPgpService extends RemoteService {
}
// version code is required and needs to correspond to version code of service!
- if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != OpenPgpApi.API_VERSION) {
+ // History of versions in org.openintents.openpgp.util.OpenPgpApi
+ // we support 3 and 4
+ if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 3
+ && data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) != 4) {
Intent result = new Intent();
OpenPgpError error = new OpenPgpError
- (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!");
+ (OpenPgpError.INCOMPATIBLE_API_VERSIONS, "Incompatible API versions!\n"
+ + "used API version: " + data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) + "\n"
+ + "supported API versions: 3, 4");
result.putExtra(OpenPgpApi.RESULT_ERROR, error);
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
return result;
@@ -588,7 +628,13 @@ public class OpenPgpService extends RemoteService {
Set<Long> allowedKeyIds =
mProviderHelper.getAllKeyIdsForApp(
ApiAccounts.buildBaseUri(currentPkg));
- return decryptAndVerifyImpl(data, input, output, allowedKeyIds);
+ return decryptAndVerifyImpl(data, input, output, allowedKeyIds, false);
+ } else if (OpenPgpApi.ACTION_DECRYPT_METADATA.equals(action)) {
+ String currentPkg = getCurrentCallingPackage();
+ Set<Long> allowedKeyIds =
+ mProviderHelper.getAllKeyIdsForApp(
+ ApiAccounts.buildBaseUri(currentPkg));
+ return decryptAndVerifyImpl(data, input, output, allowedKeyIds, true);
} else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
return getKeyImpl(data);
} else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
index 8f1f46c04..666252353 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsActivity.java
@@ -102,7 +102,7 @@ public class AccountSettingsActivity extends ActionBarActivity {
}
private void save() {
- new ProviderHelper(this).updateApiAccount(mAccountSettingsFragment.getAccSettings(), mAccountUri);
+ new ProviderHelper(this).updateApiAccount(mAccountUri, mAccountSettingsFragment.getAccSettings());
finish();
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
index d0b958844..48c76d561 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
@@ -18,11 +18,13 @@
package org.sufficientlysecure.keychain.remote.ui;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
+import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.htmltextview.HtmlTextView;
@@ -37,6 +39,7 @@ import org.sufficientlysecure.keychain.ui.SelectPublicKeyFragment;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
+import java.security.Provider;
import java.util.ArrayList;
public class RemoteServiceActivity extends ActionBarActivity {
@@ -76,10 +79,17 @@ public class RemoteServiceActivity extends ActionBarActivity {
// select pub keys view
private SelectPublicKeyFragment mSelectFragment;
+ private ProviderHelper mProviderHelper;
+
+ // for ACTION_CREATE_ACCOUNT
+ boolean mUpdateExistingAccount;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mProviderHelper = new ProviderHelper(this);
+
handleActions(getIntent(), savedInstanceState);
}
@@ -94,6 +104,14 @@ public class RemoteServiceActivity extends ActionBarActivity {
final byte[] packageSignature = extras.getByteArray(EXTRA_PACKAGE_SIGNATURE);
Log.d(Constants.TAG, "ACTION_REGISTER packageName: " + packageName);
+ setContentView(R.layout.api_remote_register_app);
+
+ mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
+ R.id.api_app_settings_fragment);
+
+ AppSettings settings = new AppSettings(packageName, packageSignature);
+ mAppSettingsFragment.setAppSettings(settings);
+
// Inflate a "Done"/"Cancel" custom action bar view
ActionBarHelper.setTwoButtonView(getSupportActionBar(),
R.string.api_register_allow, R.drawable.ic_action_done,
@@ -102,8 +120,7 @@ public class RemoteServiceActivity extends ActionBarActivity {
public void onClick(View v) {
// Allow
- new ProviderHelper(RemoteServiceActivity.this).insertApiApp(
- mAppSettingsFragment.getAppSettings());
+ mProviderHelper.insertApiApp(mAppSettingsFragment.getAppSettings());
// give data through for new service call
Intent resultData = extras.getParcelable(EXTRA_DATA);
@@ -120,18 +137,34 @@ public class RemoteServiceActivity extends ActionBarActivity {
}
}
);
-
- setContentView(R.layout.api_remote_register_app);
-
- mAppSettingsFragment = (AppSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_app_settings_fragment);
-
- AppSettings settings = new AppSettings(packageName, packageSignature);
- mAppSettingsFragment.setAppSettings(settings);
} else if (ACTION_CREATE_ACCOUNT.equals(action)) {
final String packageName = extras.getString(EXTRA_PACKAGE_NAME);
final String accName = extras.getString(EXTRA_ACC_NAME);
+ setContentView(R.layout.api_remote_create_account);
+
+ mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
+ R.id.api_account_settings_fragment);
+
+ TextView text = (TextView) findViewById(R.id.api_remote_create_account_text);
+
+ // update existing?
+ Uri uri = KeychainContract.ApiAccounts.buildByPackageAndAccountUri(packageName, accName);
+ AccountSettings settings = mProviderHelper.getApiAccountSettings(uri);
+ if (settings == null) {
+ // create new account
+ settings = new AccountSettings(accName);
+ mUpdateExistingAccount = false;
+
+ text.setText(R.string.api_create_account_text);
+ } else {
+ // update existing account
+ mUpdateExistingAccount = true;
+
+ text.setText(R.string.api_update_account_text);
+ }
+ mAccSettingsFragment.setAccSettings(settings);
+
// Inflate a "Done"/"Cancel" custom action bar view
ActionBarHelper.setTwoButtonView(getSupportActionBar(),
R.string.api_settings_save, R.drawable.ic_action_done,
@@ -145,9 +178,17 @@ public class RemoteServiceActivity extends ActionBarActivity {
mAccSettingsFragment.setErrorOnSelectKeyFragment(
getString(R.string.api_register_error_select_key));
} else {
- new ProviderHelper(RemoteServiceActivity.this).insertApiAccount(
- KeychainContract.ApiAccounts.buildBaseUri(packageName),
- mAccSettingsFragment.getAccSettings());
+ if (mUpdateExistingAccount) {
+ Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(packageName);
+ Uri accountUri = baseUri.buildUpon().appendEncodedPath(accName).build();
+ mProviderHelper.updateApiAccount(
+ accountUri,
+ mAccSettingsFragment.getAccSettings());
+ } else {
+ mProviderHelper.insertApiAccount(
+ KeychainContract.ApiAccounts.buildBaseUri(packageName),
+ mAccSettingsFragment.getAccSettings());
+ }
// give data through for new service call
Intent resultData = extras.getParcelable(EXTRA_DATA);
@@ -166,13 +207,6 @@ public class RemoteServiceActivity extends ActionBarActivity {
}
);
- setContentView(R.layout.api_remote_create_account);
-
- mAccSettingsFragment = (AccountSettingsFragment) getSupportFragmentManager().findFragmentById(
- R.id.api_account_settings_fragment);
-
- AccountSettings settings = new AccountSettings(accName);
- mAccSettingsFragment.setAccSettings(settings);
} else if (ACTION_CACHE_PASSPHRASE.equals(action)) {
long secretKeyId = extras.getLong(EXTRA_SECRET_KEY_ID);
final Intent resultData = extras.getParcelable(EXTRA_DATA);
@@ -190,7 +224,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
RemoteServiceActivity.this.finish();
}
- });
+ }
+ );
} else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
@@ -286,7 +321,8 @@ public class RemoteServiceActivity extends ActionBarActivity {
RemoteServiceActivity.this.setResult(RESULT_CANCELED);
RemoteServiceActivity.this.finish();
}
- });
+ }
+ );
setContentView(R.layout.api_remote_error_message);