Support numeric9x4 passphrase-format during decryption

This commit is contained in:
Vincent Breitmoser
2018-04-13 19:07:59 +02:00
parent cb56a44f77
commit ded58588ad
9 changed files with 288 additions and 12 deletions

View File

@@ -627,6 +627,8 @@ public abstract class OperationResult implements Parcelable {
MSG_DC_ASYM (LogLevel.DEBUG, R.string.msg_dc_asym),
MSG_DC_CHARSET (LogLevel.DEBUG, R.string.msg_dc_charset),
MSG_DC_BACKUP_VERSION (LogLevel.DEBUG, R.string.msg_dc_backup_version),
MSG_DC_PASSPHRASE_FORMAT (LogLevel.DEBUG, R.string.msg_dc_passphrase_format),
MSG_DC_PASSPHRASE_BEGIN (LogLevel.DEBUG, R.string.msg_dc_passphrase_begin),
MSG_DC_CLEAR_DATA (LogLevel.DEBUG, R.string.msg_dc_clear_data),
MSG_DC_CLEAR_DECOMPRESS (LogLevel.DEBUG, R.string.msg_dc_clear_decompress),
MSG_DC_CLEAR_META_FILE (LogLevel.DEBUG, R.string.msg_dc_clear_meta_file),

View File

@@ -93,6 +93,7 @@ import static java.lang.String.format;
public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInputParcel> {
public static final int PROGRESS_STRIDE_MILLISECONDS = 200;
public static final String PASSPHRASE_FORMAT_NUMERIC9X4 = "numeric9x4";
public PgpDecryptVerifyOperation(Context context, KeyRepository keyRepository, Progressable progressable) {
super(context, keyRepository, progressable);
@@ -230,6 +231,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
private static class ArmorHeaders {
String charset = null;
Integer backupVersion = null;
String passphraseFormat;
String passphraseBegin;
}
private ArmorHeaders parseArmorHeaders(InputStream in, OperationLog log, int indent) {
@@ -261,6 +264,14 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
}
break;
}
case "passphrase-format": {
armorHeaders.passphraseFormat = pieces[1].trim();
break;
}
case "passphrase-begin": {
armorHeaders.passphraseBegin = pieces[1].trim();
break;
}
default: {
// continue;
}
@@ -272,6 +283,12 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
if (armorHeaders.backupVersion != null) {
log.add(LogType.MSG_DC_BACKUP_VERSION, indent, Integer.toString(armorHeaders.backupVersion));
}
if (armorHeaders.passphraseFormat != null) {
log.add(LogType.MSG_DC_PASSPHRASE_FORMAT, indent, armorHeaders.passphraseFormat);
}
if (armorHeaders.passphraseBegin != null) {
log.add(LogType.MSG_DC_PASSPHRASE_BEGIN, indent, armorHeaders.passphraseBegin);
}
}
}
@@ -294,9 +311,11 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
// parse ASCII Armor headers
ArmorHeaders armorHeaders = parseArmorHeaders(in, log, indent);
String charset = armorHeaders.charset;
boolean useBackupCode = false;
RequiredInputParcel customRequiredInputParcel = null;
if (armorHeaders.backupVersion != null && armorHeaders.backupVersion == 2) {
useBackupCode = true;
customRequiredInputParcel = RequiredInputParcel.createRequiredBackupCode();
} else if (PASSPHRASE_FORMAT_NUMERIC9X4.equalsIgnoreCase(armorHeaders.passphraseFormat)) {
customRequiredInputParcel = RequiredInputParcel.createRequiredNumeric9x4(armorHeaders.passphraseBegin);
}
OpenPgpDecryptionResultBuilder decryptionResultBuilder = new OpenPgpDecryptionResultBuilder();
@@ -311,7 +330,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
if (obj instanceof PGPEncryptedDataList) {
esResult = handleEncryptedPacket(
input, cryptoInput, (PGPEncryptedDataList) obj, log, indent, useBackupCode);
input, cryptoInput, (PGPEncryptedDataList) obj, log, indent, customRequiredInputParcel);
// if there is an error, nothing left to do here
if (esResult.errorResult != null) {
@@ -565,7 +584,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
}
private EncryptStreamResult handleEncryptedPacket(PgpDecryptVerifyInputParcel input, CryptoInputParcel cryptoInput,
PGPEncryptedDataList enc, OperationLog log, int indent, boolean useBackupCode) throws PGPException {
PGPEncryptedDataList enc, OperationLog log, int indent, RequiredInputParcel customRequiredInputParcel)
throws PGPException {
EncryptStreamResult result = new EncryptStreamResult();
@@ -723,9 +743,8 @@ 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();
RequiredInputParcel requiredInputParcel = customRequiredInputParcel != null ?
customRequiredInputParcel : RequiredInputParcel.createRequiredSymmetricPassphrase();
return result.with(new DecryptVerifyResult(log,
requiredInputParcel,
cryptoInput));
@@ -771,9 +790,8 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
result.cleartextStream = encryptedDataSymmetric.getDataStream(decryptorFactory);
} catch (PGPDataValidationException e) {
log.add(LogType.MSG_DC_ERROR_SYM_PASSPHRASE, indent + 1);
RequiredInputParcel requiredInputParcel = useBackupCode ?
RequiredInputParcel.createRequiredBackupCode() :
RequiredInputParcel.createRequiredSymmetricPassphrase();
RequiredInputParcel requiredInputParcel = customRequiredInputParcel != null ?
customRequiredInputParcel : RequiredInputParcel.createRequiredSymmetricPassphrase();
return result.with(new DecryptVerifyResult(log, requiredInputParcel, cryptoInput));
}

View File

@@ -33,7 +33,7 @@ public class RequiredInputParcel implements Parcelable {
public enum RequiredInputType {
PASSPHRASE, PASSPHRASE_SYMMETRIC, PASSPHRASE_AUTH,
BACKUP_CODE,
BACKUP_CODE, NUMERIC_9X4,
SECURITY_TOKEN_SIGN, SECURITY_TOKEN_AUTH, SECURITY_TOKEN_DECRYPT,
SECURITY_TOKEN_MOVE_KEY_TO_CARD, SECURITY_TOKEN_RESET_CARD,
ENABLE_ORBOT, UPLOAD_FAIL_RETRY
@@ -179,6 +179,11 @@ public class RequiredInputParcel implements Parcelable {
null, null, null, (long[]) null, null);
}
public static RequiredInputParcel createRequiredNumeric9x4(String beginChars) {
return new RequiredInputParcel(RequiredInputType.NUMERIC_9X4,
null, null, null, (long[]) null, null);
}
public static RequiredInputParcel createRequiredPassphrase(
RequiredInputParcel req) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,

View File

@@ -201,6 +201,30 @@ public class PassphraseDialogActivity extends FragmentActivity {
return dialog;
}
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4) {
LayoutInflater inflater = LayoutInflater.from(theme);
View view = inflater.inflate(R.layout.passphrase_dialog_numeric_9x4, null);
alert.setView(view);
mBackupCodeEditText = new EditText[9];
mBackupCodeEditText[0] = view.findViewById(R.id.transfer_code_block_1);
mBackupCodeEditText[1] = view.findViewById(R.id.transfer_code_block_2);
mBackupCodeEditText[2] = view.findViewById(R.id.transfer_code_block_3);
mBackupCodeEditText[3] = view.findViewById(R.id.transfer_code_block_4);
mBackupCodeEditText[4] = view.findViewById(R.id.transfer_code_block_5);
mBackupCodeEditText[5] = view.findViewById(R.id.transfer_code_block_6);
mBackupCodeEditText[6] = view.findViewById(R.id.transfer_code_block_7);
mBackupCodeEditText[7] = view.findViewById(R.id.transfer_code_block_8);
mBackupCodeEditText[8] = view.findViewById(R.id.transfer_code_block_9);
setupEditTextFocusNext(mBackupCodeEditText);
AlertDialog dialog = alert.create();
dialog.setButton(DialogInterface.BUTTON_POSITIVE,
activity.getString(R.string.btn_unlock), (DialogInterface.OnClickListener) null);
return dialog;
}
LayoutInflater inflater = LayoutInflater.from(theme);
mLayout = (ViewAnimator) inflater.inflate(R.layout.passphrase_dialog, null);
alert.setView(mLayout);
@@ -432,6 +456,23 @@ public class PassphraseDialogActivity extends FragmentActivity {
return;
}
if (mRequiredInput.mType == RequiredInputType.NUMERIC_9X4) {
StringBuilder backupCodeInput = new StringBuilder(36);
for (EditText editText : mBackupCodeEditText) {
if (editText.getText().length() < 4) {
return;
}
backupCodeInput.append(editText.getText());
backupCodeInput.append('-');
}
backupCodeInput.deleteCharAt(backupCodeInput.length() - 1);
Passphrase passphrase = new Passphrase(backupCodeInput.toString());
finishCaching(passphrase, null);
return;
}
final Passphrase passphrase = new Passphrase(mPassphraseEditText);
final int timeToLiveSeconds = mTimeToLiveSpinner.getSelectedTimeToLive();

View File

@@ -162,7 +162,8 @@ public class CryptoOperationHelper<T extends Parcelable, S extends OperationResu
case PASSPHRASE:
case PASSPHRASE_SYMMETRIC:
case BACKUP_CODE: {
case BACKUP_CODE:
case NUMERIC_9X4: {
Intent intent = new Intent(activity, PassphraseDialogActivity.class);
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
intent.putExtra(PassphraseDialogActivity.EXTRA_CRYPTO_INPUT, cryptoInputParcel);