-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathAPDUResponse.swift
66 lines (57 loc) · 1.76 KB
/
APDUResponse.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* ISO7816-4 R-APDU.
*/
public struct APDUResponse {
public let data: [UInt8]
public let sw1: UInt8
public let sw2: UInt8
public var sw: UInt16 {
get {
return (UInt16(self.sw1) << 8) | UInt16(self.sw2)
}
}
public init(rawData: [UInt8]) {
precondition(rawData.count >= 2, "rawData must contain at least the Status Word (2 bytes)")
self.sw1 = rawData[rawData.count - 2]
self.sw2 = rawData[rawData.count - 1]
self.data = rawData.count > 2 ? Array(rawData.prefix(upTo: rawData.count - 2)) : []
}
public init(sw1: UInt8, sw2: UInt8, data: [UInt8]) {
self.sw1 = sw1
self.sw2 = sw2
self.data = data
}
@discardableResult
public func checkOK() throws -> APDUResponse {
try checkSW(StatusWord.ok)
}
@discardableResult
public func checkAuthOK() throws -> APDUResponse {
if (self.sw & StatusWord.wrongPINMask.rawValue) == StatusWord.wrongPINMask.rawValue {
throw CardError.wrongPIN(retryCounter: Int(self.sw2 & 0x0F))
} else {
return try checkOK()
}
}
@discardableResult
public func checkSW(_ codes: StatusWord...) throws -> APDUResponse {
try checkSW(codes: codes.map({ $0.rawValue }))
}
@discardableResult
public func checkSW(_ codes: UInt16...) throws -> APDUResponse {
try checkSW(codes: codes)
}
@discardableResult
public func checkSW(codes: [UInt16]) throws -> APDUResponse {
for code in codes {
if (self.sw == code) {
return self;
}
}
if let aSW = StatusWord(rawValue: self.sw) {
throw aSW
} else {
throw StatusWord.unknownError
}
}
}