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 support for additional TLS options in NIOTS transport #18

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

gjcairo
Copy link
Collaborator

@gjcairo gjcairo commented Oct 29, 2024

This PR adds support for a few additional TLS options in the NIOTS transport, to bring it in line with the NIOPosix implementation. In particular, it now supports custom trust roots, which means mTLS can be enabled when using NIOTS, and E2E testing is possible (because we can use self-signed certificates).

Some code has been refactored to be shared across transport implementations, and a small bug with how errors were being surfaced has been fixed.

@gjcairo gjcairo added the semver/minor Adds new public API. label Oct 29, 2024
@gjcairo gjcairo requested a review from glbrntt October 29, 2024 15:18
Copy link
Collaborator

@glbrntt glbrntt left a comment

Choose a reason for hiding this comment

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

Couple of nits but mostly looks good. I assume the tests are in #20?


switch tlsConfig.trustRoots.wrapped {
case .certificates(let certificates):
let verifyQueue = DispatchQueue(label: "certificateVerificationQueue")
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: should be prefixed with io.grpc, we can also drop "queue" from the name, it's a bit redundant here.

Suggested change
let verifyQueue = DispatchQueue(label: "certificateVerificationQueue")
let verifyQueue = DispatchQueue(label: "io.grpc.CertificateVerification")

certificateBytes = Data(bytes)

case .file(_, let format), .bytes(_, let format):
fatalError("Certificate format must be DER, but was \(format).")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm – do we document this requirement somewhere?

Comment on lines +284 to +329
switch tlsConfig.trustRoots.wrapped {
case .certificates(let certificates):
let verifyQueue = DispatchQueue(label: "certificateVerificationQueue")
let verifyBlock: sec_protocol_verify_t = { (metadata, trust, verifyCompleteCallback) in
let actualTrust = sec_trust_copy_ref(trust).takeRetainedValue()

let customAnchors: [SecCertificate]
do {
customAnchors = try certificates.map { certificateSource in
let certificateBytes: Data
switch certificateSource.wrapped {
case .file(let path, .der):
certificateBytes = try Data(contentsOf: URL(filePath: path))

case .bytes(let bytes, .der):
certificateBytes = Data(bytes)

case .file(_, let format), .bytes(_, let format):
fatalError("Certificate format must be DER, but was \(format).")
}

guard let certificate = SecCertificateCreateWithData(nil, certificateBytes as CFData)
else {
fatalError("Certificate was not a valid DER-encoded X509 certificate.")
}
return certificate
}
} catch {
verifyCompleteCallback(false)
return
}

SecTrustSetAnchorCertificates(actualTrust, customAnchors as CFArray)
SecTrustEvaluateAsyncWithError(actualTrust, verifyQueue) { _, trusted, _ in
verifyCompleteCallback(trusted)
}
}

sec_protocol_options_set_verify_block(
self.securityProtocolOptions,
verifyBlock,
verifyQueue
)

case .systemDefault:
()
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is all copy-pasta from the client equivalent, can we avoid the duplication?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver/minor Adds new public API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants