-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[Collections] Signing (part 1): certificate and key types #3238
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
Conversation
Sources/PackageCollectionsSigning/Certificate/Certificate.swift
Outdated
Show resolved
Hide resolved
case keyExtractionFailure | ||
case indeterminateKeyType | ||
case unsupportedKeyType | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice <3
This is part 2 of a series of PRs to support package collection signing. [Part 1](swiftlang#3238) Modifications: - Add support for signing with EC and RSA keys - Add `Signature`, which is similar to JWS - Introduce `CertificatePolicy` protocol (more on this in part 3) - `PackageCollectionsSigning` - given a package collection, certificate and its private key, generate a "signed" collection; and reverse that process to validate collection signature.
This is part 2 of a series of PRs to support package collection signing. [Part 1](swiftlang#3238) Modifications: - Add support for signing with EC and RSA keys - Add `Signature`, which is similar to JWS - Introduce `CertificatePolicy` protocol (more on this in part 3) - `PackageCollectionsSigning` - given a package collection, certificate and its private key, generate a "signed" collection; and reverse that process to validate collection signature.
@Lukasa @FredericJacobs - would appreciate your review on this (and upcoming PRs) 🙇♀️ |
seems good to me on the surface - would be good to wait for @Lukasa and/or @FredericJacobs feedback |
0266358
to
ce1432b
Compare
Sources/PackageCollectionsSigning/Certificate/Certificate.swift
Outdated
Show resolved
Hide resolved
Sources/PackageCollectionsSigning/Certificate/Certificate.swift
Outdated
Show resolved
Hide resolved
_ closure: (UnsafeMutablePointer<BIO>) -> (T?)) throws -> T where Data: DataProtocol { | ||
let bytes = data.copyBytes() | ||
|
||
let bio = CCryptoBoringSSL_BIO_new(CCryptoBoringSSL_BIO_s_mem()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can elide a copy in this code path by getting the backing pointer to bytes
and using BIO_new_mem_buf
. This doesn't take ownership of the pointer and won't free it, thus saving the call to BIO_write
. The downside, however, is that the BIO is read-only. Not sure how much of a problem that'll be here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code was using BIO_new_mem_buf
originally:
let bytes = data.copyBytes()
let bio = CCryptoBoringSSL_BIO_new_mem_buf(bytes, numericCast(bytes.count))
defer { CCryptoBoringSSL_BIO_free(bio) }
guard let bioPointer = bio, let result = closure(bioPointer) else {
throw BoringSSLKeyError.bioConversionFailure
}
return result
but one of Linux CI builds failed consistently with bioConversionFailure
. I couldn't tell if it was because bio
was nil
(unlikely I would think?) or there were issues loading the key (maybe it was the read-only issue that you noted). I wasn't able to reproduce the problem locally. Out of desperation I changed the code to this because it solved some other weird issue I had before when I was implementing OCSP support, and the error went away.
I will add a code comment on this.
|
||
init<Data>(pem data: Data) throws where Data: DataProtocol { | ||
let pem = String(decoding: data, as: UTF8.self) | ||
// TODO: init(pemRepresentation:) is available on macOS 11.0+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this support any macOS version older than that? Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've only recently bumped SPM's minimum required macOS version from 10.10 to 10.15 when we added the swift-crypto dependency. I could add code to check for 11.0 availability and use init(pemRepresentation:)
then fallback to the current logic on older versions.
cc @catmurdoch |
@swift-ci please smoke test |
// From the output of `openssl pkey -in eckey.pem -text -noout`, the P256 private key is 32-byte long. | ||
// PEM format is 7-byte pre_string || 32-byte private key || 14-byte mid_string || 65-byte public key | ||
// See: https://stackoverflow.com/questions/48101258/how-to-convert-an-ecdsa-key-to-pem-format | ||
self.underlying = try CryptoECPrivateKey(rawRepresentation: data.dropFirst(7).prefix(32)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems unsafe, it's missing a lot of validation about what kind of key this all is.
Do we have to support macOS Catalina?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else { | ||
let data = try KeyUtilities.stripHeaderAndFooter(pem: pem) | ||
// The P256 public key is 65-byte long and there's PEM prefix | ||
self.underlying = try CryptoECPublicKey(x963Representation: data.suffix(65)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same applies here. We should do some validation on the bytes we strip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rewrote this code. See #3238 (comment)
} | ||
|
||
enum KeyType { | ||
case RSA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sent you an email to discuss further. From a security standpoint, we would prefer not supporting RSA for this use case as there doesn't seem to be a backwards compatibility requirement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per my email reply, we need to support RSA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sources/PackageCollectionsSigning/Certificate/Certificate.swift
Outdated
Show resolved
Hide resolved
This is part 1 of a series of PRs to support package collection signing. Modifications: - New `PackageCollectionsSigning` module - Add `Certificate` type - Add EC and RSA key types
This is part 1 of a series of PRs to support package collection signing on **Apple** platforms. Originally swiftlang#3238. Modifications: - New `PackageCollectionsSigning` module - Add `Certificate` type - Add EC and RSA key types
This is part 1 of a series of PRs to support package collection signing on **Apple** platforms. Originally swiftlang#3238. Modifications: - New `PackageCollectionsSigning` module - Add `Certificate` type - Add EC and RSA key types
This is part 1 of a series of PRs to support package collection signing on **non-Apple** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **Apple** platforms. Originally swiftlang#3238. Modifications: - New `PackageCollectionsSigning` module - Add `Certificate` type - Add EC and RSA key types
This is part 1 of a series of PRs to support package collection signing on **non-Apple** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **Apple** platforms. Originally swiftlang#3238. Modifications: - New `PackageCollectionsSigning` module - Add `Certificate` type - Add EC and RSA key types
This is part 1 of a series of PRs to support package collection signing on **Apple** platforms. Originally #3238. Modifications: - New `PackageCollectionsSigning` module - Add `Certificate` type - Add EC and RSA key types
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238. Depends on swiftlang#3259
* [Collections] Signing (all, 1): certificate and key types This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally #3238. Depends on #3259 * [Collections] Signing (all, 2): signed collections This is part 2 of a series of PRs to support package collection signing on **all** platforms. Originally #3242. Depends on #3260, #3264 * [Collections] Signing (all, 3): certificate validations This is part 3 of a series of PRs to support package collection signing on **all** platforms. Originally #3245. Depends on #3265, #3269 * [Collections] Signing (all, 3.b): OCSP support for non-Apple platforms This is part 3.b of a series of PRs to support package collection signing on **all** platforms. Depends on #3270 Modifications: - Add `PackageCollectionsSigningLibc` module - Add OCSP support for non-Apple platforms through `PackageCollectionsSigningLibc` * Use shared callbackQueue and diagnosticsEngine in tests * Update platform check * Better OCSP error handling and cache OCSP results * Don't default to BoringSSL * OpenSSL license * fixup * Use ptr.count * Don't blindly drop X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION error * Add withUnsafeMutablePointer for accessing underlying X509 pointer * Fix leaks * Use withExtendedLifetime * OSCP response handling * Delete remove from cache call * OCSP should fail open * Verify OCSP response * Create new X509_STORE per invocation
This is part 1 of a series of PRs to support package collection signing.
Modifications:
PackageCollectionsSigning
moduleCertificate
type