Merge pull request #1210 from josecastillo/development

Maintain client-side state for PIN verification operations
This commit is contained in:
Vincent 2015-04-21 10:28:16 +02:00
commit a658d3c1e1

View File

@ -57,6 +57,9 @@ public abstract class BaseNfcActivity extends BaseActivity {
public static final int REQUEST_CODE_PASSPHRASE = 1; public static final int REQUEST_CODE_PASSPHRASE = 1;
protected Passphrase mPin; protected Passphrase mPin;
protected boolean mPw1ValidForMultipleSignatures;
protected boolean mPw1ValidatedForSignature;
protected boolean mPw1ValidatedForDecrypt; // Mode 82 does other things; consider renaming?
private NfcAdapter mNfcAdapter; private NfcAdapter mNfcAdapter;
private IsoDep mIsoDep; private IsoDep mIsoDep;
@ -197,10 +200,15 @@ public abstract class BaseNfcActivity extends BaseActivity {
+ "06" // Lc (number of bytes) + "06" // Lc (number of bytes)
+ "D27600012401" // Data (6 bytes) + "D27600012401" // Data (6 bytes)
+ "00"; // Le + "00"; // Le
if ( ! nfcCommunicate(opening).equals(accepted)) { // activate connection if ( ! nfcCommunicate(opening).endsWith(accepted)) { // activate connection
throw new IOException("Initialization failed!"); throw new IOException("Initialization failed!");
} }
byte[] pwStatusBytes = nfcGetPwStatusBytes();
mPw1ValidForMultipleSignatures = (pwStatusBytes[0] == 1);
mPw1ValidatedForSignature = false;
mPw1ValidatedForDecrypt = false;
onNfcPerform(); onNfcPerform();
mIsoDep.close(); mIsoDep.close();
@ -278,6 +286,15 @@ public abstract class BaseNfcActivity extends BaseActivity {
return fptlv.mV; return fptlv.mV;
} }
/** Return the PW Status Bytes from the card. This is a simple DO; no TLV decoding needed.
*
* @return Seven bytes in fixed format, plus 0x9000 status word at the end.
*/
public byte[] nfcGetPwStatusBytes() throws IOException {
String data = "00CA00C400";
return mIsoDep.transceive(Hex.decode(data));
}
/** Return the fingerprint from application specific data stored on tag, or /** Return the fingerprint from application specific data stored on tag, or
* null if it doesn't exist. * null if it doesn't exist.
* *
@ -316,7 +333,9 @@ public abstract class BaseNfcActivity extends BaseActivity {
* @return a big integer representing the MPI for the given hash * @return a big integer representing the MPI for the given hash
*/ */
public byte[] nfcCalculateSignature(byte[] hash, int hashAlgo) throws IOException { public byte[] nfcCalculateSignature(byte[] hash, int hashAlgo) throws IOException {
if (!mPw1ValidatedForSignature) {
nfcVerifyPIN(0x81); // (Verify PW1 with mode 81 for signing) nfcVerifyPIN(0x81); // (Verify PW1 with mode 81 for signing)
}
// dsi, including Lc // dsi, including Lc
String dsi; String dsi;
@ -391,6 +410,10 @@ public abstract class BaseNfcActivity extends BaseActivity {
Log.d(Constants.TAG, "final response:" + status); Log.d(Constants.TAG, "final response:" + status);
if (!mPw1ValidForMultipleSignatures) {
mPw1ValidatedForSignature = false;
}
if ( ! "9000".equals(status)) { if ( ! "9000".equals(status)) {
throw new IOException("Bad NFC response code: " + status); throw new IOException("Bad NFC response code: " + status);
} }
@ -410,7 +433,9 @@ public abstract class BaseNfcActivity extends BaseActivity {
* @return the decoded session key * @return the decoded session key
*/ */
public byte[] nfcDecryptSessionKey(byte[] encryptedSessionKey) throws IOException { public byte[] nfcDecryptSessionKey(byte[] encryptedSessionKey) throws IOException {
if (!mPw1ValidatedForDecrypt) {
nfcVerifyPIN(0x82); // (Verify PW1 with mode 82 for decryption) nfcVerifyPIN(0x82); // (Verify PW1 with mode 82 for decryption)
}
String firstApdu = "102a8086fe"; String firstApdu = "102a8086fe";
String secondApdu = "002a808603"; String secondApdu = "002a808603";
@ -458,6 +483,12 @@ public abstract class BaseNfcActivity extends BaseActivity {
handlePinError(); handlePinError();
throw new IOException("Bad PIN!"); throw new IOException("Bad PIN!");
} }
if (mode == 0x81) {
mPw1ValidatedForSignature = true;
} else if (mode == 0x82) {
mPw1ValidatedForDecrypt = true;
}
} }
} }