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{
}
}
}
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 {
isPrimitive = true;
break;
case 0x20:
isPrimitive = false;
isPrimitive = false; // is constructed
break;
}
switch (b & 0x1F) {
......
......@@ -166,6 +166,8 @@ public class PassportApplet extends Applet implements ISO7816 {
private byte[] chainingTmp;
static final byte INS_TESTING = (byte)0xff;
// This is as long we suspect a card verifiable certifcate could be
private static final short CHAINING_BUFFER_LENGTH = 400;
......@@ -254,6 +256,11 @@ public class PassportApplet extends Applet implements ISO7816 {
// available.
// org.globalplatform.GPSystem.setATRHistBytes(ATRGlobal.ATR_HIST,
// (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;
}
......@@ -309,10 +316,10 @@ public class PassportApplet extends Applet implements ISO7816 {
short responseLength = 0;
switch (ins) {
case INS_GET_CHALLENGE:
case INS_GET_CHALLENGE: //defined in 9303-11
responseLength = processGetChallenge(apdu, protectedApdu, le);
break;
case INS_EXTERNAL_AUTHENTICATE:
case INS_EXTERNAL_AUTHENTICATE: //defined in 9303-11
responseLength = processMutualAuthenticate(apdu, protectedApdu);
break;
case INS_PSO:
......@@ -327,23 +334,28 @@ public class PassportApplet extends Applet implements ISO7816 {
}
responseLength = processMSE(apdu);
break;
case INS_INTERNAL_AUTHENTICATE:
case INS_INTERNAL_AUTHENTICATE: //defined in 9303-11
responseLength = processInternalAuthenticate(apdu, protectedApdu);
break;
case INS_SELECT_FILE:
processSelectFile(apdu);
case INS_SELECT_FILE: //defined in 9303-10
responseLength = processSelectFile(apdu);
break;
case INS_READ_BINARY:
case INS_READ_BINARY: //defined in 9303-10
responseLength = processReadBinary(apdu, le, protectedApdu);
break;
case INS_UPDATE_BINARY:
case INS_UPDATE_BINARY: //defined in 9303-10
processUpdateBinary(apdu);
break;
case INS_CREATE_FILE:
processCreateFile(apdu);
break;
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;
default:
ISOException.throwIt(SW_INS_NOT_SUPPORTED);
......@@ -458,7 +470,7 @@ public class PassportApplet extends Applet implements ISO7816 {
return 0;
}
private void processPutData(APDU apdu) {
private short processPutData(APDU apdu) {
if (isLocked()) {
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
}
......@@ -468,6 +480,7 @@ public class PassportApplet extends Applet implements ISO7816 {
short lc = (short) (buffer[OFFSET_LC] & 0xff);
short p1 = (short) (buffer[OFFSET_P1] & 0xff);
short p2 = (short) (buffer[OFFSET_P2] & 0xff);
short returnLength = 0;
// sanity check
if (buffer.length < (short) (buffer_p + lc)) {
......@@ -476,7 +489,8 @@ public class PassportApplet extends Applet implements ISO7816 {
if (p1 == 0xde && p2 == 0xad) {
persistentState |= LOCKED;
} else if (p1 == 0 && p2 == PRIVMODULUS_TAG) {
}
else if (p1 == 0 && p2 == PRIVMODULUS_TAG) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p); // tag ==
// PRIVMODULUS_TAG
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length ==
......@@ -493,7 +507,8 @@ public class PassportApplet extends Applet implements ISO7816 {
keyStore.rsaPrivateKey.setModulus(buffer, modOffset, modLength);
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 ==
// PRIVEXP_TAG
buffer_p = BERTLVScanner.readLength(buffer, buffer_p); // length ==
......@@ -511,31 +526,38 @@ public class PassportApplet extends Applet implements ISO7816 {
keyStore.rsaPrivateKey.setExponent(buffer, expOffset, expLength);
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,
// dateOfExpiry
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
buffer_p = BERTLVScanner.readLength(buffer, buffer_p);
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short docNrOffset = BERTLVScanner.readLength(buffer, buffer_p);
short docNrLength = BERTLVScanner.valueLength;
short docNumberOffset = BERTLVScanner.readLength(buffer, buffer_p);
short docNumberLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short dobOffset = BERTLVScanner.readLength(buffer, buffer_p);
short dobLength = BERTLVScanner.valueLength;
short birthOffset = BERTLVScanner.readLength(buffer, buffer_p);
short birthLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue();
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
short doeOffset = BERTLVScanner.readLength(buffer, buffer_p);
short doeLength = BERTLVScanner.valueLength;
short expiryOffset = BERTLVScanner.readLength(buffer, buffer_p);
short expiryLength = BERTLVScanner.valueLength;
buffer_p = BERTLVScanner.skipValue();
documentNumber = new byte[(short)(docNrLength+1)];
Util.arrayCopyNonAtomic(buffer, docNrOffset, documentNumber,
(short) 0, docNrLength);
documentNumber[docNrLength] = PassportInit.checkDigit(documentNumber,(short)0, docNrLength);
// ISOException.throwIt((short)0xfaaf);//break point
short keySeed_offset = passportInit.computeKeySeed(buffer, docNrOffset,
docNrLength, dobOffset, dobLength, doeOffset, doeLength);
documentNumber = new byte[(short)(docNumberLength+1)];
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 encKey_p = (short) (keySeed_offset + KEYMATERIAL_LENGTH + KEY_LENGTH);
......@@ -546,7 +568,13 @@ public class PassportApplet extends Applet implements ISO7816 {
keyStore.setMutualAuthenticationKeys(buffer, macKey_p, buffer,
encKey_p);
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);
while (buffer_p < finish) {
buffer_p = BERTLVScanner.readTag(buffer, buffer_p);
......@@ -598,7 +626,7 @@ public class PassportApplet extends Applet implements ISO7816 {
// short k = Util.getShort(buffer, buffer_p);
break;
default:
ISOException.throwIt(SW_WRONG_DATA);
ISOException.throwIt(SW_WRONG_DATA);//6a80
break;
}
buffer_p = BERTLVScanner.skipValue();
......@@ -608,7 +636,8 @@ public class PassportApplet extends Applet implements ISO7816 {
} else {
ISOException.throwIt(SW_WRONG_DATA);
}
} else if (p2 == CVCERTIFICATE_TAG) {
}
else if (p2 == CVCERTIFICATE_TAG) {
if ((byte) (persistentState & HAS_CVCERTIFICATE) == HAS_CVCERTIFICATE) {
// We already have the certificate initialized
ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED);
......@@ -616,9 +645,11 @@ public class PassportApplet extends Applet implements ISO7816 {
certificate.parseCertificate(buffer, buffer_p, lc, true);
certificate.setRootCertificate(buffer, p1);
persistentState |= HAS_CVCERTIFICATE;
} else {
}
else {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
return returnLength;
}
/**
......@@ -875,7 +906,7 @@ public class PassportApplet extends Applet implements ISO7816 {
* @param apdu
* where the first 2 data bytes encode the file to select.
*/
private void processSelectFile(APDU apdu) {
private short processSelectFile(APDU apdu) {
if (isLocked() & !hasMutuallyAuthenticated()) {
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
}
......@@ -889,6 +920,7 @@ public class PassportApplet extends Applet implements ISO7816 {
if (apdu.getCurrentState() == APDU.STATE_INITIAL) {
apdu.setIncomingAndReceive();
}
if (apdu.getCurrentState() != APDU.STATE_FULL_INCOMING) {
// need all data in one APDU.
ISOException.throwIt(SW_INTERNAL_ERROR);
......@@ -899,10 +931,14 @@ public class PassportApplet extends Applet implements ISO7816 {
if (fileSystem.getFile(fid) != null) {
selectedFile = fid;
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();
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
return (short)0;
}
/**
......
......@@ -272,10 +272,10 @@ public class PassportCrypto {
// }
public short unwrapCommandAPDU(byte[] ssc, APDU apdu) {
byte[] buf = apdu.getBuffer();
byte[] buffer = apdu.getBuffer();
short apdu_p = (short) (ISO7816.OFFSET_CDATA & 0xff);
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 do87DataLen = 0;
short do87Data_p = 0;
......@@ -287,11 +287,11 @@ public class PassportCrypto {
incrementSSC(ssc);
if (buf[apdu_p] == (byte) 0x87) {
if (buffer[apdu_p] == (byte) 0x87) {
apdu_p++;
// do87
if ((buf[apdu_p] & 0xff) > 0x80) {
do87LenBytes = (short) (buf[apdu_p] & 0x7f);
if ((buffer[apdu_p] & 0xff) > 0x80) {
do87LenBytes = (short) (buffer[apdu_p] & 0x7f);
apdu_p++;
} else {
do87LenBytes = 1;
......@@ -300,11 +300,11 @@ public class PassportCrypto {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
}
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;
if (buf[apdu_p] != 1) {
if (buffer[apdu_p] != 1) {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
}
// store pointer to data and defer decrypt to after mac check (do8e)
......@@ -313,31 +313,31 @@ public class PassportCrypto {
do87DataLen--; // compensate for 0x01 marker
}
if (buf[apdu_p] == (byte) 0x97) {
if (buffer[apdu_p] == (byte) 0x97) {
// do97
if (buf[++apdu_p] != 1)
if (buffer[++apdu_p] != 1)
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
le = (short) (buf[++apdu_p] & 0xff);
le = (short) (buffer[++apdu_p] & 0xff);
apdu_p++;
}
// do8e
if (buf[apdu_p] != (byte) 0x8e) {
if (buffer[apdu_p] != (byte) 0x8e) {
ISOException.throwIt(PassportApplet.SW_INTERNAL_ERROR);
}
if (buf[++apdu_p] != 8) {
if (buffer[++apdu_p] != 8) {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
// verify mac
initMac(Signature.MODE_VERIFY);
updateMac(ssc, (short)0, (short)ssc.length);
updateMac(buf, (short)0, hdrLen);
updateMac(buffer, (short)0, hdrLen);
updateMac(PAD_DATA, (short)0, hdrPadLen);
if (!verifyMacFinal(buf,
if (!verifyMacFinal(buffer,
start_p,
(short) (apdu_p - 1 - start_p),
buf,
buffer,
(short)(apdu_p + 1))) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
......@@ -347,16 +347,16 @@ public class PassportCrypto {
if (do87DataLen != 0) {
// decrypt data, and leave room for lc
decryptInit();
plaintextLength = decryptFinal(buf,
plaintextLength = decryptFinal(buffer,
do87Data_p,
do87DataLen,
buf,
buffer,
(short) (hdrLen + 1));
plaintextLc = PassportUtil.calcLcFromPaddedData(buf,
plaintextLc = PassportUtil.calcLcFromPaddedData(buffer,
(short) (hdrLen + 1),
do87DataLen);
buf[hdrLen] = (byte) (plaintextLc & 0xff);
buffer[hdrLen] = (byte) (plaintextLc & 0xff);
}
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