Skip to content

Conversation

josephnoir
Copy link
Collaborator

Motivation:

The peer certificate chain can contain relevant information in some mTLS scenarios. NIO SSL only exposes the validated certificate chain when using custom verification callbacks. Now that this configuration option is available here, we can expose this property as well.

Modifications:

Make the property available and expose it as a validated certificate chain type from swift-certificates. Add tests to confirm the implementation.

Result:

The validated certificate chain is available when using mTLS with a custom certificate validation callback.

Motivation:

The peer certificate chain can contain relevant information in some mTLS
scenarios. NIO SSL only exposes the validated certificate chain when
using custom verification callbacks. Now that this configuration option
is available here, we can expose this property as well.

Modifications:

Make the property available and expose it as a validated certificate
chain type from swift-certificates. Add tests to confirm the
implementation.

Result:

The validated certificate chain is available when using mTLS with a
custom certificate validation callback.
@josephnoir josephnoir added the 🆕 semver/minor Adds new public API. label Sep 16, 2025
if let peerValidatedCertificateChain =
try await channel.nioSSL_peerValidatedCertificateChain().get()
{
context.peerValidatedCertificateChain =
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we grab the peer cert from the chain to make the do-catch block above a little cheaper?


/// The validated peer certificate chain from the mTLS handshake. This is only available when using a custom verification callback.
@available(gRPCSwiftNIOTransport 2.2, *)
public var peerValidatedCertificateChain: X509.ValidatedCertificateChain?
Copy link
Collaborator

Choose a reason for hiding this comment

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

This name makes it sound like the peer validated the cert chain. Do we need validated in the name at all here? It's documented and in the type name so I think peerCertificateChain would be sufficient.

Comment on lines 21 to 32
@available(gRPCSwiftNIOTransport 2.2, *)
extension NIOSSL.ValidatedCertificateChain {
// The precondition holds because the `NIOSSL.ValidatedCertificateChain` always contains one `NIOSSLCertificate`.
func usingX509Certificates() throws -> X509.ValidatedCertificateChain {
return .init(
uncheckedCertificateChain: try self.map {
let derBytes = try $0.toDERBytes()
return try Certificate(derEncoded: derBytes)
}
)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

The more natural spelling here is probably an extension on X509.ValidatedCertificateChain which adds an init(_ chain: NIOSSL.ValidatedCertificateChain) throws

Comment on lines 351 to 355
let expectedCertificateChain: [Certificate]
init(_ expectedCertificateChain: [Certificate]) {
self.expectedCertificateChain = expectedCertificateChain
}
func intercept<Input, Output>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let expectedCertificateChain: [Certificate]
init(_ expectedCertificateChain: [Certificate]) {
self.expectedCertificateChain = expectedCertificateChain
}
func intercept<Input, Output>(
let expectedCertificateChain: [Certificate]
init(_ expectedCertificateChain: [Certificate]) {
self.expectedCertificateChain = expectedCertificateChain
}
func intercept<Input, Output>(

@josephnoir
Copy link
Collaborator Author

Thank you for the review! I pushed a commit to address your feedback.

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.

LGTM, thanks @josephnoir!

@josephnoir josephnoir merged commit 5056709 into grpc:main Sep 16, 2025
34 checks passed
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