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 | 58 |
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); } } |