package de.persosim.simulator.tlv; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import org.junit.Test; import de.persosim.simulator.exception.ISO7816Exception; import de.persosim.simulator.utils.Utils; public class TlvLengthTest { /** * Positive test case: Extract 1 byte length from a range out of a larger * byte array. The range is smaller than the length of the byte array and * larger than the minimum range required for the respective length */ @Test public void testConstructor_1ByteLengthLargeRange() { /* set arbitrary but valid 1-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x0A }; /* dummy data to prepend */ byte[] byteArrayPre = new byte[] { (byte) 0xFF, (byte) 0xFF }; /* dummy data to append */ byte[] byteArrayPost = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; /* build actual byte array */ byte[] byteArray = Utils.concatByteArrays(byteArrayPre, lengthExpected, byteArrayPost); TlvLength lengthExtracted = new TlvLength(byteArray, byteArrayPre.length, byteArray.length); assertArrayEquals("Equals expected byte array representation", lengthExtracted.toByteArray(), lengthExpected); } /** * Positive test case: Extract 1 byte length from a range out of a larger * byte array. The range is smaller than the length of the byte array and * matches the minimum range required for the respective length */ @Test public void testConstructor_1ByteLengthMinRange() { /* set arbitrary but valid 1-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x0A }; /* dummy data to prepend */ byte[] byteArrayPre = new byte[] { (byte) 0xFF, (byte) 0xFF }; /* dummy data to append */ byte[] byteArrayPost = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; /* build actual byte array */ byte[] byteArray = Utils.concatByteArrays(byteArrayPre, lengthExpected, byteArrayPost); TlvLength lengthExtracted = new TlvLength(byteArray, byteArrayPre.length, byteArrayPre.length + lengthExpected.length); assertArrayEquals("Equals expected byte array representation", lengthExtracted.toByteArray(), lengthExpected); } /** * Positive test case: Extract 2 byte length from a range out of a larger * byte array. The range is smaller than the length of the byte array and * matches the minimum range required for the respective length */ @Test public void testConstructor_2ByteLength() { /* set arbitrary but valid 2-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x81, (byte) 0x88 }; /* dummy data to prepend */ byte[] byteArrayPre = new byte[] { (byte) 0xFF, (byte) 0xFF }; /* dummy data to append */ byte[] byteArrayPost = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; /* build actual byte array */ byte[] byteArray = Utils.concatByteArrays(byteArrayPre, lengthExpected, byteArrayPost); TlvLength lengthExtracted = new TlvLength(byteArray, byteArrayPre.length, byteArrayPre.length + lengthExpected.length); assertArrayEquals("Equals expected byte array representation", lengthExtracted.toByteArray(), lengthExpected); } /** * Negative test case: Extract 2 byte length from a range out of a larger * byte array. The range is smaller than the length of the byte array and is * 1 byte smaller than the minimum range required for the respective length */ @Test(expected = ISO7816Exception.class) public void testConstructor_2ByteLengthTooShortRange() { /* set arbitrary but valid 2-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x81, (byte) 0x88 }; /* dummy data to prepend */ byte[] byteArrayPre = new byte[] { (byte) 0xFF, (byte) 0xFF }; /* dummy data to append */ byte[] byteArrayPost = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; /* build actual byte array */ byte[] byteArray = Utils.concatByteArrays(byteArrayPre, lengthExpected, byteArrayPost); new TlvLength(byteArray, byteArrayPre.length, byteArrayPre.length + lengthExpected.length - 1); } /** * Positive test case: Extract 5 byte length from a range out of a larger * byte array. The range is smaller than the length of the byte array and * matches the minimum range required for the respective length */ @Test public void testConstructor_5ByteLength() { /* set arbitrary but valid 5-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x84, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; /* dummy data to prepend */ byte[] byteArrayPre = new byte[] { (byte) 0xFF, (byte) 0xFF }; /* dummy data to append */ byte[] byteArrayPost = new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }; /* build actual byte array */ byte[] byteArray = Utils.concatByteArrays(byteArrayPre, lengthExpected, byteArrayPost); TlvLength lengthExtracted = new TlvLength(byteArray, byteArrayPre.length, byteArrayPre.length + lengthExpected.length); assertArrayEquals("Equals expected byte array representation", lengthExtracted.toByteArray(), lengthExpected); } /** * Negative test case: First byte of Length field must not be 0x80 * This value is disallowed by ISO7816 */ @Test(expected = ISO7816Exception.class) public void testConstructor_FirstByte80() { /* set arbitrary length with invalid length encoding */ byte[] lengthExpected = new byte[] { (byte) 0x80, (byte) 0x01, (byte) 0x00 }; new TlvLength(lengthExpected); } /** * Negative test case: First byte of Length field must not be 0x85 to 0xFF * These values are disallowed by ISO7816 */ @Test(expected = ISO7816Exception.class) public void testConstructor_FirstByte85() { byte[] lengthExpected = new byte[] { (byte) 0x85, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; new TlvLength(lengthExpected); } /** * Positive test case: Return indicated length */ @Test public void testGetIndicatedLength() { byte[] lengthExpected = new byte[] { (byte) 0x81, (byte) 0x01 }; TlvLength lengthExtracted = new TlvLength(lengthExpected); assertEquals("Equals indicated length", lengthExtracted.getIndicatedLength(), 1); } /** * Positive test case: Whether encoding is BER compliant */ @Test public void testIsValidBerEncoding_NonDer() { /* set arbitrary but valid 5-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x81, (byte) 0x01 }; TlvLength lengthExtracted = new TlvLength(lengthExpected); assertEquals("Equals BER encoding", lengthExtracted.isValidBerEncoding(), true); } /** * Positive test case: Check a BER 5-byte length for BER validity */ @Test public void testIsValidBerEncoding() { /* set arbitrary but valid 1-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x7E }; TlvLength lengthExtracted = new TlvLength(lengthExpected); assertEquals("Equals BER encoding", lengthExtracted.isValidBerEncoding(), true); } /** * Negative test case: Check a BER but non-DER encoded 5-byte length for DER * validity */ @Test public void testIsValidDerEncoding_BerNonDer() { /* set arbitrary but valid 5-byte BER but non-DER length */ byte[] lengthExpected = new byte[] { (byte) 0x84, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01 }; TlvLength lengthExtracted = new TlvLength(lengthExpected); assertEquals("Equals DER encoding", lengthExtracted.isValidDerEncoding(), false); } /** * Positive test case: Check DER encoded 1-byte length for DER validity */ @Test public void testIsValidDerEncoding() { /* set arbitrary but valid 1-byte DER encoded length */ byte[] lengthExpected = new byte[] { (byte) 0x7E }; TlvLength lengthExtracted = new TlvLength(lengthExpected); assertEquals("Equals DER encoding", lengthExtracted.isValidDerEncoding(), true); } //TODO missing testcase tesIsValidDerEncoding_2ByteLength /** * Positive test case: Check DER encoded 2-byte length for DER validity */ @Test public void testIsValidDerEncoding2byte() { /* set arbitrary but valid 1-byte DER encoded length */ byte[] lengthExpected = new byte[] { (byte) 0x7E, (byte) 0x7E}; TlvLength lengthExtracted = new TlvLength(lengthExpected); assertEquals("Equals DER encoding", lengthExtracted.isValidDerEncoding(), true); } /** * Positive test case: check equals for same object and same constructor * arguments */ @Test public void testEquals() { /* set arbitrary but valid 1-byte length */ byte[] lengthExpected = new byte[] { (byte) 0x7E }; TlvLength lengthFieldExpected1 = new TlvLength(lengthExpected); TlvLength lengthFieldExpected2 = new TlvLength(lengthExpected); assertEquals("Equals self", lengthFieldExpected1, lengthFieldExpected1); assertEquals("Equals same constructor arguments", lengthFieldExpected1, lengthFieldExpected2); } /** * Negative test case: check equals for different constructor arguments */ @Test public void testEquals_DifferentValue() { /* set arbitrary but valid 1-byte length */ byte[] lengthExpected1 = new byte[] { (byte) 0x7E }; /* set arbitrary but valid 1-byte length */ byte[] lengthExpected2 = new byte[] { (byte) 0x7D }; TlvLength lengthFieldExpected1 = new TlvLength(lengthExpected1); TlvLength lengthFieldExpected2 = new TlvLength(lengthExpected2); assertNotEquals(lengthFieldExpected1, lengthFieldExpected2); } /** * Negative test case: check equals for different BER encodings of the same * length */ @Test public void testEquals_DifferentEncoding() { /* set arbitrary but valid 1-byte length */ byte[] lengthExpected1 = new byte[] { (byte) 0x01 }; /* set arbitrary but valid 2-byte length with same BER encoded length */ byte[] lengthExpected2 = new byte[] { (byte) 0x81, (byte) 0x01 }; TlvLength lengthFieldExpected1 = new TlvLength(lengthExpected1); TlvLength lengthFieldExpected2 = new TlvLength(lengthExpected2); assertEquals(lengthFieldExpected1.equals(lengthFieldExpected2), false); } /** * Negative test case: check for lengthFieldInput = null. */ @Test(expected=NullPointerException.class) public void lengthFieldInputnull() { TlvLength lengthFieldInput = new TlvLength(2); byte[] testarray = null; lengthFieldInput.setLengthField(testarray, 1, 2); } /** * Negative test case: check for minOffset smaller then zero. */ @Test(expected=IllegalArgumentException.class) public void minoffsetsmallerthenzero() { TlvLength lengthFieldInput = new TlvLength(2); byte[] testarray = new byte[4]; lengthFieldInput.setLengthField(testarray, -9, 2); } /** * Negative test case: check for minOffset bigger then maxOffset. */ @Test(expected=IllegalArgumentException.class) public void minoffsetbiggerthenmaxoffset() { TlvLength lengthFieldInput = new TlvLength(2); byte[] testarray = new byte[4]; lengthFieldInput.setLengthField(testarray, 4, 3); } /** * Negative test case: check for lengthFieldInput.length bigger then maxoffset */ @Test(expected=IllegalArgumentException.class) public void maxoffsetbiggerthenlengthfieldinput() { TlvLength lengthFieldInput = new TlvLength(2); byte[] testarray = new byte[4]; lengthFieldInput.setLengthField(testarray, 2, 5); } /** * Negative test case: check for minOffset equals maxOffset. */ @Test(expected=IllegalArgumentException.class) public void minoffsetequalsmaxoffset() { TlvLength lengthFieldInput = new TlvLength(2); byte[] testarray = new byte[4]; lengthFieldInput.setLengthField(testarray, 4, 4); } /** * Negative test case: check for lengthfieldinput is zero. */ @Test(expected=NullPointerException.class) public void forcelengthfieldinputiszero() { TlvLength tlvlength = new TlvLength(2); byte[] lengthFieldInput = null; tlvlength.forceLengthField(lengthFieldInput); } /** * Negative test case: check for lengthfieldinput is zero. */ @Test(expected=NullPointerException.class) public void indicatedLengthsmallerthenzero() { int i = -1; TlvLength.getLengthEncoding(i); } }