diff options
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.java | 52 |
1 files changed, 41 insertions, 11 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 492ade7c3..6bc623b85 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java @@ -29,6 +29,7 @@ import org.openintents.openpgp.OpenPgpMetadata; 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; @@ -50,6 +51,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 { @@ -136,7 +138,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); @@ -174,9 +195,12 @@ public class OpenPgpService extends RemoteService { } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - return getPassphraseBundleIntent(data, accSettings.getKeyId()); + 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); @@ -191,9 +215,9 @@ public class OpenPgpService extends RemoteService { builder.setEnableAsciiArmorOutput(asciiArmor) .setVersionHeader(PgpHelper.getVersionForHeader(this)) .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); @@ -206,8 +230,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(); @@ -294,12 +326,11 @@ public class OpenPgpService extends RemoteService { } if (passphrase == null) { // get PendingIntent for passphrase input, add it to given params and return to client - return getPassphraseBundleIntent(data, accSettings.getKeyId()); + return getPassphraseIntent(data, accSettings.getKeyId()); } // sign and encrypt builder.setSignatureHashAlgorithm(accSettings.getHashAlgorithm()) - .setSignatureForceV3(false) .setSignatureMasterKeyId(accSettings.getKeyId()) .setSignaturePassphrase(passphrase); } else { @@ -316,6 +347,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)); } @@ -401,9 +434,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!"); } @@ -517,8 +548,7 @@ public class OpenPgpService extends RemoteService { } 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); } } |