aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java58
1 files changed, 44 insertions, 14 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 5ed95acb3..eae217e16 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -28,6 +28,7 @@ import org.openintents.openpgp.IOpenPgpService;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpApi;
+import org.openkeychain.nfc.NfcActivity;
import org.spongycastle.util.Arrays;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@@ -49,6 +50,7 @@ import org.sufficientlysecure.keychain.util.Log;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Date;
import java.util.Set;
public class OpenPgpService extends RemoteService {
@@ -135,7 +137,26 @@ public class OpenPgpService extends RemoteService {
return result;
}
- private Intent getPassphraseBundleIntent(Intent data, long keyId) {
+ private Intent getNfcIntent(Intent data, byte[] hashToSign) {
+ // build PendingIntent for Yubikey NFC operations
+ Intent intent = new Intent(getBaseContext(), NfcActivity.class);
+ intent.setAction(NfcActivity.ACTION_SIGN_HASH);
+ intent.putExtra(NfcActivity.EXTRA_NFC_HASH_TO_SIGN, hashToSign);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ // pass params through to activity that it can be returned again later to repeat pgp operation
+ intent.putExtra(NfcActivity.EXTRA_DATA, data);
+ PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0,
+ intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+
+ // return PendingIntent to be executed by client
+ Intent result = new Intent();
+ result.putExtra(OpenPgpApi.RESULT_INTENT, pi);
+ result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED);
+ return result;
+ }
+
+ private Intent getPassphraseIntent(Intent data, long keyId) {
// build PendingIntent for passphrase input
Intent intent = new Intent(getBaseContext(), RemoteServiceActivity.class);
intent.setAction(RemoteServiceActivity.ACTION_CACHE_PASSPHRASE);
@@ -167,10 +188,12 @@ public class OpenPgpService extends RemoteService {
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
- return passphraseBundle;
+ return getPassphraseIntent(data, accSettings.getKeyId());
}
+ byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH);
+ Date nfcCreationTimestamp = new Date(data.getLongExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, 0));
+
// Get Input- and OutputStream from ParcelFileDescriptor
InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
@@ -185,9 +208,9 @@ public class OpenPgpService extends RemoteService {
inputData, os);
builder.setEnableAsciiArmorOutput(asciiArmor)
.setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
- .setSignatureForceV3(false)
.setSignatureMasterKeyId(accSettings.getKeyId())
- .setSignaturePassphrase(passphrase);
+ .setSignaturePassphrase(passphrase)
+ .setNfcState(nfcSignedHash, nfcCreationTimestamp);
// TODO: currently always assume cleartext input, no sign-only of binary currently!
builder.setCleartextInput(true);
@@ -200,8 +223,16 @@ public class OpenPgpService extends RemoteService {
throw new Exception(getString(R.string.error_could_not_extract_private_key));
} catch (PgpSignEncrypt.NoPassphraseException e) {
throw new Exception(getString(R.string.error_no_signature_passphrase));
+ } catch (PgpSignEncrypt.WrongPassphraseException e) {
+ throw new Exception(getString(R.string.error_wrong_passphrase));
} catch (PgpSignEncrypt.NoSigningKeyException e) {
throw new Exception(getString(R.string.error_no_signature_key));
+ } catch (PgpSignEncrypt.NeedNfcDataException e) {
+ // return PendingIntent to execute NFC activity
+ // pass through the signature creation timestamp to be used again on second execution
+ // of PgpSignEncrypt when we have the signed hash!
+ data.putExtra(OpenPgpApi.EXTRA_NFC_SIG_CREATION_TIMESTAMP, e.mCreationTimestamp.getTime());
+ return getNfcIntent(data, e.mHashToSign);
}
} finally {
is.close();
@@ -212,6 +243,7 @@ public class OpenPgpService extends RemoteService {
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
+ Log.d(Constants.TAG, "signImpl", e);
Intent result = new Intent();
result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
@@ -282,13 +314,11 @@ public class OpenPgpService extends RemoteService {
}
if (passphrase == null) {
// get PendingIntent for passphrase input, add it to given params and return to client
- Intent passphraseBundle = getPassphraseBundleIntent(data, accSettings.getKeyId());
- return passphraseBundle;
+ return getPassphraseIntent(data, accSettings.getKeyId());
}
// sign and encrypt
builder.setSignatureHashAlgorithm(accSettings.getHashAlgorithm())
- .setSignatureForceV3(false)
.setSignatureMasterKeyId(accSettings.getKeyId())
.setSignaturePassphrase(passphrase);
} else {
@@ -305,6 +335,8 @@ public class OpenPgpService extends RemoteService {
throw new Exception(getString(R.string.error_could_not_extract_private_key));
} catch (PgpSignEncrypt.NoPassphraseException e) {
throw new Exception(getString(R.string.error_no_signature_passphrase));
+ } catch (PgpSignEncrypt.WrongPassphraseException e) {
+ throw new Exception(getString(R.string.error_wrong_passphrase));
} catch (PgpSignEncrypt.NoSigningKeyException e) {
throw new Exception(getString(R.string.error_no_signature_key));
}
@@ -317,6 +349,7 @@ public class OpenPgpService extends RemoteService {
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
+ Log.d(Constants.TAG, "encryptAndSignImpl", e);
Intent result = new Intent();
result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
@@ -375,9 +408,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
- Intent passphraseBundle =
- getPassphraseBundleIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
- return passphraseBundle;
+ return getPassphraseIntent(data, decryptVerifyResult.getKeyIdPassphraseNeeded());
} else if (PgpDecryptVerifyResult.SYMMETRIC_PASSHRASE_NEEDED ==
decryptVerifyResult.getStatus()) {
throw new PgpGeneralException("Decryption of symmetric content not supported by API!");
@@ -411,6 +442,7 @@ public class OpenPgpService extends RemoteService {
result.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
return result;
} catch (Exception e) {
+ Log.d(Constants.TAG, "decryptAndVerifyImpl", e);
Intent result = new Intent();
result.putExtra(OpenPgpApi.RESULT_ERROR,
new OpenPgpError(OpenPgpError.GENERIC_ERROR, e.getMessage()));
@@ -480,10 +512,8 @@ public class OpenPgpService extends RemoteService {
return result;
} else {
// get key ids based on given user ids
-
String[] userIds = data.getStringArrayExtra(OpenPgpApi.EXTRA_USER_IDS);
- Intent result = getKeyIdsFromEmails(data, userIds);
- return result;
+ return getKeyIdsFromEmails(data, userIds);
}
}