Parsing X509 Certificate Bundles in nodeJS - node.js

I am trying to parse a x509 certificate bundle which is a pem file consisting of multiple certificates in the following format:
-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----
I am able to read and parse a single certificate pem file using jsrsasign X509 library like so:
import r from "jsrsasign";
const cert = new r.X509();
cert.readCertPEM(input);
issuer = cert.getIssuerString();
I need to parse the certificate bundles in a similar fashion. How can I do it ? I am using Nodejs.
I tried using Regular Expressions to extract individual certificates as strings and pass it to cert.readCertPEM(input) in a loop. But I was not able to figure out the proper RE to do so.
If using RE is the way to go, then can I please know how I can do it.
Thanks.

Youcould match the begin certificate part, then capture in a group matching all lines that do not start with ----- using a negative lookahead (?!-----) and after that match the end certificate part.
^-----BEGIN CERTIFICATE-----\r?\n((?:(?!-----).*\r?\n)*)-----END CERTIFICATE-----
Regex demo
const regex = /^-----BEGIN CERTIFICATE-----\r?\n((?:(?!-----).*\r?\n)*)-----END CERTIFICATE-----/gm;
const str = `-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
xxxx
xxxx
xxxx
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
xxxx
-----END CERTIFICATE-----`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
console.log(m[1]);
}

Related

How to find header and footer of generated openssl key and what is the value of public key

Hello friends I got a task from my univerzity at home and i don't know how to answer on some questions. I appreciate it some help.
1.First of all i have to generate key with open ssl library
openssl genrsa -out private.pem 1024
Question: What is the method used to create a key? ( I think RSA?)
Cat private.pem
Question: What is the header and footer of file
Output:
cat private.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCXz+Vo+e6mX4HBMWdhmmLpbeQhlRhO+Ie8KQLmFlbOKHWaSeKJ
YJF21iadaNKdZUxVSCSpFHPvfdv7KtmiXj6xcGIaFQRKZbeAepTOiowpIBIvyunc
BMk6+PrkIR0ULiLdgmRZy5xVuy3pL58f4GwF/ZeyfeHDMzi0JBAZ01boswIDAQAB
AoGAYqnx3gz5ZlWR/d4+4zc0a6NI7e55UvHBPa+lu6XvGqM+81xrh38kawh5Jjp3
D2ZDevWdJeouAwtYSd+qfBUmRqmU3kJTSMU7hpIn3Lpk/0yWVVEamVMDi+DTwP4z
5dgrwFfFeb7rkA+bcBSAb/b0bKZiB1sIIgC3Q1kLytYf88ECQQDFUzV95y9ja5JP
qj0BfwnBgR7u+eKrfvROcDzDYjr5uJZgq6JfRPRrIhfBDQXcPBKwPmW3Z9Qgh7xO
WNOYEW7hAkEAxPQl0FEz79lWcY9FhUQxAym99hzz/vFjo9SKWSmjMGcTxqKnwf5M
6ZWSYif6xy+Gqm1uI3dG7wGOC1h9zEduEwJAfE1CcSFlFLf63vxamcqxFpiEJ/55
75Z1x8OkQ2Bpzk2dTSBRlLoXTjWXySCvBGFDVIq6AKMDWcqnsKL8B9tTgQJBAKie
DbGnk7uIasWWT4KkuwFmP0fxycM+jnu4fymOyDOsS/YHU3B2cwqYD1cRu1XEjppi
TaT3fTcqMZ3tCOZXURkCQCK9GUaRw0EJNp7X+QkH0HipuIdSQxeey26yGu3IS4xm
EZEoRxgpP/bSdgqL3uLZzTqW36fzwDUSa5xIOCDSvU8=
-----END RSA PRIVATE KEY-----
Question: what is value of public key
openssl rsa -in private.pem -text
Output:
Private-Key: (1024 bit)
modulus:
00:97:cf:e5:68:f9:ee:a6:5f:81:c1:31:67:61:9a:
62:e9:6d:e4:21:95:18:4e:f8:87:bc:29:02:e6:16:
56:ce:28:75:9a:49:e2:89:60:91:76:d6:26:9d:68:
d2:9d:65:4c:55:48:24:a9:14:73:ef:7d:db:fb:2a:
d9:a2:5e:3e:b1:70:62:1a:15:04:4a:65:b7:80:7a:
94:ce:8a:8c:29:20:12:2f:ca:e9:dc:04:c9:3a:f8:
fa:e4:21:1d:14:2e:22:dd:82:64:59:cb:9c:55:bb:
2d:e9:2f:9f:1f:e0:6c:05:fd:97:b2:7d:e1:c3:33:
38:b4:24:10:19:d3:56:e8:b3
publicExponent: 65537 (0x10001)
privateExponent:
62:a9:f1:de:0c:f9:66:55:91:fd:de:3e:e3:37:34:
6b:a3:48:ed:ee:79:52:f1:c1:3d:af:a5:bb:a5:ef:
1a:a3:3e:f3:5c:6b:87:7f:24:6b:08:79:26:3a:77:
0f:66:43:7a:f5:9d:25:ea:2e:03:0b:58:49:df:aa:
7c:15:26:46:a9:94:de:42:53:48:c5:3b:86:92:27:
dc:ba:64:ff:4c:96:55:51:1a:99:53:03:8b:e0:d3:
c0:fe:33:e5:d8:2b:c0:57:c5:79:be:eb:90:0f:9b:
70:14:80:6f:f6:f4:6c:a6:62:07:5b:08:22:00:b7:
43:59:0b:ca:d6:1f:f3:c1
prime1:
00:c5:53:35:7d:e7:2f:63:6b:92:4f:aa:3d:01:7f:
09:c1:81:1e:ee:f9:e2:ab:7e:f4:4e:70:3c:c3:62:
3a:f9:b8:96:60:ab:a2:5f:44:f4:6b:22:17:c1:0d:
05:dc:3c:12:b0:3e:65:b7:67:d4:20:87:bc:4e:58:
d3:98:11:6e:e1
prime2:
00:c4:f4:25:d0:51:33:ef:d9:56:71:8f:45:85:44:
31:03:29:bd:f6:1c:f3:fe:f1:63:a3:d4:8a:59:29:
a3:30:67:13:c6:a2:a7:c1:fe:4c:e9:95:92:62:27:
fa:c7:2f:86:aa:6d:6e:23:77:46:ef:01:8e:0b:58:
7d:cc:47:6e:13
exponent1:
7c:4d:42:71:21:65:14:b7:fa:de:fc:5a:99:ca:b1:
16:98:84:27:fe:79:ef:96:75:c7:c3:a4:43:60:69:
ce:4d:9d:4d:20:51:94:ba:17:4e:35:97:c9:20:af:
04:61:43:54:8a:ba:00:a3:03:59:ca:a7:b0:a2:fc:
07:db:53:81
exponent2:
00:a8:9e:0d:b1:a7:93:bb:88:6a:c5:96:4f:82:a4:
bb:01:66:3f:47:f1:c9:c3:3e:8e:7b:b8:7f:29:8e:
c8:33:ac:4b:f6:07:53:70:76:73:0a:98:0f:57:11:
bb:55:c4:8e:9a:62:4d:a4:f7:7d:37:2a:31:9d:ed:
08:e6:57:51:19
coefficient:
22:bd:19:46:91:c3:41:09:36:9e:d7:f9:09:07:d0:
78:a9:b8:87:52:43:17:9e:cb:6e:b2:1a:ed:c8:4b:
8c:66:11:91:28:47:18:29:3f:f6:d2:76:0a:8b:de:
e2:d9:cd:3a:96:df:a7:f3:c0:35:12:6b:9c:48:38:
20:d2:bd:4f
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCXz+Vo+e6mX4HBMWdhmmLpbeQhlRhO+Ie8KQLmFlbOKHWaSeKJ
YJF21iadaNKdZUxVSCSpFHPvfdv7KtmiXj6xcGIaFQRKZbeAepTOiowpIBIvyunc
BMk6+PrkIR0ULiLdgmRZy5xVuy3pL58f4GwF/ZeyfeHDMzi0JBAZ01boswIDAQAB
AoGAYqnx3gz5ZlWR/d4+4zc0a6NI7e55UvHBPa+lu6XvGqM+81xrh38kawh5Jjp3
D2ZDevWdJeouAwtYSd+qfBUmRqmU3kJTSMU7hpIn3Lpk/0yWVVEamVMDi+DTwP4z
5dgrwFfFeb7rkA+bcBSAb/b0bKZiB1sIIgC3Q1kLytYf88ECQQDFUzV95y9ja5JP
qj0BfwnBgR7u+eKrfvROcDzDYjr5uJZgq6JfRPRrIhfBDQXcPBKwPmW3Z9Qgh7xO
WNOYEW7hAkEAxPQl0FEz79lWcY9FhUQxAym99hzz/vFjo9SKWSmjMGcTxqKnwf5M
6ZWSYif6xy+Gqm1uI3dG7wGOC1h9zEduEwJAfE1CcSFlFLf63vxamcqxFpiEJ/55
75Z1x8OkQ2Bpzk2dTSBRlLoXTjWXySCvBGFDVIq6AKMDWcqnsKL8B9tTgQJBAKie
DbGnk7uIasWWT4KkuwFmP0fxycM+jnu4fymOyDOsS/YHU3B2cwqYD1cRu1XEjppi
TaT3fTcqMZ3tCOZXURkCQCK9GUaRw0EJNp7X+QkH0HipuIdSQxeey26yGu3IS4xm
EZEoRxgpP/bSdgqL3uLZzTqW36fzwDUSa5xIOCDSvU8=
-----END RSA PRIVATE KEY-----
1024bit RSA
-----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----
3.Public key is modulus + public Exponent
modulus:
00:97:cf:e5:68:f9:ee:a6:5f:81:c1:31:67:61:9a:
62:e9:6d:e4:21:95:18:4e:f8:87:bc:29:02:e6:16:
56:ce:28:75:9a:49:e2:89:60:91:76:d6:26:9d:68:
d2:9d:65:4c:55:48:24:a9:14:73:ef:7d:db:fb:2a:
d9:a2:5e:3e:b1:70:62:1a:15:04:4a:65:b7:80:7a:
94:ce:8a:8c:29:20:12:2f:ca:e9:dc:04:c9:3a:f8:
fa:e4:21:1d:14:2e:22:dd:82:64:59:cb:9c:55:bb:
2d:e9:2f:9f:1f:e0:6c:05:fd:97:b2:7d:e1:c3:33:
38:b4:24:10:19:d3:56:e8:b3
publicExponent: 65537 (0x10001)

How to use getAttributeValue() in ClientIdentity for fabric shim?

I am using nodejs sdk for hyperledger fabric, inside my chaincode i need to get name of the identity (sam) who is execting the transaction.
{"name":"sam","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"5aad871581d63447218743ee79289c0c6f531a032d3cf1f0be32083e8c0cbaea","identity":{"certificate":"-----BEGIN CERTIFICATE-----\nMIICizCCAjGgAwIBAgIUQq0tPLPFsLujCsRclZc9POmAh6EwCgYIKoZIzj0EAwIw\nczELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT\nE2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTkxMTE5MDU0ODAwWhcNMjAxMTE4MDU1\nMzAwWjBAMTAwDQYDVQQLEwZjbGllbnQwCwYDVQQLEwRvcmcxMBIGA1UECxMLZGVw\nYXJ0bWVudDExDDAKBgNVBAMTA3NhbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA\nBGbtyGsC9QNBlO0Z5sumDzEaYR4m8GJpXW2f8Qlvjt79IzCWDjGwFePAIOfnUojz\naDbr0VHgpnWOtUIKUqTVPOujgdUwgdIwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB\n/wQCMAAwHQYDVR0OBBYEFCR78iTBbBSCYjxajhOMyYrWDO8iMCsGA1UdIwQkMCKA\nIHWD+xHmJ7l80nLYW67w4+Bftya5oeDfD9d4KXfnqn3NMGYGCCoDBAUGBwgBBFp7\nImF0dHJzIjp7ImhmLkFmZmlsaWF0aW9uIjoib3JnMS5kZXBhcnRtZW50MSIsImhm\nLkVucm9sbG1lbnRJRCI6InNhbSIsImhmLlR5cGUiOiJjbGllbnQifX0wCgYIKoZI\nzj0EAwIDSAAwRQIhAJcIBDcygI6Z67ueo46b3WnJCZr+D1HzhaWNp6Lj/+7oAiA6\nRRc9JjnWFvaFaqIJTyNaE7/HFXTXKr+HIkig/UEZpQ==\n-----END CERTIFICATE-----\n"}}}
I have used the below code
async approve(ctx) {
try {
const owId = new clientIdentity(ctx.stub).getAttributeValue('name')
return owId.toString();
} catch(error) {
console.log(error);
throw new Error(`Low on amount`);
}
}
but the above code is not returning the name or any other attributes.
Help will be appreciated!!!
The attributes you retrieve with getAttributeValue() in the Smart Contract are created as follows with the command line:
fabric-ca-client register --id.name clare --id.secret hursley1 --id.maxenrollments -1 --id.attrs 'department=Finance:ecert,location=Berkshire:ecert'
So I'm creating 2 attributes for department and location. Note the :ecert on the end which means that I want the attributres written to the certificate, not just stored in the CA database. Note also that the attributes aren't added to existing certificates, but only "appear" when you have enrolled or renrolled.
Using the node SDK this is a snippet of code that would add the department attribute when registering an Identity:
//create user attr array
let registerAttrs = [];
let registerAttribute = {
name: "department",
value: "Finance",
ecert: true
};
registerAttrs.push(registerAttribute);
// at this point we should have the admin user
// first need to register the user with the CA server
return fabric_ca_client.register(
{
enrollmentID: username,
affiliation: "org1",
role: "client",
attrs: registerAttrs
},
admin_user
);
In your smart contract you can then access the attribute:
ctx.clientIdentity.getAttributeValue('department');
Note that with the fabric-contract-api the clientIdentity object is already populated so you don't need a new clientIdentity object.
You have no attribute named "name". If you analyze your X.509 certificate...
openssl x509 -text -noout -in yourcert.pem
...you get...
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
42:ad:2d:3c:b3:c5:b0:bb:a3:0a:c4:5c:95:97:3d:3c:e9:80:87:a1
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = California, L = San Francisco, O = org1.example.com, CN = ca.org1.example.com
Validity
Not Before: Nov 19 05:48:00 2019 GMT
Not After : Nov 18 05:53:00 2020 GMT
Subject: OU = client + OU = org1 + OU = department1, CN = sam
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:66:ed:c8:6b:02:f5:03:41:94:ed:19:e6:cb:a6:
0f:31:1a:61:1e:26:f0:62:69:5d:6d:9f:f1:09:6f:
8e:de:fd:23:30:96:0e:31:b0:15:e3:c0:20:e7:e7:
52:88:f3:68:36:eb:d1:51:e0:a6:75:8e:b5:42:0a:
52:a4:d5:3c:eb
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
24:7B:F2:24:C1:6C:14:82:62:3C:5A:8E:13:8C:C9:8A:D6:0C:EF:22
X509v3 Authority Key Identifier:
keyid:75:83:FB:11:E6:27:B9:7C:D2:72:D8:5B:AE:F0:E3:E0:5F:B7:26:B9:A1:E0:DF:0F:D7:78:29:77:E7:AA:7D:CD
1.2.3.4.5.6.7.8.1:
{"attrs":{"hf.Affiliation":"org1.department1","hf.EnrollmentID":"sam","hf.Type":"client"}}
Signature Algorithm: ecdsa-with-SHA256
30:45:02:21:00:97:08:04:37:32:80:8e:99:eb:bb:9e:a3:8e:
9b:dd:69:c9:09:9a:fe:0f:51:f3:85:a5:8d:a7:a2:e3:ff:ee:
e8:02:20:3a:45:17:3d:26:39:d6:16:f6:85:6a:a2:09:4f:23:
5a:13:bf:c7:15:74:d7:2a:bf:87:22:48:a0:fd:41:19:a5
Your attribute keys are:
hf.Affiliation
hf.EnrollmentID
hf.Type
There is no "name" attribute. You are probably looking for "hf.EnrollmentID".
EDIT: You yourself indicated your certificate in your question, in enrollment.identity.certificate field. I have only saved...
-----BEGIN CERTIFICATE-----
MIICizCCAjGgAwIBAgIUQq0tPLPFsLujCsRclZc9POmAh6EwCgYIKoZIzj0EAwIw
czELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh
biBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT
E2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTkxMTE5MDU0ODAwWhcNMjAxMTE4MDU1
MzAwWjBAMTAwDQYDVQQLEwZjbGllbnQwCwYDVQQLEwRvcmcxMBIGA1UECxMLZGVw
YXJ0bWVudDExDDAKBgNVBAMTA3NhbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
BGbtyGsC9QNBlO0Z5sumDzEaYR4m8GJpXW2f8Qlvjt79IzCWDjGwFePAIOfnUojz
aDbr0VHgpnWOtUIKUqTVPOujgdUwgdIwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB
/wQCMAAwHQYDVR0OBBYEFCR78iTBbBSCYjxajhOMyYrWDO8iMCsGA1UdIwQkMCKA
IHWD+xHmJ7l80nLYW67w4+Bftya5oeDfD9d4KXfnqn3NMGYGCCoDBAUGBwgBBFp7
ImF0dHJzIjp7ImhmLkFmZmlsaWF0aW9uIjoib3JnMS5kZXBhcnRtZW50MSIsImhm
LkVucm9sbG1lbnRJRCI6InNhbSIsImhmLlR5cGUiOiJjbGllbnQifX0wCgYIKoZI
zj0EAwIDSAAwRQIhAJcIBDcygI6Z67ueo46b3WnJCZr+D1HzhaWNp6Lj/+7oAiA6
RRc9JjnWFvaFaqIJTyNaE7/HFXTXKr+HIkig/UEZpQ==
-----END CERTIFICATE-----
...as yourcert.pem to check it via openssl.

Node TLS socket : DEPTH_ZERO_SELF_SIGNED_CERT error

I am trying to setup a server and some clients using TLS in node. I am using self-signed certificates on the clients and the server. The server runs ok, but when I try to connect a client I end up with the following error on the client side:
Error: DEPTH_ZERO_SELF_SIGNED_CERT
Cert Generation
CA cert:
# Create key to sign our own certs. Act like as our own a CA.
echo "SecuresPassphrase" > ./tls/passphrase.txt
openssl ecparam -name secp521r1 -genkey -noout -out ./tls/certs/ca/ca.plain.key # Generate private key
openssl pkcs8 -topk8 -passout file:./tls/passphrase.txt -in ./tls/certs/ca/ca.plain.key -out ./tls/certs/ca/ca.key # Generate encrypted private key
rm ./tls/certs/ca/ca.plain.key; # Remove unencrypted private key
# Generate CA cert
openssl req -config ./openssl/oid_file -passin file:./tls/passphrase.txt -new -x509 -days 365 -key ./tls/certs/ca/ca.key -out ./tls/certs/ca/ca.crt
Server Cert:
openssl ecparam -name secp521r1 -genkey -noout -out ./tls/certs/servers/server.key # Generate server private key
openssl req -config ./openssl/oid_file -new -key ./tls/certs/servers/server.key -out ./tls/certs/servers/server.csr # Generate signing request
openssl x509 -passin file:./tls/passphrase.txt -req -days 365 -in ./tls/certs/servers/server.csr -CA ./tls/certs/ca/ca.crt -CAkey ./tls/certs/ca/ca.key -CAcreateserial -out ./tls/server.crt
mv ./tls/server.crt ./tls/certs/servers/
Client cert:
Client's certs are created inside a bash loop, the variable ${name} contains the name of the client and changes each iteration.
openssl ecparam -name secp521r1 -genkey -noout -out ./tls/certs/clients/${name}/client.key
openssl req -config ./openssl/oid_file -new -key ./tls/certs/clients/${name}/client.key -out ./tls/certs/clients/${name}/client.csr
openssl x509 -passin file:./tls/passphrase.txt -req -days 365 -in ./tls/certs/clients/${name}/client.csr -CA ./tls/certs/ca/ca.crt -CAkey ./tls/certs/ca/ca.key -CAcreateserial -out ./tls/client.crt
mv ./tls/client.crt ./tls/certs/clients/${name}/
I am also trying to use Perfect Forward Secrecy by using ephemereal Diffie-Hellman interchange. The parameters, for clients and server, are created as openssl dhparam -outform PEM -out ./tls/params/servers/server/dhparams.pem 2048
Server's code:
return new Promise(resolve => {
// Define parameters of TLS socket
const options = {
rejectUnauthorized: false,
requestCert: true,
// Secure Context Parameters
ca: [fs.readFileSync("tls/certs/ca/ca.crt")],
cert: fs.readFileSync("tls/certs/servers/server.crt"),
key: fs.readFileSync("tls/certs/servers/server.key"),
ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:!RC4:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!SRP:!CAMELLIA",
dhparam: fs.readFileSync("tls/params/servers/server/dhparams.pem"),
ecdhCurve: tls.DEFAULT_ECDH_CURVE,
minVersion: "TLSv1.2"
};
// Iniciar servidor TLS
this.SERVIDOR = tls.createServer(options, function (socket) {
console.log("Server created.");
});
this.SERVIDOR.listen(this.puerto, this.direccion, function () {
console.log("Listening");
});
this.SERVIDOR.on("secureConnection", (socket) => this.handleRequest(socket));
this.SERVIDOR.on("tlsClientError", (error) => console.log("Error client TLs. %s", error));
});
Client's code:
return new Promise(resolve => {
// Define parameters of TLS socket
const options = {
host: this.NODE,
port: this.NODE_PORT,
rejectUnauthorized: false,
secureContext: tls.createSecureContext({
ca: [fs.readFileSync("tls/certs/ca/ca.crt")],
cert: fs.readFileSync("tls/certs/clients/" + this.NAME + "/client.crt"),
key: fs.readFileSync("tls/certs/clients/" + this.NAME + "/client.key"),
ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:!RC4:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!SRP:!CAMELLIA",
dhparam: fs.readFileSync("tls/params/clients/" + this.NAME + "/dhparams.pem"),
ecdhCurve: tls.DEFAULT_ECDH_CURVE,
minVersion: "TLSv1.2"
})
};
// Initialize TLS socket
this.WEB_SOCKET = tls.connect(options, function () {
// Check if TLS auth worked
if (this.authorized) {
console.log("Connection authorized by a Cert. Authority ");
} else {
console.log("Authorization not granted. Error: " + this.authorizationError);
}
});
What I have tried:
Set rejectUnauthorized to false.
Tried to run the code with NODE_TLS_REJECT_UNAUTHORIZED = "0";. It didn't work and I think is not a good option for production.
Checked similar questions on SO, this one it looks pretty similar to my problem. But the most upvoted answer is from 2014 and I couldn't find too much information about Distinguished name on the docs.
I checked the certs using openssl x509 -in *.cert -text and they looked good.
¿Am I wrongly generating the certs? Any help is appreciated.
Thanks!
EDIT. 16/10/2019
There was a problem in the code, I didn't use resolve(); when the sockets were up. The same problem remains... BUT despite of getting an authorization error on the client, the server fires up the "secureConnection" event and messages are interchanged. ¿Does this makes sense? *Yes, it makes sense since the server accepts unauthorized connections. If I set the server to reject not certified connections the clients hung up *
The problem was I was using the same configuration file (./openssl/oid_file) for all the certificates. Using different configuration files and different Alternative names solved this issue.
I ended with an "UNABLE_TO_VERIFY_LEAF_SIGNATURE" error. The certificates were properly generated but it didn't work. I couldn't find a working example of self-signed certificates in nodejs. Most of them simply deprecated the use of certificates by disabling SSL or accepting unathorized transactions, which is the opposite of what TLS is supposed to do.
Finally, I used this tool to generate the certificates: https://github.com/FiloSottile/mkcert . The best and simplest way to generate self-signed certificates in a testing environment. You only need to set the node variable NODE_EXTRA_CA_CERTS to point the root certificate:
process.env.NODE_EXTRA_CA_CERTS = [os.homedir() + "/.local/share/mkcert/rootCA.pem"];
-

Different certificate chain order when using Node's HTTPS/TLS vs. OpenSSL s_client

I'm trying to parse the certificate chain using Node's HTTPS request. I'm testing it on npmjs.com (not www.npmjs.com). When I test it on OpenSSL, it shows me that the chain is in the incorrect order.
openssl s_client -connect npmjs.com:443 -showcerts
OpenSSL Response First Certificate
subject: /OU=GT40876434/OU=See www.rapidssl.com/resources/cps (c)14/OU=Domain Control Validated - RapidSSL(R)/CN=*.npmjs.com
issuer: /C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
Next Certificate ->
subject: /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
issuer: /C=US/O=Equifax/OU=Equifax Secure Certificate Authority
Next Certificate ->
subject: /C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
issuer: /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
However, when I go to step through the certificate chain using my Node's HTTPS request, when the socket is emitted and I do
socket.getPeerCertificate(true)
the chain is in the correct order and I'm getting one different certificate on the Node request than I am on the openssl request.
Node's Response First Certificate:
subject
{ OU:
[ 'GT40876434',
'See www.rapidssl.com/resources/cps (c)14',
'Domain Control Validated - RapidSSL(R)' ],
CN: '*.npmjs.com' }
issuer
{ C: 'US', O: 'GeoTrust Inc.', CN: 'RapidSSL SHA256 CA - G3' }
Next Certificate ->
subject
{ C: 'US', O: 'GeoTrust Inc.', CN: 'RapidSSL SHA256 CA - G3' }
issuer
{ C: 'US', O: 'GeoTrust Inc.', CN: 'GeoTrust Global CA' }
Next Certificate ->
subject
{ C: 'US', O: 'GeoTrust Inc.', CN: 'GeoTrust Global CA' }
issuer
{ C: 'US', O: 'GeoTrust Inc.', CN: 'GeoTrust Global CA' }
Why is this happening?
It looks like node is reordering the certificates for returning in getPeerCertificates so that they reflect the correct order in the trust chain (*). But in reality the certificates are in the wrong order, as can be seen by openssl s_client and also in the analysis of SSLLabs:
Chain issues Incorrect order
(*) the relevant code in node-4.5.0 (LTS) is in src/node_crypto.cc function void SSLWrap<Base>::GetPeerCertificate. There it retrieves the leaf certificate and the original peer certificates from the openssl library using SSL_get_peer_certificate (leaf certificate) and SSL_get_peer_cert_chain (chain). It then does not return the certificates in the original chain order but scans through the chain and adds the certificates in the order how they are depend on each other by checking with X509_check_issued.
This way it returns the certificates in proper dependency order instead of the original order as send by the peer. It also automatically skips any certificates which don't belong in the chain.
It will also add the issuer of the certificate even if it is not contained it the chain (which it usually isn't). This way you not only get a different order of certificates as seen in your example but actually different certificates. The server sends the following certificates in this order:
[A] /OU=GT40876434/OU=See www.rapidssl.com/resources/cps (c)14/OU=Domain Control Validated - RapidSSL(R)/CN=*.npmjs.com
[B] /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA, issued by Equifax
[C] /C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
But getPeerCertificate returns the following:
[A] /OU=GT40876434/OU=See www.rapidssl.com/resources/cps (c)14/OU=Domain Control Validated - RapidSSL(R)/CN=*.npmjs.com
[C] /C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G3
[R] CA/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA, self-signed
Thus certificate [B] will not be included but instead certificate [R] which is the root certificate contained in the trust store. Both have the same subject and key, but are signed by different entities. [B] is signed by Equifax while [R] is self-signed.

SSL in socket.io with express: Missing PFX or certificate + private key.

I want to socket with socket.io through SSL. I have read the other answers but nothing worked
Here is my code:
var ssl_options = {
key : fs.readFileSync(my_key_path),
cert : fs.readFileSync(my_cert_path)
};
var protocol = "https";
preparedApp = require(protocol).createServer(ssl_options,app);
var io = require('socket.io')(preparedApp);
preparedApp.listen(8080, function(){});
io.on('connection', function(socket){});
And here is the log of my ssl_options...
{ key: <Buffer 41 ...>,
cert: <Buffer 4a ...> }
This errors with the error in the title throw new Error('Missing PFX or certificate + private key.');. Does anyone know what might be happening? None of the other solutions to this answer solved my case.
Use PEM (RSA) format for your private key. Check if the private key is a base64 encoded, enclosed between "-----BEGIN RSA PRIVATE KEY-----" and "-----END RSA PRIVATE KEY-----"
From the docs:
key: A string or Buffer containing the private key of the server in PEM format
cert : A string holding the PEM encoded certificate
passphrase: A string of passphrase for the private key or pfx [optional default: null]
or
pfx : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
To convert a private key to RSA PEM: openssl rsa -in <PATH TO KEY> -out key.pem -outform PEM
To create a PKCS #12 bundle use openssl pkcs12 -export -in cert.pem -inkey key.pem -certfile ca.pem -out host.pfx
-- ADDITION --
To ensure the cert is PEM encoded run openssl x509 -in <PATH TO CERT> -out cert.pem -outform PEM

Resources