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

Custom Server Certificate Verification Logic from Client Side #1965

Open
CMCDragonkai opened this issue Nov 12, 2021 · 3 comments
Open

Custom Server Certificate Verification Logic from Client Side #1965

CMCDragonkai opened this issue Nov 12, 2021 · 3 comments

Comments

@CMCDragonkai
Copy link

CMCDragonkai commented Nov 12, 2021

Is your feature request related to a problem? Please describe.

I need to put in custom logic to verifying the server certificate from the client side (and I also want to fetch this certificate for further processing because it has useful data).

The way I've currently done it is by first disabling certificate checking, then monkey patching and getting the http2session object by reaching down into the internals and fetching the socket certificate.

This allows me to verify the server certificate using my own custom logic.

However this isn't very robust solution. I've found that in some cases the http2 session object is still null in the subchannel because the subchannel state is still idle. I thought that subchannel state would be ready by the time channel state is ready, but this appears not to be the case. How can the channel state be ready while subchannel state is still not ready? Doesn't it need to verify the certificates somehow?

Describe the solution you'd like

Ideally there would be some way of hooking into the TLS logic, and passing my own certificate verification logic without monkey patching. I actually do this on both client side and server side, but this issue is about client side.

Describe alternatives you've considered

I've also looked into overriding the channel object, but It seems quite complicated since the TLS is occurring inside the http2 which is inside a subchannel.

@CMCDragonkai CMCDragonkai changed the title Custom Server Certificate Verification Logic Custom Server Certificate Verification Logic from Client Side Nov 12, 2021
@murgatroid99
Copy link
Member

The function grpc.credentails.createSsl has a fourth argument verifyOptions, which can take an object with the field checkServerIdentity, which is a function of the type defined here. Currently, for compatibility reasons, the certificate is only provided in raw Buffer form, but other than that, it does what you are asking for.

Regarding the channel state issue you described, it should not be possible for a channel to be ready if none of its subchannels are ready. Are you sure that you were looking at the right subchannel? If so, that sounds like a bug, so it would be great if you could file another issue with code that reproduces that state.

@CMCDragonkai
Copy link
Author

I have 2 issues with that:

  1. I need the entire certificate chain presented by the server, not just the peer certificate.
  2. Would that callback still be called if this option rejectUnauthorized is made false?
    // @ts-ignore hack for undocumented property
    const connectionOptions = credentials.connectionOptions;
    // Disable default certificate path validation logic
    // polykey has custom certificate path validation logic
    connectionOptions['rejectUnauthorized'] = false;
    I remember having to disable this to ensure that I could have an entirely custom certificate verification path.

Regarding the channel state, dw about that, turns out I was creating a whole new subchannel. Anyway, I did find another thing: the docs didn't say that session property may still be null during CONNECTING subchannel state.

@murgatroid99
Copy link
Member

  1. This will be addressed by grpc-js: Provide full certificate in checkServerIdentity callback #1968.
  2. rejectUnauthorized is not a part of gRPC's API. You are directly accessing objects that are passed to tls.connect, so the behavior is just whatever that API's behavior is.

You're right, the session property can be null for part of the time that a subchannel is in the CONNECTING state. We don't document every possible value that every property can have for every possible subchannel state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants