Skip to content

[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

Closed
wants to merge 10 commits into from

Conversation

yim-lee
Copy link
Contributor

@yim-lee yim-lee commented Feb 5, 2021

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

case keyExtractionFailure
case indeterminateKeyType
case unsupportedKeyType
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nice <3

yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 6, 2021
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.
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 6, 2021
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.
@yim-lee
Copy link
Contributor Author

yim-lee commented Feb 6, 2021

@Lukasa @FredericJacobs - would appreciate your review on this (and upcoming PRs) 🙇‍♀️

@tomerd
Copy link
Contributor

tomerd commented Feb 6, 2021

seems good to me on the surface - would be good to wait for @Lukasa and/or @FredericJacobs feedback

@yim-lee yim-lee force-pushed the signing-cert branch 3 times, most recently from 0266358 to ce1432b Compare February 8, 2021 04:25
_ closure: (UnsafeMutablePointer<BIO>) -> (T?)) throws -> T where Data: DataProtocol {
let bytes = data.copyBytes()

let bio = CCryptoBoringSSL_BIO_new(CCryptoBoringSSL_BIO_s_mem())
Copy link
Contributor

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.

Copy link
Contributor Author

@yim-lee yim-lee Feb 8, 2021

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+
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@yim-lee
Copy link
Contributor Author

yim-lee commented Feb 9, 2021

cc @catmurdoch

@yim-lee
Copy link
Contributor Author

yim-lee commented Feb 9, 2021

@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))

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we have to support macOS Catalina?

Yes we do

I rewrote this code. See #3238 (comment)

} 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))

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

Copy link
Contributor Author

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

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added key size check to #3242 (ecaec8a) since I can't find a good spot to do that in this PR.

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
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 12, 2021
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
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 12, 2021
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
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 12, 2021
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
@yim-lee
Copy link
Contributor Author

yim-lee commented Feb 12, 2021

We are going to split implementation into two paths: Apple platforms and non-Apple platforms. We will review PRs for supporting collection signing on Apple platforms first, then fine tune PRs for non-Apple platforms since they contain unsafe code.

Closing this PR, which now becomes #3259 and #3260

@yim-lee yim-lee closed this Feb 12, 2021
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 13, 2021
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
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 13, 2021
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
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 17, 2021
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
yim-lee added a commit that referenced this pull request Feb 17, 2021
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
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 18, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 18, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 18, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 18, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 20, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 22, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 26, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Feb 26, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 2, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 9, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 10, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 11, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 11, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 12, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 12, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 13, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 20, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit to yim-lee/swift-package-manager that referenced this pull request Mar 22, 2021
This is part 1 of a series of PRs to support package collection signing on **all** platforms. Originally swiftlang#3238.

Depends on swiftlang#3259
yim-lee added a commit that referenced this pull request Mar 24, 2021
* [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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants