Few things to know when using GSKit and gsk8capicmd

Certificate chain in the TLS server's keystore

When using the GSKit libraries for TLS communication, the keystore of the TLS server must contain the complete certificate chain for the server's user certificate. This complete certificate chain is also used to validate the user certificate of the server. Such a validation can be performed manually. In the following example to illustrate this, a TLS server's keystore has a certificate chain with two intermediate CA certificates. The keystore contains:
 $ gsk8capicmd -cert -list -db server2.p12 -pw s2passwd
 Certificates found
 * default, - personal, ! trusted, # secret key
 ! interB2
 ! interA2
 ! rootCA2
 - server2

In the keystore, "rootCA2" is the root CA certificate that was used to sign and issue the intermediate CA certificate "interA2". This intermediate CA certificate "interA2" in turn was used to sign and issue the intermediate CA certificate "interB2". Finally, the intermediate CA certificate "interB2" was used to sign and issue the TLS server's user certificate "server2". The certificate chain therefore is "rootCA2" -> "interA2" -> "interB2" -> "server2".

Validating the user certificate "server2" in this keystore is done with the command:
$ gsk8capicmd -cert -validate -db server2.p12 -pw s2passwd -label server2
 OK

With a successful validation of this user certificate in the keystore, the TLS server can use this user certificate "server2" in a TLS communication. If the validation of the user certificate is not successful, e.g. because one of the CA certificates in the chain is missing from the keystore, the user certificate would not function properly for the TLS server's communication. For instance, if the intermediate CA certificate "interA2" would be missing in the keystore, then neither the user certificate "server2" nor the intermediate CA certificate "interB2" could be validated successfully.

When adding certificates to a keystore, it is best to do this in such an order that the certificates always can be validated successfully. For the keystore of this example, the certificates are put into the keystore with four subsequent commands, each one handling a single certificate in a separate input file:
  1. 1. Add root CA certificate "rootCA2"
  2. Add intermediate CA certificate "interA2"
  3. Add intermediate CA certificate "interB2"
  4. Receive user certificate "server2"
Note: With "gsk8capicmd" a user certificate is not simply "added" to the keystore. The keystore already contains the corresponding private key for the new user certificate, created implicitly with the certificate request. When adding the new user certificate to the keystore, it must be properly associated with the private key. Also, the certificate request in the keystore gets removed when the new user certificate is put into the keystore. All this is done correctly by "gsk8capicmd" with the "receive" operation. How to do this in detail is explained later with an example.

Dealing with commercial CAs

Even though the topic is about setting up and using an in-house CA rather than a commercial CA, there is not really much difference between the two cases. Even for an in-house CA it may be a different department that is responsible for it. Understanding how to deal with a CA in general, in-house or commercial, can be of great help.

A user certificate is signed and issued by a CA based upon a certificate request. With "gsk8capicmd", a certificate request, and with it implicitly also the corresponding private key, is created directly in the keystore. As the certificate request needs to be given to a CA, the certificate request also gets written as a copy to a PEM file. This PEM file can be given conveniently to the CA. The private key and the (original) certificate request remain in the keystore and with that in the sole possession of the requestor. The CA signs and issues a new user certificate based upon the received certificate request. The CA then sends this new certificate, commonly in a PEM file, to the requestor. As seen above, to use this new certificate in a keystore, also the CA certificates used for the signing of the new certificate are needed by the requestor. The CA therefore sends these CA certificates as well, usually also in PEM format. A CA can send each of the certificates in a separate PEM file, which makes it easy to add them correctly into the keystore as described above. However, a CA also may choose to send all the certificates in a single PEM file. And unfortunately, the order of certificate objects in a PEM file is of no significance. Therefore, it cannot be counted on that the certificates in a PEM file received from a CA are in the correct order that is needed to put them into the keystore.

When receiving certificates from a CA in a PEM file, it is therefore necessary to understand the content of the PEM file, i.e. which certificates are in the PEM file, and to identify each one of them.

Handling PEM files

PEM (Privacy-Enhanced Mail) is a de facto file format for handling and storing cryptographic objects like private keys, certificates and certificate requests. Cryptographic objects generally are ASN.1 and DER encoded objects, i.e. consist of binary data that includes non-printable character/byte sequences. PEM uses base64 encoding for binary data and adds one line for headers and footers to individual objects. The resulting text files are not really human readable, but can be handled easily, e.g. sending them via e-mail. The PEM file format is commonly used by commercial CAs to receive certificate requests and send certificates.

A PEM file can contain just a single object, like a private key or a certificate, or it can contain multiple objects. The base64 encoded binary data of each object in a PEM file is enclosed with "comment lines" that denote whether the enclosed object is a private key, an encrypted private key or a certificate. Following is a PEM file that contains one private key (not encrypted) and two certificates:
-----BEGIN PRIVATE KEY-----
 MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDtSfmahK7hu0FF
 StVHIryLTNoFPvSbBv0greOEa3tjPh5wxrNIYmgbVDbUR+smwNiVcnMrIW+YjQVa
 ...
 6qWLsVZPhAXuubHHJanD5pkz1O+Igea4baOIK1iMRTzC2SC/0OgZRdCq5JiT/3TF
 2KGgo26SkHkn09GVIpJrkJ6M
 -----END PRIVATE KEY-----
 -----BEGIN CERTIFICATE-----
 MIIEFTCCAv2gAwIBAgIIfBXp0DHqf50wDQYJKoZIhvcNAQELBQAwgZ8xCzAJBgNV
 BAYTAlVTMRAwDgYDVQQIEwdGbG9yaWRhMRAwDgYDVQQHEwdBbnl0b3duMRswGQYD
 ...
 /wE5Ft38ENmy4gzFNgSF9F0C/Keo4aV8ZD+B2o+dUstqGa1da34rQtA+Eqs4K6Vr
 5/h7MWeDk4i14N/6Iy1AxTr0aMilK4a07cXO3LKNZj02PSiYcl1tmIM=
 -----END CERTIFICATE-----
 -----BEGIN CERTIFICATE-----
 MIID+DCCAuCgAwIBAgIBNTANBgkqhkiG9w0BAQsFADCBnzELMAkGA1UEBhMCVVMx
 EDAOBgNVBAgTB0Zsb3JpZGExEDAOBgNVBAcTB0FueXRvd24xGzAZBgNVBAoTEkFj
 ...
 byJXygfgt0Fv0bWPt3K/f51XRKur9O+jRFeZAK7fBWRsg4Jm8j0wxL4KcIcU7Axg
 HeHliFDyTxs3JQYC
 -----END CERTIFICATE-----

While from the comment lines it is obvious that there is one private key and two certificates, it is rather impossible to simply "read" with the naked eye more information about these objects. But often it is necessary to figure out, what the certificates are about, whether they both are CA certificates, or which one is a user certificate and whether such a user certificate is associated with the private key or not. It is possible that before the "-----BEGIN ...-----" comment line of each object there is some human readable extra information about the object, like a "localKeyID" or Subject and Issuer distinguished names of certificates. However, such additional information is optional. The above shown example of a PEM file is the bare minimum, but perfectly valid. Therefore, it is often necessary to be able to decipher the base64 encoded binary data in order to have more information about the objects in a PEM file.

The GSKit "gsk8capicmd" utility can decipher base64 encoded binary content in PEM files just for display, albeit in a somewhat rudimentary way. "gsk8capicmd" with options "-cert -details -file" can read and decode the binary data of a certificate in the specified PEM file and display the information in a readable manner. However, for a PEM file containing multiple objects, "gsk8capicmd" does this only for the first certificate found in the PEM file. Therefore, the first step is to split a PEM file with multiple objects into several files, each containing just a single object. Thanks to the base64 encoding of the binary data, this splitting can be accomplished with any text file editor. It is important to include the respective "-----BEGIN ...-----" and "----- END ...-----" comment lines in the splitted files. Splitting the above example PEM file in this way yields 3 files, for convenience named "key1.pem", "cert1.pem" and "cert2.pem". Now, each single PEM file with a certificate can be deciphered using "gsk8capicmd" as follows:
$ gsk8capicmd -cert -details -file cert1.pem
 Label : CN=Database CA Root1/emailAddress\=dba_ca1@acme.info,OU=Database CA,O=Acme 
 Key Size : 2048
 Version : X509 V3
 Serial : 7c15e9d031ea7f9d
 Issuer : "CN=Database CA Root1/emailAddress\=dba_ca1@acme.info,OU=Database CA,O=Acm
 Subject : "CN=Database CA Root1/emailAddress\=dba_ca1@acme.info,OU=Database CA,O=Ac
 Not Before : November 13, 2022 8:28:24 AM CST
 Not After : November 14, 2023 8:28:24 AM CST
 Public Key
 30 82 01 22 30 0D 06 09 2A 86 48 86 F7 0D 01 01
 ...
 D5 02 03 01 00 01
 Public Key Type : RSA (1.2.840.113549.1.1.1)
 Fingerprint : SHA1 : 
 89 A0 58 49 20 71 94 C0 9F 7C 4E 2B FE 7A E3 37
 E8 30 50 24
 Fingerprint : MD5 : 
 4F 06 3C E8 43 E6 5A 7F 80 34 C1 AA A8 89 62 DA
 Fingerprint : SHA256 : 
 32 66 16 B2 F0 9E DB C9 AC 45 7D 01 D6 78 C2 62
 BE 22 AA 00 5C 01 5C 98 84 E4 B9 E9 B5 0C D6 0B
 Fingerprint : HPKP : 
 09J+0fhn2zKr3z4Oy7YEq+UO72Wr/2PPHJIkKyeI060=
 Extensions
 basicConstraints
 ca = true
 critical
 SubjectKeyIdentifier
 keyIdentifier:
 28 D0 B2 DD E3 F9 26 06 C9 56 76 5E 17 5E 0A 21
 C4 9A 85 46
 AuthorityKeyIdentifier
 keyIdentifier:
 28 D0 B2 DD E3 F9 26 06 C9 56 76 5E 17 5E 0A 21
 C4 9A 85 46
 authorityIdentifier:
 authorityCertSerialNumber:
 Signature Algorithm : SHA256WithRSASignature (1.2.840.113549.1.1.11)
 Value
 55 3F 85 B3 06 AE E8 C8 37 B7 09 35 D1 C4 15 9F
 ...
 C5 CE DC B2 8D 66 3D 36 3D 28 98 72 5D 6D 98 83
 Trust Status : Enabled

The distinguished name in the "Subject:" line states the owner of the certificate, the distinguished name in the "Issuer:" line states the issuer of the certificate, normally a CA. In the example shown, both distinguished names are equal, and it is clear that this is a self-signed certificate. Consequently, also the values of the "Extensions" "SubjectKeyIdentifier" and "AuthorityKeyIdentifier" are the same. The extension "basicConstraints" has the two attributes "critical" and "ca = true". Together with the "CA" in the distinguished name it can be assumed, that this is a root CA certificate. With that, the PEM file "cert1.pem" can now be given a more mnemonic file name, e.g. "rootCA1.cert.pem", as it contains the root CA certificate of "Database CA Root1" (seen in the common name field of the "Subject").

Looking at the second PEM file with a certificate, "cert2.pem", with the following command shows:
 $ gsk8capicmd -cert -details -file cert2.pem
 Label : OU=DB ServersCN\=DB Server 1/emailAddress\=db1@acme.info,O=Acme Software In
 Key Size : 2048
 Version : X509 V3
 Serial : 35
 Issuer : "CN=Database CA Root1/emailAddress\=dba_ca1@acme.info,OU=Database CA,O=Acm
 Subject : "OU=DB ServersCN\=DB Server 2/emailAddress\=db2@acme.info,O=Acme Software
 Not Before : November 15, 2022 5:02:07 AM CST
 Not After : November 16, 2023 5:02:07 AM CST
 Public Key
 30 82 01 22 30 0D 06 09 2A 86 48 86 F7 0D 01 01
 ...
 41 02 03 01 00 01
 Public Key Type : RSA (1.2.840.113549.1.1.1)
 Fingerprint : SHA1 : 
 50 52 0B F1 F4 35 5A C0 F5 1E 73 9C C8 AA 7E 03
 A1 07 51 CB
 Fingerprint : MD5 : 
 3C F4 33 8D 47 96 79 28 6D A0 92 39 6B 88 DA 16
 Fingerprint : SHA256 : 
 82 41 66 29 DD 94 C4 22 C6 2B 1E C3 08 EF 9C 6E
 B6 40 C9 C2 B1 BC 2F FA 8D FD C4 DB 14 90 D2 BE
 Fingerprint : HPKP : 
 8PqRjTnsU3u6nwvNX/RGux9aI7TgJHOtkZYJtYly7vI=
 Extensions
 basicConstraints
 ca = false
 critical
 AuthorityKeyIdentifier
 keyIdentifier:
 28 D0 B2 DD E3 F9 26 06 C9 56 76 5E 17 5E 0A 21
 C4 9A 85 46
 authorityIdentifier:
 authorityCertSerialNumber:
 SubjectKeyIdentifier
 keyIdentifier:
 F0 6A F8 9A 46 C0 76 5A 05 7D AD C4 5B 01 6A 44
 1C CB F2 D7
 Signature Algorithm : SHA256WithRSASignature (1.2.840.113549.1.1.11)
 Value
 A6 D1 5F A9 D4 86 A9 5B C0 90 30 B3 9D 57 40 86
 ...
 14 EC 0C 60 1D E1 E5 88 50 F2 4F 1B 37 25 06 02
 Trust Status : Enabled

Here, "Subject" and "Issuer" are different, as are "AuthorityKeyIdentifier" and "SubjectKeyIdentifier". Therefore, this is not a self-signed certificate. The extension "basicConstraints" has the attributes "critical" and "ca = false" which tell, that this is a user certificate. Furthermore, the "Issuer" and "AuthorityKeyIdentifier" match the "Subject" and "SubjectKeyIdentifier" of the first certificate shown before. This establishes, that this second certificate, i.e. the user certificate, was signed and issued with the first certificate, the root CA certificate. The PEM file "cert2.pem" can now be renamed to "server2.cert.pem" as it contains the user certificate of "DB Server 2" (seen in the common name field of the "Subject").

Though the example PEM file also contains a private key object, this is not of further interest for this topic of using GSKit. This is mainly because with GSKit private keys are created directly in a keystore and never leave the keystore. With "gsk8capicmd" there is no way to export a private key from a keystore, so there should not be a need to import a private key into a keystore. (It is possible to do all these things with OpenSSL. More details on this are described in the respective topic on using OpenSSL).

Using the command "gsk8capicmd -cert -import" needs extra caution

It is possible to import one or more certificates from a PEM file into a keystore using the options "-cert - import" of "gsk8capicmd". However, this command should be used cautiously. If the PEM input file contains multiple certificates, these certificates are imported to the keystore in the order in which they appear in the PEM file. Problem is, that only one option "-label ..." can be specified, providing a label name only for the first certificate in the PEM file. Subsequent certificates get imported with label names created from the respective subject distinguished name of each certificate. Such label names are rather unwieldy and can make identifying the certificates in the keystore difficult. (Labels for the objects in a keystore are a property of the keystore's internal structure. They are not an attribute in the objects (certificates or private keys) themselves. Therefore, a PEM file normally does not contain any label names that would make it easier to identify the objects. If a PEM file contains a label name (or friendly name) in the extra information of objects, then this was added by the utility that created the PEM file from a keystore.)

Also, the user certificate may be included in such a PEM file. If the import command specifies as label name the label of the certificate request in the keystore, but the corresponding user certificate is not the first certificate in the PEM file, then the certificate request and its corresponding private key in the keystore can get overwritten with the first certificate in the PEM file. If this happens, the private key is lost completely and the keystore is no longer usable, as the private key cannot be recovered. (The only help in this case would be restoring a copy of the keystore file from before the attempted import operation.)

If the private key of the keystore is lost, then a newly signed and issued user certificate for this private key also is useless. In this case, it is necessary to create a new certificate request (and with this implicitly a new private key), then use the new request to get a new user certificate from the CA. Basically, the complete procedure must be repeated from the beginning.

Rather than using the command "gsk8capicmd -cert -import" to import multiple certificates in a PEM file into the keystore, it is better to split such a PEM file into separate files each containing just one certificate as described above. And then adding or receiving each certificate with a separate "gsk8capicmd" and in the correct order.