To continue the list of PC/SC wrappers initiated in 2010 with "PC/SC sample in different languages" I now present a sample in Swift using the Apple Crypto Token Kit API.
This code is just a, more or less direct, conversion of the Objective-C source code to Swift.
I used Xcode 7.0 that implements Swift version 2.1.
Swift is a language not yet known by my colorization tool: source-highlight. The colors may not be great.
Swift may be easier to learn and use than Objective-C. Using the Crypto Token Kit API is not different if you use Objective-C or Swift.
It looks like I am the first to provide a public code sample using the Crypto Token Kit API in Swift. Great! I hope that is a good Swift sample, I am not a Swift expert.
I then discovered that if the card returns an "error" code then the
It may be difficult to differentiate errors at the card/reader communication level from "errors" returned by the card. A SW different from 0x9000 may be completely valid and expected by the application in some cases.
Crypto Token Kit API
See my previous article "PCSC sample in Objective-C" to know more about Crypto Token Kit API.Source code
Create a new Swift application in Xcode. You need to enable the App Sandbox and add/set thecom.apple.security.smartcard
entitlement to YES.This code is just a, more or less direct, conversion of the Objective-C source code to Swift.
I used Xcode 7.0 that implements Swift version 2.1.
Swift is a language not yet known by my colorization tool: source-highlight. The colors may not be great.
import CryptoTokenKit
let mngr = TKSmartCardSlotManager.defaultManager()
// Use the first reader/slot found
let slotName = mngr!.slotNames[0]
print("slotName:", slotName)
// connect to the slot
mngr?.getSlotWithName(slotName, reply: {
(slot: TKSmartCardSlot?) in
// connect to the card
let card = slot?.makeSmartCard()
if (card != nil)
{
// begin a session
card?.beginSessionWithReply({
(success: Bool, error: NSError?) in
if (success)
{
// send 1st APDU
let aid : [UInt8] = [0xA0, 0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01]
let data = NSData(bytes: aid, length: aid.count)
card?.sendIns(0xA4, p1: 0x04, p2: 0x00, data: data, le: 0, reply: {
(data: NSData?, sw: UInt16, error: NSError?) in
if (error != nil)
{
print("sendIns error:", error!)
}
else
{
print("Response:", data!, String(sw, radix: 16))
// send 2nd APDU
let data = NSData(bytes: nil, length: 0)
card?.sendIns(0x0, p1: 0x00, p2: 0x00, data: data, le: 200, reply: {
(data: NSData?, sw: UInt16, error: NSError?) in
if (error != nil)
{
print("sendIns error:", error!)
}
else
{
print("Response:", data!, String(sw, radix: 16))
let newString = NSString(bytes: data!.bytes, length: data!.length, encoding: NSASCIIStringEncoding)
print(newString!)
}
})
}
})
}
else
{
print("Session error:", error)
}
})
}
else
{
print("No card found")
}
})
// wait for the asynchronous blocks to finish
sleep(1)
Output
slotName: Gemalto PC Twin Reader
Response: <> 9000
Response: <48656c6c 6f20776f 726c6421> 9000
Hello world!
Comments
See the previous article "PCSC sample in Objective-C" for comments about the Crypto Token Kit API.Swift may be easier to learn and use than Objective-C. Using the Crypto Token Kit API is not different if you use Objective-C or Swift.
It looks like I am the first to provide a public code sample using the Crypto Token Kit API in Swift. Great! I hope that is a good Swift sample, I am not a Swift expert.
Conclusion
As I wrote in "PCSC framework will stay in Mac OS X 10.11 El Capitan" the PC/SC API is not available from Swift. So the only option (for now) to use a smart card from Swift is to use the Crypto Token Kit API.[Update 5 Oct 2015]
The sample code was not correct in the error treatment.I then discovered that if the card returns an "error" code then the
sendIns
method returns an error in the error parameter. Here is the execution output of the program with a card that does not contain the applet:slotName: Gemalto PC Twin ReaderThe card returns 0x6A82 (Wrong parameter(s) P1-P2, File not found) in SW (Status Word).
sendIns error: Error Domain=CryptoTokenKit Code=-3 "SmartCard returned error 6a82" UserInfo=0x600000060940 {NSLocalizedDescription=SmartCard returned error 6a82}
It may be difficult to differentiate errors at the card/reader communication level from "errors" returned by the card. A SW different from 0x9000 may be completely valid and expected by the application in some cases.
ConversionConversion EmoticonEmoticon