From: Eugene Crosser Date: Fri, 3 May 2013 08:21:41 +0000 (+0400) Subject: Renamed classes X-Git-Url: http://www.average.org/gitweb/?p=YkNeoCR.git;a=commitdiff_plain;h=a0d60dab1717e69b6d853eb91d0065fe378e3c28 Renamed classes --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index efcae30..684cae9 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -15,14 +15,14 @@ android:allowBackup="true" android:theme="@style/AppTheme"> - - diff --git a/src/org/average/nfcauthcr/Check.java b/src/org/average/nfcauthcr/Check.java new file mode 100644 index 0000000..c3738f7 --- /dev/null +++ b/src/org/average/nfcauthcr/Check.java @@ -0,0 +1,122 @@ +package org.average.nfcauthcr; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.PendingIntent; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.nfc.TagLostException; +import android.nfc.tech.IsoDep; +import android.util.Log; +import android.widget.Toast; + +import org.average.nfcauthcr.YkNeo; + +public class Check extends Activity { + + private final String TAG = getClass().getName(); + + private AlertDialog swipeDialog; + private PendingIntent tagIntent; + + @Override + protected void onResume() { + super.onResume(); + Log.v(TAG, "Starting the work"); + + Intent intent = getIntent(); + setResult(RESULT_CANCELED); + if (swipeDialog != null) { + swipeDialog.dismiss(); + swipeDialog = null; + } + int slot = intent.getIntExtra("slot", -1); + if (slot > 0) { + swipeDialog = makeDialog(); + swipeDialog.show(); + enableDispatch(slot); + } + } + + @Override + protected void onPause() { + super.onPause(); + Log.v(TAG, "Finished the work"); + + if(swipeDialog != null) { + swipeDialog.dismiss(); + swipeDialog = null; + } + disableDispatch(); + } + + public void onNewIntent(Intent intent) { + Log.v(TAG, "NFC Intent arrived"); + int slot = intent.getIntExtra("slot", -1); + byte[] challenge = intent.getByteArrayExtra("challenge"); + if (slot <= 0) return; + Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + if (tag == null) return; + IsoDep isoTag = IsoDep.get(tag); + byte[] response = YkNeo.doChallengeYubiKey( + isoTag, slot, challenge); + if (response != null) { + Intent data = getIntent(); + data.putExtra("response", response); + setResult(RESULT_OK, data); + } + finish(); + } + + private AlertDialog makeDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.challenging); + builder.setMessage(R.string.swipe); + builder.setOnCancelListener( + new DialogInterface.OnCancelListener() { + public void onCancel(DialogInterface dialog) { + finish(); + } + }); + return builder.create(); + } + + private void enableDispatch(int slot) { + Intent intent = getIntent(); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + intent.putExtra("slot", slot); + tagIntent = PendingIntent.getActivity(this, 0, intent, 0); + IntentFilter iso = + new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); + if (adapter == null) { + Toast.makeText(this, R.string.no_nfc, + Toast.LENGTH_LONG).show(); + finish(); + return; + } + if (! adapter.isEnabled()) { + Toast.makeText(this, R.string.nfc_disabled, + Toast.LENGTH_LONG).show(); + finish(); + return; + } + adapter.enableForegroundDispatch( + this, tagIntent, new IntentFilter[] {iso}, + new String[][] {new String[] {IsoDep.class.getName()}}); + } + + private void disableDispatch() { + if (tagIntent != null) { + tagIntent.cancel(); + tagIntent = null; + } + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); + if (adapter != null) { + adapter.disableForegroundDispatch(this); + } + } +} diff --git a/src/org/average/nfcauthcr/Enroll.java b/src/org/average/nfcauthcr/Enroll.java new file mode 100644 index 0000000..9f9d535 --- /dev/null +++ b/src/org/average/nfcauthcr/Enroll.java @@ -0,0 +1,143 @@ +package org.average.nfcauthcr; + +import java.util.Random; + +import android.os.Bundle; +import android.app.Activity; +import android.app.AlertDialog; +import android.preference.PreferenceManager; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.DialogInterface; +import android.util.Log; +import android.view.View; +import android.widget.TextView; +import android.widget.RadioButton; + +import org.average.nfcauthcr.Check; + +public class Enroll extends Activity { + + private final String TAG = getClass().getName(); + + private static boolean waitingForResult = false; + private static SharedPreferences prefs; + private static int slot; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + Log.v(TAG, "Starting"); + prefs = PreferenceManager.getDefaultSharedPreferences(this); + } + + @Override + protected void onResume() { + super.onResume(); + setContentView(R.layout.main); + slot = prefs.getInt("slot_number", -1); + Log.v(TAG, "found saved slot value " + slot); + RadioButton btn = null; + switch (slot) { + case 1: btn = (RadioButton)findViewById(R.id.slot_1); + break; + case 2: btn = (RadioButton)findViewById(R.id.slot_2); + break; + } + if (btn != null) btn.setChecked(true); + } + + @Override + protected void onPause() { + super.onPause(); + Log.v(TAG, "Going inactive, try to stop"); + if (!waitingForResult) { finish(); } + } + + @Override + protected void onStop() { + super.onStop(); + Log.v(TAG, "Stop requested"); + } + + public void onSlotSelectionClicked(View view) { + Log.v(TAG, "Radio Button selected"); + if (! ((RadioButton) view).isChecked()) return; + switch(view.getId()) { + case R.id.slot_1: slot=1; break; + case R.id.slot_2: slot=2; break; + } + Editor editor = prefs.edit(); + editor.putInt("slot_number", slot); + editor.commit(); + Log.v(TAG, "stored slot number " + slot); + } + + public void onEnrollClicked(View view) { + Log.v(TAG, "Enroll clicked"); + if (slot > 0) { + runEnrollment(slot); + } else { + showEnrollResult("Must specify which slot to use"); + } + } + + public void onActivityResult(int requestCode, int resultCode, + Intent intent) { + Log.v(TAG, "Got activity result"); + waitingForResult = false; + + if (resultCode != RESULT_OK) { + Log.v(TAG, "Error result code " + resultCode); + return; + } + byte[] challenge = intent.getByteArrayExtra("challenge"); + Log.v(TAG, "Challenge is \"" + hex(challenge) + "\""); + byte[] response = intent.getByteArrayExtra("response"); + Log.v(TAG, "Response is \"" + hex(response) + "\""); + Editor editor = prefs.edit(); + editor.putString("challenge", hex(challenge)); + editor.putString("response", hex(response)); + editor.commit(); + Log.v(TAG, "stored new challenge and response"); + } + + private void showEnrollResult(final String msg) { + Log.v(TAG, "Show result: \"" + msg + "\""); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.enrollresult); + builder.setMessage(msg); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + if (!waitingForResult) { finish(); } + } + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } + + private void runEnrollment(int slot) { + Random rng = new Random(); + byte[] challenge = new byte[63]; + rng.nextBytes(challenge); + Log.v(TAG, "Random challenge: " + hex(challenge)); + Log.v(TAG, "Launching challenging activity"); + Intent crIntent = new Intent(this, NFCAuthCRCheck.class); + crIntent.putExtra("slot", slot); + crIntent.putExtra("challenge", challenge); + this.startActivityForResult(crIntent, 0); + waitingForResult = true; + } + + private String hex(byte[] a) { + StringBuilder sb = new StringBuilder(); + if (a == null) return ""; + for (byte b: a) sb.append(String.format("%02x", b&0xff)); + return sb.toString(); + } +} diff --git a/src/org/average/nfcauthcr/NFCAuthCRCheck.java b/src/org/average/nfcauthcr/NFCAuthCRCheck.java deleted file mode 100644 index ea37128..0000000 --- a/src/org/average/nfcauthcr/NFCAuthCRCheck.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.average.nfcauthcr; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.nfc.NfcAdapter; -import android.nfc.Tag; -import android.nfc.TagLostException; -import android.nfc.tech.IsoDep; -import android.util.Log; -import android.widget.Toast; - -import org.average.nfcauthcr.NFCAuthCRYubiNeo; - -public class NFCAuthCRCheck extends Activity { - - private final String TAG = getClass().getName(); - - private AlertDialog swipeDialog; - private PendingIntent tagIntent; - - @Override - protected void onResume() { - super.onResume(); - Log.v(TAG, "Starting the work"); - - Intent intent = getIntent(); - setResult(RESULT_CANCELED); - if (swipeDialog != null) { - swipeDialog.dismiss(); - swipeDialog = null; - } - int slot = intent.getIntExtra("slot", -1); - if (slot > 0) { - swipeDialog = makeDialog(); - swipeDialog.show(); - enableDispatch(slot); - } - } - - @Override - protected void onPause() { - super.onPause(); - Log.v(TAG, "Finished the work"); - - if(swipeDialog != null) { - swipeDialog.dismiss(); - swipeDialog = null; - } - disableDispatch(); - } - - public void onNewIntent(Intent intent) { - Log.v(TAG, "NFC Intent arrived"); - int slot = intent.getIntExtra("slot", -1); - byte[] challenge = intent.getByteArrayExtra("challenge"); - if (slot <= 0) return; - Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); - if (tag == null) return; - IsoDep isoTag = IsoDep.get(tag); - byte[] response = NFCAuthCRYubiNeo.doChallengeYubiKey( - isoTag, slot, challenge); - if (response != null) { - Intent data = getIntent(); - data.putExtra("response", response); - setResult(RESULT_OK, data); - } - finish(); - } - - private AlertDialog makeDialog() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.challenging); - builder.setMessage(R.string.swipe); - builder.setOnCancelListener( - new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface dialog) { - finish(); - } - }); - return builder.create(); - } - - private void enableDispatch(int slot) { - Intent intent = getIntent(); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - intent.putExtra("slot", slot); - tagIntent = PendingIntent.getActivity(this, 0, intent, 0); - IntentFilter iso = - new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); - NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); - if (adapter == null) { - Toast.makeText(this, R.string.no_nfc, - Toast.LENGTH_LONG).show(); - finish(); - return; - } - if (! adapter.isEnabled()) { - Toast.makeText(this, R.string.nfc_disabled, - Toast.LENGTH_LONG).show(); - finish(); - return; - } - adapter.enableForegroundDispatch( - this, tagIntent, new IntentFilter[] {iso}, - new String[][] {new String[] {IsoDep.class.getName()}}); - } - - private void disableDispatch() { - if (tagIntent != null) { - tagIntent.cancel(); - tagIntent = null; - } - NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); - if (adapter != null) { - adapter.disableForegroundDispatch(this); - } - } -} diff --git a/src/org/average/nfcauthcr/NFCAuthCREnroll.java b/src/org/average/nfcauthcr/NFCAuthCREnroll.java deleted file mode 100644 index 50933cb..0000000 --- a/src/org/average/nfcauthcr/NFCAuthCREnroll.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.average.nfcauthcr; - -import java.util.Random; - -import android.os.Bundle; -import android.app.Activity; -import android.app.AlertDialog; -import android.preference.PreferenceManager; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.DialogInterface; -import android.util.Log; -import android.view.View; -import android.widget.TextView; -import android.widget.RadioButton; - -import org.average.nfcauthcr.NFCAuthCRCheck; - -public class NFCAuthCREnroll extends Activity { - - private final String TAG = getClass().getName(); - - private static boolean waitingForResult = false; - private static SharedPreferences prefs; - private static int slot; - - @Override - protected void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - Log.v(TAG, "Starting"); - prefs = PreferenceManager.getDefaultSharedPreferences(this); - } - - @Override - protected void onResume() { - super.onResume(); - setContentView(R.layout.main); - slot = prefs.getInt("slot_number", -1); - Log.v(TAG, "found saved slot value " + slot); - RadioButton btn = null; - switch (slot) { - case 1: btn = (RadioButton)findViewById(R.id.slot_1); - break; - case 2: btn = (RadioButton)findViewById(R.id.slot_2); - break; - } - if (btn != null) btn.setChecked(true); - } - - @Override - protected void onPause() { - super.onPause(); - Log.v(TAG, "Going inactive, try to stop"); - if (!waitingForResult) { finish(); } - } - - @Override - protected void onStop() { - super.onStop(); - Log.v(TAG, "Stop requested"); - } - - public void onSlotSelectionClicked(View view) { - Log.v(TAG, "Radio Button selected"); - if (! ((RadioButton) view).isChecked()) return; - switch(view.getId()) { - case R.id.slot_1: slot=1; break; - case R.id.slot_2: slot=2; break; - } - Editor editor = prefs.edit(); - editor.putInt("slot_number", slot); - editor.commit(); - Log.v(TAG, "stored slot number " + slot); - } - - public void onEnrollClicked(View view) { - Log.v(TAG, "Enroll clicked"); - if (slot > 0) { - runEnrollment(slot); - } else { - showEnrollResult("Must specify which slot to use"); - } - } - - public void onActivityResult(int requestCode, int resultCode, - Intent intent) { - Log.v(TAG, "Got activity result"); - waitingForResult = false; - - if (resultCode != RESULT_OK) { - Log.v(TAG, "Error result code " + resultCode); - return; - } - byte[] challenge = intent.getByteArrayExtra("challenge"); - Log.v(TAG, "Challenge is \"" + hex(challenge) + "\""); - byte[] response = intent.getByteArrayExtra("response"); - Log.v(TAG, "Response is \"" + hex(response) + "\""); - Editor editor = prefs.edit(); - editor.putString("challenge", hex(challenge)); - editor.putString("response", hex(response)); - editor.commit(); - Log.v(TAG, "stored new challenge and response"); - } - - private void showEnrollResult(final String msg) { - Log.v(TAG, "Show result: \"" + msg + "\""); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.enrollresult); - builder.setMessage(msg); - builder.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - if (!waitingForResult) { finish(); } - } - }); - AlertDialog dialog = builder.create(); - dialog.show(); - } - - private void runEnrollment(int slot) { - Random rng = new Random(); - byte[] challenge = new byte[63]; - rng.nextBytes(challenge); - Log.v(TAG, "Random challenge: " + hex(challenge)); - Log.v(TAG, "Launching challenging activity"); - Intent crIntent = new Intent(this, NFCAuthCRCheck.class); - crIntent.putExtra("slot", slot); - crIntent.putExtra("challenge", challenge); - this.startActivityForResult(crIntent, 0); - waitingForResult = true; - } - - private String hex(byte[] a) { - StringBuilder sb = new StringBuilder(); - if (a == null) return ""; - for (byte b: a) sb.append(String.format("%02x", b&0xff)); - return sb.toString(); - } -} diff --git a/src/org/average/nfcauthcr/NFCAuthCRYubiNeo.java b/src/org/average/nfcauthcr/NFCAuthCRYubiNeo.java deleted file mode 100644 index 67596e6..0000000 --- a/src/org/average/nfcauthcr/NFCAuthCRYubiNeo.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.average.nfcauthcr; - -import java.io.IOException; -import java.util.Arrays; - -import android.nfc.NfcAdapter; -import android.nfc.Tag; -import android.nfc.TagLostException; -import android.nfc.tech.IsoDep; -import android.util.Log; - -import org.average.nfcauthcr.NFCAuthCRYubiNeo; - -public class NFCAuthCRYubiNeo { - - private static final String TAG = "NFCAuthCRYubiNeo"; - - // Is it CCID APDU? ISO 7816-4? - - // 00 A4 04 00 xx AID - GlobalPlatform - SELECT - // Le send data = 07: A0 00 00 05 27 20 01 - // Le recv data = 00 - private static final byte[] selectCommand = - {0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xA0, - 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00}; - - private static final byte[] crCommand = - {0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}; - - private static final byte SLOT_CHAL_HMAC1 = 0x30; - private static final byte SLOT_CHAL_HMAC2 = 0x38; - - public static final byte[] doChallengeYubiKey(IsoDep isoTag, int slot, - byte[] challenge) { - try { - isoTag.connect(); - byte[] resp = isoTag.transceive(selectCommand); - int length = resp.length; - Log.v(TAG, "response to select length is " + length); - if (resp[length - 2] != (byte)0x90 || - resp[length - 1] != 0x00) { - Log.v(TAG, "Wrong response to select"); - //Toast.makeText(this, R.string.tag_error, - // Toast.LENGTH_LONG).show(); - return null; - } - byte[] apdu = new byte[69]; - apdu[0] = 0x00; // CLA - apdu[1] = 0x01; // INS - switch (slot) { - case 1: apdu[2] = SLOT_CHAL_HMAC1; break; // P1 - case 2: apdu[2] = SLOT_CHAL_HMAC2; break; // P1 - } - apdu[3] = 0x00; // P2 - apdu[4] = 63; // Lc - System.arraycopy(challenge, 0, apdu, 5, - challenge.length); - apdu[apdu.length-1] = 22; - resp = isoTag.transceive(apdu); - length = resp.length; - if (resp[length - 2] != (byte)0x90 || - resp[length - 1] != 0x00) { - Log.v(TAG, "Wrong response to challenge"); - //Toast.makeText(this, R.string.tag_error, - // Toast.LENGTH_LONG).show(); - return null; - } - Log.v(TAG, "response to challenge length is " + length); - return Arrays.copyOf(resp, length-2); - } catch (TagLostException e) { - Log.v(TAG, e.getMessage()); - //Toast.makeText(this, - // R.string.tag_lost, Toast.LENGTH_LONG).show(); - } catch (IOException e) { - Log.v(TAG, e.getMessage()); - //Toast.makeText(this, - // getText(R.string.tag_error) + - // e.getMessage(), - // Toast.LENGTH_LONG).show(); - } - return null; - } -} diff --git a/src/org/average/nfcauthcr/YkNeo.java b/src/org/average/nfcauthcr/YkNeo.java new file mode 100644 index 0000000..a291eab --- /dev/null +++ b/src/org/average/nfcauthcr/YkNeo.java @@ -0,0 +1,75 @@ +package org.average.nfcauthcr; + +import java.io.IOException; +import java.util.Arrays; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.nfc.TagLostException; +import android.nfc.tech.IsoDep; +//import android.util.Log; + +public class YkNeo { + + // This is a CCID APDU, ISO 7816-4. + // 00 A4 04 00 xx AID - GlobalPlatform - SELECT + // Lc, send data = 07: A0 00 00 05 27 20 01 + // Le, recv data = 00 + private static final byte[] selectApdu = + {0x00, (byte) 0xA4, 0x04, 0x00, 0x07, (byte) 0xA0, + 0x00, 0x00, 0x05, 0x27, 0x20, 0x01, 0x00}; + + private static final byte SLOT_CHAL_HMAC1 = 0x30; + private static final byte SLOT_CHAL_HMAC2 = 0x38; + + public static final byte[] doChallengeYubiKey(IsoDep isoTag, int slot, + byte[] challenge) { + try { + isoTag.connect(); + byte[] resp = isoTag.transceive(selectApdu); + int length = resp.length; + //Log.v(TAG, "response to select length is " + length); + if (resp[length - 2] != (byte)0x90 || + resp[length - 1] != 0x00) { + //Log.v(TAG, "Wrong response to select"); + //Toast.makeText(this, R.string.tag_error, + // Toast.LENGTH_LONG).show(); + return null; + } + byte[] crApdu = new byte[69]; + crApdu[0] = 0x00; // CLA + crApdu[1] = 0x01; // INS + switch (slot) { + case 1: crApdu[2] = SLOT_CHAL_HMAC1; break; // P1 + case 2: crApdu[2] = SLOT_CHAL_HMAC2; break; // P1 + } + crApdu[3] = 0x00; // P2 + crApdu[4] = 63; // Lc + System.arraycopy(challenge, 0, crApdu, 5, + challenge.length); // Payload + crApdu[crApdu.length-1] = 22; // Le + resp = isoTag.transceive(crApdu); + length = resp.length; + if (resp[length - 2] != (byte)0x90 || + resp[length - 1] != 0x00) { + //Log.v(TAG, "Wrong response to challenge"); + //Toast.makeText(this, R.string.tag_error, + // Toast.LENGTH_LONG).show(); + return null; + } + //Log.v(TAG, "response to challenge length is " + length); + return Arrays.copyOf(resp, length-2); + } catch (TagLostException e) { + //Log.v(TAG, e.getMessage()); + //Toast.makeText(this, + // R.string.tag_lost, Toast.LENGTH_LONG).show(); + } catch (IOException e) { + //Log.v(TAG, e.getMessage()); + //Toast.makeText(this, + // getText(R.string.tag_error) + + // e.getMessage(), + // Toast.LENGTH_LONG).show(); + } + return null; + } +}