Node.js won't load Let's Encrypt certificates - node.js

https_options:
{ key: '/etc/letsencrypt/live/mywebsite.com/privkey.pem',
cert: '/etc/letsencrypt/live/mywebsite.com/fullchain.pem' }
I just do https.createServer with the above options and get this error:
_tls_common.js:134
c.context.setCert(cert);
^
Error: error:0909006C:PEM routines:get_name:no start line
at Object.createSecureContext (_tls_common.js:134:17)
at Server.setSecureContext (_tls_wrap.js:1017:27)
at Server (_tls_wrap.js:897:8)
at new Server (https.js:61:14)
at Object.createServer (https.js:84:10)
at startWWW (myserver.js:192:9)
I tested the key/cert pair like this: (as others suggested in other questions, blog posts, forum threads)
openssl x509 -text -in /etc/letsencrypt/live/mywebsite.com/fullchain.pem
openssl rsa -text -in /etc/letsencrypt/live/mywebsite.com/privkey.pem
Both commands printed multiple lines of seemingly valid output.
lsb_release -a | grep Description
Description: Ubuntu 18.04.2 LTS

This should fix it:
key: fs.readFileSync('/etc/letsencrypt/live/mywebsite.com/privkey.pem', 'utf8'),
do the same for the cert too .(eg read in utf8 encoding)

Related

openssl certificate error for WinRM connection

I have on Windows server certificate which is valid and active and WinRM listener is active as well on port 5986 (telnet works) for WinRM connection that needs to be established from the Linux server.
I didn't copy that certificate anywhere on the linux server as I do not know where that should be or how it should be configured.
If I try to establish WinRM connection I am getting this error on the Linux server.
openssl s_client -connect 10.7.147.210:5986
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 1367 bytes and written 447 bytes
Verification error: unable to verify the first certificate
I tried by referencing CAfile and CApath and cert option but without success:
openssl s_client -cert winrmcert.pem -key winrmcert.key -CApath . -connect 10.7.147.210:5986
openssl s_client -CAfile winrmcert.pem -connect 10.7.147.210:5986
Can you please help me what I need to do and configure on Linux server for certificate generated on Windows server for WinRM connection? I am not the expert for this topic so I would appreciate all useful instructions. Thank you

NodeJS & SSL - "bad password read"

Node is failing to create a secure context for SSL communications.
Specifically, I'm trying to get remote notifications to work on iOS. I use a module, called node-apn which throws this error:
Error: error:0906A068:PEM routines:PEM_do_header:bad password read
at Error (native)
at Object.createSecureContext (_tls_common.js:108:19)
at Object.exports.connect (_tls_wrap.js:852:21)
at apnSocket (/home/Slurp/node_modules/apn/lib/socket.js:56:19)
at Connection.<anonymous> (/home/Slurp/node_modules/apn/lib/connection.js:188:17)
at _fulfilled (/home/Slurp/node_modules/apn/node_modules/q/q.js:834:54)
at self.promiseDispatch.done (/home/Slurp/node_modules/apn/node_modules/q/q.js:863:30)
at Promise.promise.promiseDispatch (/home/Slurp/node_modules/apn/node_modules/q/q.js:796:13)
This seems to be a generic error though, and isn't really related to APN specifically.
This is because you've specified a passphrase when generating the cert. This is a password that must be supplied by anyone wanting to use it.
Adding a passphrase field to the credentials solves the problem.
var credentials = {
key: fs.readFileSync('XXX.key', 'utf8'),
cert: fs.readFileSync('XXX.crt', 'utf8'),
passphrase: 'XXXX'
}
var httpsServer = https.createServer(credentials, app);
The following command will generate an unencrypted key, so you won't need to provide a passphrase:
openssl rsa -in yourKey.key -out newKey.key
This command will prompt you for the passphrase.
Use these to generate pem.
openssl genrsa -out server-key.pem 1024
openssl req -new -key server-key.pem -out server-csr.pem
openssl x509 -req -in server-csr.pem -signkey server-key.pem -out server-cert.pem

openSUSE shim certificate for uefi secure boot

Is openSUSE shim bootloader signed with openSUSE private key?
If so, where can I find the corresponding openSUSE certificate for secure boot verification purpose?
A public key can be retrieved from the shim source package:
Download
http://download.opensuse.org/source/distribution/13.1/repo/oss/suse/src/shim-0.2-3.1.src.rpm
Extract using e.g.:
rpm2cpio shim-0.2-3.1.src.rpm | cpio -dium
Unpack tar-ball that is inside:
tar-xJf shim-12.3-update.tar.xz
The certificate can now be found in the usr/lib64/efi subdir:
openssl x509 -inform der -in usr/lib64/efi/shim-opensuse.der -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=openSUSE Secure Boot CA, C=DE, L=Nuremberg, O=openSUSE Project/emailAddress=build#opensuse.org
You can verify 2nd stage bootloaders and kernels using sbverify from the sbsigntool package (that's what its called on Ubuntu)

curl openssl can't verify IIS 7 self-signed cert even when added to curl-ca-bundle.crt

I used IIS 7 on Windows Server Enterprise 2008 to generate a self-signed cert for use with IIS (basically one-click button).
However, even when I export and add this cert to a windows client's curl-ca-bundle.crt, neither it nor openssl.exe will not verify the cert correctly:
openssl s_client -CAfile curl-ca-bundle.crt -showcerts -connect myserver.ad.pri:443
CONNECTED(00000003)
depth=0 /CN=myserver.ad.pri
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /CN=myserver.ad.pri
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=myserver.ad.pri
i:/CN=myserver.ad.pri
-----BEGIN CERTIFICATE-----
MIIDADCCAeigAwIBAgIQTi9gdBLdo6pJ1h4Zljr/wzANBgkqhkiG9w0BAQUFADAp
....
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=myserver.ad.pri
issuer=/CN=myserver.ad.pri
---
No client certificate CA names sent
---
SSL handshake has read 924 bytes and written 444 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES128-SHA
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Start Time: 1377728216
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
read:errno=104
I used IE to export the cert to Base-64 Encoded, which is openssl-readable as PEM:
openssl x509 -inform PEM -in myserver.crt -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
4e:2f:60:74:12:dd:a3:aa:49:d6:1e:19:96:3a:ff:c3
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=myserver.ad.pri
Validity
Not Before: Aug 26 15:38:46 2013 GMT
Not After : Aug 26 00:00:00 2014 GMT
Subject: CN=myserver.ad.pri
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
....
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage:
Key Encipherment, Data Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha1WithRSAEncryption
...
-----BEGIN CERTIFICATE-----
....
openssl/curl with the same curl-ca-bundle.crt will verify certs from google.com:443 etc. just fine.
I also ran into this (and I'm very surprised more people haven't.) when I couldn't get a NodeJS HTTP(s) client to connect to an IIS instance with a self-signed-certificate on it (one created through IIS manager) Just got the dreaded' unable to verify the first certificate error!
It seems that this is because the certificates that IISManager creates for this purpose specify some 'Key Usage' extensions; 'Key Encipherment' and 'Data Encipherment'.
It turns out that when openssl encounters a certificate that specifies 'Key Usage' but fails to specify the 'certSign' usage then the openssl code will discount that certificate as a possible CA certificate even if it has been correctly provided to the openssl code (meaning it is unable to verify the certificate against said absent CA!).
(See the logic here https://github.com/openssl/openssl/blob/6f0ac0e2f27d9240516edb9a23b7863e7ad02898/crypto/x509v3/v3_purp.c#L503 )
The solution is as the one already above, which is to create your own certificates with the correct key usages (or no key usage extensions!)
I also thought I should include an alternative way of creating the Self Signed certificate that openssl clients would be happy with if you're in windows land.
First download the powershell script from here
In a powershell console (Administrative) execute the following commands from within a folder that contains the downloaded scripts
New-SelfsignedCertificateEx -StoreLocation "LocalMachine" -KeyUsage "DigitalSignature,KeyEncipherment,KeyCertSign" -Subject "CN=<HOST_NAME_TO_USE>" -FriendlyName "<HOST_NAME_TO_USE>" -SignatureAlgorithm sha256 -SubjectAlternativeName "<HOST_NAME_TO_USE>","anotherhost.org","someotherdomain.com"
Once you've executed the above command your LocalMachine\Personal Certificates store will contain a self-signed certificate that can be used by IIS for its SSL communications. (Please note you may also need to copy this certificate into one of the Trusted Root stores as well to guarantee that the certificate is trusted on that machine)
I solved this by using openssl to create a self-signed CA cert, then created a server cert request (also in OpenSSL, for some reason openssl does not like to sign requests generated by IIS), signed it with the former CA cert, then exported to PKCS12. Then imported into IIS. Once the CA cert is added to curl-ca-bundle.crt, it will verify the chain correctly:
Generate a CA:
openssl req -new -x509 -days 3650 -extensions v3_ca \
-keyout cakey.pem -out cacert.pem -config /etc/ssl/openssl.cnf \
-newkey rsa:2048
Generate a server key and signing request:
openssl req -new -nodes -out server-csr.pem -keyout server-key.pem -newkey rsa:2048
Sign the request with the CA:
openssl ca -config /etc/ssl/openssl.cnf -cert cacert.pem -keyfile cakey.pem \
-out server-cert.pem -in server-csr.pem
Export the server cert to PKCS#12:
openssl pkcs12 -export -out server-key-cert.pfx \
-inkey server-key.pem -in server-cert.pem -certfile cacert.pem
Import server-key-cert.pfx into IIS. (Re)bind the site binding's SSL binding to the cert.
Append cacert.pem to clients' curl-ca-bundle.crt. openssl s_client -showcerts -CAfile curl-ca-bundle.crt -connect server:443 has depth 0 and 1 and will verify return.
Notes: Make sure that keyUsage = nonRepudiation, digitalSignature, keyEncipherment is enabled under section [usr_cert] in openssl.cnf else requests won't contain those keyUsage and IIS will complain on binding.

Using Node JS TLS passphrase and cipher options when creating a server and client using elliptic curve keys (no shared cipher suites error)

In relation to this question, I am trying to start a TLS server in node.js to reflect the one I created in OpenSSL. I have tested the client and server using OpenSSL from the command line and they successfully make a connection. When I try to port the server to node.js (and still connect to it with an OpenSSL client), I receive a 'no shared cipher' error. I am wondering if there is something special I need to do when using the passphrase option with tls.createServer()
Below are my successful OpenSSL commands for server and client respectively, note that the passphrase.txt file contains a single line that is the passphrase:
$ openssl s_server -accept 8888 -cert server.cert -key server.key -pass file:passphrase.txt -CAfile ca.cert
$ openssl s_client -connect 127.0.0.1:8888 -cert client.cert -key client.key -pass file:passphrase.txt -CAfile ca.cert
I can also make a successful connection if I specify a cipher for the client and/or server with the additional argument of -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256'. I am using elliptic curve keys generated with openssl ecparam and signed with a CA created using openssl ca as discussed in my previous question.
The server code written in node.js looks like this:
var tls = require('tls');
var fs = require('fs');
var msg = '***********\n\nHello there secure client!\n\n***********';
var port = 8888;
var host = 'localhost';
var options = {
cert : fs.readFileSync('server.cert'),
key : fs.readFileSync('server.key'),
passphrase : (fs.readFileSync('passphrase.txt')).toString(),
ca : fs.readFileSync('ca.cert'),
// ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256',
// requestCert : true,
// rejectUnauthorized : true
};
tls.createServer(options, function(cleartextStream) {
if (cleartextStream.authorized) {
console.log('Server-side connection authorized by a Certificate Authority.');
} else {
// TODO this code does not appear to get executed even on failed connections
console.log('Server-side connection not authorized: ' + cleartextStream.authorizationError);
}
// send the server message to the client
cleartextStream.write(msg);
cleartextStream.setEncoding('utf8');
cleartextStream.pipe(cleartextStream);
}).listen(port, function() {
console.log('Server started on port: ' + port);
}).on('clientError', function(err){
console.log('A failed client connection attempt occurred.');
console.error(err);
console.log();
});
After calling the above code with node tlsServer.js and attempting to connect with an OpenSSL client on the command line, I receive the following messages.
SERVER:
$ node tlsServer.js
Server started on port: 8888
<< client started here >>
A failed client connection attempt occurred.
[Error: 6396:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:openssl\ssl\s3_srvr.c:1132:
]
CLIENT:
$ openssl s_client -connect 127.0.0.1:8888 -cert client.cert -key client.key -pass file:passphrase.txt -CAfile ca.cert
CONNECTED(00000003)
2674688:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
I am using node v0.6.15. And the errors do not change when I uncomment the ciphers, requestCert, and rejectUnauthorized in the options list sent to tls.createServer(). I also have a node.js cersion of the client, and I get a socket hang up code ECONNRESET when I attempt to connect to the node server, and the following error when trying to connect to a OpenSSL server:
Connection to localhost:8888 could not be made.
[Error: 6968:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:openssl\ssl\s23_clnt.c:602:
]
Thanks in advance for your help and ideas!
If the passphrase is wrong, maybe. Try removing it.
However, no_shared_cipher is an error raised when the client can't agree on a cipher suit with the server . Try first removing the cipher suit restriction on the server and seeing what it negotiates to use to isolate the problem. If this works, then place one with the client and see what happens.
Also, can you check that node is using the same openssl library as the openssl command.

Resources