npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE [duplicate] - node.js

I'm using node.js request.js to reach an api. I'm getting this error
[Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]
All of my credentials are accurate and valid, and the server's fine. I made the same request with postman.
request({
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
This code is just running in an executable script ex. node ./run_file.js, Is that why? Does it need to run on a server?

Note: the following is dangerous, and will allow API content to be intercepted and modified between the client and the server.
This also worked
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

It's not an issue with the application, but with the certificate which is signed by an intermediary CA.
If you accept that fact and still want to proceed, add the following to request options:
rejectUnauthorized: false
Full request:
request({
"rejectUnauthorized": false,
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});

The Secure Solution
Rather than turning off security you can add the necessary certificates to the chain. First install ssl-root-cas package from npm:
npm install ssl-root-cas
This package contains many intermediary certificates that browsers trust but node doesn't.
var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()
Will add the missing certificates. See here for more info:
https://git.coolaj86.com/coolaj86/ssl-root-cas.js

CoolAJ86's solution is correct and it does not compromise your security like disabling all checks using rejectUnauthorized or NODE_TLS_REJECT_UNAUTHORIZED. Still, you may need to inject an additional CA's certificate explicitly.
I tried first the root CAs included by the ssl-root-cas module:
require('ssl-root-cas/latest')
.inject();
I still ended up with the UNABLE_TO_VERIFY_LEAF_SIGNATURE error. Then I found out who issued the certificate for the web site I was connecting to by the COMODO SSL Analyzer, downloaded the certificate of that authority and tried to add only that one:
require('ssl-root-cas/latest')
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
I ended up with another error: CERT_UNTRUSTED. Finally, I injected the additional root CAs and included "my" (apparently intermediary) CA, which worked:
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

For Create React App (where this error occurs too and this question is the #1 Google result), you are probably using HTTPS=true npm start and a proxy (in package.json) which goes to some HTTPS API which itself is self-signed, when in development.
If that's the case, consider changing proxy like this:
"proxy": {
"/api": {
"target": "https://localhost:5001",
"secure": false
}
}
secure decides whether the WebPack proxy checks the certificate chain or not and disabling that ensures the API self-signed certificate is not verified so that you get your data.

It may be very tempting to do rejectUnauthorized: false or process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; but don't do it! It exposes you to man in the middle attacks.
The other answers are correct in that the issue lies in the fact that your cert is "signed by an intermediary CA." There is an easy solution to this, one which does not require a third party library like ssl-root-cas or injecting any additional CAs into node.
Most https clients in node support options that allow you to specify a CA per request, which will resolve UNABLE_TO_VERIFY_LEAF_SIGNATURE. Here's a simple example using node's built-int https module.
import https from 'https';
const options = {
host: '<your host>',
defaultPort: 443,
path: '<your path>',
// assuming the bundle file is co-located with this file
ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
headers: {
'content-type': 'application/json',
}
};
https.get(options, res => {
// do whatever you need to do
})
If, however, you can configure the ssl settings in your hosting server, the best solution would be to add the intermediate certificates to your hosting provider. That way the client requester doesn't need to specify a CA, since it's included in the server itself. I personally use namecheap + heroku. The trick for me was to create one .crt file with cat yourcertificate.crt bundle.ca-bundle > server.crt. I then opened up this file and added a newline after the first certificate. You can read more at
https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/installing-an-ssl-certificate-on-heroku-ssl

You can also try by setting strictSSL to false, like this:
{
url: "https://...",
method: "POST",
headers: {
"Content-Type": "application/json"},
strictSSL: false
}

I had the same issues. I have followed #ThomasReggi and #CoolAJ86 solution and worked well but I'm not satisfied with the solution.
Because "UNABLE_TO_VERIFY_LEAF_SIGNATURE" issue is happened due to certification configuration level.
I accept #thirdender solution but its partial solution.As per the nginx official website, they clearly mentioned certificate should be combination of The server certificate and chained certificates.

Just putting this here in case it helps someone, my case was different and a bit of an odd mix. I was getting this on a request that was accessed via superagent - the problem had nothing to do with certificates (which were setup properly) and all to do with the fact that I was then passing the superagent result through the async module's waterfall callback. To fix: Instead of passing the entire result, just pass result.body through the waterfall's callback.

Following commands worked for me :
> npm config set strict-ssl false
> npm cache clean --force
The problem is that you are attempting to install a module from a repository with a bad or untrusted SSL[Secure Sockets Layer] certificate. Once you clean the cache, this problem will be resolved.You might need to turn it to true later on.

Another approach to solving this securely is to use the following module.
node_extra_ca_certs_mozilla_bundle
This module can work without any code modification by generating a PEM file that includes all root and intermediate certificates trusted by Mozilla. You can use the following environment variable (Works with Nodejs v7.3+),
NODE_EXTRA_CA_CERTS
To generate the PEM file to use with the above environment variable. You can install the module using:
npm install --save node_extra_ca_certs_mozilla_bundle
and then launch your node script with an environment variable.
NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node your_script.js
Other ways to use the generated PEM file are available at:
https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle
NOTE: I am the author of the above module.

I had an issue with my Apache configuration after installing a GoDaddy certificate on a subdomain. I originally thought it might be an issue with Node not sending a Server Name Indicator (SNI), but that wasn't the case. Analyzing the subdomain's SSL certificate with https://www.ssllabs.com/ssltest/ returned the error Chain issues: Incomplete.
After adding the GoDaddy provided gd_bundle-g2-g1.crt file via the SSLCertificateChainFile Apache directive, Node was able to connect over HTTPS and the error went away.

If you come to this thread because you're using the node postgres / pg module, there is a better solution than setting NODE_TLS_REJECT_UNAUTHORIZED or rejectUnauthorized, which will lead to insecure connections.
Instead, configure the "ssl" option to match the parameters for tls.connect:
{
ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
cert: fs.readFileSync('/path/to/client-cert.pem').toString(),
key: fs.readFileSync('/path/to/client-key.pem').toString(),
servername: 'my-server-name' // e.g. my-project-id/my-sql-instance-id for Google SQL
}
I've written a module to help with parsing these options from environment variables like PGSSLROOTCERT, PGSSLCERT, and PGSSLKEY:
https://github.com/programmarchy/pg-ssl

Hello just a small adition to this subject since in my case the
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
didn't work out for me it kept returning error that the file could not be downloaded i had been a couple of hours into the reasearch of this particular error when I ran into this response https://stackoverflow.com/a/65442604
Since in my application we do have a proxy to proxy some of our requests as a security requirement of some of our users I found that in the case you are consulting an API that has this issue and if you can access the API url throught your browser you can proxy your request and it might fix the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE] issue.
An example of how i use my proxy
await axios.get(url, {
timeout: TIME_OUT,
headers: {
'User-Agent': 'My app'
},
params: params,
proxy: {
protocol: _proxy.protocol,
host: _proxy.hostname,
port: _proxy.port,
auth: {
username: _proxy_username,
password: _proxy_password
}
}
});

I had the same problem and I am able to fix it the following way,
Use the full-chain or just the chain certificate instead of just the certificate.
That is all.

This same error can be received when trying to install a local git shared repo from npm.
The error will read: npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
Apparently there is an issue with the certificate, however what worked for me was change the link to my shared repo in the package.json file from:
"shared-frontend": "https://myreposerver"
to:
"shared-frontend": "git+https://myreposerver"
In short, just adding git+ to the link solved it.

Another reason node could print that error is because a backend connection/service is misconfigured.
Unfortunately, the node error doesn't say which certificate it was unable to verify [feature request !]
Your server may have a perfectly good certificate chain installed for clients to connect and even show a nice padlock in the browser's URL bar, but when the server tries to connect to a backend database using a different misconfigured certificate, then it could raise an identical error.
I had this issue in some vendor code for some time. Changing a backend database connection from self-signed to an actual certificate resolved it.

You have to include the Intermediate certificate in your server. This solves the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]

Related

Certificate verification [duplicate]

I'm using node.js request.js to reach an api. I'm getting this error
[Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]
All of my credentials are accurate and valid, and the server's fine. I made the same request with postman.
request({
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
This code is just running in an executable script ex. node ./run_file.js, Is that why? Does it need to run on a server?
Note: the following is dangerous, and will allow API content to be intercepted and modified between the client and the server.
This also worked
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
It's not an issue with the application, but with the certificate which is signed by an intermediary CA.
If you accept that fact and still want to proceed, add the following to request options:
rejectUnauthorized: false
Full request:
request({
"rejectUnauthorized": false,
"url": domain+"/api/orders/originator/"+id,
"method": "GET",
"headers":{
"X-API-VERSION": 1,
"X-API-KEY": key
},
}, function(err, response, body){
console.log(err);
console.log(response);
console.log(body);
});
The Secure Solution
Rather than turning off security you can add the necessary certificates to the chain. First install ssl-root-cas package from npm:
npm install ssl-root-cas
This package contains many intermediary certificates that browsers trust but node doesn't.
var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()
Will add the missing certificates. See here for more info:
https://git.coolaj86.com/coolaj86/ssl-root-cas.js
CoolAJ86's solution is correct and it does not compromise your security like disabling all checks using rejectUnauthorized or NODE_TLS_REJECT_UNAUTHORIZED. Still, you may need to inject an additional CA's certificate explicitly.
I tried first the root CAs included by the ssl-root-cas module:
require('ssl-root-cas/latest')
.inject();
I still ended up with the UNABLE_TO_VERIFY_LEAF_SIGNATURE error. Then I found out who issued the certificate for the web site I was connecting to by the COMODO SSL Analyzer, downloaded the certificate of that authority and tried to add only that one:
require('ssl-root-cas/latest')
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
I ended up with another error: CERT_UNTRUSTED. Finally, I injected the additional root CAs and included "my" (apparently intermediary) CA, which worked:
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
For Create React App (where this error occurs too and this question is the #1 Google result), you are probably using HTTPS=true npm start and a proxy (in package.json) which goes to some HTTPS API which itself is self-signed, when in development.
If that's the case, consider changing proxy like this:
"proxy": {
"/api": {
"target": "https://localhost:5001",
"secure": false
}
}
secure decides whether the WebPack proxy checks the certificate chain or not and disabling that ensures the API self-signed certificate is not verified so that you get your data.
It may be very tempting to do rejectUnauthorized: false or process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; but don't do it! It exposes you to man in the middle attacks.
The other answers are correct in that the issue lies in the fact that your cert is "signed by an intermediary CA." There is an easy solution to this, one which does not require a third party library like ssl-root-cas or injecting any additional CAs into node.
Most https clients in node support options that allow you to specify a CA per request, which will resolve UNABLE_TO_VERIFY_LEAF_SIGNATURE. Here's a simple example using node's built-int https module.
import https from 'https';
const options = {
host: '<your host>',
defaultPort: 443,
path: '<your path>',
// assuming the bundle file is co-located with this file
ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
headers: {
'content-type': 'application/json',
}
};
https.get(options, res => {
// do whatever you need to do
})
If, however, you can configure the ssl settings in your hosting server, the best solution would be to add the intermediate certificates to your hosting provider. That way the client requester doesn't need to specify a CA, since it's included in the server itself. I personally use namecheap + heroku. The trick for me was to create one .crt file with cat yourcertificate.crt bundle.ca-bundle > server.crt. I then opened up this file and added a newline after the first certificate. You can read more at
https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/installing-an-ssl-certificate-on-heroku-ssl
You can also try by setting strictSSL to false, like this:
{
url: "https://...",
method: "POST",
headers: {
"Content-Type": "application/json"},
strictSSL: false
}
I had the same issues. I have followed #ThomasReggi and #CoolAJ86 solution and worked well but I'm not satisfied with the solution.
Because "UNABLE_TO_VERIFY_LEAF_SIGNATURE" issue is happened due to certification configuration level.
I accept #thirdender solution but its partial solution.As per the nginx official website, they clearly mentioned certificate should be combination of The server certificate and chained certificates.
Just putting this here in case it helps someone, my case was different and a bit of an odd mix. I was getting this on a request that was accessed via superagent - the problem had nothing to do with certificates (which were setup properly) and all to do with the fact that I was then passing the superagent result through the async module's waterfall callback. To fix: Instead of passing the entire result, just pass result.body through the waterfall's callback.
Following commands worked for me :
> npm config set strict-ssl false
> npm cache clean --force
The problem is that you are attempting to install a module from a repository with a bad or untrusted SSL[Secure Sockets Layer] certificate. Once you clean the cache, this problem will be resolved.You might need to turn it to true later on.
Another approach to solving this securely is to use the following module.
node_extra_ca_certs_mozilla_bundle
This module can work without any code modification by generating a PEM file that includes all root and intermediate certificates trusted by Mozilla. You can use the following environment variable (Works with Nodejs v7.3+),
NODE_EXTRA_CA_CERTS
To generate the PEM file to use with the above environment variable. You can install the module using:
npm install --save node_extra_ca_certs_mozilla_bundle
and then launch your node script with an environment variable.
NODE_EXTRA_CA_CERTS=node_modules/node_extra_ca_certs_mozilla_bundle/ca_bundle/ca_intermediate_root_bundle.pem node your_script.js
Other ways to use the generated PEM file are available at:
https://github.com/arvind-agarwal/node_extra_ca_certs_mozilla_bundle
NOTE: I am the author of the above module.
I had an issue with my Apache configuration after installing a GoDaddy certificate on a subdomain. I originally thought it might be an issue with Node not sending a Server Name Indicator (SNI), but that wasn't the case. Analyzing the subdomain's SSL certificate with https://www.ssllabs.com/ssltest/ returned the error Chain issues: Incomplete.
After adding the GoDaddy provided gd_bundle-g2-g1.crt file via the SSLCertificateChainFile Apache directive, Node was able to connect over HTTPS and the error went away.
If you come to this thread because you're using the node postgres / pg module, there is a better solution than setting NODE_TLS_REJECT_UNAUTHORIZED or rejectUnauthorized, which will lead to insecure connections.
Instead, configure the "ssl" option to match the parameters for tls.connect:
{
ca: fs.readFileSync('/path/to/server-ca.pem').toString(),
cert: fs.readFileSync('/path/to/client-cert.pem').toString(),
key: fs.readFileSync('/path/to/client-key.pem').toString(),
servername: 'my-server-name' // e.g. my-project-id/my-sql-instance-id for Google SQL
}
I've written a module to help with parsing these options from environment variables like PGSSLROOTCERT, PGSSLCERT, and PGSSLKEY:
https://github.com/programmarchy/pg-ssl
Hello just a small adition to this subject since in my case the
require('ssl-root-cas/latest')
.inject()
.addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');
didn't work out for me it kept returning error that the file could not be downloaded i had been a couple of hours into the reasearch of this particular error when I ran into this response https://stackoverflow.com/a/65442604
Since in my application we do have a proxy to proxy some of our requests as a security requirement of some of our users I found that in the case you are consulting an API that has this issue and if you can access the API url throught your browser you can proxy your request and it might fix the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE] issue.
An example of how i use my proxy
await axios.get(url, {
timeout: TIME_OUT,
headers: {
'User-Agent': 'My app'
},
params: params,
proxy: {
protocol: _proxy.protocol,
host: _proxy.hostname,
port: _proxy.port,
auth: {
username: _proxy_username,
password: _proxy_password
}
}
});
I had the same problem and I am able to fix it the following way,
Use the full-chain or just the chain certificate instead of just the certificate.
That is all.
This same error can be received when trying to install a local git shared repo from npm.
The error will read: npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
Apparently there is an issue with the certificate, however what worked for me was change the link to my shared repo in the package.json file from:
"shared-frontend": "https://myreposerver"
to:
"shared-frontend": "git+https://myreposerver"
In short, just adding git+ to the link solved it.
Another reason node could print that error is because a backend connection/service is misconfigured.
Unfortunately, the node error doesn't say which certificate it was unable to verify [feature request !]
Your server may have a perfectly good certificate chain installed for clients to connect and even show a nice padlock in the browser's URL bar, but when the server tries to connect to a backend database using a different misconfigured certificate, then it could raise an identical error.
I had this issue in some vendor code for some time. Changing a backend database connection from self-signed to an actual certificate resolved it.
You have to include the Intermediate certificate in your server. This solves the [Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE]

RPC Error - valid string HTTPs rpc in Metamask

In my project, I tried to connect with metamask on Ganache. But I got the error like the following.
inpage.js:1 MetaMask - RPC Error: Expected an array with at least one valid string HTTPS url 'rpcUrls', Received:
http://127.0.0.1:7545/
code: -32602
message: "Expected an array with at least one valid string HTTPS url 'rpcUrls', Received...
Please let me know how can fix it.
I'll be assuming your code looks like the following:
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: '0x539',
chainName: 'Gananche',
rpcUrls: 'http://127.0.0.1:7545/'
}
]
});
The rpcUrls value has to be an array, but from your error message it looks like you're passing a string. To fix this, make the value an array as follows:
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [
{
chainId: '0x539',
chainName: 'Gananche',
rpcUrls: ['http://127.0.0.1:7545/'] // Is now an array
}
]
});
you can install localtunnel to tunneling to local HTTPS server
npm install -g localtunnel
and after use the command line interface to request a tunnel to your local server:
lt --port 7545
An url will be created (ex: https://wise-mule-dig-195-131-122-13.loca.lt/)
Open the url created and click on the button "Click to continue"
After you can used this new url instead of http://127.0.0.1:7545/
I have had the same issue and I believe that it is because of the unsafe http url, since it allowed me to pass on the same parameters changing http to https.
So possibly localtunnel might work for you as Patrikoko said?
Another possibility that keeps everything local could be:
https://www.npmjs.com/package/local-ssl-proxy
This serves it with a self signed certificate
In the github readme is says you can serve it with your own trusted certificate as well:
https://github.com/cameronhunter/local-ssl-proxy#readme
local-ssl-proxy --key localhost-key.pem --cert localhost.pem --source 9001 --target 9000

Nodejs https request UNABLE_TO_GET_ISSUER_CERT_LOCALLY

OS: debian sid
Nodejs: v0.10.38
I have a request to a private service that use authentication:
var https = require('https');
var options = {
host: 'private.service.com',
path: '/accounts/' + '123323' + '/orders',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 0,
'Authorization': 'Bearer ' + 'asdsdgcvxcvxcv'
}
};
var request = https.request(options, function (res) {
console.log(res);
});
When i run the script, node throws this error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: UNABLE_TO_GET_ISSUER_CERT_LOCALLY
at SecurePair.<anonymous> (tls.js:1381:32)
at SecurePair.emit (events.js:92:17)
at SecurePair.maybeInitFinished (tls.js:980:10)
at CleartextStream.read [as _read] (tls.js:472:13)
at CleartextStream.Readable.read (_stream_readable.js:341:10)
at EncryptedStream.write [as _write] (tls.js:369:25)
at doWrite (_stream_writable.js:226:10)
at writeOrBuffer (_stream_writable.js:216:5)
at EncryptedStream.Writable.write (_stream_writable.js:183:11)
at write (_stream_readable.js:602:24)
The same exact script worked well for months, and i'm sure the authentication is correct. Today is the first time i have this situation.
Which can be the cause for this error?
After some study i found that this is a problem of the server that i'm trying to make the https request to.
Node https cannot find the ssl ISSUER_CERT on the private.service server and so it throw that exception.
The solution i used, since i'm sure i can trust that server, was to add
rejectUnauthorized: false
to the options of the https request, this way node will not throw an exception in case of certificates problem.
Anyway this solution is valid only if you know you can trust the host of your request, otherwise it's probably not the best solution.
There is a reason for SSL. Besides other features, it authenticates that you are really communicating with the server identified by private.service.com hostname. Otherwise your client software can be cheated by a Man-in-the-Middle attack.
First when anyone encounters this issue, they should update system root SSL certificates. In Debian they are contained in ca-certificates apt-get package.
If it doesn't help, the server probably uses an issuer certificate, which is not trusted by default worldwide PKI infrastructure. In this case the client should compare the certificate public key signature with a preshared value. This is known as "certificate pinning".
Specifically to your error, if it worked before, it is possible that the server certificate has expired. The server should renew it. As a temporary solution, you can turn off PKI validation by rejectUnauthorized option. However you should use it together with the pinning approach. In NodeJS, you can get the server certificate fingerprint from res.socket.getPeerCertificate().fingerprint.
After a reasearch this solved the problem:
npm set strict-ssl=false
Hope it helps.
From this GitHub issue, use the following environment variable:
export NODE_EXTRA_CA_CERTS=/path/to/certfile.crt
After this, you can run any of the npm commands and nodejs will trust your extra certificate file.
The .crt file is a file that contains a prefix line, the base64 encoded cert and a suffix line.
If you don't have your root CA cert handy, you can generate the cert file from your URL, with the openssl command:
openssl s_client \
-showcerts \
-servername <host> \
-connect <host>:443 2>/dev/null </dev/null | \
openssl x509
Where <host> is the hostname of the url. For example, using google.com for the host, the output looks something like this:
-----BEGIN CERTIFICATE-----
MIIIIDCCBwigAwIBAgIQI/1aCHwDN94QFUhXJeIwODANBgkqhkiG9w0BAQsFADBU
(42 more lines)
E+Hv1bJSbOMSNCDzqRM3JUzvM6Y=
-----END CERTIFICATE-----
Save that as your .crt file and add its path to the NODE_EXTRA_CA_CERTS environment variable and you're all set.
when I was trying to install npm on Ubuntu 16 i got the same error.
The following command worked for me.
npm config set registry http://registry.npmjs.org/

Install root certificate to Node.js (HTTPS Client)

I would like to connect to an internal corporate server with Node.js as a client via HTTPS.
How do I install my internal root certificate to Node.js, so the certificate validation is successful?
I don't want to disable certificate validation.
I solved the problem.
Use this, it works as charm: https://github.com/coolaj86/node-ssl-root-cas
Create a certificates folder
Place your root certificate there
Load the certificate with the module metnioned above
If you use Sails.js, put the code to config/bootstrap.js
Add an environment variable:
NODE_EXTRA_CA_CERTS=file
When set, the well known "root" CAs (like VeriSign) will be extended with the extra certificates in file. The file should consist of one or more trusted certificates in PEM format. A message will be emitted (once) with process.emitWarning() if the file is missing or malformed, but any errors are otherwise ignored.
Note that neither the well known nor extra certificates are used when the ca options property is explicitly specified for a TLS or HTTPS client or server.
This environment variable is ignored when node runs as setuid root or has Linux file capabilities set.
Hope this help someone:
var https = require('https');
var fs = require('fs');
var https_options = {
key: fs.readFileSync("/path/to/private.key"),
cert: fs.readFileSync("/path/to/your_domain_name.crt"),
ca: [
fs.readFileSync('path/to/CA_root.crt'),
fs.readFileSync('path/to/ca_bundle_certificate.crt')
]
};
Ref: https://cheapsslsecurity.com/blog/how-to-install-ssl-certificate-on-node-js/
And you can use this link to check your cert:
https://www.digicert.com/help/

Disabling TLS 1.1 in node.js?

I am currently experiencing a known problem with OpenSSL on Ubuntu 12.04. This problem is already fixed in Debian and I'm expecting it to be fixed soon in Ubuntu too. However, in the mean time I would need a workaround.
So is it possible to disable TLS1 in Node and have something equivalent to tls1 switch:
openssl s_client -tls1 -connect evernote.com:443
Here is a simple Node.js script to replicate the problem (on Ubuntu 12.04 w/ OpenSSL 1.0.1)
var https = require('https');
https.get({
host: 'www.evernote.com',
path: '/',
port: 443
}, function (res) {
console.log('Success!');
});
Judging from the documentation and the sources (1, 2), it should be possible to pass an options object to request that contains something like
options = { secureProtocol: 'TLSv1_method' }
in order to use TLSv1 (and just that) for this particular connection.
The default is to use OpenSSL's SSLv23_method, which means to use the highest TLS/SSL version that is possibly understood by both parties.
Although possible in OpenSSL itself, it is not possible to blacklist a particular TLS version (as in "use the highest version possible, but never this one") in node.js as far as I can see, the necessary flags to do so are not exported in node.js itself.
I ran into a bug where I couldn't connect to livefilestore.com over ssl via node. Here is what fixed it:
var https = require('https');
var HTTPS_AGENT = new https.Agent({
secureProtocol: 'SSLv3_method' // default is SSLv23_method
});
var req_opts = {...};
req_opts.agent = HTTPS_AGENT;
https.request(req_opts, function(res) { ... });
Interestingly, I was able to reproduce the error in curl with more recent versions of libopenssl, but my older boxes didn't reproduce the issue. I was able to reproduce on Ubuntu and Gentoo. In experimenting with curl, using the -2 always breaks (differently though, doesn't hang, just reports unsupported) and -3 never reproduced the problem. I don't know if that is related at all. Without specifying -3 it tries and fails to do an SSLv3 handshake. Strange.

Resources