aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2015-10-15 22:50:34 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2015-10-15 22:50:34 +0200
commitcac7c3234a6ee1d25f46a9179645e01c1c0512c2 (patch)
treef6e8cdb715249084322740605e5758c312502f00 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java
parentc03dee6fe2f60717f448178dcf49d370dce0bab0 (diff)
downloadopen-keychain-cac7c3234a6ee1d25f46a9179645e01c1c0512c2.tar.gz
open-keychain-cac7c3234a6ee1d25f46a9179645e01c1c0512c2.tar.bz2
open-keychain-cac7c3234a6ee1d25f46a9179645e01c1c0512c2.zip
Support backupVersion ASCII Armor header
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java91
1 files changed, 69 insertions, 22 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java
index 4a08ab9c1..7fe89b6f2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpDecryptVerifyOperation.java
@@ -31,6 +31,7 @@ import java.util.Iterator;
import android.content.Context;
import android.support.annotation.NonNull;
+import android.text.TextUtils;
import android.webkit.MimeTypeMap;
import org.openintents.openpgp.OpenPgpDecryptionResult;
@@ -201,6 +202,57 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
}
+ private static class ArmorHeaders {
+ String charset = null;
+ Integer backupVersion = null;
+ }
+
+ private ArmorHeaders parseArmorHeaders(InputStream in, OperationLog log, int indent) {
+ ArmorHeaders armorHeaders = new ArmorHeaders();
+
+ // If the input stream is armored, and there is a charset specified, take a note for later
+ // https://tools.ietf.org/html/rfc4880#page56
+ if (in instanceof ArmoredInputStream) {
+ ArmoredInputStream aIn = (ArmoredInputStream) in;
+ if (aIn.getArmorHeaders() != null) {
+ for (String header : aIn.getArmorHeaders()) {
+ String[] pieces = header.split(":", 2);
+ if (pieces.length != 2
+ || TextUtils.isEmpty(pieces[0])
+ || TextUtils.isEmpty(pieces[1])) {
+ continue;
+ }
+
+ switch (pieces[0].toLowerCase()) {
+ case "charset": {
+ armorHeaders.charset = pieces[1].trim();
+ break;
+ }
+ case "backupversion": {
+ try {
+ armorHeaders.backupVersion = Integer.valueOf(pieces[1].trim());
+ } catch (NumberFormatException e) {
+ continue;
+ }
+ break;
+ }
+ default: {
+ // continue;
+ }
+ }
+ }
+ if (armorHeaders.charset != null) {
+ log.add(LogType.MSG_DC_CHARSET, indent, armorHeaders.charset);
+ }
+ if (armorHeaders.backupVersion != null) {
+ log.add(LogType.MSG_DC_BACKUP_VERSION, indent, armorHeaders.backupVersion);
+ }
+ }
+ }
+
+ return armorHeaders;
+ }
+
/** Decrypt and/or verify binary or ascii armored pgp data. */
@NonNull
private DecryptVerifyResult decryptVerify(
@@ -215,23 +267,12 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
int currentProgress = 0;
updateProgress(R.string.progress_reading_data, currentProgress, 100);
- // If the input stream is armored, and there is a charset specified, take a note for later
- // https://tools.ietf.org/html/rfc4880#page56
- String charset = null;
- if (in instanceof ArmoredInputStream) {
- ArmoredInputStream aIn = (ArmoredInputStream) in;
- if (aIn.getArmorHeaders() != null) {
- for (String header : aIn.getArmorHeaders()) {
- String[] pieces = header.split(":", 2);
- if (pieces.length == 2 && "charset".equalsIgnoreCase(pieces[0])) {
- charset = pieces[1].trim();
- break;
- }
- }
- if (charset != null) {
- log.add(LogType.MSG_DC_CHARSET, indent, charset);
- }
- }
+ // parse ASCII Armor headers
+ ArmorHeaders armorHeaders = parseArmorHeaders(in, log, indent);
+ String charset = armorHeaders.charset;
+ boolean useBackupCode = false;
+ if (armorHeaders.backupVersion != null && armorHeaders.backupVersion == 1) {
+ useBackupCode = true;
}
OpenPgpDecryptionResultBuilder decryptionResultBuilder = new OpenPgpDecryptionResultBuilder();
@@ -245,7 +286,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
if (obj instanceof PGPEncryptedDataList) {
esResult = handleEncryptedPacket(
- input, cryptoInput, (PGPEncryptedDataList) obj, log, indent, currentProgress);
+ input, cryptoInput, (PGPEncryptedDataList) obj, log, indent,
+ currentProgress, useBackupCode);
// if there is an error, nothing left to do here
if (esResult.errorResult != null) {
@@ -477,7 +519,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
}
private EncryptStreamResult handleEncryptedPacket(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput,
- PGPEncryptedDataList enc, OperationLog log, int indent, int currentProgress) throws PGPException {
+ PGPEncryptedDataList enc, OperationLog log, int indent, int currentProgress, boolean useBackupCode) throws PGPException {
EncryptStreamResult result = new EncryptStreamResult();
@@ -609,8 +651,11 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
if (passphrase == null) {
log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
+ RequiredInputParcel requiredInputParcel = useBackupCode ?
+ RequiredInputParcel.createRequiredBackupCode() :
+ RequiredInputParcel.createRequiredSymmetricPassphrase();
return result.with(new DecryptVerifyResult(log,
- RequiredInputParcel.createRequiredSymmetricPassphrase(),
+ requiredInputParcel,
cryptoInput));
}
@@ -653,8 +698,10 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
result.cleartextStream = encryptedDataSymmetric.getDataStream(decryptorFactory);
} catch (PGPDataValidationException e) {
log.add(LogType.MSG_DC_ERROR_SYM_PASSPHRASE, indent + 1);
- return result.with(new DecryptVerifyResult(log,
- RequiredInputParcel.createRequiredSymmetricPassphrase(), cryptoInput));
+ RequiredInputParcel requiredInputParcel = useBackupCode ?
+ RequiredInputParcel.createRequiredBackupCode() :
+ RequiredInputParcel.createRequiredSymmetricPassphrase();
+ return result.with(new DecryptVerifyResult(log, requiredInputParcel, cryptoInput));
}
result.encryptedData = encryptedDataSymmetric;