Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add async version of SecKeyPair.matchesCertificate #63

Merged
merged 1 commit into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Sources/ShieldSecurity/SecKeyPair.swift
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,29 @@ public struct SecKeyPair {
return try encodedPublicKey() == keyData
}

#if swift(>=5.5)
/// Check if the public key of the key pair matches the public key in a certificate.
///
/// The certificate is first validated as a trusted certificate and then the key pair
/// is checked against the public key of the key pair.
///
/// - Parameters:
/// - certificate: Certificate to check for equality with the key pair's public key.
/// - trustedCertificates: Any certificates needed to complete the "chain-of-trust" for `certificate`.
/// - Returns: True if the public key of `certificate` and the key pair match.
///
public func matchesCertificate(
certificate: SecCertificate,
trustedCertificates: [SecCertificate]
) async throws -> Bool {

let keyData =
try await certificate.publicKeyValidated(trustedCertificates: trustedCertificates).encode()

return try encodedPublicKey() == keyData
}
#endif


/// Structure representing keys exported using ``export(password:derivedKeyLength:keyDerivationTiming:)``.
///
Expand Down
21 changes: 21 additions & 0 deletions Tests/SecKeyPairTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,27 @@ class SecKeyPairTests: XCTestCase {
waitForExpectations(timeout: 10.0)
}

#if swift(>=5.5)
func testCertificateMatchingAsync() async throws {

let name = try NameBuilder().add("Unit Testing", forTypeName: "CN").name

let certData =
try Certificate.Builder()
.subject(name: name)
.issuer(name: name)
.publicKey(keyPair: rsaKeyPair, usage: [.keyEncipherment])
.valid(for: 86400 * 5)
.build(signingKey: rsaKeyPair.privateKey, digestAlgorithm: .sha256)
.encoded()

let cert = SecCertificateCreateWithData(nil, certData as CFData)!

let result = try await self.rsaKeyPair.matchesCertificate(certificate: cert, trustedCertificates: [cert])
XCTAssertTrue(result)
}
#endif

func testImportExport() throws {

let exportedKeyData = try rsaKeyPair.export(password: "123")
Expand Down