Skip to content

Commit 8cbbdf6

Browse files
authored
Merge pull request #11 from swift-server/refactor2
Refactor2
2 parents a3d387f + 4ec3233 commit 8cbbdf6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1367
-394
lines changed

.swiftlint.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
disabled_rules:
2+
- comment_spacing
3+
excluded:
4+
- .build

Package.resolved

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,25 @@ let package = Package(
2121
.macOS(.v12)
2222
],
2323
products: [
24-
.library(name: "WebAuthn", targets: ["WebAuthn"]),
24+
.library(name: "WebAuthn", targets: ["WebAuthn"])
2525
],
2626
dependencies: [
2727
.package(url: "https://github.com/unrelentingtech/SwiftCBOR.git", from: "0.4.5"),
2828
.package(url: "https://github.com/apple/swift-crypto.git", from: "2.0.0"),
29-
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
29+
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0")
3030
],
3131
targets: [
3232
.target(
3333
name: "WebAuthn",
3434
dependencies: [
3535
"SwiftCBOR",
3636
.product(name: "Crypto", package: "swift-crypto"),
37-
.product(name: "Logging", package: "swift-log"),
37+
.product(name: "_CryptoExtras", package: "swift-crypto"),
38+
.product(name: "Logging", package: "swift-log")
3839
]
3940
),
4041
.testTarget(name: "WebAuthnTests", dependencies: [
41-
.target(name: "WebAuthn"),
42+
.target(name: "WebAuthn")
4243
])
4344
]
4445
)

Sources/WebAuthn/AuthenticationResponse.swift renamed to Sources/WebAuthn/Ceremonies/Authentication/AuthenticationCredential.swift

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,17 @@
1414

1515
import Foundation
1616

17-
public struct AuthenticationResponse: Codable {
18-
public let id: String
19-
public let rawID: String
17+
/// The unprocessed response received from `navigator.credentials.get()`.
18+
public struct AuthenticationCredential: Codable {
19+
public let id: URLEncodedBase64
2020
public let response: AuthenticatorAssertionResponse
2121
public let authenticatorAttachment: String?
22-
/// This is the public-key
2322
public let type: String
2423

2524
enum CodingKeys: String, CodingKey {
2625
case id
27-
case rawID = "rawId"
2826
case response
2927
case authenticatorAttachment
3028
case type
3129
}
3230
}
33-
34-
public struct AuthenticatorAssertionResponse: Codable {
35-
let clientDataJSON: String
36-
let authenticatorData: String
37-
let signature: String
38-
let userHandle: String?
39-
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the WebAuthn Swift open source project
4+
//
5+
// Copyright (c) 2022 the WebAuthn Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of WebAuthn Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
/// This is what the authenticator device returned after we requested it to authenticate a user.
16+
public struct AuthenticatorAssertionResponse: Codable {
17+
/// Representation of what we passed to `navigator.credentials.get()`
18+
public let clientDataJSON: URLEncodedBase64
19+
/// Contains the authenticator data returned by the authenticator.
20+
public let authenticatorData: URLEncodedBase64
21+
/// Contains the raw signature returned from the authenticator
22+
public let signature: URLEncodedBase64
23+
/// Contains the user handle returned from the authenticator, or null if the authenticator did not return
24+
/// a user handle. Used by to give scope to credentials.
25+
public let userHandle: String?
26+
/// Contains an attestation object, if the authenticator supports attestation in assertions.
27+
/// The attestation object, if present, includes an attestation statement. Unlike the attestationObject
28+
/// in an AuthenticatorAttestationResponse, it does not contain an authData key because the authenticator
29+
/// data is provided directly in an AuthenticatorAssertionResponse structure.
30+
public let attestationObject: String?
31+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the WebAuthn Swift open source project
4+
//
5+
// Copyright (c) 2022 the WebAuthn Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of WebAuthn Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import Foundation
16+
17+
/// The `PublicKeyCredentialRequestOptions` gets passed to the WebAuthn API (`navigator.credentials.get()`)
18+
public struct PublicKeyCredentialRequestOptions: Codable {
19+
public let challenge: String
20+
public let timeout: TimeInterval?
21+
public let rpId: String?
22+
public let allowCredentials: [PublicKeyCredentialDescriptor]?
23+
public let userVerification: UserVerificationRequirement?
24+
public let attestation: String?
25+
public let attestationFormats: [String]?
26+
// let extensions: [String: Any]
27+
}
28+
29+
public struct PublicKeyCredentialDescriptor: Codable {
30+
public enum AuthenticatorTransport: String, Codable {
31+
case usb
32+
case nfc
33+
case ble
34+
case hybrid
35+
case `internal`
36+
}
37+
38+
enum CodingKeys: String, CodingKey {
39+
case type, id, transports
40+
}
41+
42+
public let type: String
43+
public let id: [UInt8]
44+
public let transports: [AuthenticatorTransport]
45+
46+
public init(type: String, id: [UInt8], transports: [AuthenticatorTransport] = []) {
47+
self.type = type
48+
self.id = id
49+
self.transports = transports
50+
}
51+
52+
public func encode(to encoder: Encoder) throws {
53+
var container = encoder.container(keyedBy: CodingKeys.self)
54+
55+
try container.encode(type, forKey: .type)
56+
try container.encode(id.base64EncodedString(), forKey: .id)
57+
try container.encode(transports, forKey: .transports)
58+
}
59+
}
60+
61+
public enum UserVerificationRequirement: String, Codable {
62+
case required
63+
case preferred
64+
case discouraged
65+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Foundation
2+
3+
/// On successful authentication, this structure contains a summary of the authentication flow
4+
public struct VerifiedAuthentication {
5+
public enum CredentialDeviceType: String, Codable {
6+
case singleDevice = "single_device"
7+
case multiDevice = "multi_device"
8+
}
9+
10+
let credentialID: URLEncodedBase64
11+
let newSignCount: UInt32
12+
let credentialDeviceType: CredentialDeviceType
13+
let credentialBackedUp: Bool
14+
}

Tests/WebAuthnTests/WebAuthnTests.swift renamed to Sources/WebAuthn/Ceremonies/Registration/AttestationFormat.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
import WebAuthn
16-
import XCTest
17-
18-
final class WebAuthnTests: XCTestCase {
19-
func testHelloWorld() throws {
20-
let hello = "Hello, World!"
21-
XCTAssertEqual(hello, "Hello, World!")
22-
}
15+
public enum AttestationFormat: String, RawRepresentable {
16+
case packed
17+
case tpm
18+
case androidKey = "android-key"
19+
case androidSafetynet = "android-safetynet"
20+
case fidoU2F = "fido-u2f"
21+
case apple
22+
case none
2323
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the WebAuthn Swift open source project
4+
//
5+
// Copyright (c) 2022 the WebAuthn Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of WebAuthn Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import Crypto
16+
import SwiftCBOR
17+
18+
/// Contains the cryptographic attestation that a new key pair was created by that authenticator.
19+
public struct AttestationObject {
20+
let authenticatorData: AuthenticatorData
21+
let rawAuthenticatorData: [UInt8]
22+
let format: AttestationFormat
23+
let attestationStatement: CBOR
24+
25+
func verify(relyingPartyID: String, verificationRequired: Bool, clientDataHash: SHA256.Digest) throws {
26+
let relyingPartyIDHash = SHA256.hash(data: relyingPartyID.data(using: .utf8)!)
27+
28+
guard relyingPartyIDHash == authenticatorData.relyingPartyIDHash else {
29+
throw WebAuthnError.relyingPartyIDHashDoesNotMatch
30+
}
31+
32+
guard authenticatorData.flags.userPresent else {
33+
throw WebAuthnError.userPresentFlagNotSet
34+
}
35+
36+
if verificationRequired {
37+
guard authenticatorData.flags.userVerified else {
38+
throw WebAuthnError.userVerificationRequiredButFlagNotSet
39+
}
40+
}
41+
42+
switch format {
43+
case .none:
44+
// if format is `none` statement must be empty
45+
guard attestationStatement == .map([:]) else {
46+
throw WebAuthnError.attestationStatementMissing
47+
}
48+
default:
49+
throw WebAuthnError.attestationVerificationNotSupported
50+
}
51+
}
52+
}

Sources/WebAuthn/AttestedCredentialData.swift renamed to Sources/WebAuthn/Ceremonies/Registration/AttestedCredentialData.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15-
struct AttestedCredentialData {
15+
// Contains the new public key created by the authenticator.
16+
struct AttestedCredentialData: Codable {
1617
let aaguid: [UInt8]
1718
let credentialID: [UInt8]
1819
let publicKey: [UInt8]

0 commit comments

Comments
 (0)