Skip to content

Minor code cleanup in PackageSigning #6462

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

Merged
merged 1 commit into from
Apr 24, 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
10 changes: 1 addition & 9 deletions Sources/PackageSigning/SigningIdentity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,7 @@ public struct SwiftSigningIdentity: SigningIdentity {
do {
switch privateKeyType {
case .p256:
#if canImport(Security)
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
self.privateKey = try Certificate.PrivateKey(P256.Signing.PrivateKey(derRepresentation: privateKey))
} else {
throw StringError("Unsupported platform")
}
#else
self.privateKey = try Certificate.PrivateKey(P256.Signing.PrivateKey(derRepresentation: privateKey))
#endif
}
} catch let error as StringError {
throw error
Expand Down Expand Up @@ -104,7 +96,7 @@ public struct SigningIdentityStore {
return certificates.compactMap { secCertificate in
var identity: SecIdentity?
let status = SecIdentityCreateWithCertificate(nil, secCertificate, &identity)
guard status == errSecSuccess, let identity = identity else {
guard status == errSecSuccess, let identity else {
self.observabilityScope
.emit(
warning: "Failed to create SecIdentity from SecCertificate[\(secCertificate)]: status \(status)"
Expand Down
63 changes: 63 additions & 0 deletions Tests/PackageSigningTests/SigningTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,69 @@ final class SigningTests: XCTestCase {
}
}

func testCMSEndToEndWithECKeyADPCertificate() async throws {
#if ENABLE_REAL_SIGNING_IDENTITY_TEST
#else
try XCTSkipIf(true)
#endif

let keyAndCertChain = try tsc_await { ecADPKeyAndCertChain(callback: $0) }
let signingIdentity = SwiftSigningIdentity(
certificate: try Certificate(keyAndCertChain.leafCertificate),
privateKey: try Certificate
.PrivateKey(P256.Signing.PrivateKey(derRepresentation: keyAndCertChain.privateKey))
)
let content = Array("per aspera ad astra".utf8)

let cmsProvider = CMSSignatureProvider(signatureAlgorithm: .ecdsaP256)
let signature = try cmsProvider.sign(
content: content,
identity: signingIdentity,
intermediateCertificates: keyAndCertChain.intermediateCertificates,
observabilityScope: ObservabilitySystem.NOOP
)

let verifierConfiguration = VerifierConfiguration(
trustedRoots: [keyAndCertChain.rootCertificate],
includeDefaultTrustStore: true,
certificateExpiration: .enabled(validationTime: nil),
certificateRevocation: .strict(validationTime: nil)
)

let status = try await cmsProvider.status(
signature: signature,
content: content,
verifierConfiguration: verifierConfiguration,
observabilityScope: ObservabilitySystem.NOOP
)

guard case .valid = status else {
return XCTFail("Expected signature status to be .valid but got \(status)")
}

func ecADPKeyAndCertChain(callback: (Result<KeyAndCertChain, Error>) -> Void) {
do {
try fixture(name: "Signing", createGitRepo: false) { fixturePath in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the fact that fixture is callback-based the only reason to make ecADPKeyAndCertChain callback-based?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Is there an async version of fixture?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should make one!

let privateKey = try readFileContents(
in: fixturePath,
pathComponents: "Certificates", "swift_package_key.p8"
)
let certificate = try readFileContents(
in: fixturePath,
pathComponents: "Certificates", "swift_package.cer"
)

callback(.success(KeyAndCertChain(
privateKey: privateKey,
certificateChain: [certificate]
)))
}
} catch {
callback(.failure(error))
}
}
}

#if os(macOS)
func testCMS1_0_0EndToEndWithADPSigningIdentityFromKeychain() async throws {
#if ENABLE_REAL_SIGNING_IDENTITY_TEST
Expand Down