Create key wizard for blank YubiKey

This commit is contained in:
Dominik Schürmann 2015-06-29 20:48:11 +02:00
parent cf59a8fc30
commit a9c606d49b
19 changed files with 313 additions and 74 deletions

View file

@ -184,7 +184,7 @@ public class AsymmetricFileOperationTests {
handleSaveDecryptedFileIntent(savedFile, file.getName());
// save decrypted content
onView(withText(R.string.btn_save)).perform(click());
onView(withText(R.string.btn_save_file)).perform(click());
checkSnackbar(Style.OK, R.string.file_saved);
assertThat("decrypted file has been saved", true, is(savedFile.exists()));

View file

@ -95,6 +95,15 @@
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.MainActivity" />
<!-- Connect with YubiKeys. This Activity will automatically show/import/create key -->
<!--<intent-filter>-->
<!--<action android:name="android.nfc.action.NDEF_DISCOVERED"/>-->
<!--<category android:name="android.intent.category.DEFAULT"/>-->
<!--<data-->
<!--android:scheme="https"-->
<!--android:host="my.yubico.com"-->
<!--android:pathPrefix="/neo"/>-->
<!--</intent-filter>-->
</activity>
<activity
android:name=".ui.EditKeyActivity"
@ -687,17 +696,6 @@
android:launchMode="singleTop"
android:taskAffinity=":Nfc" />
<!--<activity-->
<!--android:name=".ui.NfcIntentActivity"-->
<!--android:launchMode="singleTop">-->
<!--<intent-filter>-->
<!--<action android:name="android.nfc.action.NDEF_DISCOVERED" />-->
<!--<category android:name="android.intent.category.DEFAULT" />-->
<!--<data android:host="my.yubico.com" android:scheme="https"/>-->
<!--</intent-filter>-->
<!--</activity>-->
<activity
android:name=".ui.HelpActivity"
android:label="@string/title_help" />

View file

@ -167,7 +167,7 @@ public class OpenPgpService extends RemoteService {
Intent data, RequiredInputParcel requiredInput) {
switch (requiredInput.mType) {
case NFC_KEYTOCARD:
case NFC_MOVE_KEY_TO_CARD:
case NFC_DECRYPT:
case NFC_SIGN: {
// build PendingIntent for YubiKey NFC operations

View file

@ -12,7 +12,7 @@ import android.os.Parcelable;
public class RequiredInputParcel implements Parcelable {
public enum RequiredInputType {
PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT, NFC_KEYTOCARD
PASSPHRASE, PASSPHRASE_SYMMETRIC, NFC_SIGN, NFC_DECRYPT, NFC_MOVE_KEY_TO_CARD
}
public Date mSignatureTime;
@ -226,7 +226,7 @@ public class RequiredInputParcel implements Parcelable {
ByteBuffer buf = ByteBuffer.wrap(mSubkeysToExport.get(0));
// We need to pass in a subkey here...
return new RequiredInputParcel(RequiredInputType.NFC_KEYTOCARD,
return new RequiredInputParcel(RequiredInputType.NFC_MOVE_KEY_TO_CARD,
inputHashes, null, null, mMasterKeyId, buf.getLong());
}
@ -241,7 +241,7 @@ public class RequiredInputParcel implements Parcelable {
if (!mMasterKeyId.equals(input.mMasterKeyId)) {
throw new AssertionError("Master keys must match, this is a programming error!");
}
if (input.mType != RequiredInputType.NFC_KEYTOCARD) {
if (input.mType != RequiredInputType.NFC_MOVE_KEY_TO_CARD) {
throw new AssertionError("Operation types must match, this is a programming error!");
}

View file

@ -17,8 +17,6 @@
package org.sufficientlysecure.keychain.ui;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -89,13 +87,19 @@ public class CreateKeyActivity extends BaseNfcActivity {
String nfcUserId = intent.getStringExtra(EXTRA_NFC_USER_ID);
byte[] nfcAid = intent.getByteArrayExtra(EXTRA_NFC_AID);
Fragment frag2 = CreateKeyYubiKeyImportFragment.createInstance(
nfcFingerprints, nfcAid, nfcUserId);
loadFragment(frag2, FragAction.START);
if (containsKeys(nfcFingerprints)) {
Fragment frag = CreateKeyYubiKeyImportFragment.newInstance(
nfcFingerprints, nfcAid, nfcUserId);
loadFragment(frag, FragAction.START);
setTitle(R.string.title_import_keys);
setTitle(R.string.title_import_keys);
} else {
Fragment frag = CreateKeyYubiKeyBlankFragment.newInstance();
loadFragment(frag, FragAction.START);
}
return;
} else {
// normal key creation
CreateKeyStartFragment frag = CreateKeyStartFragment.newInstance();
loadFragment(frag, FragAction.START);
}
@ -122,16 +126,7 @@ public class CreateKeyActivity extends BaseNfcActivity {
byte[] nfcAid = nfcGetAid();
String userId = nfcGetUserId();
// If all fingerprint bytes are 0, the card contains no keys.
boolean cardContainsKeys = false;
for (byte b : scannedFingerprints) {
if (b != 0) {
cardContainsKeys = true;
break;
}
}
if (cardContainsKeys) {
if (containsKeys(scannedFingerprints)) {
try {
long masterKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(scannedFingerprints);
CachedPublicKeyRing ring = new ProviderHelper(this).getCachedPublicKeyRing(masterKeyId);
@ -146,25 +141,29 @@ public class CreateKeyActivity extends BaseNfcActivity {
finish();
} catch (PgpKeyNotFoundException e) {
Fragment frag = CreateKeyYubiKeyImportFragment.createInstance(
Fragment frag = CreateKeyYubiKeyImportFragment.newInstance(
scannedFingerprints, nfcAid, userId);
loadFragment(frag, FragAction.TO_RIGHT);
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.first_time_blank_smartcard_title)
.setMessage(R.string.first_time_blank_smartcard_message)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int button) {
CreateKeyActivity.this.mUseSmartCardSettings = true;
}
})
.setNegativeButton(android.R.string.no, null).show();
Fragment frag = CreateKeyYubiKeyBlankFragment.newInstance();
loadFragment(frag, FragAction.TO_RIGHT);
}
}
private boolean containsKeys(byte[] scannedFingerprints) {
// If all fingerprint bytes are 0, the card contains no keys.
boolean cardContainsKeys = false;
for (byte b : scannedFingerprints) {
if (b != 0) {
cardContainsKeys = true;
break;
}
}
return cardContainsKeys;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@ -182,7 +181,7 @@ public class CreateKeyActivity extends BaseNfcActivity {
setContentView(R.layout.create_key_activity);
}
public static enum FragAction {
public enum FragAction {
START,
TO_RIGHT,
TO_LEFT

View file

@ -20,11 +20,11 @@ package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -37,19 +37,24 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainService;
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.util.Iterator;
public class CreateKeyFinalFragment extends Fragment {
public class CreateKeyFinalFragment extends CryptoOperationFragment<SaveKeyringParcel, OperationResult> {
public static final int REQUEST_EDIT_KEY = 0x00008007;
@ -129,6 +134,11 @@ public class CreateKeyFinalFragment extends Fragment {
}
});
// If this is a debug build, don't upload by default
if (Constants.DEBUG) {
mUploadCheckbox.setChecked(false);
}
return view;
}
@ -164,6 +174,7 @@ public class CreateKeyFinalFragment extends Fragment {
mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA,
2048, null, KeyFlags.AUTHENTICATION, 0L));
mEditText.setText(R.string.create_key_custom);
mEditButton.setEnabled(false);
} else {
mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA,
4096, null, KeyFlags.CERTIFY_OTHER, 0L));
@ -192,8 +203,9 @@ public class CreateKeyFinalFragment extends Fragment {
}
}
private void createKey() {
final CreateKeyActivity createKeyActivity = (CreateKeyActivity) getActivity();
Intent intent = new Intent(getActivity(), KeychainService.class);
intent.setAction(KeychainService.ACTION_EDIT_KEYRING);
@ -216,25 +228,29 @@ public class CreateKeyFinalFragment extends Fragment {
return;
}
if (createKeyActivity.mUseSmartCardSettings) {
// save key id in between
mSaveKeyringParcel.mMasterKeyId = result.mMasterKeyId;
cryptoOperation(new CryptoInputParcel());
return;
}
if (result.mMasterKeyId != null && mUploadCheckbox.isChecked()) {
// result will be displayed after upload
uploadKey(result);
} else {
Intent data = new Intent();
data.putExtra(OperationResult.EXTRA_RESULT, result);
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
return;
}
Intent data = new Intent();
data.putExtra(OperationResult.EXTRA_RESULT, result);
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
}
}
};
// fill values for this action
Bundle data = new Bundle();
// get selected key entries
data.putParcelable(KeychainService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
intent.putExtra(KeychainService.EXTRA_DATA, data);
// Create a new Messenger for the communication back
@ -247,6 +263,55 @@ public class CreateKeyFinalFragment extends Fragment {
getActivity().startService(intent);
}
// currently only used for moveToCard
@Override
protected SaveKeyringParcel createOperationInput() {
CachedPublicKeyRing key = (new ProviderHelper(getActivity()))
.getCachedPublicKeyRing(mSaveKeyringParcel.mMasterKeyId);
// overwrite mSaveKeyringParcel!
try {
mSaveKeyringParcel = new SaveKeyringParcel(key.getMasterKeyId(), key.getFingerprint());
} catch (PgpKeyNotFoundException e) {
Log.e(Constants.TAG, "Key that should be moved to YubiKey not found in database!");
return null;
}
Cursor cursor = getActivity().getContentResolver().query(
KeychainContract.Keys.buildKeysUri(mSaveKeyringParcel.mMasterKeyId),
new String[]{KeychainContract.Keys.KEY_ID,}, null, null, null
);
try {
while (cursor != null && cursor.moveToNext()) {
long subkeyId = cursor.getLong(0);
mSaveKeyringParcel.getOrCreateSubkeyChange(subkeyId).mMoveKeyToCard = true;
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return mSaveKeyringParcel;
}
// currently only used for moveToCard
@Override
protected void onCryptoOperationSuccess(OperationResult result) {
EditKeyResult editResult = (EditKeyResult) result;
if (editResult.mMasterKeyId != null && mUploadCheckbox.isChecked()) {
// result will be displayed after upload
uploadKey(editResult);
return;
}
Intent data = new Intent();
data.putExtra(OperationResult.EXTRA_RESULT, result);
getActivity().setResult(Activity.RESULT_OK, data);
getActivity().finish();
}
// TODO move into EditKeyOperation
private void uploadKey(final EditKeyResult saveKeyResult) {
// Send all information needed to service to upload key in other thread
@ -259,7 +324,6 @@ public class CreateKeyFinalFragment extends Fragment {
saveKeyResult.mMasterKeyId);
intent.setData(blobUri);
// fill values for this action
Bundle data = new Bundle();
// upload to favorite keyserver
@ -300,7 +364,6 @@ public class CreateKeyFinalFragment extends Fragment {
// start service with intent
getActivity().startService(intent);
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
public class CreateKeyYubiKeyBlankFragment extends Fragment {
CreateKeyActivity mCreateKeyActivity;
View mBackButton;
View mNextButton;
/**
* Creates new instance of this fragment
*/
public static CreateKeyYubiKeyBlankFragment newInstance() {
CreateKeyYubiKeyBlankFragment frag = new CreateKeyYubiKeyBlankFragment();
Bundle args = new Bundle();
frag.setArguments(args);
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.create_yubi_key_blank_fragment, container, false);
mBackButton = view.findViewById(R.id.create_key_back_button);
mNextButton = view.findViewById(R.id.create_key_next_button);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getFragmentManager().getBackStackEntryCount() == 0) {
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
} else {
mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT);
}
}
});
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nextClicked();
}
});
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCreateKeyActivity = (CreateKeyActivity) getActivity();
}
private void nextClicked() {
mCreateKeyActivity.mUseSmartCardSettings = true;
CreateKeyNameFragment frag = CreateKeyNameFragment.newInstance();
mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT);
}
}

View file

@ -64,7 +64,7 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
private TextView vSerNo;
private TextView vUserId;
public static Fragment createInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) {
public static Fragment newInstance(byte[] scannedFingerprints, byte[] nfcAid, String userId) {
CreateKeyYubiKeyImportFragment frag = new CreateKeyYubiKeyImportFragment();
@ -95,7 +95,7 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.create_yubikey_import_fragment, container, false);
View view = inflater.inflate(R.layout.create_yubi_key_import_fragment, container, false);
vSerNo = (TextView) view.findViewById(R.id.yubikey_serno);
vUserId = (TextView) view.findViewById(R.id.yubikey_userid);

View file

@ -35,7 +35,7 @@ public class CreateKeyYubiKeyWaitFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.create_yubikey_wait_fragment, container, false);
View view = inflater.inflate(R.layout.create_yubi_key_wait_fragment, container, false);
mBackButton = view.findViewById(R.id.create_key_back_button);

View file

@ -63,7 +63,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
mServiceIntent = data.getParcelable(EXTRA_SERVICE_INTENT);
// obtain passphrase for this subkey
if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_KEYTOCARD) {
if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_MOVE_KEY_TO_CARD) {
obtainYubiKeyPin(mRequiredInput);
}
}
@ -96,7 +96,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
}
break;
}
case NFC_KEYTOCARD: {
case NFC_MOVE_KEY_TO_CARD: {
ProviderHelper providerHelper = new ProviderHelper(this);
CanonicalizedSecretKeyRing secretKeyRing;
try {

View file

@ -269,7 +269,7 @@ public abstract class BaseNfcActivity extends BaseActivity {
* This method is called by onNewIntent above upon discovery of an NFC tag.
* It handles initialization and login to the application, subsequently
* calls either nfcCalculateSignature() or nfcDecryptSessionKey(), then
* finishes the activity with an appropiate result.
* finishes the activity with an appropriate result.
*
* On general communication, see also
* http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a.aspx

View file

@ -52,7 +52,7 @@ public abstract class CryptoOperationFragment <T extends Parcelable, S extends O
private void initiateInputActivity(RequiredInputParcel requiredInput) {
switch (requiredInput.mType) {
case NFC_KEYTOCARD:
case NFC_MOVE_KEY_TO_CARD:
case NFC_DECRYPT:
case NFC_SIGN: {
Intent intent = new Intent(getActivity(), NfcOperationActivity.class);

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_above="@+id/create_key_buttons">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginLeft="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/first_time_blank_yubikey" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:background="@color/holo_gray_bright"
android:id="@+id/create_key_buttons">
<TextView
android:id="@+id/create_key_back_button"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/btn_back"
android:textAllCaps="true"
android:minHeight="?android:attr/listPreferredItemHeight"
android:drawableLeft="@drawable/ic_chevron_left_grey_24dp"
android:drawablePadding="8dp"
android:gravity="left|center_vertical"
android:clickable="true"
style="?android:attr/borderlessButtonStyle"
android:layout_gravity="center_vertical" />
<TextView
android:id="@+id/create_key_next_button"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/first_time_blank_yubikey_yes"
android:textAllCaps="true"
android:minHeight="?android:attr/listPreferredItemHeight"
android:drawableRight="@drawable/ic_chevron_right_grey_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical|right"
android:clickable="true"
style="?android:attr/borderlessButtonStyle"
android:layout_gravity="center_vertical" />
</LinearLayout>
</RelativeLayout>

View file

@ -9,7 +9,7 @@
<item
android:id="@+id/decrypt_save"
android:title="@string/btn_save"
android:title="@string/btn_save_file"
android:icon="@drawable/ic_action_encrypt_file_24dp"
/>

View file

@ -63,7 +63,8 @@
<string name="btn_decrypt_verify_file">"Decrypt, verify, and save file"</string>
<string name="btn_encrypt_share_file">"Encrypt and share file"</string>
<string name="btn_encrypt_save_file">"Encrypt and save file"</string>
<string name="btn_save">"Save file"</string>
<string name="btn_save_file">"Save file"</string>
<string name="btn_save">"Save"</string>
<string name="btn_view_log">"View log"</string>
<string name="btn_do_not_save">"Cancel"</string>
<string name="btn_delete">"Delete"</string>
@ -1236,8 +1237,8 @@
<string name="first_time_import_key">"Import key from file"</string>
<string name="first_time_yubikey">"Use YubiKey NEO"</string>
<string name="first_time_skip">"Skip Setup"</string>
<string name="first_time_blank_smartcard_title">"Blank smart card / YubiKey detected"</string>
<string name="first_time_blank_smartcard_message">"Would you like to generate a smart card compatible key?"</string>
<string name="first_time_blank_yubikey">"Would you like to use this blank YubiKey NEO with OpenKeychain?\n\nPlease take away the YubiKey now, you will be prompted when it is needed again!"</string>
<string name="first_time_blank_yubikey_yes">"Use this YubiKey"</string>
<!-- unsorted -->
<string name="section_certifier_id">"Certifier"</string>

View file

@ -41,7 +41,6 @@ import org.spongycastle.bcpg.UserIDPacket;
import org.spongycastle.bcpg.sig.KeyFlags;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.BuildConfig;
import org.sufficientlysecure.keychain.WorkaroundBuildConfig;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
@ -847,7 +846,7 @@ public class PgpKeyOperationTest {
parcel, cryptoInput, LogType.MSG_MF_ERROR_BAD_NFC_ALGO);
}
{ // keytocard should return a pending NFC_KEYTOCARD result when presented with the RSA-2048
{ // keytocard should return a pending NFC_MOVE_KEY_TO_CARD result when presented with the RSA-2048
// key, and then make key divert-to-card when it gets a serial in the cryptoInputParcel.
long keyId = KeyringTestingHelper.getSubkeyId(ring, 2);
parcel.reset();
@ -858,8 +857,8 @@ public class PgpKeyOperationTest {
PgpKeyOperation op = new PgpKeyOperation(null);
PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcel);
Assert.assertTrue("keytocard operation should be pending", result.isPending());
Assert.assertEquals("required input should be RequiredInputType.NFC_KEYTOCARD",
result.getRequiredInputParcel().mType, RequiredInputType.NFC_KEYTOCARD);
Assert.assertEquals("required input should be RequiredInputType.NFC_MOVE_KEY_TO_CARD",
result.getRequiredInputParcel().mType, RequiredInputType.NFC_MOVE_KEY_TO_CARD);
// Create a cryptoInputParcel that matches what the NFCOperationActivity would return.
byte[] keyIdBytes = new byte[8];

13
tools/reset_yubikey.txt Normal file
View file

@ -0,0 +1,13 @@
/hex
scd serialno
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
scd apdu 00 e6 00 00
scd apdu 00 44 00 00
/echo Card has been successfully reset.