In cowboy's ssl directory I see 3 files
cowboy-ca.crt
, server.crt
and server.key
.
Probably somewhere the directory they have the cowboy-ca.key
which is not needed.
I can guess that cowboy-ca.crt
is the public key of some default CA, and that is being used to sign the server.crt
using csr file for server's key pair, and when the client connects to cowboy it downloads and installs the server.crt file to establish secure connections to server, am I correct?
The question is how do I generate all these there files using openssl and my own CA?
There are tutorials on the net for this, but I happen to have a record from doing it before. It has quite a bit more than you need, but will show you how to achieve the basics of creating your own CA and certificates signed from it. My record, pasted below, creates a CA, creates an intermediate CA signed by the CA, and finally creates a certificate that can be used on a server. You don't need the intermediate CA obviously, so you should skip the middle bit and sign your final / end certificate with your root CA instead of the intermediate CA, so for example, when creating end.crt, instead of signing with ../inter_ca/inter.key, use ../root_ca/rootca.key, etc.
I'm assuming you are asking the right correct question here, and that a self signed certificate really is what you want.
After the creation of the certificates and keys, there is also guidance on configuring Apache, and a description of how to use the OpenSSL tools to verify that it is working correctly (on any SSL TCP connection, so that's applicable to Cowboy or anything else too). This will show you the trust chain, though yours will be depth 1 instead of depth 2 because you'll omit the intermediate CA.
Create some directories to work with:
mkdir inter_ca_demo
cd inter_ca_demo
mkdir root_ca inter_ca end_cert
cd root_ca
Create a key:
openssl genrsa -out rootca.key 2048
Output will be something like:
Generating RSA private key, 2048 bit long modulus
...........................................................+++
.............................+++
e is 65537 (0x10001)
Self sign it to create your root CA certificate (you will have to enter various information that will be encoded into the certificate):
openssl req -x509 -new -nodes -key rootca.key -days 1024 -out rootca.pem
It should look something like (here you can see what I entered):
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:London
Locality Name (eg, city) []:London
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Method Analysis Ltd
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:methodanalysis.com
Email Address []:ca_admin@methodanalysis.com
Before moving on to the intermediate you must rename, copy or create a link to the root certificate so that it can be found by way of a hash algorithm. This is to make sure performance isn't degraded if there are a lot of trusted certificates in your CA path. To do this you must find out what the hash is with the following command:
openssl x509 -noout -hash -in rootca.pem
The output should be something like:
03ed4e37
Then create the link, adding a .0 to YOUR HASH (as output from the previous command):
ln -s rootca.pem 03ed4e37.0
Now create the intermediate CA key and a CSR (Certificate Signing Request) (you will have to enter various information that will be encoded into the certificate):
cd ../inter_ca
openssl genrsa -out inter.key 2048
openssl req -new -key inter.key -out inter.csr
It should look something like this:
$ openssl genrsa -out inter.key 2048
Generating RSA private key, 2048 bit long modulus
.........................................+++
..............................................................+++
e is 65537 (0x10001)
$ openssl req -new -key inter.key -out inter.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:London
Locality Name (eg, city) []:London
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Intermediate certificates R US Ltd
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:intermediatecasrus.com
Email Address []:ca_admin@intermediatecasrus.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Now create a file (v3x509extensions.txt) which includes data that indicates this should be an intermediate CA, then generate the intermediate certificate, signing with your root CA:
echo 'basicConstraints=CA:TRUE' > v3x509extensions.txt
openssl x509 -req -extfile v3x509extensions.txt -in inter.csr -CA ../root_ca/rootca.pem -CAkey ../root_ca/rootca.key -CAcreateserial -out inter.crt -days 200
It should look something like this:
Signature ok
subject=/C=GB/ST=London/L=London/O=Intermediate certificates R US Ltd/CN=intermediatecasrus.com/emailAddress=ca_admin@intermediatecasrus.com
Getting CA Private Key
Now create your final key (that you are going to use for an SSL website (for example)), create a CSR from it, and sign it with your intermediate certificate, generating a new certificate:
cd ../end_cert
openssl genrsa -out end.key 2048
openssl req -new -key end.key -out end.csr
openssl x509 -req -in end.csr -CA ../inter_ca/inter.crt -CAkey ../inter_ca/inter.key -CAcreateserial -out end.crt -days 500
It should look something like this:
$ openssl genrsa -out end.key 2048
Generating RSA private key, 2048 bit long modulus
................................................+++
.....................................................+++
e is 65537 (0x10001)
$ openssl req -new -key end.key -out end.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:London
Locality Name (eg, city) []:London
Organization Name (eg, company) [Internet Widgits Pty Ltd]:End User Ltd
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:intermediatecademo-enduser.com
Email Address []:support@intermediatecademo-enduser.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
$ openssl x509 -req -in end.csr -CA ../inter_ca/inter.crt -CAkey ../inter_ca/inter.key -CAcreateserial -out end.crt -days 500
Signature ok
subject=/C=GB/ST=London/L=London/O=End User Ltd/CN=intermediatecademo-enduser.com/emailAddress=support@intermediatecademo-enduser.com
Getting CA Private Key
At this point, you can check things look ok by verifying the trust chains, here I concat the intermediate and the 'end' certificates, and then verify them using only the root CA path (remember the 'end' certificate can't be verified without the intermediate CA, so it must be given with the 'end' certificate):
cat ../inter_ca/inter.crt end.crt | openssl verify -CApath ../root_ca
The output should be:
stdin: OK
If you used these keys with apache for example, you could configure them like this:
SSLCertificateFile FULL_PATH_TO/inter_ca_demo/end_cert/end.crt
SSLCertificateKeyFile FULL_PATH_TO/inter_ca_demo/end_cert/end.key
SSLCertificateChainFile FULL_PATH_TO/inter_ca_demo/inter_ca/inter.crt
SSLCACertificatePath FULL_PATH_TO/inter_ca_demo/root_ca
Apache will now provide the intermediate certificate along with its own, which allows a web client to perform the same sort of verification (along with other checks) as above using 'openssl verify'.
If you did use these certificates with apache, and you create a website with a name 'intermediatecademo-enduser.com' in keeping with the 'end' certificate you created, you can also use openssl to verify the certificates from a clients perspective:
openssl s_client -connect intermediatecademo-enduser.com:443 -CApath root_ca -verify 5
Output should be something like this:
verify depth is 5
CONNECTED(00000004)
depth=2 C = GB, ST = London, L = London, O = Method Analysis Ltd, CN = methodanalysis.com, emailAddress = ca_admin@methodanalysis.com
verify return:1
depth=1 C = GB, ST = London, L = London, O = Intermediate certificates R US Ltd, CN = intermediatecasrus.com, emailAddress = ca_admin@intermediatecasrus.com
verify return:1
depth=0 C = GB, ST = London, L = London, O = End User Ltd, CN = intermediatecademo-enduser.com, emailAddress = support@intermediatecademo-enduser.com
verify return:1
---
Certificate chain
0 s:/C=GB/ST=London/L=London/O=End User Ltd/CN=intermediatecademo-enduser.com/emailAddress=support@intermediatecademo-enduser.com
i:/C=GB/ST=London/L=London/O=Intermediate certificates R US Ltd/CN=intermediatecasrus.com/emailAddress=ca_admin@intermediatecasrus.com
1 s:/C=GB/ST=London/L=London/O=Intermediate certificates R US Ltd/CN=intermediatecasrus.com/emailAddress=ca_admin@intermediatecasrus.com
i:/C=GB/ST=London/L=London/O=Method Analysis Ltd/CN=methodanalysis.com/emailAddress=ca_admin@methodanalysis.com
---
Server certificate
...
...
...
Start Time: 1445696823
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
It will hang now, waiting for data to be sent. You can just CTRL+C to quit.