K
K
kirick2015-09-22 16:40:19
JavaScript
kirick, 2015-09-22 16:40:19

How to fix StartSSL certificate in Node.js v4.1.0?

I decided just now to upgrade from Node.js v0.12.7 to Node.js v4.1.0. After the update, the problem is that when requesting the server via curl (from the command line), this same curl refuses to make a request with an error:

* About to connect() to test.monopoly-one.com port 443 (#0)
* Trying 51.254.61.44... connected
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3 , TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
* Closing connection #0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.

The same curl request with the `-k` option:
* About to connect() to test.monopoly-one.com port 443 (#0)
* Trying 51.254.61.44... connected
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3 , TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
* subject: C=RU; CN=test.monopoly-one.com; [email protected]
* start date: 2015-06-28 08:38:09 GMT
* expire date: 2016-06-28 18:38:55 GMT
* issuer: C=IL; O=StartCom Ltd.; OU=Secure Digital Certificate Signing; CN=StartCom Class 1 Primary Intermediate Server CA
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.

At the same time, if you roll back to Node.js v0.12.7, then absolutely the same server code with exactly the same certificate and key does not cause any discomfort for curl on the same device:
* About to connect() to test.monopoly-one.com port 443 (#0)
* Trying 51.254.61.44... connected
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3 , TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
* subject: C=RU; CN=test.monopoly-one.com; [email protected]
* start date: 2015-06-28 08:38:09 GMT
* expire date: 2016-06-28 18:38:55 GMT
* issuer: C=IL; O=StartCom Ltd.; OU=Secure Digital Certificate Signing; CN=StartCom Class 1 Primary Intermediate Server CA
* SSL certificate verify ok.

That is, the problem is clearly not where curl is executed, but in the Node.js version, however, I could not find a changelog on the network that clearly describes what has changed in Node.js in terms of creating an https server.
A piece of code that creates an https server:
var __fs = require('fs'),
    __https = require('https');
self.__server = __https.createServer({
    cert: __fs.readFileSync('/valid/path/to.crt'),
    key: __fs.readFileSync('/valid/path/to_decrypted.key')
}, self.preparer);
self.__server.addContext('test.monopoly-one.com', {
    cert: __fs.readFileSync('/valid/path/to.crt'),
    key:  __fs.readFileSync('/valid/path/to_decrypted.key'),
    ca: [
        __fs.readFileSync('/valid/path/to/startssl/ca.pem')
        __fs.readFileSync('/valid/path/to/startssl/sub.class1.server.ca.pem')
    ]
});
self.__server.listen(443);

Same version, but using tls.createSecureContext() and SNICallback instead of self.__server.addContext behaves exactly the same.
UPD: I forgot to mention that all modern browsers behave exactly the same and do not show any concerns.
UPD 2: reordering the chiphers helps make curl change ECDHE-RSA-AES256-GCM-SHA384 to ECDHE-RSA-AES128-GCM-SHA256 (as before), but it still doesn't trust the certificate.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
kirick, 2016-02-04
@kirick

The solution was found - now the content of the files from the array cashould not be sent to Node.JS, but written directly to the .crt file, creating a chain. That is, the file /valid/path/to.crtmust contain the certificate itself, then it must also contain an intermediate certificate and a root one. And then everything works.

B
banifaciy, 2015-09-23
@banifaciy

That's right, pay attention to cipher.
In the first case, * SSL connection using ECDHE-RSA-AES128-GCM-SHA256
is used In the second case, * SSL connection using ECDHE-RSA-AES256-GCM-SHA384
The problem is that the guys changed the default cipher. As mentioned in the changelog: https://github.com/nodejs/node/blob/v4.1.1/CHANGEL...
Your problem is solved by setting the ciphers parameter in the options when creating the server https.createServer
You can see more details here: https://github.com/nodejs/node/pull/826

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question