diff --git a/applet/src/main/java/applet/AppletInstructions.java b/applet/src/main/java/applet/AppletInstructions.java index 8d54a83..2eb6203 100644 --- a/applet/src/main/java/applet/AppletInstructions.java +++ b/applet/src/main/java/applet/AppletInstructions.java @@ -86,4 +86,9 @@ public AppletInstructions() { public static final byte PSBT_GLOBAL_SIGHASH_SINGLE_INPUTS = 0x07; public static final byte PSBT_GLOBAL_VERSION = (byte) 0xFB; public static final byte PSBT_GLOBAL_PROPRIETARY = (byte) 0xFC; + + + public static final byte PSBT_OUT_AMOUNT = (byte) 0x03; + public static final byte PSBT_OUT_SCRIPT = (byte) 0x04; + } \ No newline at end of file diff --git a/applet/src/main/java/applet/GlobalMap.java b/applet/src/main/java/applet/GlobalMap.java index e4b3929..dcafdbb 100644 --- a/applet/src/main/java/applet/GlobalMap.java +++ b/applet/src/main/java/applet/GlobalMap.java @@ -37,4 +37,19 @@ public void fill(short arrayIndex) { map_size += key_pairs[current_key_pair].getSize(); } } + + public void reset() { + short i = 0; + while (i < NUM_OF_KEYPAIR) { + key_pairs[i].reset(); + i++; + } + input_maps_total = -1; + output_maps_total = -1; + PSBTversion = 0; + globalUnsignedTX.reset(); + map_start = -1; + current_key_pair = -1; + map_size = 0; + } } diff --git a/applet/src/main/java/applet/GlobalUnsignedTX.java b/applet/src/main/java/applet/GlobalUnsignedTX.java index 03e25c2..7da939c 100644 --- a/applet/src/main/java/applet/GlobalUnsignedTX.java +++ b/applet/src/main/java/applet/GlobalUnsignedTX.java @@ -64,4 +64,16 @@ short ignoreInput(short bytesIgnored) { short signature_scrip_size = compactWeirdoInt((short) (bytesIgnored + 36)); return (short) (signature_scrip_size + 40 + byteSizeOfCWI(signature_scrip_size)); } + + void reset() { + short i = 0; + while (i < MAX_COUNT_OF_IO) { + inputs[i].reset(); + outputs[i].reset(); + i++; + } + start = -1; + version = -1; + size = 0; + } } diff --git a/applet/src/main/java/applet/GlobalUnsignedTXInput.java b/applet/src/main/java/applet/GlobalUnsignedTXInput.java index d11267b..3e5b246 100644 --- a/applet/src/main/java/applet/GlobalUnsignedTXInput.java +++ b/applet/src/main/java/applet/GlobalUnsignedTXInput.java @@ -19,4 +19,13 @@ void fill(short start){ sequence_start = (short) (script_sig_start + script_size); size = (short) (36 + byteSizeOfCWI(script_size) + script_size + 4); // easier to read and understand this way } + + void reset(){ + previous_output_start = -1; + script_size_start = -1; + script_size = -1; + script_sig_start = -1; + sequence_start = -1; + size = 0; + } } diff --git a/applet/src/main/java/applet/GlobalUnsignedTXOutput.java b/applet/src/main/java/applet/GlobalUnsignedTXOutput.java index d277233..36d82bf 100644 --- a/applet/src/main/java/applet/GlobalUnsignedTXOutput.java +++ b/applet/src/main/java/applet/GlobalUnsignedTXOutput.java @@ -11,10 +11,18 @@ public class GlobalUnsignedTXOutput { short size = 0; void fill(short start){ - value_start = start; + value_start = start; // value has static size of 8 bytes script_size_start = (short) (start + 8); script_size = compactWeirdoInt(script_size_start); script_pub_key_start = (short) (script_size_start + byteSizeOfCWI(script_size)); size = (short) (8 + byteSizeOfCWI(script_size) + script_size); // easier to read and understand this way } + + void reset() { + value_start = -1; + script_size_start = -1; + script_size = -1; + script_pub_key_start = -1; + size = 0; + } } diff --git a/applet/src/main/java/applet/Key.java b/applet/src/main/java/applet/Key.java index 5919f49..e6e12cf 100644 --- a/applet/src/main/java/applet/Key.java +++ b/applet/src/main/java/applet/Key.java @@ -6,7 +6,7 @@ public class Key { public short start = -1; public short key_len = -1; public short key_len_bytes = 1; - public short key_type = -1; + public short key_type = -1; // in bips there is difference public void fill(short arrayIndex) { start = arrayIndex; diff --git a/applet/src/main/java/applet/MainApplet.java b/applet/src/main/java/applet/MainApplet.java index 3b48ecc..2e02abf 100755 --- a/applet/src/main/java/applet/MainApplet.java +++ b/applet/src/main/java/applet/MainApplet.java @@ -13,17 +13,18 @@ public class MainApplet extends Applet implements MultiSelectable { * class of all instructions and other hardcoded information */ - public PSBT psbt; + public static PSBT psbt; public static byte[][] additionalDataStorage; public static short[] dataStorageOffsets; public static byte[][] checkAgainstDataStorage; public static short[] checkAgainstDataStorageOffsets; public static byte[] PSBTdata; public static byte[] controlArray; - public static byte [] policy; - short transactionOffset; - short policyOffset; - short policyUploadLocked; // 0 locked, 1 - opened + public static byte[] policy; + public static byte[] totalOutput; + static short transactionOffset; + static short policyOffset; + static short policyUploadLocked; // 0 locked, 1 - opened //private byte[] data = JCSystem.makeTransientByteArray((short) (1024 * 10), // JCSystem.CLEAR_ON_DESELECT); @@ -43,6 +44,7 @@ public MainApplet(byte[] buffer, short offset, byte length) { PSBTdata = new byte[MAX_SIZE_OF_PSBT]; // to change PSBT max size change this constant policy = new byte[MAX_SIZE_OF_POLICY]; controlArray = new byte[AppletInstructions.PACKET_BUFFER_SIZE]; // historical array that is sent back to computer as confirmation + totalOutput = new byte[8]; controlArray[0] = 0; controlArray[1] = 1; controlArray[2] = 2; @@ -51,9 +53,9 @@ public MainApplet(byte[] buffer, short offset, byte length) { controlArray[5] = 5; controlArray[6] = 6; controlArray[7] = 7; - this.transactionOffset = 0; - this.policyOffset = 0; - this.policyUploadLocked = 0; + transactionOffset = 0; + policyOffset = 0; + policyUploadLocked = 0; random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM); @@ -76,16 +78,13 @@ public void process(APDU apdu) { if (ins == AppletInstructions.INS_REQUEST) { // TODO: return array size transactionOffset = 0; - psbt.reset(); // maybe arbitrary } if (ins == AppletInstructions.INS_UPLOAD) { - Util.arrayCopyNonAtomic(apduBuffer, ISO7816.OFFSET_CDATA, PSBTdata, transactionOffset, (short) (lc & 0xff)); transactionOffset += (short) (lc & 0xff); } if (ins == AppletInstructions.INS_FINISH) { - try { psbt.reset(); psbt.fill(); @@ -253,11 +252,35 @@ short validatePolicy(){ System.out.print("policy[stepcounter]: " + policy[stepCounter] + System.lineSeparator()); System.out.print("orSection: " + orSection + System.lineSeparator()); switch (policy[stepCounter]) { - case PolicyInstruction.minTotalOutput: - case PolicyInstruction.maxTotalOutput: - case PolicyInstruction.minOutputToTargetAddress: - case PolicyInstruction.maxOutputToTargetAddress: - case PolicyInstruction.minAmountofInputs: + case Policy.minTotalOutput: + if (Policy.validateTotalOutput(policy[stepCounter + 1], (short) 1)){ + orSection = 1; + } + stepCounter += 2; + break; + + case Policy.maxTotalOutput: + if (Policy.validateTotalOutput(policy[stepCounter + 1], (short) -1)){ + orSection = 1; + } + stepCounter += 2; + break; + + case Policy.minOutputWithSigScr: + if (Policy.validateValueOwSS((policy[stepCounter + 1]), (policy[stepCounter + 2]), (short) 1)) { //validate Value Output with Sign Script + orSection = 1; + } + stepCounter += 3; + break; + + case Policy.maxOutputWithSigScr: + if (Policy.validateValueOwSS((policy[stepCounter + 1]), (policy[stepCounter + 2]), (short) -1)) { + orSection = 1; + } + stepCounter += 3; + break; + + case Policy.minNumberofInputs: if (GlobalMap.PSBTversion == 0) { if (policy[stepCounter + 1] <= psbt.global_map.globalUnsignedTX.input_count) { orSection = 1; @@ -272,7 +295,7 @@ short validatePolicy(){ stepCounter += 2; break; - case PolicyInstruction.maxAmountofInputs: + case Policy.maxNumberofInputs: if (GlobalMap.PSBTversion == 0) { if (policy[stepCounter + 1] >= psbt.global_map.globalUnsignedTX.input_count) { orSection = 1; @@ -287,7 +310,7 @@ short validatePolicy(){ stepCounter += 2; break; - case PolicyInstruction.minAmountofOutputs: + case Policy.minNumberofOutputs: if (GlobalMap.PSBTversion == 0) { if (policy[stepCounter + 1] <= psbt.global_map.globalUnsignedTX.output_count) { orSection = 1; @@ -302,7 +325,7 @@ short validatePolicy(){ stepCounter += 2; break; - case PolicyInstruction.maxAmountofOutputs: + case Policy.maxNumberofOutputs: if (GlobalMap.PSBTversion == 0) { if (policy[stepCounter + 1] >= psbt.global_map.globalUnsignedTX.output_count) { orSection = 1; @@ -317,23 +340,24 @@ short validatePolicy(){ stepCounter += 2; break; - case PolicyInstruction.naiveTimeLapsed: // TODO delete - case PolicyInstruction.signedTmeLapse: - case PolicyInstruction.checkSecret: + case Policy.naiveTimeLapsed: // TODO delete + case Policy.signedTmeLapse: + case Policy.checkSecret: if ((Util.arrayCompare(additionalDataStorage[policy[stepCounter + 1]],(short) 0,checkAgainstDataStorage[policy[stepCounter + 1]],(short) 0, STORAGE_SIZE)) == 0) { + //does this compare little or big endian orSection = 1; } stepCounter += 2; break; - case PolicyInstruction.transactionVersion: + case Policy.transactionVersion: if (policy[stepCounter + 1] == GlobalMap.PSBTversion) { orSection = 1; } stepCounter += 2; break; - case PolicyInstruction.policyAnd: + case Policy.policyAnd: if (orSection == 0) { return validationReturnProcedure((short) 0); } @@ -355,7 +379,7 @@ boolean checkStorageUsage() { while (stepCounter < policyOffset) { System.out.print("policy[stepcounter]: " + policy[stepCounter] + System.lineSeparator()); switch (policy[stepCounter]) { - case PolicyInstruction.minTotalOutput: + case Policy.minTotalOutput: if (dataStorageOffsets[policy[stepCounter + 1]] == 0){ System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -364,7 +388,7 @@ boolean checkStorageUsage() { stepCounter += 2; break; - case PolicyInstruction.maxTotalOutput: + case Policy.maxTotalOutput: if (dataStorageOffsets[policy[stepCounter + 1]] == 0){ System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -373,7 +397,7 @@ boolean checkStorageUsage() { stepCounter += 2; break; - case PolicyInstruction.minOutputToTargetAddress: + case Policy.minOutputWithSigScr: if (dataStorageOffsets[policy[stepCounter + 1]] == 0 || dataStorageOffsets[policy[stepCounter + 2]] == 0){ System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -382,7 +406,7 @@ boolean checkStorageUsage() { stepCounter += 3; break; - case PolicyInstruction.maxOutputToTargetAddress: + case Policy.maxOutputWithSigScr: if (dataStorageOffsets[policy[stepCounter + 1]] == 0 || dataStorageOffsets[policy[stepCounter + 2]] == 0){ System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -391,20 +415,20 @@ boolean checkStorageUsage() { stepCounter += 3; break; - case PolicyInstruction.minAmountofInputs: + case Policy.minNumberofInputs: stepCounter += 2; break; - case PolicyInstruction.maxAmountofInputs: + case Policy.maxNumberofInputs: stepCounter += 2; break; - case PolicyInstruction.minAmountofOutputs: + case Policy.minNumberofOutputs: stepCounter += 2; break; - case PolicyInstruction.maxAmountofOutputs: + case Policy.maxNumberofOutputs: stepCounter += 2; break; - case PolicyInstruction.naiveTimeLapsed: + case Policy.naiveTimeLapsed: if (dataStorageOffsets[policy[stepCounter + 1]] == 0){ System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -413,7 +437,7 @@ boolean checkStorageUsage() { stepCounter += 2; break; - case PolicyInstruction.signedTmeLapse: + case Policy.signedTmeLapse: if (dataStorageOffsets[policy[stepCounter + 1]] == 0 || dataStorageOffsets[policy[stepCounter + 2]] == 0) { System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -422,7 +446,7 @@ boolean checkStorageUsage() { stepCounter += 3; break; - case PolicyInstruction.checkSecret: + case Policy.checkSecret: if (dataStorageOffsets[policy[stepCounter + 1]] == 0) { System.out.println("seems like unused storage in memory with pointer: " + policy[stepCounter + 1]); System.out.println("with PolicyInstruction: " + policy[stepCounter]); @@ -431,11 +455,11 @@ boolean checkStorageUsage() { stepCounter += 2; break; - case PolicyInstruction.transactionVersion: + case Policy.transactionVersion: stepCounter += 2; break; - case PolicyInstruction.policyAnd: + case Policy.policyAnd: stepCounter++; break; default: diff --git a/applet/src/main/java/applet/PSBT.java b/applet/src/main/java/applet/PSBT.java index f9bb1a1..e5bc728 100644 --- a/applet/src/main/java/applet/PSBT.java +++ b/applet/src/main/java/applet/PSBT.java @@ -1,6 +1,9 @@ package applet; +import java.util.Arrays; + import static applet.MainApplet.PSBTdata; +import static applet.MainApplet.totalOutput; public class PSBT { public static final short MAX_OF_IO_MAPS = 8; @@ -54,11 +57,26 @@ public void fill() throws Exception { byte_size++; current_output_map++; } - + Tools.getTotalOutput(); } public void reset() { + short i = 0; + global_map.reset(); + while (i < MAX_OF_IO_MAPS) { + input_maps[i].reset(); + output_maps[i].reset(); + i++; + } + + i = 0; + while (i < 8) { + MainApplet.totalOutput[i] = 0; + i++; + } + current_input_map = 0; + current_output_map = 0; byte_size = 0; } } diff --git a/applet/src/main/java/applet/Policy.java b/applet/src/main/java/applet/Policy.java new file mode 100644 index 0000000..b16b033 --- /dev/null +++ b/applet/src/main/java/applet/Policy.java @@ -0,0 +1,72 @@ +package applet; +import javacard.framework.Util; + +import java.util.Arrays; + +public class Policy { + public static final byte minTotalOutput = 0; + public static final byte maxTotalOutput = 1; + public static final byte minOutputWithSigScr = 2; + public static final byte maxOutputWithSigScr = 3; + public static final byte minNumberofInputs = 4; + public static final byte maxNumberofInputs = 5; + public static final byte minNumberofOutputs = 6; + public static final byte maxNumberofOutputs = 7; + public static final byte naiveTimeLapsed = 8; + public static final byte signedTmeLapse = 9; + public static final byte checkSecret = 10; + public static final byte transactionVersion = 12; + public static final byte policyAnd = 13; + + public static boolean validateTotalOutput(byte storageValue, short notRes) { + return ((Tools.littleEndianCompareArrays(MainApplet.additionalDataStorage[storageValue], (short) 0, MainApplet.totalOutput, + (short) 0, (short) 8)) != notRes); // notRes: min = 1, max = -1 + } + + public static boolean validateValueOwSS(byte storageValue, byte storageSigScr, short notRes) { + short sigScrStart = 0; + short valueStart = 0; + if (GlobalMap.PSBTversion == 0) { + short i = 0; + while (i < MainApplet.psbt.global_map.globalUnsignedTX.output_count) { + valueStart = MainApplet.psbt.global_map.globalUnsignedTX.outputs[i].value_start; + sigScrStart = MainApplet.psbt.global_map.globalUnsignedTX.outputs[i].script_pub_key_start; + if (checkItself(storageValue, valueStart, storageSigScr, sigScrStart, notRes)) { + return true; + } + i++; + } + } + + if (GlobalMap.PSBTversion == 2) { + short i = 0; + short keytype; + while (i < MainApplet.psbt.global_map.output_maps_total) { + short key_pair = 0; + while (key_pair < MainApplet.psbt.output_maps[i].current_key_pair) { + keytype = MainApplet.psbt.output_maps[i].key_pairs[key_pair].key.key_type; + if (keytype == AppletInstructions.PSBT_OUT_AMOUNT) { + valueStart = MainApplet.psbt.output_maps[i].key_pairs[key_pair].value.start; + } + if (keytype == AppletInstructions.PSBT_OUT_SCRIPT) { + sigScrStart = MainApplet.psbt.output_maps[i].key_pairs[key_pair].value.start; + } + key_pair++; + } + if (checkItself(storageValue, valueStart, storageSigScr, sigScrStart, notRes)) { + return true; + } + i++; + } + } + return false; + } + + static boolean checkItself(byte storageValue, short valueStart, byte storageScrSig, short sigScrStart, short notRes) { + return ((Tools.littleEndianCompareArrays(MainApplet.additionalDataStorage[storageValue], (short) 0, MainApplet.PSBTdata, + valueStart, (short) (MainApplet.dataStorageOffsets[storageValue] & 0xFF)) != notRes) // min = 1, max = -1 + && + (Util.arrayCompare(MainApplet.additionalDataStorage[storageScrSig], (short) 0, + MainApplet.PSBTdata, sigScrStart, (short) 8) == 0)); + } +} diff --git a/applet/src/main/java/applet/PolicyInstruction.java b/applet/src/main/java/applet/PolicyInstruction.java deleted file mode 100644 index a7abcbd..0000000 --- a/applet/src/main/java/applet/PolicyInstruction.java +++ /dev/null @@ -1,17 +0,0 @@ -package applet; - -public class PolicyInstruction { - public static final byte minTotalOutput = 0; - public static final byte maxTotalOutput = 1; - public static final byte minOutputToTargetAddress = 2; - public static final byte maxOutputToTargetAddress = 3; - public static final byte minAmountofInputs = 4; - public static final byte maxAmountofInputs = 5; - public static final byte minAmountofOutputs = 6; - public static final byte maxAmountofOutputs = 7; - public static final byte naiveTimeLapsed = 8; - public static final byte signedTmeLapse = 9; - public static final byte checkSecret = 10; - public static final byte transactionVersion = 12; - public static final byte policyAnd = 13; -} diff --git a/applet/src/main/java/applet/Tools.java b/applet/src/main/java/applet/Tools.java index e7e9459..eb92c51 100644 --- a/applet/src/main/java/applet/Tools.java +++ b/applet/src/main/java/applet/Tools.java @@ -1,6 +1,6 @@ package applet; -import static applet.MainApplet.PSBTdata; +import static applet.MainApplet.*; public class Tools { @@ -36,4 +36,50 @@ public static short byteSizeOfCWI(short CWI) { } return 3; } + + public static short littleEndianCompareArrays(byte[] ar1, short start1, byte[] ar2, short start2, short length) { + short i = 1; + while (i <= length) { // this could be simplified + if ((ar1[(short) (start1 + length - i)] & 0xFF) > (ar2[(short) (start2 + length - i)] & 0xFF)) { return 1; } + if ((ar1[(short) (start1 + length - i)] & 0xFF) < (ar2[(short) (start2 + length - i)] & 0xFF)) { return -1; } + i++; + } + return 0; + } + public static void getTotalOutput() { + short i = 0; + if (GlobalMap.PSBTversion == 0) { + while (i < MainApplet.psbt.global_map.globalUnsignedTX.output_count) { + satoshisPlusLE(totalOutput, PSBTdata, MainApplet.psbt.global_map.globalUnsignedTX.outputs[i].value_start); + i++; + } + } + if (GlobalMap.PSBTversion == 2) { + short keytype; + while (i < MainApplet.psbt.global_map.output_maps_total) { + short key_pair = 0; + while (key_pair < MainApplet.psbt.output_maps[i].current_key_pair) { + keytype = MainApplet.psbt.output_maps[i].key_pairs[key_pair].key.key_type; + if (keytype == AppletInstructions.PSBT_OUT_AMOUNT) { + satoshisPlusLE(totalOutput, PSBTdata, MainApplet.psbt.output_maps[i].key_pairs[key_pair].value.start); + } + key_pair++; + } + i++; + } + } + } + + public static void satoshisPlusLE(byte[] res, byte[] plusArray, short startArray){ // my future self, keep in mind this is very targeted function + short i = 7; + while (i >= 0) { + if ((short) (((res[i] & 0xff) + (plusArray[(short) (startArray + i)] & 0xff))) > 0xff) { + res[i] = (byte) ((res[i] & 0xff) + (plusArray[(short) (startArray + i)] & 0xff)); + res[i - 1]++; // this should not overflow considering maxSatoshis = "000040075AF07507"; + } else { + res[i] = (byte) ((res[i] & 0xff) + (plusArray[(short) (startArray + i)] & 0xff)); + } + i--; + } + } } diff --git a/applet/src/main/java/main/Run.java b/applet/src/main/java/main/Run.java index fadf2b8..8689953 100644 --- a/applet/src/main/java/main/Run.java +++ b/applet/src/main/java/main/Run.java @@ -20,5 +20,4 @@ public static void main(String[] args) throws Exception { ap.UploadTransaction(); ap.DownloadDebug(); } - } \ No newline at end of file diff --git a/applet/src/test/java/tests/AppletTest.java b/applet/src/test/java/tests/AppletTest.java index 5e9e0b4..6287177 100755 --- a/applet/src/test/java/tests/AppletTest.java +++ b/applet/src/test/java/tests/AppletTest.java @@ -22,6 +22,8 @@ * * @author xsvenda, Dusan Klinec (ph4r05) */ + + public class AppletTest extends BaseTest { public AppletTest() { // Change card type here if you want to use physical card @@ -85,6 +87,34 @@ public void hel() throws Exception { System.out.print(Arrays.toString(responseAPDU.getBytes()) + System.lineSeparator()); System.out.print("Test hell: passed" + System.lineSeparator()); } + + @Test + void littleEndianCompareTest() throws Exception { + byte[] ar1 = new byte[4]; + byte[] ar2 = new byte[4]; + int i = 0; + while (i < 4) { + ar1[i] = 0; + ar2[i] = 0; + i++; + } + assertEquals(0, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 4)); + ar1[0] = (byte) 1; + assertEquals(1, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 4)); + assertEquals(0, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 0)); + assertEquals(0, applet.Tools.littleEndianCompareArrays(ar1, (short) 1, ar2, (short) 0, (short) 3)); + ar2[3] = (byte) 1; + assertEquals(1, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 3)); + ar2[0] = (byte) 2; + assertEquals(-1, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 3)); + ar1[3] = (byte) 2; + assertEquals(1, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 4)); + ar2[3] = (byte) 2; + assertEquals(-1, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 4)); + ar2[3] = (byte) 200; + assertEquals(-1, applet.Tools.littleEndianCompareArrays(ar1, (short) 0, ar2, (short) 0, (short) 4)); + } + @Test void simpleDeletion_OfAccessibleSpace_applet_test() throws Exception { Download download = new Download(); @@ -147,6 +177,103 @@ void simpleDeletion_OfAccessibleSpace_applet_test() throws Exception { Assertions.assertEquals(1, download.downloadValidation(manager)); Assertions.assertEquals(0, download.downloadValidation(manager)); } + @Test + void applet_max_total_outputs_test() throws Exception { + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value = fromHex("ffffffffffffffff"); + byte[] policy = fromHex("0100"); // policy checks min total output + + upload.sendData(value, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager) ); + } + + @Test + void applet_max_total_outputs_test2() throws Exception { + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value = fromHex("0000000000000000"); + byte[] policy = fromHex("0100"); // policy checks min total output + + upload.sendData(value, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager) ); + } + + @Test + void applet_min_total_outputs_test2() throws Exception { + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value = fromHex("0fffffffffffffff"); + byte[] policy = fromHex("0000"); // policy checks min total output + + upload.sendData(value, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager) ); + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager) ); + } + + @Test + void applet_min_total_outputs_test() throws Exception { + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value = fromHex("1000000000000000"); + byte[] policy = fromHex("0000"); // policy checks min total output + + upload.sendData(value, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager) ); + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager) ); + } + + @Test + void applet_exact_total_output_test() throws Exception { + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value = fromHex("ee5fea0b00000000"); // used sparrow and random online convertor + byte[] policy = fromHex("00000d0100"); // policy checks min total output + + upload.sendData(value, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager) ); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager) ); + + } @Test void policy_not_using_storage_test1() throws Exception { @@ -169,44 +296,197 @@ void policy_not_using_storage_test2() throws Exception { } @Test - void simple_applet_test() throws Exception { + void applet_two_exact_outputs_wSS_test() throws Exception { //OtTA stands for Output with Script Signature Download download = new Download(); Upload upload = new Upload(); CardManager manager = connect(); byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value1 = fromHex("603bea0b00000000"); + byte[] scriptSig1 = fromHex("76a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac"); + + byte[] value2 = fromHex("8e24000000000000"); + byte[] scriptSig2 = fromHex("76a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac"); + + byte[] policy = fromHex("0200010d0300010d0202030d030203"); // policy checks exact output value with ScriptSig + + upload.sendData(value1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + upload.sendData(value2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); + upload.sendData(scriptSig2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 3, (byte) 0, manager); + + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); - byte[] policy = fromHex("0a000d04010d05010d0a00"); // policy checks one secret and exactly one input and psbt version 0 - byte[] secret = fromHex("01020304050102030405"); - System.out.print(Arrays.toString(download.downloadPolicy(manager)) + "this is policy\n"); - byte additionalDataSequence = 0; - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager) ); + } + + @Test + void applet_maxOwSS_test3() throws Exception { //OtTA stands for Output with Script Signature + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + byte[] value1 = fromHex("0000000000000000"); + byte[] scriptSig1 = fromHex("76a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac"); + + byte[] policy = fromHex("030001"); // policy checks min output value with ScriptSig, addition: + "0d" + "030001" + + upload.sendData(value1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); + } + + @Test + void applet_maxOwSS_test1() throws Exception { //OtTA stands for Output with Script Signature + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value1 = fromHex("603bea0b00000000"); + byte[] scriptSig1 = fromHex("76a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac"); + + byte[] policy = fromHex("030001"); // policy checks min output value with ScriptSig, addition: + "0d" + "030001" + + upload.sendData(value1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); - System.out.print(Arrays.toString(download.downloadPolicy(manager)) + "this is policy\n"); + Assertions.assertEquals(0, download.downloadValidation(manager)); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager)); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); + } + + @Test + void applet_maxOwSS_test2() throws Exception { //OtTA stands for Output with Script Signature + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + byte[] value1 = fromHex("ffffffffffffffff"); + byte[] scriptSig1 = fromHex("76a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac"); + + byte[] policy = fromHex("030001"); // policy checks min output value with ScriptSig, addition: + "0d" + "030001" + upload.sendData(value1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager)); + } + + @Test + void applet_minOwSS_test1() throws Exception { //OtTA stands for Output with Script Signature + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value1 = fromHex("603bea0b00000000"); + byte[] scriptSig1 = fromHex("76a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac"); + + byte[] policy = fromHex("020001"); // policy checks min output value with ScriptSig, addition: + "0d" + "030001" + + upload.sendData(value1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); Assertions.assertEquals(0, download.downloadValidation(manager)); - byte checkAgainstDataSequence = 0; - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager)); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); + } + @Test + void applet_minOwSS_test2() throws Exception { //OtTA stands for Output with Script Signature + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] value2 = fromHex("8e24000000000000"); + byte[] scriptSig2 = fromHex("76a9146f4620b553fa095e721b9ee0efe9fa039cca459788ac"); + + // those values are taken directly from sparrow from transaction2 + + byte[] policy = fromHex("020001"); // policy checks min output value with ScriptSig, addition: + "0d" + "030001" + + upload.sendData(value2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); Assertions.assertEquals(1, download.downloadValidation(manager) ); + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); - System.out.print("The result of validation is: " + download.downloadValidation(manager) + System.lineSeparator()); + Assertions.assertEquals(0, download.downloadValidation(manager)); + } + @Test + void applet_minOwSS_test3() throws Exception { //OtTA stands for Output with Script Signature + Download download = new Download(); + Upload upload = new Upload(); + CardManager manager = connect(); + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + byte[] transaction2 = fromHex(TransactionsImported.validTransaction2); + + byte[] minvalue = fromHex("0000000000000000"); + byte[] scriptSig1 = fromHex("76a914768a40bbd740cbe81d988e71de2a4d5c71396b1d88ac"); + + byte[] policy = fromHex("020001"); // policy checks min output value with ScriptSig, addition: + "0d" + "030001" + + upload.sendData(minvalue, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(scriptSig1, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + + upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); + + upload.sendData(transaction2, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(1, download.downloadValidation(manager)); + + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + Assertions.assertEquals(0, download.downloadValidation(manager)); } @Test - void applet_live_through_with_transaction1() throws Exception { + void simple_applet_test() throws Exception { Download download = new Download(); Upload upload = new Upload(); CardManager manager = connect(); byte[] transaction = fromHex(TransactionsImported.validTransaction1); upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); - assert download.downloadNumOfInp(manager) == 1; - assert download.downloadNumOfOut(manager) == 2; + byte[] policy = fromHex("0a000d04010d05010d0a00"); // policy checks one secret and exactly one input and psbt version 0 byte[] secret = fromHex("01020304050102030405"); System.out.print(Arrays.toString(download.downloadPolicy(manager)) + "this is policy\n"); @@ -226,66 +506,53 @@ void applet_live_through_with_transaction1() throws Exception { Assertions.assertEquals(1, download.downloadValidation(manager) ); upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); System.out.print("The result of validation is: " + download.downloadValidation(manager) + System.lineSeparator()); + } @Test - void applet_live_through2() throws Exception { + void applet_live_through_with_transaction1() throws Exception { Download download = new Download(); Upload upload = new Upload(); CardManager manager = connect(); - byte[] policy = fromHex("0a000d0a010d0a02"); // policy checks three secret - + byte[] transaction = fromHex(TransactionsImported.validTransaction1); + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + assert download.downloadNumOfInp(manager) == 1; + assert download.downloadNumOfOut(manager) == 2; + byte[] policy = fromHex("0a000d04010d05010d0a00"); // policy checks one secret and exactly one input and psbt version 0 byte[] secret = fromHex("01020304050102030405"); - byte[] secret2 = fromHex("11111111111111111111"); - byte[] secret3 = fromHex("33333333333102030405"); + System.out.print(Arrays.toString(download.downloadPolicy(manager)) + "this is policy\n"); byte additionalDataSequence = 0; - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); - additionalDataSequence++; - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); - additionalDataSequence++; - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); - Assertions.assertEquals(0, download.downloadValidation(manager)); - - byte checkAgainstDataSequence = 0; - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - checkAgainstDataSequence++; - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - //checkAgainstDataSequence++; // secret num3 writes itself on shelf of secret2 - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + System.out.print(Arrays.toString(download.downloadPolicy(manager)) + "this is policy\n"); Assertions.assertEquals(0, download.downloadValidation(manager)); - checkAgainstDataSequence = 0; + byte checkAgainstDataSequence = 0; upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - checkAgainstDataSequence++; - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - checkAgainstDataSequence++; - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); + Assertions.assertEquals(1, download.downloadValidation(manager) ); + upload.sendData(transaction, (byte) AppletInstructions.CLASS_PSBT_UPLOAD, manager); + System.out.print("The result of validation is: " + download.downloadValidation(manager) + System.lineSeparator()); } + @Test - void applet_live_through3() throws Exception { + void applet_2_out_of_3_secret_test() throws Exception { Download download = new Download(); Upload upload = new Upload(); CardManager manager = connect(); - byte[] policy = fromHex("0a00"+"0a01"+"0b"+"0a01"+"0a02"+"0b"+"0a00"+"0a02"); // policy for 2-3 secrets + byte[] policy = fromHex("0a00"+"0a01"+"0d"+"0a01"+"0a02"+"0d"+"0a00"+"0a02"); // policy for 2-3 secrets byte[] secret = fromHex("01020304050102030405"); byte[] secret2 = fromHex("11111111111111111111"); byte[] secret3 = fromHex("33333333333102030405"); - byte additionalDataSequence = 0; - - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); - additionalDataSequence++; - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); - additionalDataSequence++; - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); + upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); @@ -295,47 +562,30 @@ void applet_live_through3() throws Exception { Assertions.assertEquals(0, download.downloadValidation(manager)); upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); + Assertions.assertEquals(0, download.downloadValidation(manager)); upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); - } - - @Test - void applet_live_through4() throws Exception { - Download download = new Download(); - Upload upload = new Upload(); - CardManager manager = connect(); - byte[] policy = fromHex("0a00"+"0a01"+"0b"+"0a01"+"0a02"+"0b"+"0a00"+"0a02"); // policy for 2-3 secrets - - byte[] secret = fromHex("01020304050102030405"); - byte[] secret2 = fromHex("11111111111111111111"); - byte[] secret3 = fromHex("33333333333102030405"); - byte additionalDataSequence = 0; + Assertions.assertEquals(0, download.downloadValidation(manager)); - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); - additionalDataSequence++; - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); - additionalDataSequence++; - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, additionalDataSequence, (byte) 0, manager); + upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + Assertions.assertEquals(1, download.downloadValidation(manager)); - upload.sendData(policy, (byte) AppletInstructions.CLASS_POLICY_UPLOAD, manager); + upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); + upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); + Assertions.assertEquals(1, download.downloadValidation(manager)); - byte checkAgainstDataSequence = 0; - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - checkAgainstDataSequence++; - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - checkAgainstDataSequence++; - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); + upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); + upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); Assertions.assertEquals(1, download.downloadValidation(manager)); } @Test - void applet_live_through5() throws Exception { + void applet_secret() throws Exception { Download download = new Download(); Upload upload = new Upload(); CardManager manager = connect(); - byte[] policy = fromHex("0a00"+"0a01"+"0b"+"0a01"+"0a02"+"0b"+"0a00"+"0a02"); // policy for 2-3 secrets + byte[] policy = fromHex("0a000d0a010d0a02"); // policy checks three secret byte[] secret = fromHex("01020304050102030405"); byte[] secret2 = fromHex("11111111111111111111"); @@ -353,35 +603,25 @@ void applet_live_through5() throws Exception { Assertions.assertEquals(0, download.downloadValidation(manager)); byte checkAgainstDataSequence = 0; + upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); + checkAgainstDataSequence++; + upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); + //checkAgainstDataSequence++; // secret num3 writes itself on shelf of secret2 + upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); Assertions.assertEquals(0, download.downloadValidation(manager)); - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); - - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); - + checkAgainstDataSequence = 0; upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); checkAgainstDataSequence++; upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); checkAgainstDataSequence++; upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, checkAgainstDataSequence, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); - upload.sendData(secret, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 0, (byte) 0, manager); - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); - upload.sendData(secret2, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 1, (byte) 0, manager); - upload.sendData(secret3, (byte) AppletInstructions.CLASS_ADDITIONAL_DATA_UPLOAD, (byte) 2, (byte) 0, manager); - Assertions.assertEquals(1, download.downloadValidation(manager)); } - @Test + + //@Test public void policy1() throws Exception { Download download = new Download(); Upload upload = new Upload();