Skip to content

Commit 2b83c68

Browse files
authored
Fix NFC card actions for iOS 26.4. (#11)
NFC-147 Fix NFC card actions for iOS 26.4.
1 parent 421d3d1 commit 2b83c68

1 file changed

Lines changed: 33 additions & 3 deletions

File tree

nfc-lib/nfc-lib/nfclib/CardActions/CardReaderNFC.swift

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class CardReaderNFC: CardReader, @unchecked Sendable {
6767
typealias TLV = TKBERTLVRecord
6868

6969
let tag: SendableISO7816Tag
70-
var ksEnc: Bytes
71-
var ksMac: Bytes
70+
var ksEnc: Bytes = AES.Zero
71+
var ksMac: Bytes = AES.Zero
7272
var SSC: Bytes = AES.Zero
7373

7474
init(_ tag: NFCISO7816Tag, CAN: String) async throws {
@@ -79,7 +79,8 @@ class CardReaderNFC: CardReader, @unchecked Sendable {
7979
CardReaderNFC.logger.debug("Read CardAccess")
8080
let data = try await self.tag.sendCommand(cls: 0x00, ins: 0xB0, p1Byte: 0x00, p2Byte: 0x00, leByte: 256)
8181

82-
guard let (mappingType, parameterId) = TLV.sequenceOfRecords(from: data)?
82+
let sanitizedData = sanitizedTLV(data)
83+
guard let (mappingType, parameterId) = TLV.sequenceOfRecords(from: sanitizedData)?
8384
.flatMap({ cardAccess in TLV.sequenceOfRecords(from: cardAccess.value) ?? [] })
8485
.compactMap({ tlv in
8586
if let records = TLV.sequenceOfRecords(from: tlv.value),
@@ -201,6 +202,35 @@ class CardReaderNFC: CardReader, @unchecked Sendable {
201202
}
202203
}
203204

205+
private func sanitizedTLV(_ data: Data) -> Data {
206+
guard data.count >= 2 else { return data }
207+
208+
var index = 1
209+
let firstLengthByte = data[index]
210+
index += 1
211+
212+
let valueLength: Int
213+
214+
if firstLengthByte & 0x80 == 0 {
215+
valueLength = Int(firstLengthByte)
216+
} else {
217+
let lengthByteCount = Int(firstLengthByte & 0x7F)
218+
219+
guard data.count >= index + lengthByteCount else {
220+
return data
221+
}
222+
223+
valueLength = data[index..<(
224+
index + lengthByteCount
225+
)].reduce(0) { ($0 << 8) | Int($1) }
226+
227+
index += lengthByteCount
228+
}
229+
230+
let totalLength = index + valueLength
231+
return data.prefix(min(totalLength, data.count))
232+
}
233+
204234
private func getDO87(_ apdu: NFCISO7816APDU) throws -> Data {
205235
if let data = apdu.data, !data.isEmpty {
206236
let ivValue = try AES.CBC(key: ksEnc).encrypt(SSC)

0 commit comments

Comments
 (0)