aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2015-07-02 17:31:01 +0200
committerDominik Schürmann <dominik@dominikschuermann.de>2015-07-02 17:31:01 +0200
commit195508ed92434197d0d6ab2d3ef6e0b4bd0780b6 (patch)
tree50ed562c2db60cdcab183b33898de48cab30e521 /OpenKeychain/src
parent9fe05ed1e7fff479430f0042c47842151a0cb68d (diff)
downloadopen-keychain-195508ed92434197d0d6ab2d3ef6e0b4bd0780b6.tar.gz
open-keychain-195508ed92434197d0d6ab2d3ef6e0b4bd0780b6.tar.bz2
open-keychain-195508ed92434197d0d6ab2d3ef6e0b4bd0780b6.zip
Change PIN and Admin PIN after move to key operation
Diffstat (limited to 'OpenKeychain/src')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java18
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java73
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinFragment.java32
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinRepeatFragment.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java33
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java25
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java13
-rw-r--r--OpenKeychain/src/main/res/values/strings.xml6
13 files changed, 172 insertions, 80 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
index f0561bef2..245623762 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
@@ -510,6 +510,8 @@ public abstract class OperationResult implements Parcelable {
MSG_MF_NOTATION_PIN (LogLevel.DEBUG, R.string.msg_mf_notation_pin),
MSG_MF_NOTATION_EMPTY (LogLevel.DEBUG, R.string.msg_mf_notation_empty),
MSG_MF_PASSPHRASE (LogLevel.INFO, R.string.msg_mf_passphrase),
+ MSG_MF_PIN (LogLevel.INFO, R.string.msg_mf_pin),
+ MSG_MF_ADMIN_PIN (LogLevel.INFO, R.string.msg_mf_admin_pin),
MSG_MF_PASSPHRASE_KEY (LogLevel.DEBUG, R.string.msg_mf_passphrase_key),
MSG_MF_PASSPHRASE_EMPTY_RETRY (LogLevel.DEBUG, R.string.msg_mf_passphrase_empty_retry),
MSG_MF_PASSPHRASE_FAIL (LogLevel.WARN, R.string.msg_mf_passphrase_fail),
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
index a018815f3..8445272fc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpKeyOperation.java
@@ -1039,6 +1039,26 @@ public class PgpKeyOperation {
indent -= 1;
}
+ // 7. if requested, change PIN and/or Admin PIN on card
+ if (saveParcel.mCardPin != null) {
+ progress(R.string.progress_modify_pin, 90);
+ log.add(LogType.MSG_MF_PIN, indent);
+ indent += 1;
+
+ nfcKeyToCardOps.setPin(saveParcel.mCardPin);
+
+ indent -= 1;
+ }
+ if (saveParcel.mCardAdminPin != null) {
+ progress(R.string.progress_modify_admin_pin, 90);
+ log.add(LogType.MSG_MF_ADMIN_PIN, indent);
+ indent += 1;
+
+ nfcKeyToCardOps.setAdminPin(saveParcel.mCardAdminPin);
+
+ indent -= 1;
+ }
+
} catch (IOException e) {
Log.e(Constants.TAG, "encountered IOException while modifying key", e);
log.add(LogType.MSG_MF_ERROR_ENCODE, indent+1);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
index e2c4dc542..679f4f817 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/SaveKeyringParcel.java
@@ -61,6 +61,10 @@ public class SaveKeyringParcel implements Parcelable {
public ArrayList<String> mRevokeUserIds;
public ArrayList<Long> mRevokeSubKeys;
+ // if these are non-null, PINs will be changed on the card
+ public Passphrase mCardPin;
+ public Passphrase mCardAdminPin;
+
public SaveKeyringParcel() {
reset();
}
@@ -80,6 +84,8 @@ public class SaveKeyringParcel implements Parcelable {
mChangeSubKeys = new ArrayList<>();
mRevokeUserIds = new ArrayList<>();
mRevokeSubKeys = new ArrayList<>();
+ mCardPin = null;
+ mCardAdminPin = null;
}
public boolean isEmpty() {
@@ -225,6 +231,9 @@ public class SaveKeyringParcel implements Parcelable {
mRevokeUserIds = source.createStringArrayList();
mRevokeSubKeys = (ArrayList<Long>) source.readSerializable();
+
+ mCardPin = source.readParcelable(Passphrase.class.getClassLoader());
+ mCardAdminPin = source.readParcelable(Passphrase.class.getClassLoader());
}
@Override
@@ -236,7 +245,7 @@ public class SaveKeyringParcel implements Parcelable {
destination.writeByteArray(mFingerprint);
// yes, null values are ok for parcelables
- destination.writeParcelable(mNewUnlock, 0);
+ destination.writeParcelable(mNewUnlock, flags);
destination.writeStringList(mAddUserIds);
destination.writeSerializable(mAddUserAttribute);
@@ -247,6 +256,9 @@ public class SaveKeyringParcel implements Parcelable {
destination.writeStringList(mRevokeUserIds);
destination.writeSerializable(mRevokeSubKeys);
+
+ destination.writeParcelable(mCardPin, flags);
+ destination.writeParcelable(mCardAdminPin, flags);
}
public static final Creator<SaveKeyringParcel> CREATOR = new Creator<SaveKeyringParcel>() {
@@ -274,7 +286,9 @@ public class SaveKeyringParcel implements Parcelable {
out += "mChangeSubKeys: " + mChangeSubKeys + "\n";
out += "mChangePrimaryUserId: " + mChangePrimaryUserId + "\n";
out += "mRevokeUserIds: " + mRevokeUserIds + "\n";
- out += "mRevokeSubKeys: " + mRevokeSubKeys;
+ out += "mRevokeSubKeys: " + mRevokeSubKeys + "\n";
+ out += "mCardPin: " + mCardPin + "\n";
+ out += "mCardAdminPin: " + mCardAdminPin;
return out;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java
index efe844145..4eca8d8f9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/input/RequiredInputParcel.java
@@ -1,13 +1,16 @@
package org.sufficientlysecure.keychain.service.input;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import org.spongycastle.util.Arrays;
+import org.sufficientlysecure.keychain.util.Passphrase;
+
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
-import android.os.Parcel;
-import android.os.Parcelable;
-
public class RequiredInputParcel implements Parcelable {
@@ -19,16 +22,16 @@ public class RequiredInputParcel implements Parcelable {
public final RequiredInputType mType;
- public final byte[][] mInputHashes;
+ public final byte[][] mInputData;
public final int[] mSignAlgos;
private Long mMasterKeyId;
private Long mSubKeyId;
- private RequiredInputParcel(RequiredInputType type, byte[][] inputHashes,
+ private RequiredInputParcel(RequiredInputType type, byte[][] inputData,
int[] signAlgos, Date signatureTime, Long masterKeyId, Long subKeyId) {
mType = type;
- mInputHashes = inputHashes;
+ mInputData = inputData;
mSignAlgos = signAlgos;
mSignatureTime = signatureTime;
mMasterKeyId = masterKeyId;
@@ -38,25 +41,25 @@ public class RequiredInputParcel implements Parcelable {
public RequiredInputParcel(Parcel source) {
mType = RequiredInputType.values()[source.readInt()];
- // 0 = none, 1 = both, 2 = only hashes (decrypt)
- int hashTypes = source.readInt();
- if (hashTypes != 0) {
+ // 0 = none, 1 = signAlgos + inputData, 2 = only inputData (decrypt)
+ int inputDataType = source.readInt();
+ if (inputDataType != 0) {
int count = source.readInt();
- mInputHashes = new byte[count][];
- if (hashTypes == 1) {
+ mInputData = new byte[count][];
+ if (inputDataType == 1) {
mSignAlgos = new int[count];
for (int i = 0; i < count; i++) {
- mInputHashes[i] = source.createByteArray();
+ mInputData[i] = source.createByteArray();
mSignAlgos[i] = source.readInt();
}
} else {
mSignAlgos = null;
for (int i = 0; i < count; i++) {
- mInputHashes[i] = source.createByteArray();
+ mInputData[i] = source.createByteArray();
}
}
} else {
- mInputHashes = null;
+ mInputData = null;
mSignAlgos = null;
}
@@ -83,9 +86,9 @@ public class RequiredInputParcel implements Parcelable {
}
public static RequiredInputParcel createNfcDecryptOperation(
- long masterKeyId, long subKeyId, byte[] inputHash) {
+ long masterKeyId, long subKeyId, byte[] encryptedSessionKey) {
return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT,
- new byte[][] { inputHash }, null, null, masterKeyId, subKeyId);
+ new byte[][] { encryptedSessionKey }, null, null, masterKeyId, subKeyId);
}
public static RequiredInputParcel createRequiredSignPassphrase(
@@ -119,11 +122,11 @@ public class RequiredInputParcel implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType.ordinal());
- if (mInputHashes != null) {
+ if (mInputData != null) {
dest.writeInt(mSignAlgos != null ? 1 : 2);
- dest.writeInt(mInputHashes.length);
- for (int i = 0; i < mInputHashes.length; i++) {
- dest.writeByteArray(mInputHashes[i]);
+ dest.writeInt(mInputData.length);
+ for (int i = 0; i < mInputData.length; i++) {
+ dest.writeByteArray(mInputData[i]);
if (mSignAlgos != null) {
dest.writeInt(mSignAlgos[i]);
}
@@ -200,7 +203,7 @@ public class RequiredInputParcel implements Parcelable {
throw new AssertionError("operation types must match, this is a progrmming error!");
}
- Collections.addAll(mInputHashes, input.mInputHashes);
+ Collections.addAll(mInputHashes, input.mInputData);
for (int signAlgo : input.mSignAlgos) {
mSignAlgos.add(signAlgo);
}
@@ -215,19 +218,31 @@ public class RequiredInputParcel implements Parcelable {
public static class NfcKeyToCardOperationsBuilder {
ArrayList<byte[]> mSubkeysToExport = new ArrayList<>();
Long mMasterKeyId;
+ byte[] mPin;
+ byte[] mAdminPin;
public NfcKeyToCardOperationsBuilder(Long masterKeyId) {
mMasterKeyId = masterKeyId;
}
public RequiredInputParcel build() {
- byte[][] inputHashes = new byte[mSubkeysToExport.size()][];
- mSubkeysToExport.toArray(inputHashes);
+ byte[][] inputData = new byte[mSubkeysToExport.size() + 2][];
+
+ // encode all subkeys into inputData
+ byte[][] subkeyData = new byte[mSubkeysToExport.size()][];
+ mSubkeysToExport.toArray(subkeyData);
+
+ // first two are PINs
+ inputData[0] = mPin;
+ inputData[1] = mAdminPin;
+ // then subkeys
+ System.arraycopy(subkeyData, 0, inputData, 2, subkeyData.length);
+
ByteBuffer buf = ByteBuffer.wrap(mSubkeysToExport.get(0));
// We need to pass in a subkey here...
return new RequiredInputParcel(RequiredInputType.NFC_MOVE_KEY_TO_CARD,
- inputHashes, null, null, mMasterKeyId, buf.getLong());
+ inputData, null, null, mMasterKeyId, buf.getLong());
}
public void addSubkey(long subkeyId) {
@@ -237,6 +252,14 @@ public class RequiredInputParcel implements Parcelable {
mSubkeysToExport.add(subKeyId);
}
+ public void setPin(Passphrase pin) {
+ mPin = pin.toStringUnsafe().getBytes();
+ }
+
+ public void setAdminPin(Passphrase adminPin) {
+ mAdminPin = adminPin.toStringUnsafe().getBytes();
+ }
+
public void addAll(RequiredInputParcel input) {
if (!mMasterKeyId.equals(input.mMasterKeyId)) {
throw new AssertionError("Master keys must match, this is a programming error!");
@@ -245,7 +268,7 @@ public class RequiredInputParcel implements Parcelable {
throw new AssertionError("Operation types must match, this is a programming error!");
}
- Collections.addAll(mSubkeysToExport, input.mInputHashes);
+ Collections.addAll(mSubkeysToExport, input.mInputData);
}
public boolean isEmpty() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
index 36ab62cb4..1db93d2c0 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java
@@ -58,8 +58,8 @@ public class CreateKeyActivity extends BaseNfcActivity {
Passphrase mPassphrase;
boolean mFirstTime;
boolean mCreateYubiKey;
- String mYubiKeyPin;
- String mYubiKeyAdminPin;
+ Passphrase mYubiKeyPin;
+ Passphrase mYubiKeyAdminPin;
Fragment mCurrentFragment;
@@ -93,8 +93,8 @@ public class CreateKeyActivity extends BaseNfcActivity {
mPassphrase = savedInstanceState.getParcelable(EXTRA_PASSPHRASE);
mFirstTime = savedInstanceState.getBoolean(EXTRA_FIRST_TIME);
mCreateYubiKey = savedInstanceState.getBoolean(EXTRA_CREATE_YUBI_KEY);
- mYubiKeyPin = savedInstanceState.getString(EXTRA_YUBI_KEY_PIN);
- mYubiKeyAdminPin = savedInstanceState.getString(EXTRA_YUBI_KEY_ADMIN_PIN);
+ mYubiKeyPin = savedInstanceState.getParcelable(EXTRA_YUBI_KEY_PIN);
+ mYubiKeyAdminPin = savedInstanceState.getParcelable(EXTRA_YUBI_KEY_ADMIN_PIN);
mCurrentFragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
} else {
@@ -200,8 +200,8 @@ public class CreateKeyActivity extends BaseNfcActivity {
outState.putParcelable(EXTRA_PASSPHRASE, mPassphrase);
outState.putBoolean(EXTRA_FIRST_TIME, mFirstTime);
outState.putBoolean(EXTRA_CREATE_YUBI_KEY, mCreateYubiKey);
- outState.putString(EXTRA_YUBI_KEY_PIN, mYubiKeyPin);
- outState.putString(EXTRA_YUBI_KEY_ADMIN_PIN, mYubiKeyAdminPin);
+ outState.putParcelable(EXTRA_YUBI_KEY_PIN, mYubiKeyPin);
+ outState.putParcelable(EXTRA_YUBI_KEY_ADMIN_PIN, mYubiKeyAdminPin);
}
@Override
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
index 8c7abb874..94bb68f7e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
@@ -267,10 +267,11 @@ public class CreateKeyFinalFragment extends Fragment {
}
private void moveToCard(final EditKeyResult saveKeyResult) {
- CachedPublicKeyRing key = (new ProviderHelper(getActivity()))
- .getCachedPublicKeyRing(saveKeyResult.mMasterKeyId);
+ final CreateKeyActivity createKeyActivity = (CreateKeyActivity) getActivity();
final SaveKeyringParcel changeKeyringParcel;
+ CachedPublicKeyRing key = (new ProviderHelper(getActivity()))
+ .getCachedPublicKeyRing(saveKeyResult.mMasterKeyId);
try {
changeKeyringParcel = new SaveKeyringParcel(key.getMasterKeyId(), key.getFingerprint());
} catch (PgpKeyNotFoundException e) {
@@ -278,6 +279,7 @@ public class CreateKeyFinalFragment extends Fragment {
return;
}
+ // define subkeys that should be moved to the card
Cursor cursor = getActivity().getContentResolver().query(
KeychainContract.Keys.buildKeysUri(changeKeyringParcel.mMasterKeyId),
new String[]{KeychainContract.Keys.KEY_ID,}, null, null, null
@@ -293,6 +295,10 @@ public class CreateKeyFinalFragment extends Fragment {
}
}
+ // define new PIN and Admin PIN for the card
+ changeKeyringParcel.mCardPin = createKeyActivity.mYubiKeyPin;
+ changeKeyringParcel.mCardAdminPin = createKeyActivity.mYubiKeyAdminPin;
+
CryptoOperationHelper.Callback<SaveKeyringParcel, EditKeyResult> callback
= new CryptoOperationHelper.Callback<SaveKeyringParcel, EditKeyResult>() {
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
index 3379e0a6d..6de5e71b3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java
@@ -107,8 +107,8 @@ public class CreateKeyPassphraseFragment extends Fragment {
// initial values
// TODO: using String here is unsafe...
if (mCreateKeyActivity.mPassphrase != null) {
- mPassphraseEdit.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray()));
- mPassphraseEditAgain.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray()));
+ mPassphraseEdit.setText(mCreateKeyActivity.mPassphrase.toStringUnsafe());
+ mPassphraseEditAgain.setText(mCreateKeyActivity.mPassphrase.toStringUnsafe());
}
mPassphraseEdit.requestFocus();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinFragment.java
index 8744762fe..a793b31f2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinFragment.java
@@ -29,6 +29,7 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
+import org.sufficientlysecure.keychain.util.Passphrase;
import java.security.SecureRandom;
@@ -63,30 +64,38 @@ public class CreateYubiKeyPinFragment extends Fragment {
mNextButton = view.findViewById(R.id.create_key_next_button);
if (mCreateKeyActivity.mYubiKeyPin == null) {
- new AsyncTask<Void, Void, Pair<String, String>>() {
+ new AsyncTask<Void, Void, Pair<Passphrase, Passphrase>>() {
@Override
- protected Pair<String, String> doInBackground(Void... unused) {
+ protected Pair<Passphrase, Passphrase> doInBackground(Void... unused) {
SecureRandom secureRandom = new SecureRandom();
// min = 6, we choose 6
- String pin = "" + secureRandom.nextInt(999999);
+ String pin = "" + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9);
// min = 8, we choose 10, but 6 are equals the PIN
- String adminPin = pin + secureRandom.nextInt(9999);
+ String adminPin = pin + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9)
+ + secureRandom.nextInt(9);
- return new Pair<>(pin, adminPin);
+ return new Pair<>(new Passphrase(pin), new Passphrase(adminPin));
}
@Override
- protected void onPostExecute(Pair<String, String> pair) {
+ protected void onPostExecute(Pair<Passphrase, Passphrase> pair) {
mCreateKeyActivity.mYubiKeyPin = pair.first;
mCreateKeyActivity.mYubiKeyAdminPin = pair.second;
- mPin.setText(mCreateKeyActivity.mYubiKeyPin);
- mAdminPin.setText(mCreateKeyActivity.mYubiKeyAdminPin);
+ mPin.setText(mCreateKeyActivity.mYubiKeyPin.toStringUnsafe());
+ mAdminPin.setText(mCreateKeyActivity.mYubiKeyAdminPin.toStringUnsafe());
}
}.execute();
} else {
- mPin.setText(mCreateKeyActivity.mYubiKeyPin);
- mAdminPin.setText(mCreateKeyActivity.mYubiKeyAdminPin);
+ mPin.setText(mCreateKeyActivity.mYubiKeyPin.toStringUnsafe());
+ mAdminPin.setText(mCreateKeyActivity.mYubiKeyAdminPin.toStringUnsafe());
}
mBackButton.setOnClickListener(new View.OnClickListener() {
@@ -114,9 +123,6 @@ public class CreateYubiKeyPinFragment extends Fragment {
private void nextClicked() {
- // save state
-// mCreateKeyActivity.mPassphrase = new Passphrase(mPassphraseEdit);
-
CreateYubiKeyPinRepeatFragment frag = CreateYubiKeyPinRepeatFragment.newInstance();
mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinRepeatFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinRepeatFragment.java
index dc437577a..2e752e609 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinRepeatFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyPinRepeatFragment.java
@@ -124,9 +124,9 @@ public class CreateYubiKeyPinRepeatFragment extends Fragment {
private void nextClicked() {
if (isEditTextNotEmpty(getActivity(), mPin)
- && checkPin(getActivity(), mPin, mCreateKeyActivity.mYubiKeyPin)
+ && checkPin(getActivity(), mPin, mCreateKeyActivity.mYubiKeyPin.toStringUnsafe())
&& isEditTextNotEmpty(getActivity(), mAdminPin)
- && checkPin(getActivity(), mAdminPin, mCreateKeyActivity.mYubiKeyAdminPin)) {
+ && checkPin(getActivity(), mAdminPin, mCreateKeyActivity.mYubiKeyAdminPin.toStringUnsafe())) {
CreateKeyFinalFragment frag = CreateKeyFinalFragment.newInstance();
hideKeyboard();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
index addfb6a23..8a455bcec 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
@@ -80,16 +80,16 @@ public class NfcOperationActivity extends BaseNfcActivity {
switch (mRequiredInput.mType) {
case NFC_DECRYPT: {
- for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) {
- byte[] hash = mRequiredInput.mInputHashes[i];
- byte[] decryptedSessionKey = nfcDecryptSessionKey(hash);
- inputParcel.addCryptoData(hash, decryptedSessionKey);
+ for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
+ byte[] encryptedSessionKey = mRequiredInput.mInputData[i];
+ byte[] decryptedSessionKey = nfcDecryptSessionKey(encryptedSessionKey);
+ inputParcel.addCryptoData(encryptedSessionKey, decryptedSessionKey);
}
break;
}
case NFC_SIGN: {
- for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) {
- byte[] hash = mRequiredInput.mInputHashes[i];
+ for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
+ byte[] hash = mRequiredInput.mInputData[i];
int algo = mRequiredInput.mSignAlgos[i];
byte[] signedHash = nfcCalculateSignature(hash, algo);
inputParcel.addCryptoData(hash, signedHash);
@@ -97,6 +97,10 @@ public class NfcOperationActivity extends BaseNfcActivity {
break;
}
case NFC_MOVE_KEY_TO_CARD: {
+ // TODO: assume PIN and Admin PIN to be default for this operation
+ mPin = new Passphrase("123456");
+ mAdminPin = new Passphrase("12345678");
+
ProviderHelper providerHelper = new ProviderHelper(this);
CanonicalizedSecretKeyRing secretKeyRing;
try {
@@ -107,8 +111,11 @@ public class NfcOperationActivity extends BaseNfcActivity {
throw new IOException("Couldn't find subkey for key to card operation.");
}
- for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) {
- byte[] subkeyBytes = mRequiredInput.mInputHashes[i];
+ byte[] newPin = mRequiredInput.mInputData[0];
+ byte[] newAdminPin = mRequiredInput.mInputData[1];
+
+ for (int i = 2; i < mRequiredInput.mInputData.length; i++) {
+ byte[] subkeyBytes = mRequiredInput.mInputData[i];
ByteBuffer buf = ByteBuffer.wrap(subkeyBytes);
long subkeyId = buf.getLong();
@@ -155,8 +162,18 @@ public class NfcOperationActivity extends BaseNfcActivity {
throw new IOException("Inappropriate key flags for smart card key.");
}
+ // TODO: Is this really needed?
inputParcel.addCryptoData(subkeyBytes, cardSerialNumber);
}
+
+ // change PINs afterwards
+ nfcModifyPIN(0x81, newPin);
+ nfcModifyPIN(0x83, newAdminPin);
+
+ break;
+ }
+ default: {
+ throw new AssertionError("Unhandled mRequiredInput.mType");
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java
index bede16b2a..ba8dd3b55 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseNfcActivity.java
@@ -179,8 +179,10 @@ public abstract class BaseNfcActivity extends BaseActivity {
Notify.create(this, getString(R.string.error_nfc_unknown), Style.WARN).show();
break;
}
- default:
+ default: {
Notify.create(this, getString(R.string.error_nfc, e.getMessage()), Style.WARN).show();
+ break;
+ }
}
}
@@ -311,9 +313,6 @@ public abstract class BaseNfcActivity extends BaseActivity {
mPw1ValidatedForDecrypt = false;
mPw3Validated = false;
- // TODO: Handle non-default Admin PIN
- mAdminPin = new Passphrase("12345678");
-
onNfcPerform();
mIsoDep.close();
@@ -569,12 +568,12 @@ public abstract class BaseNfcActivity extends BaseActivity {
*/
public void nfcVerifyPIN(int mode) throws IOException {
if (mPin != null || mode == 0x83) {
- byte[] pin;
+ byte[] pin;
if (mode == 0x83) {
- pin = new String(mAdminPin.getCharArray()).getBytes();
+ pin = mAdminPin.toStringUnsafe().getBytes();
} else {
- pin = new String(mPin.getCharArray()).getBytes();
+ pin = mPin.toStringUnsafe().getBytes();
}
// SW1/2 0x9000 is the generic "ok" response, which we expect most of the time.
@@ -611,12 +610,11 @@ public abstract class BaseNfcActivity extends BaseActivity {
* @param pw For PW1, this is 0x81. For PW3 (Admin PIN), mode is 0x83.
* @param newPinString The new PW1 or PW3.
*/
- public void nfcModifyPIN(int pw, String newPinString) throws IOException {
+ public void nfcModifyPIN(int pw, byte[] newPin) throws IOException {
final int MAX_PW1_LENGTH_INDEX = 1;
final int MAX_PW3_LENGTH_INDEX = 3;
byte[] pwStatusBytes = nfcGetPwStatusBytes();
- byte[] newPin = newPinString.getBytes();
if (pw == 0x81) {
if (newPin.length < 6 || newPin.length > pwStatusBytes[MAX_PW1_LENGTH_INDEX]) {
@@ -631,11 +629,10 @@ public abstract class BaseNfcActivity extends BaseActivity {
}
byte[] pin;
-
if (pw == 0x83) {
- pin = new String(mAdminPin.getCharArray()).getBytes();
+ pin = mAdminPin.toStringUnsafe().getBytes();
} else {
- pin = new String(mPin.getCharArray()).getBytes();
+ pin = mPin.toStringUnsafe().getBytes();
}
// Command APDU for CHANGE REFERENCE DATA command (page 32)
@@ -700,7 +697,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
throw new IOException("Invalid key slot");
}
- RSAPrivateCrtKey crtSecretKey = null;
+ RSAPrivateCrtKey crtSecretKey;
try {
secretKey.unlock(passphrase);
crtSecretKey = secretKey.getCrtSecretKey();
@@ -719,7 +716,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
}
if (!mPw3Validated) {
- nfcVerifyPIN(0x83); // (Verify PW1 with mode 83)
+ nfcVerifyPIN(0x83); // (Verify PW3 with mode 83)
}
byte[] header= Hex.decode(
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java
index 06efdde4d..fe42c7a2c 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/Passphrase.java
@@ -117,6 +117,13 @@ public class Passphrase implements Parcelable {
}
}
+ /**
+ * Creates a new String from the char[]. This is considered unsafe!
+ */
+ public String toStringUnsafe() {
+ return new String(mPassphrase);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -127,11 +134,7 @@ public class Passphrase implements Parcelable {
}
Passphrase that = (Passphrase) o;
- if (!Arrays.equals(mPassphrase, that.mPassphrase)) {
- return false;
- }
-
- return true;
+ return Arrays.equals(mPassphrase, that.mPassphrase);
}
@Override
diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml
index 619c67ee3..a1a863e17 100644
--- a/OpenKeychain/src/main/res/values/strings.xml
+++ b/OpenKeychain/src/main/res/values/strings.xml
@@ -342,6 +342,8 @@
<string name="progress_modify_subkeystrip">"stripping subkeys…"</string>
<string name="progress_modify_subkeyadd">"adding subkeys…"</string>
<string name="progress_modify_passphrase">"changing password…"</string>
+ <string name="progress_modify_pin">"changing PIN…"</string>
+ <string name="progress_modify_admin_pin">"changing Admin PIN…"</string>
<plurals name="progress_exporting_key">
<item quantity="one">"exporting key…"</item>
@@ -660,7 +662,7 @@
<string name="create_key_add_email_text">"Additional email addresses are also associated to this key and can be used for secure communication."</string>
<string name="create_key_email_already_exists_text">"Email address has already been added"</string>
<string name="create_key_email_invalid_email">"Email address format is invalid"</string>
- <string name="create_key_yubi_key_pin_text">"Please remember these PINs. They are required to use your YubiKey later. If possible write down the Admin PIN and store it in a safe place."</string>
+ <string name="create_key_yubi_key_pin_text">"Please remember the PIN, it is required to use your YubiKey later. Please write down the Admin PIN and store it in a safe place."</string>
<string name="create_key_yubi_key_pin">"PIN"</string>
<string name="create_key_yubi_key_admin_pin">"Admin PIN"</string>
<string name="create_key_yubi_key_pin_repeat_text">"Please enter the PIN and Admin PIN to proceed."</string>
@@ -957,6 +959,8 @@
<string name="msg_mf_notation_empty">"Adding empty notation packet"</string>
<string name="msg_mf_notation_pin">"Adding PIN notation packet"</string>
<string name="msg_mf_passphrase">"Changing password for keyring"</string>
+ <string name="msg_mf_pin">"Changing PIN on card"</string>
+ <string name="msg_mf_admin_pin">"Changing Admin PIN on card"</string>
<string name="msg_mf_passphrase_key">"Re-encrypting subkey %s with new password"</string>
<string name="msg_mf_passphrase_empty_retry">"Setting new password failed, trying again with empty old password"</string>
<string name="msg_mf_passphrase_fail">"Password for subkey could not be changed! (Does it have a different one from the other keys?)"</string>