2020-12-02 17:14:12 +03:00

65 lines
2.1 KiB
Swift

import Foundation
import Keycard
@available(iOS 13.0, *)
class SmartCard {
func nfcIsSupported() -> Bool {
return KeycardController.isAvailable
}
func initialize(channel: CardChannel, pin: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let puk = self.randomPUK()
let pairingPassword = self.randomPairingPassword();
let cmdSet = KeycardCommandSet(cardChannel: channel)
try cmdSet.select().checkOK()
try cmdSet.initialize(pin: pin, puk: puk, pairingPassword: pairingPassword).checkOK();
resolve(["pin": pin, "puk": puk, "password": pairingPassword])
}
func pair(channel: CardChannel, pairingPassword: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet = KeycardCommandSet(cardChannel: channel)
try cmdSet.select().checkOK()
try cmdSet.autoPair(password: pairingPassword);
resolve(Data(cmdSet.pairing!.bytes).base64EncodedString());
}
func signPinless(channel: CardChannel, hash: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet = CashCommandSet(cardChannel: channel)
try cmdSet.select().checkOK()
let message = self.hexToBytes(hash)
let res = try cmdSet.sign(data: message).checkOK()
resolve(res.data.toHexString())
}
func randomPUK() -> String {
return String(format: "%012d", Int.random(in: 0..<999999999999))
}
func randomPairingPassword() -> String {
let letters = "23456789ABCDEFGHJKLMNPRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
return String((0..<16).map{ _ in letters.randomElement()! })
}
func hexToBytes(_ hex: String) -> [UInt8] {
var last = hex.first
return hex.dropFirst().compactMap {
guard
let lastHexDigitValue = last?.hexDigitValue,
let hexDigitValue = $0.hexDigitValue
else {
last = $0
return nil
}
defer {
last = nil
}
return UInt8(lastHexDigitValue * 16 + hexDigitValue)
}
}
}