Moved checks from fragment to operation, impoved logging.

This commit is contained in:
Joey Castillo 2015-05-12 17:31:14 -04:00
parent 76241e90ad
commit a0107afd3e
4 changed files with 72 additions and 53 deletions

View File

@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.operations;
import android.content.Context; import android.content.Context;
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
import org.sufficientlysecure.keychain.operations.results.NfcKeyToCardResult; import org.sufficientlysecure.keychain.operations.results.NfcKeyToCardResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
@ -26,6 +27,7 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing;
import org.sufficientlysecure.keychain.pgp.Progressable; import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
public class NfcKeyToCardOperation extends BaseOperation { public class NfcKeyToCardOperation extends BaseOperation {
public NfcKeyToCardOperation(Context context, ProviderHelper providerHelper, Progressable progressable) { public NfcKeyToCardOperation(Context context, ProviderHelper providerHelper, Progressable progressable) {
@ -43,32 +45,46 @@ public class NfcKeyToCardOperation extends BaseOperation {
CanonicalizedSecretKeyRing keyRing = CanonicalizedSecretKeyRing keyRing =
mProviderHelper.getCanonicalizedSecretKeyRing(masterKeyId); mProviderHelper.getCanonicalizedSecretKeyRing(masterKeyId);
log.add(OperationResult.LogType.MSG_KC_SECRET, indent); log.add(OperationResult.LogType.MSG_KC_SECRET, indent,
KeyFormattingUtils.convertKeyIdToHex(masterKeyId));
// fetch the specific subkey // fetch the specific subkey
CanonicalizedSecretKey subKey = keyRing.getSecretKey(subKeyId); CanonicalizedSecretKey subKey = keyRing.getSecretKey(subKeyId);
switch (subKey.getSecretKeyType()) { // Key algorithm must be RSA
case DIVERT_TO_CARD: int algorithm = subKey.getAlgorithm();
case GNU_DUMMY: { if (algorithm != PublicKeyAlgorithmTags.RSA_ENCRYPT &&
throw new AssertionError( algorithm != PublicKeyAlgorithmTags.RSA_SIGN &&
"Cannot export GNU_DUMMY/DIVERT_TO_CARD key to a smart card!" algorithm != PublicKeyAlgorithmTags.RSA_GENERAL) {
+ " This is a programming error!"); log.add(OperationResult.LogType.MSG_K2C_ERROR_BAD_ALGO, indent + 1);
} return new NfcKeyToCardResult(NfcKeyToCardResult.RESULT_ERROR, log);
case PIN:
case PATTERN:
case PASSPHRASE: {
log.add(OperationResult.LogType.MSG_PSE_PENDING_NFC, indent);
return new NfcKeyToCardResult(log, RequiredInputParcel
.createNfcKeyToCardOperation(masterKeyId, subKeyId));
}
default: {
throw new AssertionError("Unhandled SecretKeyType! (should not happen)");
}
} }
// Key size must be 2048
int keySize = subKey.getBitStrength();
if (keySize != 2048) {
log.add(OperationResult.LogType.MSG_K2C_ERROR_BAD_SIZE, indent + 1);
return new NfcKeyToCardResult(NfcKeyToCardResult.RESULT_ERROR, log);
}
// Secret key parts must be available
CanonicalizedSecretKey.SecretKeyType type = subKey.getSecretKeyType();
if (type == CanonicalizedSecretKey.SecretKeyType.DIVERT_TO_CARD ||
type == CanonicalizedSecretKey.SecretKeyType.GNU_DUMMY) {
log.add(OperationResult.LogType.MSG_K2C_ERROR_BAD_STRIPPED, indent + 1);
return new NfcKeyToCardResult(NfcKeyToCardResult.RESULT_ERROR, log);
}
if (type == CanonicalizedSecretKey.SecretKeyType.PIN ||
type == CanonicalizedSecretKey.SecretKeyType.PATTERN ||
type == CanonicalizedSecretKey.SecretKeyType.PASSPHRASE ||
type == CanonicalizedSecretKey.SecretKeyType.PASSPHRASE_EMPTY) {
log.add(OperationResult.LogType.MSG_PSE_PENDING_NFC, indent);
return new NfcKeyToCardResult(log, RequiredInputParcel
.createNfcKeyToCardOperation(masterKeyId, subKeyId));
}
throw new AssertionError("Unhandled SecretKeyType! (should not happen)");
} catch (ProviderHelper.NotFoundException e) { } catch (ProviderHelper.NotFoundException e) {
log.add(OperationResult.LogType.MSG_PSE_ERROR_UNLOCK, indent); log.add(OperationResult.LogType.MSG_PSE_ERROR_UNLOCK, indent);
return new NfcKeyToCardResult(NfcKeyToCardResult.RESULT_ERROR, log); return new NfcKeyToCardResult(NfcKeyToCardResult.RESULT_ERROR, log);

View File

@ -17,6 +17,8 @@
package org.sufficientlysecure.keychain.operations.results; package org.sufficientlysecure.keychain.operations.results;
import android.os.Parcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
public class NfcKeyToCardResult extends InputPendingResult { public class NfcKeyToCardResult extends InputPendingResult {
@ -27,4 +29,23 @@ public class NfcKeyToCardResult extends InputPendingResult {
public NfcKeyToCardResult(OperationLog log, RequiredInputParcel requiredInput) { public NfcKeyToCardResult(OperationLog log, RequiredInputParcel requiredInput) {
super(log, requiredInput); super(log, requiredInput);
} }
public NfcKeyToCardResult(Parcel source) {
super(source);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
}
public static Creator<NfcKeyToCardResult> CREATOR = new Creator<NfcKeyToCardResult>() {
public NfcKeyToCardResult createFromParcel(final Parcel source) {
return new NfcKeyToCardResult(source);
}
public NfcKeyToCardResult[] newArray(final int size) {
return new NfcKeyToCardResult[size];
}
};
} }

View File

@ -736,6 +736,11 @@ public abstract class OperationResult implements Parcelable {
MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN(LogLevel.ERROR,R.string.msg_export_log_error_fopen), MSG_EXPORT_LOG_EXPORT_ERROR_FOPEN(LogLevel.ERROR,R.string.msg_export_log_error_fopen),
MSG_EXPORT_LOG_EXPORT_ERROR_WRITING(LogLevel.ERROR,R.string.msg_export_log_error_writing), MSG_EXPORT_LOG_EXPORT_ERROR_WRITING(LogLevel.ERROR,R.string.msg_export_log_error_writing),
MSG_EXPORT_LOG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_log_success), MSG_EXPORT_LOG_EXPORT_SUCCESS (LogLevel.OK, R.string.msg_export_log_success),
// NFC keytocard
MSG_K2C_ERROR_BAD_ALGO(LogLevel.ERROR, R.string.edit_key_error_bad_nfc_algo),
MSG_K2C_ERROR_BAD_SIZE(LogLevel.ERROR, R.string.edit_key_error_bad_nfc_size),
MSG_K2C_ERROR_BAD_STRIPPED(LogLevel.ERROR, R.string.edit_key_error_bad_nfc_stripped),
; ;
public final int mMsgId; public final int mMsgId;

View File

@ -36,14 +36,12 @@ import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ListView; import android.widget.ListView;
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.SingletonResult; import org.sufficientlysecure.keychain.operations.results.SingletonResult;
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
@ -430,35 +428,6 @@ public class EditKeyFragment extends CryptoOperationFragment implements
break; break;
} }
case EditSubkeyDialogFragment.MESSAGE_KEYTOCARD: { case EditSubkeyDialogFragment.MESSAGE_KEYTOCARD: {
// Three checks to verify that this is a smart card compatible key:
// 1. Key algorithm must be RSA
int algorithm = mSubkeysAdapter.getAlgorithm(position);
if (algorithm != PublicKeyAlgorithmTags.RSA_ENCRYPT &&
algorithm != PublicKeyAlgorithmTags.RSA_SIGN &&
algorithm != PublicKeyAlgorithmTags.RSA_GENERAL) {
Notify.create(getActivity(), R.string.edit_key_error_bad_nfc_algo,
Notify.Style.ERROR).show();
return;
}
// 2. Key size must be 2048
if (mSubkeysAdapter.getKeySize(position) != 2048) {
Notify.create(getActivity(), R.string.edit_key_error_bad_nfc_size,
Notify.Style.ERROR).show();
return;
}
// 3. Secret key parts must be available
CanonicalizedSecretKey.SecretKeyType type =
mSubkeysAdapter.getSecretKeyType(position);
if (type == CanonicalizedSecretKey.SecretKeyType.DIVERT_TO_CARD ||
type == CanonicalizedSecretKey.SecretKeyType.GNU_DUMMY) {
Notify.create(getActivity(), R.string.edit_key_error_bad_nfc_stripped,
Notify.Style.ERROR).show();
return;
}
SubkeyChange change; SubkeyChange change;
change = mSaveKeyringParcel.getSubkeyChange(keyId); change = mSaveKeyringParcel.getSubkeyChange(keyId);
if (change == null) { if (change == null) {
@ -480,7 +449,15 @@ public class EditKeyFragment extends CryptoOperationFragment implements
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) { ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) { public void handleMessage(Message message) {
super.handleMessage(message); super.handleMessage(message);
EditKeyFragment.this.handlePendingMessage(message); if (EditKeyFragment.this.handlePendingMessage(message)) {
return;
}
Bundle data = message.getData();
OperationResult result = data.getParcelable(OperationResult.EXTRA_RESULT);
if (result.getResult() == OperationResult.RESULT_ERROR) {
result.createNotify(getActivity()).show();
}
} }
}; };
// Create a new Messenger for the communication back // Create a new Messenger for the communication back