Support numeric9x4 passphrase-format during decryption
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="14dp"
|
||||
android:paddingTop="14dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/passphrase_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/passphrase_transfer"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<include layout="@layout/transfer_code_input" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="invisible">
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
style="?android:attr/textAppearanceMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:padding="4dp"
|
||||
android:text="@string/label_unlock" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
135
OpenKeychain/src/main/res/layout/transfer_code_input.xml
Normal file
135
OpenKeychain/src/main/res/layout/transfer_code_input.xml
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
tools:showIn="@layout/backup_code_fragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="1234"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_8"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeTextSep" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/transfer_code_block_9"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TransferCodeText"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -333,6 +333,7 @@
|
||||
<string name="passphrase_for_any">"Enter password"</string>
|
||||
<string name="passphrase_keyboard_hint_alpha">"Switch to alphabetic keyboard"</string>
|
||||
<string name="passphrase_keyboard_hint_numeric">"Switch to numeric keyboard"</string>
|
||||
<string name="passphrase_transfer">"Enter transfer code"</string>
|
||||
<string name="pin_for">"Enter PIN for '%s'"</string>
|
||||
<string name="security_token_pin_for">"Enter PIN to access Security Token for '%s'"</string>
|
||||
<string name="security_token_nfc_text">"Hold Security Token against the NFC marker at the back of your device."</string>
|
||||
@@ -1176,6 +1177,8 @@
|
||||
<string name="msg_dc_asym">"Found block of asymmetrically encrypted data for key %s"</string>
|
||||
<string name="msg_dc_charset">"Found charset header: '%s'"</string>
|
||||
<string name="msg_dc_backup_version">"Found backupVersion header: '%s'"</string>
|
||||
<string name="msg_dc_passphrase_format">"Found Passphrase-Format header: '%s'"</string>
|
||||
<string name="msg_dc_passphrase_begin">"Found Passphrase-Begin header: '%s'"</string>
|
||||
<string name="msg_dc_clear_data">"Processing literal data"</string>
|
||||
<string name="msg_dc_clear_decompress">"Unpacking compressed data"</string>
|
||||
<string name="msg_dc_clear_meta_file">"Filename: %s"</string>
|
||||
|
||||
@@ -65,4 +65,22 @@
|
||||
<item name="android:textSize" tools:ignore="SpUsage">14dp</item>
|
||||
</style>
|
||||
|
||||
<style name="TransferCodeText">
|
||||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
<item name="android:hint">1234</item>
|
||||
<item name="android:textColorHint">@android:color/transparent</item>
|
||||
<item name="android:textSize">18sp</item>
|
||||
<item name="android:minHeight">42sp</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:typeface">monospace</item>
|
||||
<item name="android:textColor">#000</item>
|
||||
<item name="android:inputType">numberPassword|textVisiblePassword</item>
|
||||
</style>
|
||||
|
||||
<style name="TransferCodeTextSep" parent="TransferCodeText">
|
||||
<item name="android:hint"></item>
|
||||
<item name="android:text">-</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user