Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision Both sides next revision
tutorial:adm:caw_driver [2019/08/08 17:43]
tsunami ↷ Page moved from devel:documentation:adm:caw_driver to tutorial:adm:caw_driver
tutorial:adm:caw_driver [2019/11/19 13:02]
fiserp
Line 42: Line 42:
 </code> </code>
  
-In its core, CAW uses a well-known OSSL CA all with its **openssl.cnf** file and such. Therefore every configuration which can be specified in **openssl.cnf** can be made available in the CAW. CAW makes use of **openssl.cnf** as often as possible (i.e. with defaults for the **openssl req** command) and very often invokes openssl using **-batch** argument.+In its core, CAW uses a well-known OSSL CA all with its ''openssl.cnf'' file and such. Therefore every configuration which can be specified in ''openssl.cnf'' can be made available in the CAW. CAW makes use of ''openssl.cnf'' as often as possible (i.e. with defaults for the ''openssl req'' command) and very often invokes ''openssl'' using ''-batch'' argument.
  
-**But beware**, CAW has also its own configuration file **caw\_settings.source**. This file contains some options that need to be in sync with options in **openssl.cnf**. So if you are fiddling with **openssl.cnf**, always also check **caw\_settings.source**.+**But beware**, CAW has also its own configuration file ''caw\_settings.source''. This file contains some options that need to be in sync with options in ''ca\_openssl.cnf''. So if you are fiddling with ''ca\_openssl.cnf'', always also check ''caw\_settings.source''.
  
 Additional information can be found in one of those three places: Additional information can be found in one of those three places:
-  * In the CAW usage page. Simply invoke **./caw**+  * In the CAW usage page. Simply invoke ''./caw''
-  * As a comment in the **caw\_settings.source** file.+  * As a comment in the ''caw\_settings.source'' file.
   * As a comment in the CAW script itself (i. e. **authors**, **changelog**, **TODOs**).   * As a comment in the CAW script itself (i. e. **authors**, **changelog**, **TODOs**).
 ==== Core functions ==== ==== Core functions ====
   * Self-contained CA   * Self-contained CA
-    * CAW does not depend on the global **/etc/openssl.cnf**, it brings its own **openssl.cnf** along. That means, your CA is completely separated from others.+    * CAW does not depend on the global ''/etc/openssl.cnf'', it brings its own ''ca\_openssl.cnf'' along. That means, your CA is completely separated from others.
     * You can run different CAs just by giving each its own folder.     * You can run different CAs just by giving each its own folder.
     * Installation is merely unpacking a tarball and generating CA certificate and starting serial number.     * Installation is merely unpacking a tarball and generating CA certificate and starting serial number.
   * Handling concurrency problems   * Handling concurrency problems
-    * OpenSSL CA (**openssl ca ...**) must not be invoked in multiple instances at the same time. CAW uses lockfiles to prevent that.+    * OpenSSL CA (''openssl ca ...'') must not be invoked in multiple instances at the same time. CAW uses lockdir to prevent that.
   * Private key and CSR private storage   * Private key and CSR private storage
     * CAW archives all files it has created, including users' private keys and CSRs. Private keys all always AES-encrypted by a password which the end-user specifies. Therefore even the CA does not have an access to the private key.     * CAW archives all files it has created, including users' private keys and CSRs. Private keys all always AES-encrypted by a password which the end-user specifies. Therefore even the CA does not have an access to the private key.
   * Support for hardware tokens using PKCS11   * Support for hardware tokens using PKCS11
-    * If your OpenSSL version can support your hardware token, you can use it in CAW. Only thing you need to do is to configure it in **openssl.cnf** and **caw\_settings.source** (and there is already a template for that).+    * If your OpenSSL version can support your hardware token, you can use it in CAW. Only thing you need to do is to configure it in ''ca\_openssl.cnf'' and ''caw\_settings.source'' (and there is already a template for that).
   * Unix-like style of invocation   * Unix-like style of invocation
-    * Everything that goes into the CAW is a **command line argument**. Everything that goes out of the CAW is either a output of successful operation (on **STDOUT**) or an error (on **STDERR**). +    * Everything that goes into the CAW is a **command line argument**. Everything that goes out of the CAW is either a output of successful operation (on ''STDOUT'') or an error (on ''STDERR''). 
-    * Return code for successful operation is **0**, for error it is **1**.+    * Return code for successful operation is ''0'', for error it is ''1''.
     * All information going to/from CAW is in **printable form**, large data mainly as PEM or base64-encoded.     * All information going to/from CAW is in **printable form**, large data mainly as PEM or base64-encoded.
   * Usable as a root or intermediary CA   * Usable as a root or intermediary CA
Line 70: Line 70:
     * When user supplies just the **SubjectDN components**, the private key, CSR and certificate are automatically generated. You can validate the SubjectDN components by regex-based engine.     * When user supplies just the **SubjectDN components**, the private key, CSR and certificate are automatically generated. You can validate the SubjectDN components by regex-based engine.
   * CSR signing   * CSR signing
-    * User-provided CSR is checked for sufficient **signature algorithm** and for **SubjectDN components**. CAW makes sure the comparison is text-based (by regexes) and does not care about datatypes. This effectively solves usability problems with OpenSSL'**policy_match** in heterogenous environments.+    * User-provided CSR is checked for sufficient **signature algorithm** and for **SubjectDN components**. CAW makes sure the comparison is text-based (by regexes) and does not care about datatypes. This effectively solves usability problems with OpenSSL'''policy_match'' in heterogenous environments.
   * Certificate prolongation   * Certificate prolongation
     * Because CAW stores CSRs, it is possible to prolong certificate by reissuing it with new validity period. All that is needed is certificate's serial number.     * Because CAW stores CSRs, it is possible to prolong certificate by reissuing it with new validity period. All that is needed is certificate's serial number.
Line 83: Line 83:
     * When requesting the bundle with private key, user must specify the password he has given during the certificate creation.     * When requesting the bundle with private key, user must specify the password he has given during the certificate creation.
   * CRL issuing and publishing   * CRL issuing and publishing
-    * CAW enables you to create CRLs just by calling **./caw create-crl**. Another user can then publish the CRL into public destination by calling **./caw publish-crl**.+    * CAW enables you to create CRLs just by calling ''./caw create-crl''. Another user can then publish the CRL into public destination by calling ''./caw publish-crl''.
   * Housekeeping tasks   * Housekeeping tasks
-    * CAW takes care of orphan files and similar things that can happen during the life of CA. All those tasks are done by **./caw housekeep**.+    * CAW takes care of orphan files and similar things that can happen during the life of CA. All those tasks are done by ''./caw housekeep''.
  
 ==== Installation ==== ==== Installation ====
-  - Create separate user for your authority. **Ensure that no other user can read the home directory.** This happens for example on the (open)SuSE where each home is granted to the *usersgroup which encompasses all users.<code>+  - Create separate user for your authority. **Ensure that no other user can read the home directory.** This happens for example on the (open)SuSE where each home is granted to the ''users'' group which encompasses all users.<code>
 [root@ca ~]# useradd -r -m -s /bin/bash authority1 [root@ca ~]# useradd -r -m -s /bin/bash authority1
 </code> </code>
Line 101: Line 101:
 [root@ca authority1]# chmod 750 caw [root@ca authority1]# chmod 750 caw
 </code> </code>
-  - Ensure that **caw** script is runnable.<code>+  - Ensure that ''caw'' script is runnable.<code>
 [root@ca authority1]# cd caw/ [root@ca authority1]# cd caw/
 [root@ca caw]# chmod 750 caw [root@ca caw]# chmod 750 caw
 </code> </code>
-  - Create new starting serial number. This number can be, say, *01but there is a caveat attached to this - OpenSSL then works with 8bit serial mode (**this is potentially dangerous**). Better way is to create truly random 128bit serial number as the example shows.<code>+  - Create new starting serial number. This number can be, say, ''01'' but there is a caveat attached to this - OpenSSL then works with 8bit serial mode (**this is potentially dangerous**). Better way is to create truly random 128bit serial number as the example shows.<code>
 [root@ca caw]# cd ca/ [root@ca caw]# cd ca/
 [root@ca ca]# openssl rand -hex 16 > serial [root@ca ca]# openssl rand -hex 16 > serial
 </code> </code>
-  - If you want to use serial number prefixes, now it is the time to set it up. **If you don't know what it is, you can safely skip this step.** Suppose the random serial was *b1676557ad077ef7144c227d16a55025*. Then we simply edit the starting serial to have our desired prefix (say, *aaaccc000*). Total length of the serial number must remain 128b, so our new serial will be *aaaccc000d077ef7144c227d16a55025*. Write it into the **serial** file. We can, possibly, overflow to the prefix *aaaccc001so be aware of it - our "prefix" is not a real prefix. It is merely a cleverly chosen starting number. +  - **If you want** to use serial number prefixes, now it is the time to set it up. **If you don't know what it is, you can safely skip this step.** Suppose the random serial was ''b1676557ad077ef7144c227d16a55025''. Then we simply edit the starting serial to have our desired prefix (say, ''aaaccc000''). Total length of the serial number must remain 128b, so our new serial will be ''aaaccc000d077ef7144c227d16a55025''. Write it into the ''serial'' file. We can, possibly, overflow to the prefix ''aaaccc001'' so be aware of it - our "prefix" is not a real prefix. It is merely a cleverly chosen starting number. 
-  - Generate your CA certificate the usual way. For how to set it up with PKCS11 crypto token, see the end of this document. **Select the appropriate private key size.** Also, there are x509v3 certificate extensions which are handy to have in the authority's certificate. Default are in **ca\_crt.extensions** file. Edit them (and command line parameters in the example below) according to your needs.<code>+  - Generate your CA certificate the usual way. For how to set it up with PKCS11 crypto token, see the end of this document. **Select the appropriate private key size.** Also, there are x509v3 certificate extensions which are handy to have in the authority's certificate. Default are in ''ca\_crt.extensions'' file. Edit them (and command line parameters in the example below) according to your needs.<code>
 [root@ca ca]# su - authority1 [root@ca ca]# su - authority1
 [authority1@ca ~]$ cd caw/ca/ [authority1@ca ~]$ cd caw/ca/
Line 121: Line 121:
 [authority1@ca ca]$ rm ca.csr [authority1@ca ca]$ rm ca.csr
 </code> </code>
-  - CAW folder comes with a number of empty directories. Although needless now, they are automatically used by the **caw** script for managing the authority. Do not delete them. +  - CAW folder comes with a number of empty directories. Although needless now, they are automatically used by the ''caw'' script for managing the authority. Do not delete them. 
-  - Check the **ca\_openssl.cnf** configuration file and configure your authority. This file is an ordinary openssl.cnf, but is realized in local variant. This enables multiple caw-based CAs to coexist one along the other just by separating their directories. The ca\_openssl.cnf contains preconfigured CA so only small adjustments should be necessary. Follow the comments in the file itself. The most important things to set up are:+  - Check the ''ca\_openssl.cnf'' configuration file and configure your authority. This file is an ordinary openssl.cnf, but is realized in local variant. This enables multiple caw-based CAs to coexist one along the other just by separating their directories. The ''ca\_openssl.cnf'' contains preconfigured CA so only small adjustments should be necessary. Follow the comments in the file itself. The most important things to set up are:
     - Enable (configure) the PKCS11 engine or disable it entirely (comment it out).     - Enable (configure) the PKCS11 engine or disable it entirely (comment it out).
-    - Configure **default\_days** and **default\_crl\_days** and other certificate-related settings. +    - Configure ''default\_days'' and ''default\_crl\_days'' and other certificate-related settings. 
-    - Configure parameters in the **req** stanza - those are used for generating new keys and requests. +    - Configure parameters in the ''req'' stanza - those are used for generating new keys and requests. 
-    - Configure certificate extensions in the **issued\_cert\_ext** stanza. Do not forget to set up the **crlDistributionPoints** correctly. +    - Configure certificate extensions in the ''issued\_cert\_ext'' stanza. Do not forget to set up the ''crlDistributionPoints'' correctly. 
-  - Check the **caw\_settings.source** configuration file and configure it accordingly. The tricky part there is that some settings have to have the same values as in **ca\_openssl.cnf**. Again, the comments in the file will help you. The most important things to set up are: +  - Check the ''caw\_settings.source'' configuration file and configure it accordingly. The tricky part there is that some settings have to have the same values as in ''ca\_openssl.cnf''. Again, the comments in the file will help you. The most important things to set up are: 
-    - Configure **CA_OSSL\_ENGINE\_PARAM** if you want to use PKCS11 token. Set it to an empty string if you store the CA's private key in the file. +    - Configure ''CA\_OSSL\_ENGINE\_PARAM'' if you want to use PKCS11 token. Set it to an empty string if you store the CA's private key in the file. 
-    - Configure the **CA\_OSSL\_ROOT\_CHAIN** if your CAW authority is not the root authority. +    - Configure the ''CA\_OSSL\_ROOT\_CHAIN'' if your CAW authority is not the root authority. 
-    - Configure the **SubjectDN** and **CSR** validation prefixes. This also lets you set a basic policy for user's passphrase complexity. Also, set allowed signature algorithms.+    - Configure the ''SubjectDN'' and ''CSR'' validation prefixes. This also lets you set a basic policy for user's passphrase complexity. Also, set allowed signature algorithms
 +  - **If you do not use PKCS11 crypto token (that is, you want to use ''ca.key'')**, deconfigure PKCS11 engine template according to [[9.7:documentation:modules_crt:adm:caw_driver#deconfiguring_default_pkcs11_engine|this howto]].
   - Generate the empty CRL file.<code>   - Generate the empty CRL file.<code>
 [authority1@ca caw]$ ./caw create-crl [authority1@ca caw]$ ./caw create-crl
Line 158: Line 159:
 [root@ca ~]# ./caw create-crl [root@ca ~]# ./caw create-crl
 </code> </code>
 +
 +==== Deconfiguring default PKCS11 engine ====
 +By default, CAW comes with a preconfigured template for the PKCS11-enabled crypto engine. In some deployments, this is not necessary and the goal is to have CA's private key and certificate stored on the machine's filesystem.
 +This short howto will show you how to swap preconfigured PKCS11 engine for the more usual setup.
 +
 +The ''ca\_openssl.cnf'' file has several sections, referred as "stanzas". Stanza starts with ''[stanza name]'' and ends when another stanza starts.
 +
 +To deconfigure the PKCS11 template:
 +  - Edit the ''ca\_openssl.cnf'' file.
 +    - Comment out ''openssl\_conf = openssl\_init'' at the top of the file.
 +    - Comment out whole ''[openssl\_init]'' stanza.
 +    - Comment out whole ''[engine\_section]'' stanza.
 +    - Comment out whole ''[pkcs11\_engine]'' stanza.
 +    - In the ''[CA\_default]'' stanza, uncomment the ''private\_key = ...'' line. Set it to a path to your private key or create private key in the ''$dir/private/ca.key'' path. The key has to have at most ''600'' (''-rw\-\-\-\-\-\-\-'') privileges.
 +  - Edit the ''caw\_settings.source'' file.
 +    - Set the ''CA\_OSSL\_ENGINE\_PARAM="..."'' to ''CA\_OSSL\_ENGINE\_PARAM=""'' (empty variable).
 +==== Configuring CAW with the PKCS11 crypto token ====
 +<note warning>
 +**DISCLAIMER:** This howto is flawed in terms of overall security. Therein, we describe how to generate private key and then store it in the PKCS11 token. The token we use is SoftHSM, which is not a real physical token. To make it truly secure, you have to (at least):
 +  * Use real hardware crypto token.
 +  * Generate CA private key directly on the token (via openssl, p11-tool or such).
 +  * The private key pin (and security pin) really should not be 1234 (or 123456 respectively). Use reasonably strong pins.
 +
 +**If you modify the example below according to those remarks, then your setup should be secure enough.**
 +</note>
 +  - First, we generate the CA private key. This is not secure, but it is quicker for demonstration purposes. For more info, see the disclaimer.<code>
 +[root@ca ~]# openssl genrsa -out ca.key 4096
 +</code>
 +  - Create the CA CSR.<code>
 +[root@ca ~]# openssl req -new -key ca.key -out ca.csr -sha512
 +</code>
 +  - Create the CA certificate with appropriate extensions.<code>
 +[root@ca ~]# openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt -sha512 -extfile ca_extensions.txt
 +</code>
 +  - SoftHSM needs the key to be in PKCS8 format. The default generated from OpenSSL is PKCS5 so we have to convert it. Also, using ''-nocrypt'' option is a bad idea. But, again, we should be generating private key directly on the token.<code>
 +[root@ca ~]# openssl pkcs8 -in ca.key -topk8 -out ca_pk8.key -nocrypt
 +</code>
 +  - Suppose the SoftHSM is installed and configured. The SoftHSM's default data dir is in /var so you have to run it as root or reconfigure the data directory location - see the next section on how to configure SoftHSM to run under non-root user. Anyway, we first init the token and then import the CA private key.<code>
 +[root@ca ~]# softhsm2-util --init-token --slot 0 --label ca --so-pin 123456 --pin 1234
 +The token has been initialized.
 +[root@ca ~]# softhsm2-util --pin 1234 --so-pin 123456 --import ca_pk8.key --label ca --id A1B2 --no-public-key --slot 0
 +The key pair has been imported.
 +</code>
 +  - We have to link our token with openssl and test the setup. If everything goes right, we get the output similar to this one:<code>
 +[root@ca ~]# openssl engine -t dynamic -pre SO_PATH:/usr/lib64/openssl/engines/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib64/pkcs11/libsofthsm2.so -pre VERBOSE -pre PIN:1234
 +(dynamic) Dynamic engine loading support
 +Success: SO_PATH:/usr/lib64/openssl/engines/pkcs11.so
 +Success: ID:pkcs11
 +Success: LIST_ADD:1
 +Success: LOAD
 +Success: MODULE_PATH:/usr/lib64/pkcs11/libsofthsm2.so
 +Success: PIN:1234
 +Loaded: (pkcs11) pkcs11 engine
 +  [ available ]
 +</code>
 +  - Now create the user certificate request the usual way and try to sign it with the CA. We have stored ours in user.csr. We will also need an identifier of the PKSC11 token, which we can get by invoking ''softhsm2-util --show-slots''. Certificate signing should look basically like this (we used openssl shell in this snippet):<code>
 +[root@ca usercert]# openssl
 +OpenSSL> engine -t dynamic -pre SO_PATH:/usr/lib64/openssl/engines/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib64/pkcs11/libsofthsm2.so -pre VERBOSE -pre PIN:1234
 +(dynamic) Dynamic engine loading support
 +Success: SO_PATH:/usr/lib64/openssl/engines/pkcs11.so
 +Success: ID:pkcs11
 +Success: LIST_ADD:1
 +Success: LOAD
 +Success: MODULE_PATH:/usr/lib64/pkcs11/libsofthsm2.so
 +Success: VERBOSE
 +Success: PIN:1234
 +Loaded: (pkcs11) pkcs11 engine
 +PKCS#11: Initializing the engine
 +Found 2 slots
 +  [ available ]
 +OpenSSL> x509 -req -engine pkcs11 -CAkeyform engine -CAkey slot_0-label_ca -CA ca.crt -days 1000 -set_serial 15 -sha256 -in user.csr -out user.crt
 +PKCS#11: Initializing the engine
 +Found 2 slots
 +engine "pkcs11" set.
 +Signature ok
 +subject=/C=CZ/ST=Czech Republic/L=Prague/O=BCV/OU=TEST/CN=user.test.bcv
 +Getting CA Private Key
 +Loading private key "slot_0-label_ca"
 +Looking in slot 0 for key: label=ca
 +[0] SoftHSM slot 0             login             (ca)
 +[1] SoftHSM slot 1             uninitialized, login  (no label)
 +Found slot:  SoftHSM slot 0
 +Found token: ca
 +Found 0 certificate:
 +No private keys found.
 +Loading private key "slot_0-label_ca"
 +Looking in slot 0 for key: label=ca
 +[0] SoftHSM slot 0             login             (ca)
 +[1] SoftHSM slot 1             uninitialized, login  (no label)
 +Found slot:  SoftHSM slot 0
 +Found token: ca
 +Found 0 certificate:
 +Found 1 private key:
 +1 P  id=ffffffa2ffffffb2 label=ca
 +^C
 +</code>
 +  - Then we can verify the signing was correct:<code>
 +[root@ca usercert]# openssl verify -CAfile ca.crt user.crt
 +user.crt: OK
 +</code>
 +  - This tells us that openssl integration with the PKCS11 engine is working. To configure it in CAW, edit the ''[engine]'' section in the ''ca_openssl.cnf'' and supply the values you just used on the command line.
 +  - The last step is to configure ''CA\_OSSL\_ENGINE\_PARAM'' variable in the ''caw\_settings.source'' file. There is already template for that, the only value that needs changing should be an identifier of the PKCS11 slot.
 +
 +==== Using SoftHSM under non-root user ====
 +<note warning>SoftHSM is not a real crypto token. It is very handy during development but not meant for high-security production use.</note>
 +
 +We are installing SoftHSM on CentOS 7 operating system. Then, we will configure it to run under authority1 OS user.
 +  - Add the EPEL repository and install necessary packages.<code>
 +[root@ca ~]# yum install epel-release
 +[root@ca ~]# yum install softhsm opensc engine_pkcs11
 +</code>
 +  - Check if there is a system-wide configuration file.<code>
 +[root@ca ~]# cat /etc/softhsm2.conf
 +# SoftHSM v2 configuration file
 +directories.tokendir = /var/lib/softhsm/tokens/
 +objectstore.backend = file
 +# ERROR, WARNING, INFO, DEBUG
 +log.level = INFO
 +</code>
 +  - We have two options:
 +    * Change the system-wide configuration to point to a directory the ''authority1'' user can access.
 +    * Create local configuration file. This is better in cases where we want to have separate SoftHSM token storages.
 +  - We go for the second option. First, we change to the authority1 user and create our directory structure and config file.<code>
 +[root@ca ~]# su - authority1
 +[authority1@ca ~]$ pwd
 +/home/authority1
 +[authority1@ca ~]$ mkdir -pv softhsm/tokens
 +mkdir: created directory ‘softhsm’
 +mkdir: created directory ‘softhsm/tokens’
 +[authority1@ca ~]$ chmod 750 softhsm
 +[authority1@ca ~]$ vim softhsm/softhsm2.conf
 +[authority1@ca ~]$ cat softhsm/softhsm2.conf
 +directories.tokendir = /home/authority1/softhsm/tokens/
 +objectstore.backend = file
 +# ERROR, WARNING, INFO, DEBUG
 +log.level = INFO
 +</code>
 +  - SoftHSM is managed with the ''softhsm2-util'' program. This program reads environment variable ''SOFTHSM2\_CONF''. When the variable is not defined, it uses configuration ''/etc/softhsm2.conf''. We will export the variable with proper path to config file. **If you modified the system-wide config, you can skip this step.**<code>
 +[authority1@ca ~]$ export SOFTHSM2_CONF=/home/authority1/softhsm/softhsm2.conf
 +</code>
 +  - Now we simply call the ''softhsm2-util'' and initialize a new token. **Please DO NOT use PINs like 1234 or 123456 in the real world scenarios.**<code>
 +[authority1@ca ~]$ softhsm2-util --init-token --slot 0 --label test_slot --pin 1234 --so-pin 123456
 +</code>
 +  - We can check, that new token object was created in the configured backend store.<code>
 +[authority1@ca ~]$ find /home/authority1/softhsm/tokens/ -type f
 +/home/authority1/softhsm/tokens/ee48c4b2-b28e-8c2d-7921-59236dda0866/token.lock
 +/home/authority1/softhsm/tokens/ee48c4b2-b28e-8c2d-7921-59236dda0866/generation
 +/home/authority1/softhsm/tokens/ee48c4b2-b28e-8c2d-7921-59236dda0866/token.object
 +</code>
 +  - SoftHSM is working! To use such configuration with CAW, edit the ''caw\_settings.source'' and append the ''export SOFTHSM2_CONF...'' line to it. This will make CAW use the configured store. **If you modified the system-wide config, you can skip this step.**
  • by stekld