-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
NodeJs doesn't download intermediate certificate #16336
Comments
Does Chrome actually fetch the intermediate certificate or did it see it before and cache it? Because I believe that's what Firefox does. If you have the intermediate certificate, |
i checked it with wireshark. in chrome or edge in windows fetch from link with this headers
in chrome on linux
this is url http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt issue like this. mozilla/tls-observatory#121 |
Interesting. What you could do is connect to a host with note: example only, not for production use // rejectUnauthorized=false makes authentication failures non-fatal
let c = tls.connect({ rejectUnauthorized: false, ...options });
c.on('secureConnect', () => {
if (c.authorized)
return next(c);
if (c.authorizationError === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE') {
// download intermediate CA certs
const urls = c.getPeerCertificate().infoAccess['CA Issuers - URI'];
download(urls, function(cas) {
// try again, this time with the certs
c = tls.connect({ ca: cas, ...options });
c.on('secureConnect', () => next(c));
});
}
c.destroy();
}); |
I'll close this out as works-as-intended. I considered tagging this feature-request but I don't think it properly belongs in the https or tls modules, and a workaround exists (the snippet I posted, which anyone is free to take and spin off into a third-party module.) |
@bnoordhuis your snippet workaround it's actually, a rubber stamp for every certificate, is not it? |
If you mean that it's not very sophisticated yet: no, it's not. It's an example, a starting point. |
@bnoordhuis I'd say that code is a lot worse than "not very sophisticated". If I'm understanding it correctly, it's saying "if the leaf cert can't be validated, then grab its issuer cert and trust that issuer as a new CA." End result: pretty much any cert with an issuer URI will be considered valid, including self-signed ones, and therefore all manner of snooping, man-in-the-middle attacks, etc. are possible. I really hope no one is using that code! I've run into the same issue as the original poster, while connecting to a server that I don't control so I can't easily fix it on that end. Chrome, Firefox, IE11, and Edge are all ok with the certificate (they download the intermediate cert automatically), but Node.js/Request is not. I think this issue should be re-opened. |
@kring : Intermediate certificate needs to validated before its added as new CA (or maybe just kept in separate cache). Not be blindly added as trusted CA. |
Yes of course, @zimbabao, but that's not what the code above is doing, right? |
@kring : True. I think it was intended as PoC. |
@bnoordhuis said while closing this issue:
PoC, sure, but this is not a workaround. Turning it into an actual workaround would be relatively involved and error-prone, and because this is security-critical code, getting it wrong could mean an exploitable bug in your application. I understand if this isn't high priority (I'm an open-source developer myself), but I think it's a legitimate feature request and should be re-opened. But mostly I posted so that no one thinks this is an actual workaround and uses the code as-is, because that would be extremely dangerous. |
Yes. I agree to that. The request is legitimate and your concerns are valid. |
They'd be rather stupid if they did because it should be blindingly obvious that the snippet is to showcase how to get the list of intermediate certificates, nothing more. The reason I don't think this is a valid feature request is that it means node.js starts doing too much work ("magic") on behalf of the user, and inflexibly at that. That's okay for an end user product like a browser or a module like A possible way forward is to make the verification phase more pluggable so it could cover this use case but that almost certainly requires upstream changes in openssl first. |
Ok, you could be right. It was indeed obvious to me. It wasn't hard to imagine, though, a developer googling their error message, seeing some code that a node.js developer describes as a "workaround", pasting it into their app, seeing that it "solves" their problem, and moving on. Anyway, thanks for your time, I'll see myself out. :) |
I've added a note to the example saying it's an, eh, example, not something to copy verbatim. |
@bnoordhuis |
i dream on this code const tls = require("tls");
var caStore = tls.createCertStore();
caStore.addCerts([cas]);
var chainStore = tls.createCertStore();
chainStore.addCerts([cas]);
function onGetChain(cert,callback){
download(cert.infoAccess['CA Issuers - URI'], function(cert) {
chainStore.addCert(cert);
callback(null,cert);
});
}
let c = tls.connect({ caStore: caStore , chainStore: chainStore , host , port , onGetChain: onGetChain }); |
@magicode |
@bnoordhuis OK. but nodejs not have option to set chain_cert_store , |
You can already pass in a chain of certificates with |
it's not chain_store it's verify_store https://github.com/nodejs/node/blob/v8.8.0/src/node_crypto.cc#L2604 |
You'll have to explain why the |
if i use chain_store i not need to verify intermediate certificate. i can add to chain_store untrusted certificates. |
I think I understand what you're getting at but can you explain why verify_store isn't sufficient? OpenSSL already verifies that the intermediate certificate is signed by the root certificate, right? |
@bnoordhuis This option is supported by the following functions of OPENSSL SSL_set1_chain_cert_store |
I did a module for verify certificate |
A possible workaround till intermediate certificate download is implemented: node_extra_ca_certs_mozilla_bundle It generates a PEM file that includes all root and intermediate certificates trusted by Mozilla. It uses the following environment variable To generate the PEM file to use with the above environment variable. You can install the module using:
and then launch your node script with an environment variable.
Other ways to use the generated PEM file are available at: NOTE: I am the author of the above module. |
www.campofelice.it server returns incomplete certificate chain browsers can download missing intermediary certs but node does not do it see: nodejs/node#16336 instead we are providing missing cert in: meta/ca/ca_intermediate_bundle.pem please note `NODE_EXTRA_CA_CERTS` had to be configured and point to that file
this site https://incomplete-chain.badssl.com/ configured without intermediate certificate.
In Google Chrome it work well. because Google Chrome does download the intermediate certificate. Now, the problem is, that since Chrome is by far the most popular browser, website owners configure their website to work in Chrome.
in nodejs emit error "Error: unable to verify the first certificate"
code example:
in .net framework is work well.
example: https://dotnetfiddle.net/Th5M0c (c#)
in curl have error:
curl "https://incomplete-chain.badssl.com/"
All errors occur because there is no intermediate certificate.
I download certificate from website incomplete-chain.badssl.com
$ echo -n | openssl s_client -servername incomplete-chain.badssl.com -connect incomplete-chain.badssl.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > incomplete-chain.badssl.com.crt
I see the details
$ openssl x509 -in incomplete-chain.badssl.com.crt -text -noout
in first certificate have link to intermediate certificate.
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
I guess. Google Chrome. or .net framework. download this intermediate certificate. and check it.
nodejs no download it.
Someone have an idea.
How to make a nodejs work like Google Chrome or c#.
or how i can to inject intermediate certificate. before node check certificate
or how i can to rewrite the function that verifies the certificate
The text was updated successfully, but these errors were encountered: