Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

Using the npm client with registry behind client certificates fails #7672

Closed
atamon opened this issue Mar 18, 2015 · 4 comments
Closed

Using the npm client with registry behind client certificates fails #7672

atamon opened this issue Mar 18, 2015 · 4 comments
Labels

Comments

@atamon
Copy link

atamon commented Mar 18, 2015

I'm trying to provide the NPM client with client certificates using the key and cert options.

This because I need to be able to connect to a local registry running sinopia, and the server has client certificate verification set up as outer protection.

However, I get this error even before NPM can make a connection to the sinopia server

npm verb stack Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
npm verb stack     at Object.exports.createCredentials (crypto.js:100:17)
npm verb stack     at Object.exports.connect (tls.js:1331:27)
npm verb stack     at Agent.createConnection (https.js:79:14)
npm verb stack     at Agent.createSocket (http.js:1297:16)
npm verb stack     at Agent.addRequest (http.js:1273:23)
npm verb stack     at new ClientRequest (http.js:1420:16)
npm verb stack     at Object.exports.request (https.js:123:10)
npm verb stack     at Request.start (/Users/atamon/code/npm/node_modules/request/request.js:906:30)
npm verb stack     at Request.end (/Users/atamon/code/npm/node_modules/request/request.js:1637:10)
npm verb stack     at end (/Users/atamon/code/npm/node_modules/request/request.js:676:14)

Where my .npmrc config looks like this at the moment (I have also tried using the paths as well as different ways of inlining the certificates)

registry=https://npm.domain.com
cert=/path/to/correct/cert.pem
key=/path/to/correct/key.pem

I know that both cert and key are correct as I can connect to our server with them using stunnel or openssl.

I downloaded the npm repo to try to debug this. And after much digging I noticed that I can get this to work with a small change in the registry client. See pull request attached for details

Is this the correct way of handling this issue? Maybe this isn't even an issue and I just missed completely on how client certificates should be provided?

Cheers

@othiym23
Copy link
Contributor

The configuration documentation is maybe not as explicit about this as it should be, but the way it works right now is how it's documented and intended to work – ca, cert, and key are all meant to be used with the actual contents of the PEM-formatted files put into the relevant configuration properties, with something like npm config set cert "$(cat certfile.pem)".

Because proxies are relatively common, @chrisdickinson contributed a patch (back when npmconf was a separate module, before we combined it with npm again) that allows you to pass a filename to a separate config parameter, cafile. As you can see if you read that patch, it's not a simple drop-in to just read the file, because OpenSSL can be particular about extra material being included in the pemfile.

If you wanted to add support for keyfile and certfile parameters, I'm open to that. A patch for that would need both tests and documentation (and probably a little extra clarifying text pointing out the difference between the cert / certfile pair, because you're not the first person to be confused by this). Alternately, I'd love it if somebody tweaked the config documentation to make it clearer that cert, key, and ca are for file contents, not paths.

@atamon
Copy link
Author

atamon commented Mar 18, 2015

Thanks for the great explanation @othiym23 ! Now I get the cert and key configurations to get picked up properly.

However, I still have problems with the cert option not reaching the server. I get the error

npm info retry will retry, error on last attempt: Error: 140735288345344:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:1275:SSL alert number 40

Reading up on the request lib that is used in npm-registry-client, I find that request expects an object called "agent" that should contain the ssl certificate option.

npm-registry-client tries to provide that through here https://github.com/npm/npm-registry-client/blob/88399fa1ebc5473125466ffa940c5b7df9e693bc/lib/initialize.js#L68. But from npm you send the option ssl.certificate, when what is sent through to request is ssl.cert, which is never read from config as far as I can see.

I suppose this is an issue for the npm-registry-client instead though. As it actually accepts the ssl.certificate option a few lines above https://github.com/npm/npm-registry-client/blob/88399fa1ebc5473125466ffa940c5b7df9e693bc/lib/initialize.js#L24

@othiym23
Copy link
Contributor

This stuff is fiendishly difficult to test, so things fall through the cracks sometimes. I'll take a look at your PR on npm-registry-client. Thanks for figuring this out / thanks for your time!

@atamon
Copy link
Author

atamon commented Mar 19, 2015

Thanks for the superly awesome short feedback loop on this! Happy to help. :-)

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

No branches or pull requests

2 participants