I am having an issue with chained certs.
Update: Using this tutorial, it is closer.
https://www.golinuxcloud.com/openssl-create-certificate-chain-linux/
But not solved. See the part below starting at EDIT: ADDITIONAL PROGRESS.:
I am using OpenSSL 1.0.1g for both command line and compiling the programs.
I have a company CA which works fine. I have signed certs with it no problem. And have the CA imported into the Windows store, so I get no warnings from any use of a certificate singed by it.
Since I won't post it's details here, We will call it "RootCA".
I want the ability to create this chain, so someone can install an intermediate CA:
RootCA
^- MyIntermediateCA
^- SomeonesCert
But I am getting NET::ERR_CERT_INVALID "When Chrome tried to connect to "website" this time, the website sent back unusual and incorrect credentials."
These are the steps I am taking:
Go into the MyIntermediateCA location, and create a MyIntermediateCA.CSR. Fill out all the fields.
openssl req -config CARequest.cnf -newkey rsa:2048 -sha256 -nodes -out MyIntermediateCA.csr -outform PEMTake the MyIntermediateCA.CSR and go into the RootCA location and sign it
openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out MyIntermediateCA.pem -infiles MyIntermediateCA.csr
No errors
Go back to the MyIntermediateCA location with the MyIntermediateCA.pem and create a new SomeonesCert.CSR
openssl req -config CertRequest.cnf -newkey rsa:2048 -sha256 -nodes -out SomeonesCert.csr -outform PEMThen sign it with the intermeadite CA called MyIntermeadiate... (I had to alter the config file)
openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out SomeonesCert.pem -infiles SomeonesCert.csr
No errors.
(Yes, there are a number of config files, but they are almost the same except for default subject fields.)
Then I add them into one big PEM
-----BEGIN CERTIFICATE-----
... SomeonesCert
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... MyIntermediateCA
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... RootCA
-----END CERTIFICATE-----
and load with with SSL_CTX_use_certificate_chain_file(...), then load the key to the first one. Everything loads fine with the OpenSSL functions, but the browser gives NET::ERR_CERT_INVALID
If I remove ONLY the MyIntermediateCA, I don't get the error, but I do get the warning NET::ERR_CERT_AUTHORITY_INVALID. That would be normal and expected, since the intermediate CA is missing, and the "SomeonesCert" is signed by an unknown.
If I remove ONLY the SomeonesCert, and update the key for the MyIntermediateCA one, I don't get the error, but I do get the warning NET::ERR_CERT_COMMON_NAME_INVALID. This also is normal and expected, since the URL name doesn't match the certificate. (If I add the domain name to my hosts file, to allow a lookup, the URL name now matches the cert, and I get no error, as expected)
If I remove ONLY the RootCA, the browser gives NET::ERR_CERT_INVALID, just like before.
I have to figure I'm creating the MyIntermediateCA incorrectly, except it works on it's own, as it's signed by RootCA
So perhaps there is a setting in the conf file (.cnf in windows) that needs to change for the MyIntermediateCA? I followed a number of tutorials, but none gave details on the conf file. And the same code uses the same conf file for everything, so its loaded with values which are not explained whethere they apply to creating a CSR, or signing one.
Since I can't post the RootCA or internal company details of names, any advice to steer me in a better direction would be appreciated, or point to a good tutorial which I hadn't found yet.
EDIT: ADDITIONAL PROGRESS.
I followed the tutorial almost step by step. Just had to change some paths, and I changed a few names.
I added the RootCA to the Windows store. That will eliminate any complaint about the Cert authority being unknown. That isn't the problem anyway.
To get past the original error (which happened with this tutorial as well) I had to remove PathLen. The tutorial said "or just remove is in the following section" but there was nothing in the "following section". So there was some vagueness in the explanation.
To save space I will not copy/paste every config file and command here, since the tutorial has all of them. I only had to alter some directories to run in Windows. The final domain is named "sample:
Now, I am getting the following error:
NET::ERR_CERT_COMMON_NAME_INVALID
And the details:
This server could not prove that it is sample; its security certificate does not specify Subject Alternative Names.
Okay, that's straight forward enough.
I duplicated the openssl-intermediate.cnf to openssl-server.cnf so that the [req_distinguished_name] section could use different defaults than the request that is used to create the intermediate certificate.
Now I create the last server certificate with the following:
openssl req -config openssl-server.cnf -key private\www.example.com.key.pem -new -sha256 -out csr\www.example.com.csr.pem
Then I sign it with the following:
openssl ca -config openssl-intermediate.cnf -extensions server_cert -days 375 -notext -md sha256 -in csr\www.example.com.csr.pem -out certs\www.example.com.cert.pem
The resulting prompt for signing is:
Subject:
countryName = US
stateOrProvinceName = CC
localityName = CC City
organizationName = sample Organization
organizationalUnitName = sample Unit
commonName = sample
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Authority Key Identifier:
keyid:53:97:1D:81:C4:FF:A8:25:F6:0C:40:A8:77:04:59:75:95:2E:E0:E9
Sign the certificate? [y/n]:
There is no subjectAltName as expected. So I try to add that setting to the openssl-server.cnf file...
Except no matter where I try to put an entry for the subjectAltName in the openssl-server.cnf file, it doesn't show up in the server certificate. And I am lost trying to unravel the spaghetti that is the OpenSSL conf file.
Here the assumptions I am following in the openssl-server.cnf being used to create the CSR...
I assume it used the [ req ] section, since this is a "request"
[ req ] # Request settings
default_bits = 2048 # Default key size
distinguished_name = req_distinguished_name # Default DN template
string_mask = utf8only # UTF-8 encoding
default_md = sha256 # Default message digest
x509_extensions = v3_server_req # Extensions for server certificate
And the section [ req_distinguished_name ] is prepopulated with defaults as expected. So it appears this is working.
And the x509_extensions point to a section named [ v3_server_req ]. I added a subjectAltName and pointed it to alternate_names, as this was the way a different config file was set (but that one fails when chained, as I describe originally above)
[ v3_server_req ] # Intermediate CA certificate extensions
subjectKeyIdentifier = hash # Subject key identifier
authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
basicConstraints = critical, CA:true # Basic constraints for a CA
keyUsage = critical, digitalSignature, cRLSign, keyCertSign # Key usage for a CA
subjectAltName = @alternate_names
And added
[ alternate_names ]
DNS.1 = sample
DNS.2 = *.sample
However, the subjectAltName is not appearing in the certificate to be signed.
Well, in this config file, copied from the openssl-intermediate.cnf, there are also a [ server_cert ] and [ server_req_extensions ] sections. However, adding subjectAltName to them doesn't do anything either.
[ v3_server_req ] # Intermediate CA certificate extensions
subjectKeyIdentifier = hash # Subject key identifier
authorityKeyIdentifier = keyid:always,issuer # Authority key identifier
basicConstraints = critical, CA:true # Basic constraints for a CA
keyUsage = critical, digitalSignature, cRLSign, keyCertSign # Key usage for a CA
subjectAltName = @alternate_names
[ server_cert ] # Server certificate extensions
basicConstraints = CA:TRUE # Not a CA certificate
nsCertType = server # Server certificate type
keyUsage = critical, digitalSignature, keyEncipherment # Key usage for a server cert
extendedKeyUsage = serverAuth # Extended key usage for server authentication purposes (e.g., TLS/SSL servers).
authorityKeyIdentifier = keyid,issuer # Authority key identifier linking the certificate to the issuer's public key.
subjectAltName = @alternate_names
[ server_req_extensions ]
subjectKeyIdentifier = hash
basicConstraints = CA:TRUE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = alternate_names
nsComment = "OpenSSL Generated Certificate"
[ alternate_names ]
DNS.1 = sample
DNS.2 = *.sample
But to make it worse, changing other settings in those sections doesn't change what is in the server certificate request. I repeatedly changed the basicConstraints and keyUsage, but they didn't change:
Subject:
countryName = US
stateOrProvinceName = CC
localityName = CC City
organizationName = sample Organization
organizationalUnitName = sample Unit
commonName = sample
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE <- THIS IS TRUE IN THE CONFIG FILE
Netscape Cert Type:
SSL Server
X509v3 Key Usage: critical
Digital Signature, Key Encipherment <- THIS IS MISSING OTHER USES
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Authority Key Identifier:
keyid:53:97:1D:81:C4:FF:A8:25:F6:0C:40:A8:77:04:59:75:95:2E:E0:E9
Some values are prepended by an @ to indicate they are subsequent sections, some are not. This is why I call this whole config file stuff spaghetti.
To summarize, how do I add the subjectAltName to the final server certificate being signed?
-Scotty