Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ class CardReaderNFC: @unchecked CardReader, Loggable {
typealias TLV = TKBERTLVRecord

let tag: SendableISO7816Tag
var ksEnc: Bytes
var ksMac: Bytes
var ksEnc: Bytes = AES.Zero
var ksMac: Bytes = AES.Zero
var SSC: Bytes = AES.Zero

init(_ tag: NFCISO7816Tag, CAN: String) async throws {
Expand All @@ -78,8 +78,9 @@ class CardReaderNFC: @unchecked CardReader, Loggable {
_ = try await self.tag.sendCommand(cls: 0x00, ins: 0xA4, p1Byte: 0x02, p2Byte: 0x0C, data: Data([0x01, 0x1C]))
CardReaderNFC.logger().debug("Read CardAccess")
let data = try await self.tag.sendCommand(cls: 0x00, ins: 0xB0, p1Byte: 0x00, p2Byte: 0x00, leByte: 256)
let sanitizedData = sanitizedTLV(data)

guard let (mappingType, parameterId) = TLV.sequenceOfRecords(from: data)?
guard let (mappingType, parameterId) = TLV.sequenceOfRecords(from: sanitizedData)?
.flatMap({ cardAccess in TLV.sequenceOfRecords(from: cardAccess.value) ?? [] })
.compactMap({ tlv in
if let records = TLV.sequenceOfRecords(from: tlv.value),
Expand Down Expand Up @@ -201,6 +202,35 @@ class CardReaderNFC: @unchecked CardReader, Loggable {
}
}

private func sanitizedTLV(_ data: Data) -> Data {
guard data.count >= 2 else { return data }

var index = 1
let firstLengthByte = data[index]
index += 1

let valueLength: Int

if firstLengthByte & 0x80 == 0 {
valueLength = Int(firstLengthByte)
} else {
let lengthByteCount = Int(firstLengthByte & 0x7F)

guard data.count >= index + lengthByteCount else {
return data
}

valueLength = data[index..<(
index + lengthByteCount
)].reduce(0) { ($0 << 8) | Int($1) }

index += lengthByteCount
}

let totalLength = index + valueLength
return data.prefix(min(totalLength, data.count))
}

private func getDO87(_ apdu: NFCISO7816APDU) throws -> Data {
if let data = apdu.data, !data.isEmpty {
let ivValue = try AES.CBC(key: ksEnc).encrypt(SSC)
Expand Down
Loading