For convenience we will create certificate chains contained in one file.
Intermediate + CA Certificate
For certificate chain verification it is convenient to store Intermediate and CA certificates in one file, in that order. We will create a new folder for storing this chain. This folder "ipublic" will be inside of the intermediate CA folder "iCA".
During TLS handshake, the server will send the whole certificate chain except the root certificate. It is convenient to store these chains in "cert" folders. Each leaf subject has such folder ( "scerts, pcerts, ccerts" ).
The leaf certificates are revoked by using Intermediate CA. In the "iindex.txt" file we currently have three issued certificates.
We issued certificates for the server, person and web client.
I will revoke person's certificate.
cd iCA
openssl ca -config iCA.cnf -revoke ../person/pcerts/pera.crt -crl_reason keyCompromise
In the "iindex.txt" file, person's certificate is labeled with "R".
We will create new CRl file. We will place it into "icrl" folder.
openssl ca -config iCA.cnf -gencrl -out ./icrl/iCA.crl
We can read from this CRL file. Inside of it we will see that the certificate with the serial number 5011 is revoked. openssl crl -in ./icrl/iCA.crl -noout -text
There are two ways to verify the CRL. We can check only the leaf certificate revocation status, or we can check both leaf and intermediate revocation status.
OCSP responses must be signed by the intermediate CA. For OCSP we must create a directory system, just like we have created for server, person and web client. This directory system will be inside of the "/iCA/iOCSP" folder.
We can verify this new certificate. openssl verify -CAfile ./ipublic/CA-chain.crt -purpose ocsphelper ./iocsp/ocerts/iocsp.crt
OpenSSL OCSP Command
OpenSSL can create a simple OCSP responder. This responder is not suitable for production. It should be only use for demonstration and testing. We will use OCSP command to show how OCSP works.
In the "iCA" configuration file, we can find that address for the OCSP service is "http://ocsp.example.com:7000". Our educational OCSP responder will not use this address, but will use a localhost.
I will start the responder on the port 7000. Responses from this responder will be valid for one day. This responder will read from the "iindex.txt" file to see which certificates are valid and which are revoked.
"-Verify 1" option means that we are allowing only one intermediate CA. Root CA "myCA.crt" is trusted, and below it there can be only one intermediate certificate in the chain "CA-chain.crt".
Option "-www" means that "s_server" will run like a simple web server.
This is interactive prompt on the side of the client. Here we can enter this message: GET / HTTP/1.0
As a response we will get a long text. That text is HTML page containing TLS connection information.
Exporting PKCS#12 Key
We can export web client certificate to PKCS#12 format which is convenient for Android and Windows clients. It will go to "cp12" folder.
openssl pkcs12 -export-name "Friendly Name of Certificate" -inkey ../client/cprivate/client.key -in ../client/ccerts/client.crt -certfile ./ipublic/CA-chain.crt -out ../client/cp12/client.p12 # enter password two times
We can read this CSR and verify it, in the same time. openssl req -in scsr/server.csr -noout -text -verify
SAN is the only extension.
We will copy CSR to intermediate CA directory. cp scsr/server.csr ../iCA/icsr/server.csr
We will jump to intermediate CA folder. From there we can sign the CSR. cd /home/fff/Desktop/iCA
We can now create certificate. We will confirm signing. We will write to the "index.txt" that belongs to intermediate CA. openssl ca -config iCA.cnf -extfile iCA.cnf -extensions v3_server -in icsr/server.csr -out ../server/scerts/server.crt
We can read from our certificate. openssl x509 -in ../server/scerts/server.crt -noout -text
Inside of it we will find all of the extensions from the iCA.cnf file, but we will not find SAN extension. We have to fix this problem!
How to Include SAN extension?
Our extensions are currently inside of the intermediate ca "iCA.cnf" configuration file, while SAN extension is inside of the leaf "server.cnf" configuration file. The "ca" command will only accept extensions from one configuration file. We have somehow to consolidate these 2 files.
The solution is to use "include" command. We must go back to "iCA.cnf" file, and there we must include SAN extension.
At the top of this configuration file, we will place include command: .include ../server/server.cnf
In the section "v3_server", of "iCA.cnf" file, I will add SAN extension.
We can also join both CA certificates into one file. Intermediate CA certificate must be first. We are starting from the bottom of a hierarchy. cat icerts/iCA.crt../myCA/certs/myCA.crt > /home/fff/Desktop/all.crt cat /home/fff/Desktop/all.crt
Now we have both certificates in one file.
We can verify the server certificate with the certificate chain file. openssl verify -CAfile /home/fff/Desktop/all.crt ../server/scerts/server.crt
../server/scerts/server.crt: OK
We can verify purpose and hostname of a certificate as a separate property.
We will copy CSR file, and we will jump to iCA folder.
cp ccsr/client.csr ../iCA/icsr/client.csr cd ../iCA
We can now create a certificate. openssl ca -config iCA.cnf -extfile iCA.cnf -extensions client_cert -in icsr/client.csr -out ../client/ccerts/client.crt
We can verify this certificate too. We can verify certificate chain, and we can verify its purpose.
openssl verify -CAfile ../myCA/certs/myCA.crt -untrusted icerts/iCA.crt ../client/ccerts/client.crt # OK
Intermediate CA is almost the same as the root CA. We will follow the same steps; there will some small differences. I will use the name "iCA".
Intermediate CA File System
Everything needed for "iCA" must be placed into one file system. At the top we will have "iCA" folder, other files/folders are inside of the "iCA" folder.
iprivate
This is a folder where we will store the "iCA" private key.
inewcerts
Every certificate signed by the "iCA" will be stored here. Names of the files will be certificate serial numbers. This folder is used by OpenSSL to keep track of issued certificates, revocations, and duplicates.
iindex.txt
This is file that stores a list of all of the issued certificates. V 280101120000Z 1000 unknown /CN=server1 # valid E 280101120000Z 1001 unknown /CN=server2 # expired R 270501120000Z 1002 unknown /CN=oldserver # revoked
iserial.txt
This file will store the serial number for a new certificate. If that number is "X", the next certificate will be given serial number "X", and OpenSSL will update this text file to store the next serial number, which would be "X+1".
icerts
This directory is optional. Here we can place any certificate, and we can give meaningful names to those files. We can store here "iCA" certificate, and we can organize certificate chains for deployment.
icsr
Convinient folder where we can place intermediate CA CSR's.
icrl
This is folder where we keep our CRL list.
icrlnumber.txt
This file is similar to "serial". It holds the number for the next version of CRL list.
iCA.cnf
This is configuration file used by the "iCA".
As we can see, everything is the same as for the root CA. I will use prefix "i" to differentiate root CA and intermediate CA files.
Permissions should be the same as for the "myCA" directories and files. I will not repeat those settings here.
Creation of the File System
cd /home/fff/Desktop
This is our current directory.
mkdir iCA
We will make root folder. We will jump to that folder.
cd iCA
mkdir iprivate
This empty folder is for a private key.
mkdir inewcerts
Issued certificates will be stored here.
touch iindex.txt
Here we will register newly issued certificates.
touch iserial.txt
Inside of this file we will write initial hexadecimal serial number 5010.
echo 5010 > iserial.txt #even number of digits
mkdir icerts
This folder is optional.
mkdir icsr
Here we will place CSRs for leaf certificates.
mkdir icrl
Empty folder for CRL files.
touch icrlnumber.txt
We will set initial hexadecimal serial number for CRLs, in this file.
echo 5010 > icrlnumber.txt #even number of digits
Creation of the iCA Configuration File
[ca] default_ca = CA_default
"[ca]" is one of the main sections. We will immediately refer to specialized section "[ca_default]".
Distinguish name in leaf CSRs must match the same values in this configuration file. If they do not match then this intermediate CA can not sign that CSR. – match – they must match perfectly. – supplied – value doesn't have to match, but CSR should provide some value. – optional – whatever. There is no restriction.
[req] default_md = sha256 prompt = no distinguished_name = intermediate_ca_dn
These settings are used for intermediate CA certificate. We will not provide any extensions for this certificate. Extensions, for intermediate CA, will be determined by the CA configuration file.
[intermediate_ca_dn] countryName = RS stateOrProvinceName = Serbia localityName = Belgrade organizationName = iCA organization organizationalUnitName = iCA unit commonName = Intermediate CA
These values will be used as intermediate CA distinguish name.
These are extensions that will be used when we sign some server certificate. These are the default extensions that will be used if we don't provide "-extensions" command line option.
For clients and users we will have to specify their extensions with the "-extensions" command line option.
For signing OCSP responds, we will use these extensions.
We will talk about OCSP responder later. For now, you should know that OCSP responder is a separate entity, placed on the internet facing server, that has its own private key and certificate. This OCSP responder certificate can not be verified with the same OCSP service, because that would create a circular dependency. That is the meaning behind extension "noCheck".
We will create configuration file "touch iCA.cnf", and we will copy the text from above into that file.
Creating Private Key and Certificate for Intermediate CA
We can read and verify this CSR in one step. openssl req -in icsr/iCA.csr -noout -text -verify
Creation of the Intermediate CA Certificate
For CA to sign our CSR request, we must first copy that request. We are copying it into "myCA" folder. cp icsr/iCA.csr ../myCA/csr/iCA.csr
I will jump to "myCA" folder.
cd ../myCA
openssl ca -config myCA.cnf -extensions v3_intermediate_ca -in csr/iCA.csr -out ../iCA/icerts/iCA.crt
We are now ready to sign intermediate CA certificate. We will use "ca" command.
We have a problem. In the DN section, organization name is different between CSR file and CA configuration file according to policy. We have to correct. I will correct intermediate CA configuration file, and I will again generate CSR file.
cd ../myCA openssl ca -config myCA.cnf -extensions v3_intermediate_ca -in csr/iCA.csr -out ../iCA/icerts/iCA.crt
I will sign CSR file again. This time I will be asked to sign the certificate. I will confirm that.
We will be asked to update "index.txt" file. When using "ca" command everything will be updated.
Verifying Changes
We can read from our certificate. cd ../iCA openssl x509 -in icerts/iCA.crt -noout -text We can see that extensions are taken from the "myCA" configuration file.
We can also notice that "authorityKeyIdentifier" doesn't include issuer data. It seems that this version of OpenSSL doesn't do that.
We can verify our intermediate CA certificate. We are using CA certificate to verify intermediate CA certificate. openssl verify -CAfile../myCA/certs/myCA.crticerts/iCA.crt
This time we will check whether intermediate CA certificate is revoked or not. For that we will use "myCA.crl" file. openssl verify -CAfile../myCA/certs/myCA.crt-CRLfile ../myCA/crl/myCA.crl-crl_check icerts/iCA.crt Certificate is not revoked.
Problem is that we want to check all CRL files in the chain. I will create an empty CRL file for "iCA". openssl ca -config iCA.cnf -gencrl -out icrl/iCA.crl
We now have two CRL files. One is for "myCA" and the other for "iCA". We can provide only one file in the option "-CRLfile". Solution is to concatenate these two files into one. cat ../myCA/crl/myCA.crl icrl/iCA.crl > /home/fff/Desktop/all.crl cat /home/fff/Desktop/all.crl
I will use this concatenated file to verify intermediate CA certificate. openssl verify -CAfile../myCA/certs/myCA.crt-CRLfile /home/fff/Desktop/all.crl-crl_check icerts/iCA.crt
Other Changes
This is the first time we created certificate using "ca" command. Many files will change. They will change in the "myCA" folder.
We will have a new entry in the "index.txt" file. Because we used "ca" command to create a certificate, we now have one valid entry.
The number in the file "serial.txt" is increased to 2731. That number will be used for the next signed certificate.
Two new files appeared. They are both "old" files used for backup. "serial.txt.old" holds old serial number 2730. The file "index.txt.attr.old" is a copy that still has a value "unique_subject = no".
OpenSSL can be used to create a CA that we manage. A private CA is useful for creating an internal PKI and gaining control over internally used certificates. A private CA can be the best solution in networks that do not have access to the Internet. Without the Internet, it is not possible to access commercial CRL and OCSP services.
For larger projects, enterprises use dedicated software that provides web interface, access control, auditing. Examples of such software are Dogtag Certificate System, Microsoft Active Directory Certificate Services, HashiCorp Vault.
Creation of Your Own CA
We will use name "myCA" to refer to CA that we will create.
Directory Structure
Everything needed for "myCA" must be placed into one directory system. At the top we will have "myCA" folder, other files/folders are inside of the "myCA" folder.
private
This is a folder where we will store the "myCA" private key.
newcerts
Every certificate signed by the "myCA" will be stored here. Names of the files will be certificate serial numbers. This folder is used by OpenSSL to keep track of issued certificates, revocations, and duplicates.
index.txt
This is file that stores a list of all of the issued certificates. V 280101120000Z 1000 unknown /CN=server1 # valid E 280101120000Z 1001 unknown /CN=server2 # expired R 270501120000Z 1002 unknown /CN=oldserver # revoked
serial.txt
This file will store the serial number for a new certificate. If that number is "X", the next certificate will be given serial number "X", and OpenSSL will update this text file to store the next serial number, which would be "X+1".
certs
This directory is optional. Here we can place any certificate, and we can give meaningful names to those files. We can store here "myCA" certificate, and we can organize certificate chains for deployment.
csr
Convinient folder where we can place intermediate CA CSR's.
crl
This is folder where we keep our CRL list.
crlnumber.txt
This file is similar to "serial". It holds the number for the next version of CRL list.
myCA.cnf
This is configuration file used by the "myCA".
Creation of a Directory Structure
We will create files/folders needed for "myCA". We will place initial values into some of the files.
cd /home/fff/Desktop
This is our current directory.
mkdir myCA
We will make root folder. We will jump to that folder.
cd myCA
mkdir private
This empty folder is for a private key.
mkdir newcerts
Issued certificates will be stored here.
touch index.txt
Here we will register newly issued certificates.
touch serial.txt
Inside of this file we will write initial hexadecimal serial number 2730.
echo 2730 > serial.txt #even number of digits
mkdir certs
This folder is optional.
mkdir csr
Here we will place CSRs for intermediate CAs.
mkdir crl
Empty folder for CRL file.
touch crlnumber.txt
We will set initial hexadecimal serial number for CRLs, in this file.
echo 2730 > crlnumber.txt #even number of digits
Creation of OpenSSL Configuration File
[ca] default_ca = CA_default
This section will direct us toward "CA_default" section.
This section is the major section. Here we will write locations of all of the main folders and files, and other CA related data.
Option "x509_extensions" refers to default extensions that CA will use when it signs some certificate. Because this CA will only sign intermediate CA's certificates, we will be explicit and we will place those extensions in the section "v3_intermediate_ca".
Section "policy" will refer to section where we will specify what Distinguish Name values ( Country, State, City ) must match between intermediate CA CSR and this configuration file.
New option is "copy-extension". That means that none of the intermediate CA CSR extensions will be copied to certificate. Ony extensions specified in the section "v3_intermediate_ca" will be used. We want the full control.
Option "unique_subject" will allow us to issue several certificates for the same Subject. Without this option, we will be prohibited to have two valid certificates for the same subject in "index.txt".
Here we will place data that will define characteristics of the CA self-signed certificate.
[ca_dn] countryName = RS stateOrProvinceName = Serbia localityName = Belgrade organizationName = CA organization organizationalUnitName = CA unit commonName = Root CA
This is a section for distinguished name for the CA self-signed certificate.
These extensions will be added to CA certificate. Pathlen is set to 1 because we only allow one intermediate CA.
Here we can see keyword "always". This keyword means that if we can not include some element ( key hash in this case ) in a certificate, then creation of a certificate should fail.
This section will tell what options from the CSR must match options in "myCA.cnf" file. Possible values are "match, supplied, optional". - match > the values must match. If they do not match, we will not be able to sign CSR. - supplied > option must exist, but it does not have to have the same value as in "myCA.cnf" file. - optional > we can do whatever.
These are extensions that will be added to intermediate CA certificates.
Notice that we are using the sign "@" for "crlDistributionPoints". Some options expect a section name so there is no need for "@" sign. This option "crlDistributionPoints" is not expecting a section name. That is why in this case we use "@" prefix.
We can notice that only sections "ca" and "req" are colored in black. They are the main sections that must exist. Every other section is just for better organization, must be referenced from somewhere, and can be named anyway we like.
Sections "req, ca_dn, v3_ca" are for the self signed CA certificate. Sections "policy_intermediate_ca"and"v3_intermediate_ca" are for the certificates of the intermediate CAs.
We will create configuration file "touch myCA.cnf", and we will copy the text from above into that file.
Random Serial Numbers
Inside of the [CA_default] section, we can have this option. If we use this option, then the "serial" file will be unused. rand_serial = yes
This option means that serial number of certificates will not be serial number ( 1000, 1001, 1002… ). Instead of that, it will be random hexadecimal number ( 4F8A91D03B7E2C11, A93C72E5B18D904F…).
We should use this option set to "yes". That would make our setup safer, and it is recommended. I will not set it to "yes" in my example. Instead of that I used random number 2730 as my first serial number. This is usually enough to distinguish serial numbers from "myCA" and some other internal CA that could also exist in our organization.
We should always have file "serial" file. Some OpenSSL commands and external tools expect this file to be present.
Permissions of the Files and Folders
Now that we have all of the files and folders, we can protect them. I will not apply these permissions because this is just educational demonstration, but in production these are the levels of protection that you need. I will remind you that "4 (read) + 2 (write) + 1 (execute) = 7".
chmod 700 /home/fff/Desktop/myCA
Only administrator should have access to "myCA" folder.
chmod 700 private chmod 600 private/*
It is the same for a "private" folder and its content.
chmod 755 newcerts chmod 644 newcerts/*
Certificates are public. For them we can put less restrictive permissions.
chmod 600 index.txt
Index file is important for functioning of the CA, so we will protect it strictly.
chmod 600 serial.txt
The same as for "index.txt", because messing with this folder can corrupt CA.
chmod 755 certs chmod 644 certs/*
This is the same as for "newcerts" folder.
chmod 755 csr chmod 644 csr/*
These are the permissions for CSRs.
chmod 755 crl chmod 644 crl/*
CRLs are public information. The same as for certificates.
chmod 600 crlnumber chmod 600 crlnumber/*
It is recommended that only root has access to this folder.
chmod 644 myCA.cnf
Configuration file should be protected, too.
Creation of the CA Private Key and Certificate
We will create the CA private key and we will place it into "private" folder.
Now that we have a key, we can create CA CSR file. For it, we have to provide the name of a configuration file. openssl req -config myCA.cnf -new -key private/myCA.key -out csr/myCA.csr
Inside of the CSR file we can see our Subject, and no Extensions. openssl req -in csr/myCA.csr -noout -text
We will sign CA certificate using "req" command. We will use extensions from v3_ca section. Note that when we create a certificate with "-x509" option, there will be no new entry in "index.txt, newcerts or serial.txt". There is no need to register CA certificate.
When we use "ca" command for signing, only then there will be changes in the "index.txt, serial.txt, newcerts". For selfsigning CA certificate we don't need that. That is why we will use ordinary "req" command.
We can read from the newly create certificate. openssl x509 -in certs/myCA.crt -noout -text
We can notice one thing. There is no "issuer" for "Authority Key Identifier", we only have "keyID". This is normal because we are using self signed certificate, so there is no need for repetition. Subject and Authority are the same.
openssl ca -config myCA.cnf -gencrl -out crl/myCA.crl
A new file will be created inside of the "crl" folder. This file will look like any other certificate or key, some text and base64 encoding between. Inside of the "crlnumber.txt" file, a number will increase by 1, and will become 2730 + 1 = 2731.
One new file will appear. This is a copy of "crlnumber.txt" file. It will have the old CRL serial number 2730.
We can read from the CRL file. We will see inside that there are no revoked certificates. openssl crl -in crl/myCA.crl -noout -text
We will verify the CRL file. openssl crl -in crl/myCA.crl -CAfile certs/myCA.crt -noout -verify
We must copy the CRL file onto web server for download.
Certificate Revocation
This is how we revoke the certificate we made. openssl ca -config myCA.cnf -revoke certs/myCA.crt -crl_reason keyCompromise
These are the possible values for "-crl_reason".
unspecified
keyCompromise
CACompromise
affiliationChanged
superseeded
cessationOfOperation
privilegeWithdrawn
No specific reason.
Subject private key is compromised.
CA private key is compromised.
Subject had organizational change.
A new certificate is issued.
Subject is closed.
Usage and constraints of a certificate are changed.
Revoked certificate will be registered in the "index.txt" file. Letter "R" means that this certificate is Revoked. cat index.txt
The first time we write something into "index.txt" database, the new files could appear. The file "index.txt.old" is backup of the "index.txt" file. In our case it is empty, because there was nothing in the "index.txt" file previously. The file "index.txt.attr" contains the value of the option "unique_subject = no".
Now that we have a new key, we will create a new CRL file. openssl ca -config myCA.cnf -gencrl -out crl/myCA.crl We can read from this new CRL file. openssl crl -in crl/myCA.crl -noout -text
Inside of the CRL file, we will see our certificate revoked.
We can verify our CRL file. openssl crl -in crl/myCA.crl -CAfile certs/myCA.crt -verify
Names of configuration file sections are following established convention, but there is nothing that enforce that convention. We don't have to name our sections "req, req_dn, v3_req". We can name them "req, req_distinguish_name, req_ext". These are just labels for better organization.
The only time a section name matters is when something references it.
req_extensions = my_ext
There are a few exceptions. If we want to use configuration file with "openssl -req" command, we should have "[req]" section. For "openssl -ca" command we should prepare "[ca]" section.
Configuration File for Creation of a CSR
When we want to create CSR file, we usually use these three sections:
[req] – major CSR options.
[req_dn] – country, state, city.
[v3_req] – extensions.
[req] Section
prompt = no
This option means that we will not be asked for Country, State, City. Instead of entering these values through interactive prompt, the values will be taken from configuration file. If we say "prompt = yes", the values from the configuration file will be default values inside of the interactive prompt.
default_bits = 4096
The size of RSA key.
default_md = sha256
We use this option if we want to specify what hash algorithm should be used.
default_keyfile = private.key
The default filename for the generated private key. This name will be used if not specified on the CLI.
– We will not be asked to provide DN data, we will not be asked for a password for the private key. – The name of a file with a private key will be taken from configuration file.
We can use the same configuration file to create elliptic curve key and associate CSR file.
This time, a Certificate Authority will sign our CSR file. I don't have a CA private key, so I will again use custom made private key. We will pretend that it was a CA that signed my CSR file.
I will create new configuration file. This file is different because it doesn't have "[v3_req]" section. This configuration file will have "[server_cert]" that is used when a CA sign a leaf certificate. touch cert.cnf
[req] distinguished_name = req_dn prompt = no x509_extensions = server_cert
[req_dn] C = US O = Example CA CN = Example Root CA
"[server_cert]" section is for extensions as we can see from its content.
subjectKeyIdentifier = hash
We will get this in a certificate: X509v3 Subject Key Identifier: 24:A5:57:C8:96:47:19:44:19:EC:AB:0C:18:A5:D7:49:58:EF:E0:A1
This extension is asking for inclusion of SKI in the final certificate. We will use hash in the SKI.
authorityKeyIdentifier = keyid,issuer
We will get this in certificate: X509v3 Authority Key Identifier: keyid:AB:CD:EF:12:C8:96:47:19:44:19:EC:AB:0C:18:A5:D7:49:58:EF:E0:A1 DirName:/C=US/O=Example CA/CN=Example Root CA
This extension is the same, but for AKI. Here we will use hash and distinguish name.
Creation of a Certificate
I will create one EC key, and only the key. openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out server.key
I will use settings from the configuration file to create CSR file. openssl req -new -key server.key -out server.csr -config cert.cnf
I will read from the new CSR file. We will see no extensions. Extensions will appear in CSR file only when we have "[v3_req]" section. This time we assume that CA is the one who will define what extensions will be used. That is why we placed extensions in the "[server_cert]" section. openssl req -in server.csr -text -noout
I will assume that we are now Certificate authority. We will sign the CSR. In the certificate we will place extensions from the "[server_cert]".
Notice that we explicitly had to declare what is our configuration file and from where to pull extensions. When we create a certificate based on the CSR file, the command must be explicit what extensions to use. When the CA sign CSR file, CA must declared what extensions to use from the configuration file.
We will take a look into our certificate. openssl x509 -in server.crt -text -noout
Now, we can see the extensions. We have 6 extensions in our configuration file, and we can see all of their values here.
Self Creation of a Certificate
There is another way how we can create a certificate. We can create a certificate directly from the private key. This is again a self signed certificate, but we are doing everything in two steps. First, we run a command to create a private key, and then we run a command to create a certificate from that private key. This time we will not create CSR file at all.
This time, CA is not involved, we will consider that "cert.cnf" file is our configuration file.
What is interesting about this command is that we don't have to be explicit. This command knows about "x509_extensions" option. That option will direct this command to "[server_cert]" section.
If we read from this certificate, we will see the same extensions as previous. There will be no difference in the certificate. openssl x509 -in server2.crt -text -noout
Why is OpenSSL API so Convoluted?
You've probably noticed by now that the OpenSSL API is far from easy to use. While it's the most important cryptographic library in existence, OpenSSL certainly has a "cryptic" user interface. Every command looks the same. This is due to:
– the complexity of the problem – the accumulated decades of compatibility requirements – the need to introduce new cryptographic technologies and methods – the limitations of the ecosystem, a library with millions of users cannot be developed as aggressively as a newer project – OpenSSL provides low-level primitives that support many workflows – OpenSSL was created by cryptographic experts, but is now used by self-taught hobbyists
This is the same problem that plagues Qt, Git and Python Pandas. They seemingly perform simple functions, but somehow always seem overly complicated. Software entropy is a price for a long-term success.