Commit b27a470a authored by Josh Ji's avatar Josh Ji

add some scripts

parent e3667545
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
...@@ -54,4 +54,49 @@ javacard{ ...@@ -54,4 +54,49 @@ javacard{
} }
} }
} }
scripts {
script {
name 'select'
apdu '00a4040007a0000002471001'
}
script{
name 'testing'
apdu '00ff000000'
}
script {
name 'putData_MRZ'
apdu '00da00621d401bc009413132333435363738c106393930393232c206323231323331'
}
script{
name 'create_file_DG1'
apdu '00e00000066304005a010100'
}
task {
name 'put_data_mrz'
scripts 'select','putData_MRZ'
}
task {
name 'create_file'
scripts 'select','create_file_DG1'
}
script{
name 'select_file_DG1'
apdu '00a4000002010100'
}
script{
name 'update_binary_DG1'
apdu '00000000'
}
task {
name 'update_binary_DG1'
scripts 'select','select_file_DG1','update_binary_DG1'
}
task {
name 'select_file_dg1'
scripts 'select', 'select_file_DG1'
}
}
} }
\ No newline at end of file
...@@ -55,7 +55,7 @@ public class BERTLVScanner { ...@@ -55,7 +55,7 @@ public class BERTLVScanner {
isPrimitive = true; isPrimitive = true;
break; break;
case 0x20: case 0x20:
isPrimitive = false; isPrimitive = false; // is constructed
break; break;
} }
switch (b & 0x1F) { switch (b & 0x1F) {
......
...@@ -166,6 +166,8 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -166,6 +166,8 @@ public class PassportApplet extends Applet implements ISO7816 {
private byte[] chainingTmp; private byte[] chainingTmp;
static final byte INS_TESTING = (byte)0xff;
// This is as long we suspect a card verifiable certifcate could be // This is as long we suspect a card verifiable certifcate could be
private static final short CHAINING_BUFFER_LENGTH = 400; private static final short CHAINING_BUFFER_LENGTH = 400;
...@@ -254,6 +256,11 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -254,6 +256,11 @@ public class PassportApplet extends Applet implements ISO7816 {
// available. // available.
// org.globalplatform.GPSystem.setATRHistBytes(ATRGlobal.ATR_HIST, // org.globalplatform.GPSystem.setATRHistBytes(ATRGlobal.ATR_HIST,
// (short) 0x00, ATRGlobal.ATR_HIST_LEN); // (short) 0x00, ATRGlobal.ATR_HIST_LEN);
byte[] hello = new byte[]{'H','E','L','L','O'};
for (short i = 0; i < hello.length; i++) {
buffer[i] = hello[i];
}
apdu.setOutgoingAndSend((short)0, (short)hello.length);
return; return;
} }
...@@ -309,10 +316,10 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -309,10 +316,10 @@ public class PassportApplet extends Applet implements ISO7816 {
short responseLength = 0; short responseLength = 0;
switch (ins) { switch (ins) {
case INS_GET_CHALLENGE: case INS_GET_CHALLENGE: //defined in 9303-11
responseLength = processGetChallenge(apdu, protectedApdu, le); responseLength = processGetChallenge(apdu, protectedApdu, le);
break; break;
case INS_EXTERNAL_AUTHENTICATE: case INS_EXTERNAL_AUTHENTICATE: //defined in 9303-11
responseLength = processMutualAuthenticate(apdu, protectedApdu); responseLength = processMutualAuthenticate(apdu, protectedApdu);
break; break;
case INS_PSO: case INS_PSO:
...@@ -327,23 +334,28 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -327,23 +334,28 @@ public class PassportApplet extends Applet implements ISO7816 {
} }
responseLength = processMSE(apdu); responseLength = processMSE(apdu);
break; break;
case INS_INTERNAL_AUTHENTICATE: case INS_INTERNAL_AUTHENTICATE: //defined in 9303-11
responseLength = processInternalAuthenticate(apdu, protectedApdu); responseLength = processInternalAuthenticate(apdu, protectedApdu);
break; break;
case INS_SELECT_FILE: case INS_SELECT_FILE: //defined in 9303-10
processSelectFile(apdu); responseLength = processSelectFile(apdu);
break; break;
case INS_READ_BINARY: case INS_READ_BINARY: //defined in 9303-10
responseLength = processReadBinary(apdu, le, protectedApdu); responseLength = processReadBinary(apdu, le, protectedApdu);
break; break;
case INS_UPDATE_BINARY: case INS_UPDATE_BINARY: //defined in 9303-10
processUpdateBinary(apdu); processUpdateBinary(apdu);
break; break;
case INS_CREATE_FILE: case INS_CREATE_FILE:
processCreateFile(apdu); processCreateFile(apdu);
break; break;
case INS_PUT_DATA: case INS_PUT_DATA:
processPutData(apdu); responseLength = processPutData(apdu);
break;
case INS_TESTING:
byte[] testing = new byte[]{'t','e','s','t','i','n','g'};
Util.arrayCopyNonAtomic(testing,(byte)0, apdu.getBuffer(), (byte)0,(byte)testing.length);
responseLength = (byte)testing.length;
break; break;
default: default:
ISOException.throwIt(SW_INS_NOT_SUPPORTED); ISOException.throwIt(SW_INS_NOT_SUPPORTED);
...@@ -458,7 +470,7 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -458,7 +470,7 @@ public class PassportApplet extends Applet implements ISO7816 {
return 0; return 0;
} }
private void processPutData(APDU apdu) { private short processPutData(APDU apdu) {
if (isLocked()) { if (isLocked()) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED); ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
} }
...@@ -468,6 +480,7 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -468,6 +480,7 @@ public class PassportApplet extends Applet implements ISO7816 {
short lc = (short) (buffer[OFFSET_LC] & 0xff); short lc = (short) (buffer[OFFSET_LC] & 0xff);
short p1 = (short) (buffer[OFFSET_P1] & 0xff); short p1 = (short) (buffer[OFFSET_P1] & 0xff);
short p2 = (short) (buffer[OFFSET_P2] & 0xff); short p2 = (short) (buffer[OFFSET_P2] & 0xff);
short returnLength = 0;
// sanity check // sanity check
if (buffer.length < (short) (buffer_p + lc)) { if (buffer.length < (short) (buffer_p + lc)) {
...@@ -476,7 +489,8 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -476,7 +489,8 @@ public class PassportApplet extends Applet implements ISO7816 {
if (p1 == 0xde && p2 == 0xad) { if (p1 == 0xde && p2 == 0xad) {
persistentState |= LOCKED; persistentState |= LOCKED;
} else if (p1 == 0 && p2 == PRIVMODULUS_TAG) { }
else if (p1 == 0 && p2 == PRIVMODULUS_TAG) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag == buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag ==
// PRIVMODULUS_TAG // PRIVMODULUS_TAG
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length == buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length ==
...@@ -493,7 +507,8 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -493,7 +507,8 @@ public class PassportApplet extends Applet implements ISO7816 {
keyStore.rsaPrivateKey.setModulus(buffer, modOffset, modLength); keyStore.rsaPrivateKey.setModulus(buffer, modOffset, modLength);
persistentState |= HAS_MODULUS; persistentState |= HAS_MODULUS;
} else if (p1 == 0 && p2 == PRIVEXPONENT_TAG) { }
else if (p1 == 0 && p2 == PRIVEXPONENT_TAG) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag == buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag ==
// PRIVEXP_TAG // PRIVEXP_TAG
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length == buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length ==
...@@ -511,31 +526,38 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -511,31 +526,38 @@ public class PassportApplet extends Applet implements ISO7816 {
keyStore.rsaPrivateKey.setExponent(buffer, expOffset, expLength); keyStore.rsaPrivateKey.setExponent(buffer, expOffset, expLength);
persistentState |= HAS_EXPONENT; persistentState |= HAS_EXPONENT;
} else if (p1 == 0 && p2 == MRZ_TAG) { }
else if (p1 == 0 && p2 == MRZ_TAG) {
// data is BERTLV object with three objects; docNr, dataOfBirth, // data is BERTLV object with three objects; docNr, dataOfBirth,
// dateOfExpiry // dateOfExpiry
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); buffer_p = BERTLVScanner.readLength(buffer, buffer_p);
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short docNrOffset = BERTLVScanner.readLength(buffer, buffer_p); short docNumberOffset = BERTLVScanner.readLength(buffer, buffer_p);
short docNrLength = BERTLVScanner.valueLength; short docNumberLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue(); buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short dobOffset = BERTLVScanner.readLength(buffer, buffer_p); short birthOffset = BERTLVScanner.readLength(buffer, buffer_p);
short dobLength = BERTLVScanner.valueLength; short birthLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue(); buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short doeOffset = BERTLVScanner.readLength(buffer, buffer_p); short expiryOffset = BERTLVScanner.readLength(buffer, buffer_p);
short doeLength = BERTLVScanner.valueLength; short expiryLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue(); buffer_p = BERTLVScanner.skipValue();
documentNumber = new byte[(short)(docNrLength+1)]; // ISOException.throwIt((short)0xfaaf);//break point
Util.arrayCopyNonAtomic(buffer, docNrOffset, documentNumber,
(short) 0, docNrLength);
documentNumber[docNrLength] = PassportInit.checkDigit(documentNumber,(short)0, docNrLength);
short keySeed_offset = passportInit.computeKeySeed(buffer, docNrOffset, documentNumber = new byte[(short)(docNumberLength+1)];
docNrLength, dobOffset, dobLength, doeOffset, doeLength); Util.arrayCopyNonAtomic(buffer, docNumberOffset, documentNumber,
(short) 0, docNumberLength);
documentNumber[docNumberLength] = PassportInit.checkDigit(documentNumber,(short)0, docNumberLength);
short keySeed_offset = passportInit.computeKeySeed(buffer, docNumberOffset,
docNumberLength, birthOffset, birthLength, expiryOffset, expiryLength);
short macKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH); short macKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH);
short encKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH + KEY_LENGTH); short encKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH + KEY_LENGTH);
...@@ -546,7 +568,13 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -546,7 +568,13 @@ public class PassportApplet extends Applet implements ISO7816 {
keyStore.setMutualAuthenticationKeys(buffer, macKey_p, buffer, keyStore.setMutualAuthenticationKeys(buffer, macKey_p, buffer,
encKey_p); encKey_p);
persistentState |= HAS_MUTUALAUTHENTICATION_KEYS; persistentState |= HAS_MUTUALAUTHENTICATION_KEYS;
} else if (p1 == 0 && p2 == ECPRIVATEKEY_TAG) {
byte[] mrz_tag = new byte[]{'m','r','z','_','t','a','g'};
Util.arrayCopyNonAtomic(mrz_tag,(short)0,buffer,(short)0,(short)mrz_tag.length);
returnLength = (short) mrz_tag.length;
}
else if (p1 == 0 && p2 == ECPRIVATEKEY_TAG) {
short finish = (short) (buffer_p + lc); short finish = (short) (buffer_p + lc);
while (buffer_p < finish) { while (buffer_p < finish) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
...@@ -598,7 +626,7 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -598,7 +626,7 @@ public class PassportApplet extends Applet implements ISO7816 {
// short k = Util.getShort(buffer, buffer_p); // short k = Util.getShort(buffer, buffer_p);
break; break;
default: default:
ISOException.throwIt(SW_WRONG_DATA); ISOException.throwIt(SW_WRONG_DATA);//6a80
break; break;
} }
buffer_p = BERTLVScanner.skipValue(); buffer_p = BERTLVScanner.skipValue();
...@@ -608,7 +636,8 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -608,7 +636,8 @@ public class PassportApplet extends Applet implements ISO7816 {
} else { } else {
ISOException.throwIt(SW_WRONG_DATA); ISOException.throwIt(SW_WRONG_DATA);
} }
} else if (p2 == CVCERTIFICATE_TAG) { }
else if (p2 == CVCERTIFICATE_TAG) {
if ((byte) (persistentState & HAS_CVCERTIFICATE) == HAS_CVCERTIFICATE) { if ((byte) (persistentState & HAS_CVCERTIFICATE) == HAS_CVCERTIFICATE) {
// We already have the certificate initialized // We already have the certificate initialized
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED); ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
...@@ -616,9 +645,11 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -616,9 +645,11 @@ public class PassportApplet extends Applet implements ISO7816 {
certificate.parseCertificate(buffer, buffer_p, lc, true); certificate.parseCertificate(buffer, buffer_p, lc, true);
certificate.setRootCertificate(buffer, p1); certificate.setRootCertificate(buffer, p1);
persistentState |= HAS_CVCERTIFICATE; persistentState |= HAS_CVCERTIFICATE;
} else {
ISOException.throwIt(SW_INCORRECT_P1P2);
} }
else {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
return returnLength;
} }
/** /**
...@@ -875,7 +906,7 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -875,7 +906,7 @@ public class PassportApplet extends Applet implements ISO7816 {
* @param apdu * @param apdu
* where the first 2 data bytes encode the file to select. * where the first 2 data bytes encode the file to select.
*/ */
private void processSelectFile(APDU apdu) { private short processSelectFile(APDU apdu) {
if (isLocked() & !hasMutuallyAuthenticated()) { if (isLocked() & !hasMutuallyAuthenticated()) {
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
} }
...@@ -889,6 +920,7 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -889,6 +920,7 @@ public class PassportApplet extends Applet implements ISO7816 {
if (apdu.getCurrentState() == APDU.STATE_INITIAL) { if (apdu.getCurrentState() == APDU.STATE_INITIAL) {
apdu.setIncomingAndReceive(); apdu.setIncomingAndReceive();
} }
if (apdu.getCurrentState() != APDU.STATE_FULL_INCOMING) { if (apdu.getCurrentState() != APDU.STATE_FULL_INCOMING) {
// need all data in one APDU. // need all data in one APDU.
ISOException.throwIt(SW_INTERNAL_ERROR); ISOException.throwIt(SW_INTERNAL_ERROR);
...@@ -899,10 +931,14 @@ public class PassportApplet extends Applet implements ISO7816 { ...@@ -899,10 +931,14 @@ public class PassportApplet extends Applet implements ISO7816 {
if (fileSystem.getFile(fid) != null) { if (fileSystem.getFile(fid) != null) {
selectedFile = fid; selectedFile = fid;
volatileState[0] |= FILE_SELECTED; volatileState[0] |= FILE_SELECTED;
return; byte[] select_file = new byte[]{'s','e','l','e','c','t','_','f','i','l','e'};
Util.arrayCopyNonAtomic(select_file,(short) 0,buffer,(short)0,
(short)select_file.length);
return (short) select_file.length;
} }
setNoFileSelected(); setNoFileSelected();
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND); ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
return (short)0;
} }
/** /**
......
...@@ -272,10 +272,10 @@ public class PassportCrypto { ...@@ -272,10 +272,10 @@ public class PassportCrypto {
// } // }
public short unwrapCommandAPDU(byte[] ssc, APDU apdu) { public short unwrapCommandAPDU(byte[] ssc, APDU apdu) {
byte[] buf = apdu.getBuffer(); byte[] buffer = apdu.getBuffer();
short apdu_p = (short) (ISO7816.OFFSET_CDATA & 0xff); short apdu_p = (short) (ISO7816.OFFSET_CDATA & 0xff);
short start_p = apdu_p; short start_p = apdu_p;
short lc = (short) (buf[ISO7816.OFFSET_LC] & 0xff); short lc = (short) (buffer[ISO7816.OFFSET_LC] & 0xff);
short le = 0; short le = 0;
short do87DataLen = 0; short do87DataLen = 0;
short do87Data_p = 0; short do87Data_p = 0;
...@@ -287,11 +287,11 @@ public class PassportCrypto { ...@@ -287,11 +287,11 @@ public class PassportCrypto {
incrementSSC(ssc); incrementSSC(ssc);
if (buf[apdu_p] == (byte) 0x87) { if (buffer[apdu_p] == (byte) 0x87) {
apdu_p++; apdu_p++;
// do87 // do87
if ((buf[apdu_p] & 0xff) > 0x80) { if ((buffer[apdu_p] & 0xff) > 0x80) {
do87LenBytes = (short) (buf[apdu_p] & 0x7f); do87LenBytes = (short) (buffer[apdu_p] & 0x7f);
apdu_p++; apdu_p++;
} else { } else {
do87LenBytes = 1; do87LenBytes = 1;
...@@ -300,11 +300,11 @@ public class PassportCrypto { ...@@ -300,11 +300,11 @@ public class PassportCrypto {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR); ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
} }
for (short i = 0; i < do87LenBytes; i++) { for (short i = 0; i < do87LenBytes; i++) {
do87DataLen += (short) ((buf[(short)(apdu_p + i)] & 0xff) << (short) ((do87LenBytes - 1 - i) * 8)); do87DataLen += (short) ((buffer[(short)(apdu_p + i)] & 0xff) << (short) ((do87LenBytes - 1 - i) * 8));
} }
apdu_p += do87LenBytes; apdu_p += do87LenBytes;
if (buf[apdu_p] != 1) { if (buffer[apdu_p] != 1) {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR); ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
} }
// store pointer to data and defer decrypt to after mac check (do8e) // store pointer to data and defer decrypt to after mac check (do8e)
...@@ -313,31 +313,31 @@ public class PassportCrypto { ...@@ -313,31 +313,31 @@ public class PassportCrypto {
do87DataLen--; // compensate for 0x01 marker do87DataLen--; // compensate for 0x01 marker
} }
if (buf[apdu_p] == (byte) 0x97) { if (buffer[apdu_p] == (byte) 0x97) {
// do97 // do97
if (buf[++apdu_p] != 1) if (buffer[++apdu_p] != 1)
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR); ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
le = (short) (buf[++apdu_p] & 0xff); le = (short) (buffer[++apdu_p] & 0xff);
apdu_p++; apdu_p++;
} }
// do8e // do8e
if (buf[apdu_p] != (byte) 0x8e) { if (buffer[apdu_p] != (byte) 0x8e) {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR); ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
} }
if (buf[++apdu_p] != 8) { if (buffer[++apdu_p] != 8) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID); ISOException.throwIt(ISO7816.SW_DATA_INVALID);
} }
// verify mac // verify mac
initMac(Signature.MODE_VERIFY); initMac(Signature.MODE_VERIFY);
updateMac(ssc, (short)0, (short)ssc.length); updateMac(ssc, (short)0, (short)ssc.length);
updateMac(buf, (short)0, hdrLen); updateMac(buffer, (short)0, hdrLen);
updateMac(PAD_DATA, (short)0, hdrPadLen); updateMac(PAD_DATA, (short)0, hdrPadLen);
if (!verifyMacFinal(buf, if (!verifyMacFinal(buffer,
start_p, start_p,
(short) (apdu_p - 1 - start_p), (short) (apdu_p - 1 - start_p),
buf, buffer,
(short)(apdu_p + 1))) { (short)(apdu_p + 1))) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED); ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
} }
...@@ -347,16 +347,16 @@ public class PassportCrypto { ...@@ -347,16 +347,16 @@ public class PassportCrypto {
if (do87DataLen != 0) { if (do87DataLen != 0) {
// decrypt data, and leave room for lc // decrypt data, and leave room for lc
decryptInit(); decryptInit();
plaintextLength = decryptFinal(buf, plaintextLength = decryptFinal(buffer,
do87Data_p, do87Data_p,
do87DataLen, do87DataLen,
buf, buffer,
(short) (hdrLen + 1)); (short) (hdrLen + 1));
plaintextLc = PassportUtil.calcLcFromPaddedData(buf, plaintextLc = PassportUtil.calcLcFromPaddedData(buffer,
(short) (hdrLen + 1), (short) (hdrLen + 1),
do87DataLen); do87DataLen);
buf[hdrLen] = (byte) (plaintextLc & 0xff); buffer[hdrLen] = (byte) (plaintextLc & 0xff);
} }
return le; return le;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment