You don't have to mess around with the openssl.cnf
file in any way.
The following command demonstrates how to generate a self-signed certificate with SAN for the email nobody@example.com
:
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout example.key -out example.crt -subj '/CN=Nobody' \
-extensions san \
-config <(echo '[req]'; echo 'distinguished_name=req';
echo '[san]'; echo 'subjectAltName=email:nobody@example.com')
The trick here is to include a minimal [req]
section that is good enough for OpenSSL to get along without its main openssl.cnf
file.
In OpenSSL ≥ 1.1.1, this can be shortened to:
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout example.key -out example.crt -subj '/CN=Nobody' \
-addext 'subjectAltName=email:nobody@example.com'
Here we are using the new -addext
option, so we don't need -extensions
and -config
anymore.
Don't forget to verify the contents of the generated certificate:
openssl x509 -noout -text -in example.crt
See also: https://security.stackexchange.com/a/198409/133603 and https://stackoverflow.com/a/41366949/19163
Yes what you've described is technically correct but there's a little bit more going on. The browser is determining that the host's CN is correct based on a few indicators.
The primary indication is that the host serving the HTTPS traffic's SSL certificate is being served from the correct domain, and that the signing chain of the certificate is also correct based on the CA (Certificate Authority) that issued & chain signed the certificate.
You can use openssl
's s_client
to get a sense of the back and forth that your browser would also be performing.
Example
$ openssl s_client -connect encrypted.google.com:443 < /dev/null | head -10
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = *.google.com
verify return:1
CONNECTED(00000003)
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
...
...
DONE
If you use this command you'll notice the CN that was used when generating the SSL certs:
$ openssl s_client -connect encrypted.google.com:443 < /dev/null|& grep "CN.*google"
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = *.google.com
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
So the browser will confirm that the hostname that's serving this cert falls within the hierarchy of the CN=...
that's included in the cert.
SNI
It used to be the case that you had to have a specific IP address set aside for each SSL server's hostname that you wanted to make use of over HTTPS. However this is no longer the case thanks to SNI (Server Name Indication).
excerpt
This works really well when a site has one SSL certificate installed per IP address (this used to be a hard requirement). With Server Name Indication (SNI), a web server can have multiple SSL certificates installed on the same IP address. SNI-capable browsers will specify the hostname of the server they’re trying to reach during the initial handshake process. This allows the web server to determine the correct SSL certificate to use for the connection.
Again using openssl
you can simulate what your browser would be doing in this scenario:
$ openssl s_client -connect someserver:443 -servername sslsite-example.com
excerpt
SSL negotiation must occur prior to sending the HTTP request through to the remote server. That means that the browser and the server have to do the certificate exchange earlier in the process and the browser wouldn’t get the opportunity to specify which site it’s trying to reach. SNI fixes that by allowing a Host: header type of exchange during the SSL negotiation process.
References
Best Answer
s_client
by default does not send SNI (Server Name Indication) data but a browser does. The server may choose to respond with a different certificate based on the contents of that SNI - or if no SNI is present then it will serve a default certificate. Try adding-servername api.paczkomaty.pl
to yours_client
command line