Skip to content

Commit 8b85211

Browse files
committed
Merge branch 'joao/prefix-smartcard-connections'
2 parents 67773d7 + 7d02375 commit 8b85211

28 files changed

+197
-186
lines changed

FullStackTests/AllowedConnections.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ enum TestableConnections {
4646
#endif
4747
}
4848

49-
static func create(with kind: Kind = .default) async throws -> Connection {
49+
static func create(with kind: Kind = .default) async throws -> SmartCardConnection {
5050

51-
let connection: Connection?
51+
let connection: SmartCardConnection?
5252
switch kind {
5353
case .smartCard:
5454
connection = try await smartCard()
@@ -77,8 +77,8 @@ enum TestableConnections {
7777
return connection
7878
}
7979

80-
private static func smartCard() async throws -> Connection? {
81-
let smartCardConnections = try await SmartCardConnection.all
80+
private static func smartCard() async throws -> SmartCardConnection? {
81+
let smartCardConnections = try await USBSmartCardConnection.all
8282
for connection in smartCardConnections {
8383
if try await connection.isAllowed {
8484
return connection
@@ -90,35 +90,35 @@ enum TestableConnections {
9090
}
9191

9292
#if os(iOS)
93-
private static func lightning() async throws -> Connection? {
94-
let connection = try await LightningConnection.connection()
93+
private static func lightning() async throws -> SmartCardConnection? {
94+
let connection = try await LightningSmartCardConnection.connection()
9595
guard try await connection.isAllowed else { return nil }
9696
return connection
9797
}
9898

99-
private static func nfc(alertMessage: String? = nil) async throws -> Connection? {
100-
let connection = try await NFCConnection.connection(alertMessage: alertMessage)
99+
private static func nfc(alertMessage: String? = nil) async throws -> SmartCardConnection? {
100+
let connection = try await NFCSmartCardConnection.connection(alertMessage: alertMessage)
101101
guard try await connection.isAllowed else { return nil }
102102
return connection
103103
}
104104
#endif
105105
}
106106

107-
extension SmartCardConnection {
108-
fileprivate static var all: [Connection] {
107+
extension USBSmartCardConnection {
108+
fileprivate static var all: [SmartCardConnection] {
109109
get async throws {
110-
let slots = try await SmartCardConnection.availableSlots
110+
let slots = try await USBSmartCardConnection.availableSlots
111111

112-
var connections: [Connection?] = []
112+
var connections: [SmartCardConnection?] = []
113113
for slot in slots {
114-
connections.append(try? await SmartCardConnection.connection(slot: slot))
114+
connections.append(try? await USBSmartCardConnection.connection(slot: slot))
115115
}
116116
return connections.compactMap { $0 }
117117
}
118118
}
119119
}
120120

121-
extension Connection {
121+
extension SmartCardConnection {
122122
fileprivate var isAllowed: Bool {
123123
get async throws {
124124
let session = try await ManagementSession.session(withConnection: self)

FullStackTests/Tests/ConnectionFullStackTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import XCTest
2020

2121
class ConnectionFullStackTests: XCTestCase {
2222

23-
typealias Connection = SmartCardConnection
23+
typealias Connection = USBSmartCardConnection
2424

2525
func testSingleConnection() throws {
2626
runAsyncTest {
@@ -169,15 +169,15 @@ class SmartCardConnectionFullStackTests: XCTestCase {
169169

170170
func testSmartCardConnectionWithSlot() throws {
171171
runAsyncTest {
172-
let allSlots = try await SmartCardConnection.availableSlots
172+
let allSlots = try await USBSmartCardConnection.availableSlots
173173
allSlots.enumerated().forEach { index, slot in
174174
print("\(index): \(slot.name)")
175175
}
176176
let random = allSlots.randomElement()
177177
// we need at least one YubiKey connected
178178
XCTAssertNotNil(random)
179179
guard let random else { return }
180-
let connection = try await SmartCardConnection.connection(slot: random)
180+
let connection = try await USBSmartCardConnection.connection(slot: random)
181181
print("✅ Got connection \(connection)")
182182
XCTAssertNotNil(connection)
183183
}

FullStackTests/Tests/ManagementFullStackTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,13 @@ extension XCTestCase {
256256
in file: StaticString = #file,
257257
at line: UInt = #line,
258258
withTimeout timeout: TimeInterval = 20,
259-
test: @escaping (Connection, ManagementSession, DeviceTransport) async throws -> Void
259+
test: @escaping (SmartCardConnection, ManagementSession, DeviceTransport) async throws -> Void
260260
) {
261261
runAsyncTest(named: testName, in: file, at: line, withTimeout: timeout) {
262262
let connection = try await TestableConnections.create()
263263
let transport: DeviceTransport
264264
#if os(iOS)
265-
if connection as? NFCConnection != nil {
265+
if connection as? NFCSmartCardConnection != nil {
266266
transport = .nfc
267267
} else {
268268
transport = .usb

FullStackTests/Tests/SCP/SCP11FullStackTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ final class SCP11aFullStackTests: XCTestCase {
147147
}
148148
}
149149

150-
private func importScp03Key(connection: Connection) async throws -> SCPKeyParams {
150+
private func importScp03Key(connection: SmartCardConnection) async throws -> SCPKeyParams {
151151
let scp03Ref = SCPKeyRef(kid: 0x01, kvn: 0x01)
152152

153153
let staticKeys = StaticKeys(

FullStackTests/Tests/SCP/XCTestCase+SCP.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import XCTest
1818
@testable import YubiKit
1919

2020
extension XCTestCase: HasTestLogger {
21-
var connection: Connection {
21+
var connection: SmartCardConnection {
2222
_connection!
2323
}
2424

@@ -48,7 +48,7 @@ extension XCTestCase: HasTestLogger {
4848
}
4949
}
5050

51-
private var _connection: Connection!
51+
private var _connection: SmartCardConnection!
5252

5353
private let _defaultKeyParams: SCP03KeyParams = {
5454
let defaultKeyRef = SCPKeyRef(kid: .scp03, kvn: 0xff)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ in Swift and SwiftUI based applications. The async/await syntax provides an easy
99
creating connections and sending commands to the different applications on the YubiKey.
1010

1111
```swift
12-
let connection = try await NFCConnection.connection()
12+
let connection = try await NFCSmartCardConnection.connection()
1313
let session = try await OATHSession.session(withConnection: connection)
1414
let codes = try await session.calculateCodes()
1515
```

Samples/OATHSample/OATHSample/OATHListModel.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class OATHListModel: OATHListModelProtocol {
4444
error = nil
4545
guard !Task.isCancelled else { return }
4646
// Wait for a suitable wired connection for the current device.
47-
let connection = try await WiredConnection.connection()
47+
let connection = try await WiredSmartCardConnection.connection()
4848
guard !Task.isCancelled else { return }
4949
try await calculateCodes(connection: connection)
5050
// Wait for the connection to close, i.e the YubiKey to be unplugged from the device.
@@ -68,7 +68,7 @@ class OATHListModel: OATHListModelProtocol {
6868
Task { @MainActor in
6969
do {
7070
self.error = nil
71-
let connection = try await NFCConnection.connection()
71+
let connection = try await NFCSmartCardConnection.connection()
7272
try await calculateCodes(connection: connection)
7373
await connection.nfcConnection?.close(message: "Code calculated")
7474
} catch {
@@ -80,7 +80,7 @@ class OATHListModel: OATHListModelProtocol {
8080
func calculateNFCCodes() {} // do nothing on macOS
8181
#endif
8282

83-
@MainActor private func calculateCodes(connection: Connection) async throws {
83+
@MainActor private func calculateCodes(connection: SmartCardConnection) async throws {
8484
self.error = nil
8585
let session = try await OATHSession.session(withConnection: connection)
8686
let result = try await session.calculateCodes()
@@ -95,20 +95,20 @@ struct Account: Identifiable {
9595
let code: String
9696
}
9797

98-
extension Connection {
98+
extension SmartCardConnection {
9999
var connectionType: String {
100100
#if os(iOS)
101-
if self as? NFCConnection != nil {
101+
if self as? NFCSmartCardConnection != nil {
102102
return "NFC"
103-
} else if self as? LightningConnection != nil {
103+
} else if self as? LightningSmartCardConnection != nil {
104104
return "Lightning"
105-
} else if self as? SmartCardConnection != nil {
105+
} else if self as? USBSmartCardConnection != nil {
106106
return "SmartCard"
107107
} else {
108108
return "Unknown"
109109
}
110110
#else
111-
if self as? SmartCardConnection != nil {
111+
if self as? USBSmartCardConnection != nil {
112112
return "SmartCard"
113113
} else {
114114
return "Unknown"

Samples/OATHSample/OATHSample/SettingsModel.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ class SettingsModel: SettingsModelProtocol {
3232
Task { @MainActor in
3333
self.error = nil
3434
do {
35-
let connection = try await AnyConnection.connection()
35+
let connection = try await AnySmartCardConnection.connection()
3636
let session = try await ManagementSession.session(withConnection: connection)
3737
self.keyVersion = session.version.description
3838
#if os(iOS)
3939
if let nfcConnection = connection.nfcConnection {
4040
self.connection = "NFC"
4141
await nfcConnection.close(message: "YubiKey version read")
4242
} else {
43-
self.connection = connection as? SmartCardConnection != nil ? "SmartCard" : "Lightning"
43+
self.connection = connection as? USBSmartCardConnection != nil ? "SmartCard" : "Lightning"
4444
}
4545
#else
4646
self.connection = "SmartCard"

YubiKit/YubiKit/Connection.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import Foundation
1818
///
1919
/// Use a connection to create a ``Session``. The connection can also be used for sending raw ``APDU``'s to the YubiKey.
2020
///
21-
/// Protocol implemented in ``LightningConnection``, ``NFCConnection`` and ``SmartCardConnection``.
21+
/// Protocol implemented in ``LightningSmartCardConnection``, ``NFCSmartCardConnection`` and ``USBSmartCardConnection``.
2222

23-
public protocol Connection: Sendable {
23+
public protocol SmartCardConnection: Sendable {
2424

25-
/// Create a new Connection to the YubiKey.
25+
/// Create a new SmartCardConnection to the YubiKey.
2626
///
2727
/// Call this method to get a connection to a YubiKey. The method will wait
2828
/// until a connection to a YubiKey has been established and then return it.
@@ -33,9 +33,9 @@ public protocol Connection: Sendable {
3333
/// If a connection has been established and this method is called again the
3434
/// first connection will be closed and ``connectionDidClose()`` will return for
3535
/// the previous connection.
36-
static func connection() async throws -> Connection
36+
static func connection() async throws -> SmartCardConnection
3737

38-
/// Close the current Connection.
38+
/// Close the current SmartCardConnection.
3939
///
4040
/// This closes the connection sending the optional error to the ``connectionDidClose()`` method.
4141
func close(error: Error?) async
@@ -46,9 +46,9 @@ public protocol Connection: Sendable {
4646
/// error will be returned.
4747
func connectionDidClose() async -> Error?
4848

49-
/// Send an APDU to the Connection.
49+
/// Send an APDU to the SmartCardConnection.
5050
///
51-
/// This will send the APDU to the YubiKey using the Connection. Commands returning data to big
51+
/// This will send the APDU to the YubiKey using the SmartCardConnection. Commands returning data to big
5252
/// to be handled by a single read operation will be handled automatically by the SDK and the
5353
/// complete result will be returned by the function. Only operations returning a 0x9000 status
5454
/// code will return data. Operations returning a 0x61XX (more data) status code will be handled
@@ -57,16 +57,16 @@ public protocol Connection: Sendable {
5757
@discardableResult
5858
func send(apdu: APDU) async throws -> Data
5959

60-
/// Send a command as Data to the Connection and handle the result manually.
60+
/// Send a command as Data to the SmartCardConnection and handle the result manually.
6161
///
62-
/// This will send the Data to the YubiKey using the Connection. The full result will be
62+
/// This will send the Data to the YubiKey using the SmartCardConnection. The full result will be
6363
/// returned as Data. If the returned data is to big for a single read operation this has
6464
/// to be handled manually.
6565
@discardableResult
6666
func send(data: Data) async throws -> Data
6767
}
6868

69-
/// Connection Errors.
69+
/// SmartCardConnection Errors.
7070
public enum ConnectionError: Error {
7171
/// No current connection.
7272
case noConnection
@@ -76,7 +76,7 @@ public enum ConnectionError: Error {
7676
case missingResult
7777
/// Awaiting call to connect() was cancelled.
7878
case cancelled
79-
/// Connection was closed.
79+
/// SmartCardConnection was closed.
8080
case closed
8181
}
8282

YubiKit/YubiKit/LightningConnection.swift renamed to YubiKit/YubiKit/LightningSmartCardConnection.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ import OSLog
2020

2121
/// A connection to the YubiKey utilizing the Lightning port and External Accessory framework.
2222
@available(iOS 16.0, *)
23-
public struct LightningConnection: Connection, Sendable {
23+
public struct LightningSmartCardConnection: SmartCardConnection, Sendable {
2424
let accessoryConnectionID: Int
2525

2626
// Starts lightning and wait for a connection
27-
public static func connection() async throws -> Connection {
27+
public static func connection() async throws -> SmartCardConnection {
2828
trace(message: "requesting new connection")
2929
return try await LightningConnectionManager.shared.connect()
3030
}
@@ -56,13 +56,13 @@ public struct LightningConnection: Connection, Sendable {
5656
// MARK: - Internal helpers / extensions
5757

5858
// Downcast helper
59-
extension Connection {
60-
public var lightningConnection: LightningConnection? {
61-
self as? LightningConnection
59+
extension SmartCardConnection {
60+
public var lightningConnection: LightningSmartCardConnection? {
61+
self as? LightningSmartCardConnection
6262
}
6363
}
6464

65-
extension LightningConnection: HasLightningLogger {}
65+
extension LightningSmartCardConnection: HasLightningLogger {}
6666
extension LightningConnectionManager: HasLightningLogger {}
6767
extension EAAccessoryWrapper: HasLightningLogger {}
6868

@@ -72,13 +72,13 @@ private actor LightningConnectionManager {
7272

7373
static let shared = LightningConnectionManager()
7474

75-
private var connectionTask: Task<LightningConnection, Error>?
76-
private var pendingConnectionPromise: Promise<LightningConnection>?
75+
private var connectionTask: Task<LightningSmartCardConnection, Error>?
76+
private var pendingConnectionPromise: Promise<LightningSmartCardConnection>?
7777
private var connectionState: (connectionID: ConnectionID, didCloseConnection: (Promise<Error?>))?
7878

7979
private init() {}
8080

81-
func connect() async throws -> LightningConnection {
81+
func connect() async throws -> LightningSmartCardConnection {
8282
// If a connection task is already running, await its result
8383
if let connectionTask {
8484
trace(message: "awaiting existing connection task")
@@ -89,7 +89,7 @@ private actor LightningConnectionManager {
8989
}
9090

9191
// Otherwise, create and store a new connection task.
92-
let task = Task { () -> LightningConnection in
92+
let task = Task { () -> LightningSmartCardConnection in
9393
// When the task finishes (on any path), clear it to allow a new connection.
9494
defer { self.connectionTask = nil }
9595

@@ -103,7 +103,7 @@ private actor LightningConnectionManager {
103103
}
104104

105105
// Create a promise to bridge the callback from EAAccessoryWrapper
106-
let connectionPromise: Promise<LightningConnection> = .init()
106+
let connectionPromise: Promise<LightningSmartCardConnection> = .init()
107107
self.pendingConnectionPromise = connectionPromise
108108

109109
// Connect to YubiKeys that are already plugged in
@@ -130,7 +130,7 @@ private actor LightningConnectionManager {
130130
return try await task.value
131131
}
132132

133-
func transmit(request: Data, for connection: LightningConnection) async throws -> Data {
133+
func transmit(request: Data, for connection: LightningSmartCardConnection) async throws -> Data {
134134
let connectionID = connection.accessoryConnectionID
135135
trace(message: "\(request.count) bytes to connection \(connectionID)")
136136

@@ -144,7 +144,7 @@ private actor LightningConnectionManager {
144144
return try await EAAccessoryWrapper.shared.transmit(id: connectionID, data: request)
145145
}
146146

147-
func close(for connection: LightningConnection, error: Error?) async {
147+
func close(for connection: LightningSmartCardConnection, error: Error?) async {
148148
guard let state = connectionState,
149149
state.connectionID == connection.accessoryConnectionID
150150
else { return }
@@ -155,7 +155,7 @@ private actor LightningConnectionManager {
155155
connectionState = nil
156156
}
157157

158-
func didClose(for connection: LightningConnection) async -> Error? {
158+
func didClose(for connection: LightningSmartCardConnection) async -> Error? {
159159
guard let state = connectionState,
160160
state.connectionID == connection.accessoryConnectionID
161161
else { return nil }
@@ -169,7 +169,7 @@ private actor LightningConnectionManager {
169169
guard let promise = pendingConnectionPromise else { return }
170170

171171
connectionState = (connectionID: connectionID, didCloseConnection: Promise<Error?>())
172-
let connection = LightningConnection(accessoryConnectionID: connectionID)
172+
let connection = LightningSmartCardConnection(accessoryConnectionID: connectionID)
173173
await promise.fulfill(connection)
174174
}
175175

0 commit comments

Comments
 (0)