github.com/zondax/ledger-go@v0.14.3/apduWrapper_test.go (about) 1 /******************************************************************************* 2 * (c) 2018 - 2022 ZondaX AG 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ********************************************************************************/ 16 17 package ledger_go 18 19 import ( 20 "bytes" 21 "math" 22 "testing" 23 "unsafe" 24 25 "github.com/stretchr/testify/assert" 26 ) 27 28 func Test_SerializePacket_EmptyCommand(t *testing.T) { 29 var command = make([]byte, 1) 30 31 _, _, err := SerializePacket(0x0101, command, 64, 0) 32 assert.Nil(t, err, "Commands smaller than 3 bytes should return error") 33 } 34 35 func Test_SerializePacket_PacketSize(t *testing.T) { 36 37 var packetSize = 64 38 type header struct { 39 channel uint16 40 tag uint8 41 sequenceIdx uint16 42 commandLen uint16 43 } 44 45 h := header{channel: 0x0101, tag: 0x05, sequenceIdx: 0, commandLen: 32} 46 47 var command = make([]byte, h.commandLen) 48 49 result, _, _ := SerializePacket( 50 h.channel, 51 command, 52 packetSize, 53 h.sequenceIdx) 54 55 assert.Equal(t, len(result), packetSize, "Packet size is wrong") 56 } 57 58 func Test_SerializePacket_Header(t *testing.T) { 59 60 var packetSize = 64 61 type header struct { 62 channel uint16 63 tag uint8 64 sequenceIdx uint16 65 commandLen uint16 66 } 67 68 h := header{channel: 0x0101, tag: 0x05, sequenceIdx: 0, commandLen: 32} 69 70 var command = make([]byte, h.commandLen) 71 72 result, _, _ := SerializePacket( 73 h.channel, 74 command, 75 packetSize, 76 h.sequenceIdx) 77 78 assert.Equal(t, codec.Uint16(result), h.channel, "Channel not properly serialized") 79 assert.Equal(t, result[2], h.tag, "Tag not properly serialized") 80 assert.Equal(t, codec.Uint16(result[3:]), h.sequenceIdx, "SequenceIdx not properly serialized") 81 assert.Equal(t, codec.Uint16(result[5:]), h.commandLen, "Command len not properly serialized") 82 } 83 84 func Test_SerializePacket_Offset(t *testing.T) { 85 86 var packetSize = 64 87 type header struct { 88 channel uint16 89 tag uint8 90 sequenceIdx uint16 91 commandLen uint16 92 } 93 94 h := header{channel: 0x0101, tag: 0x05, sequenceIdx: 0, commandLen: 100} 95 96 var command = make([]byte, h.commandLen) 97 98 _, offset, _ := SerializePacket( 99 h.channel, 100 command, 101 packetSize, 102 h.sequenceIdx) 103 104 assert.Equal(t, packetSize-int(unsafe.Sizeof(h))+1, offset, "Wrong offset returned. Offset must point to the next command byte that needs to be packetized.") 105 } 106 107 func Test_WrapCommandAPDU_NumberOfPackets(t *testing.T) { 108 109 var packetSize = 64 110 type firstHeader struct { 111 channel uint16 112 sequenceIdx uint16 113 commandLen uint16 114 tag uint8 115 } 116 117 h1 := firstHeader{channel: 0x0101, tag: 0x05, sequenceIdx: 0, commandLen: 100} 118 119 var command = make([]byte, h1.commandLen) 120 121 result, _ := WrapCommandAPDU( 122 h1.channel, 123 command, 124 packetSize) 125 126 assert.Equal(t, packetSize*2, len(result), "Result buffer size is not correct") 127 } 128 129 func Test_WrapCommandAPDU_CheckHeaders(t *testing.T) { 130 131 var packetSize = 64 132 type firstHeader struct { 133 channel uint16 134 sequenceIdx uint16 135 commandLen uint16 136 tag uint8 137 } 138 139 h1 := firstHeader{channel: 0x0101, tag: 0x05, sequenceIdx: 0, commandLen: 100} 140 141 var command = make([]byte, h1.commandLen) 142 143 result, _ := WrapCommandAPDU( 144 h1.channel, 145 command, 146 packetSize) 147 148 assert.Equal(t, h1.channel, codec.Uint16(result), "Channel not properly serialized") 149 assert.Equal(t, h1.tag, result[2], "Tag not properly serialized") 150 assert.Equal(t, 0, int(codec.Uint16(result[3:])), "SequenceIdx not properly serialized") 151 assert.Equal(t, int(h1.commandLen), int(codec.Uint16(result[5:])), "Command len not properly serialized") 152 153 var offsetOfSecondPacket = packetSize 154 assert.Equal(t, h1.channel, codec.Uint16(result[offsetOfSecondPacket:]), "Channel not properly serialized") 155 assert.Equal(t, h1.tag, result[offsetOfSecondPacket+2], "Tag not properly serialized") 156 assert.Equal(t, 1, int(codec.Uint16(result[offsetOfSecondPacket+3:])), "SequenceIdx not properly serialized") 157 } 158 159 func Test_WrapCommandAPDU_CheckData(t *testing.T) { 160 161 var packetSize = 64 162 type firstHeader struct { 163 channel uint16 164 sequenceIdx uint16 165 commandLen uint16 166 tag uint8 167 } 168 169 h1 := firstHeader{channel: 0x0101, tag: 0x05, sequenceIdx: 0, commandLen: 200} 170 171 var command = make([]byte, h1.commandLen) 172 173 for i := range command { 174 command[i] = byte(i % 256) 175 } 176 177 result, _ := WrapCommandAPDU( 178 h1.channel, 179 command, 180 packetSize) 181 182 // Check data in the first packet 183 assert.True(t, bytes.Equal(command[0:64-7], result[7:64])) 184 185 result = result[64:] 186 command = command[64-7:] 187 // Check data in the second packet 188 assert.True(t, bytes.Equal(command[0:64-5], result[5:64])) 189 190 result = result[64:] 191 command = command[64-5:] 192 // Check data in the third packet 193 assert.True(t, bytes.Equal(command[0:64-5], result[5:64])) 194 195 result = result[64:] 196 command = command[64-5:] 197 198 // Check data in the last packet 199 assert.True(t, bytes.Equal(command[0:], result[5:5+len(command)])) 200 201 // The remaining bytes in the result should be zeros 202 result = result[5+len(command):] 203 assert.True(t, bytes.Equal(result, make([]byte, len(result)))) 204 } 205 206 func Test_DeserializePacket_FirstPacket(t *testing.T) { 207 208 var sampleCommand = []byte{'H', 'e', 'l', 'l', 'o', 0} 209 210 var packetSize = 64 211 var firstPacketHeaderSize = 7 212 packet, _, _ := SerializePacket(0x0101, sampleCommand, packetSize, 0) 213 214 output, totalSize, isSequenceZero, err := DeserializePacket(0x0101, packet, 0) 215 216 assert.Nil(t, err, "Simple deserialize should not have errors") 217 assert.Equal(t, len(sampleCommand), int(totalSize), "TotalSize is incorrect") 218 assert.Equal(t, packetSize-firstPacketHeaderSize, len(output), "Size of the deserialized packet is wrong") 219 assert.Equal(t, true, isSequenceZero, "Test Case Should Find Sequence == 0") 220 assert.True(t, bytes.Compare(output[:len(sampleCommand)], sampleCommand) == 0, "Deserialized message does not match the original") 221 } 222 223 func Test_DeserializePacket_SecondMessage(t *testing.T) { 224 var sampleCommand = []byte{'H', 'e', 'l', 'l', 'o', 0} 225 226 var packetSize = 64 227 var firstPacketHeaderSize = 5 // second packet does not have responseLength (uint16) in the header 228 packet, _, _ := SerializePacket(0x0101, sampleCommand, packetSize, 1) 229 230 output, totalSize, isSequenceZero, err := DeserializePacket(0x0101, packet, 1) 231 232 assert.Nil(t, err, "Simple deserialize should not have errors") 233 assert.Equal(t, 0, int(totalSize), "TotalSize should not be returned from deserialization of non-first packet") 234 assert.Equal(t, packetSize-firstPacketHeaderSize, len(output), "Size of the deserialized packet is wrong") 235 assert.Equal(t, false, isSequenceZero, "Test Case Should Find Sequence == 1") 236 assert.True(t, bytes.Equal(output[:len(sampleCommand)], sampleCommand), "Deserialized message does not match the original") 237 } 238 239 func Test_UnwrapApdu_SmokeTest(t *testing.T) { 240 const channel uint16 = 0x8002 241 242 inputSize := 200 243 var packetSize = 64 244 245 // Initialize some dummy input 246 var input = make([]byte, inputSize) 247 for i := range input { 248 input[i] = byte(i % 256) 249 } 250 251 serialized, _ := WrapCommandAPDU(channel, input, packetSize) 252 253 // Allocate enough buffers to keep all the packets 254 pipe := make(chan []byte, int(math.Ceil(float64(inputSize)/float64(packetSize)))) 255 // Send all the packets to the pipe 256 for len(serialized) > 0 { 257 pipe <- serialized[:packetSize] 258 serialized = serialized[packetSize:] 259 } 260 261 output, _ := UnwrapResponseAPDU(channel, pipe, packetSize) 262 263 //fmt.Printf("INPUT : %x\n", input) 264 //fmt.Printf("SERIALIZED: %x\n", serialized) 265 //fmt.Printf("OUTPUT : %x\n", output) 266 267 assert.Equal(t, len(input), len(output), "Input and output messages have different size") 268 assert.True(t, 269 bytes.Equal(input, output), 270 "Input message does not match message which was serialized and then deserialized") 271 }