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

support custom peer certificates on mock socket #2227

Open
pke opened this issue Sep 13, 2021 · 5 comments
Open

support custom peer certificates on mock socket #2227

pke opened this issue Sep 13, 2021 · 5 comments

Comments

@pke
Copy link

pke commented Sep 13, 2021

Context

My node app checks peer-certificates on the socket level like this:

req.on("socket", (socket: TLSSocket) => {
  socket.on("secureConnect", () => {
    // socket.getPeerCertificate()
  })
})

I tried to use nock like this:

nock(hostname)[method](path).reply(statusCode, body).on("socket", socket => {
  console.log("inside secureSocket")
  socket.getPeerCertificate = function() {
    return {}
  }

But it does not override the getPeerCertificate function. It still returns the random string from the mock socket.

If the feature request is accepted, would you be willing to submit a PR?

Yes, I think it could be similary implemented like the socket delay.

nock(...).peerCertificate(...).reply() or when creating the scope: nock(base, { peerCertificate })

@mastermatt
Copy link
Member

Thanks for the request @pke

Some things to come to mind right off the bat:

  • The current implementation of getPeerCertificate on Nock's mock Socket class is just flat out wrong. It returns a random base64 string, but per the docs this method has always returned a plain object with the cert info.
  • The mock Socket instance is created, attached to the router, and emitted on the request (req.emit('socket', socket)) before a single Scope or Interceptor is selected. This is going to be a big challenge with the feature request, unless we add some global cert registry.

@pke if the Nock Socket class simply added a setPeerCertificate method that you could call in a 'socket' event handler (like your example) would that work for you? It wouldn't have the same API as some of the other Nock settings, but all those settings affect the reply which happen later in the flow.
Your implementation would then look like the following:

nock(hostname)[method](path).reply(statusCode, body).on("socket", socket => {
  console.log("inside secureSocket")
  socket.setPeerCertificate({
    raw: <Buffer ... >
    subject: { ... }
   ....
})

Or if you're using Node v15.6.0+, you could use the new, fancy X509Certificate class.

nock(hostname)[method](path).reply(statusCode, body).on("socket", socket => {
  console.log("inside secureSocket")
  const x509 = new X509Certificate('{... pem encoded cert ...}');
  socket.setPeerCertificate(x509.toLegacyObject())
})

@pke
Copy link
Author

pke commented Sep 14, 2021

Yes Matt, that looks good enough for me! Didn't know about the X509Certificate class until now, thanks!

All I really need is the pubkey of the legacy object, so lets give it a try! My e2e tests will be green again ;)

Maybe we can type the argument in a way that it is back compatible with older node versions?
setPeerCertificate(Buffer | X509Certificate) if this makes sense?

@gr2m gr2m added the support General questions or support. label Nov 8, 2021
@gr2m
Copy link
Member

gr2m commented Nov 8, 2021

Is there anything actionable left for us to do here?

@mastermatt
Copy link
Member

yes. despite my best intentions, I never added this functionality. This should be marked as a solid feature request.

@pke
Copy link
Author

pke commented Nov 8, 2021

The back-compatible way would be fine with me, as I stated before ;)

@gr2m gr2m added feature pull request welcome and removed support General questions or support. labels Nov 8, 2021
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

3 participants