From 38df202cdb3c46cc6361cce010a041294e153920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 31 Aug 2023 14:24:15 +0300 Subject: [PATCH] Update PKCS#11 section in the ARM Add instructions for pkcs11-provider and generalize common sections. --- doc/arm/pkcs11.inc.rst | 185 +++++++++++++++++++++++++++++------------ 1 file changed, 133 insertions(+), 52 deletions(-) diff --git a/doc/arm/pkcs11.inc.rst b/doc/arm/pkcs11.inc.rst index 5fd29d4e3d..78de07bcf3 100644 --- a/doc/arm/pkcs11.inc.rst +++ b/doc/arm/pkcs11.inc.rst @@ -23,14 +23,17 @@ library which provides a low-level PKCS#11 interface to drive the HSM hardware. The PKCS#11 provider library comes from the HSM vendor, and it is specific to the HSM to be controlled. -BIND 9 uses engine_pkcs11 for PKCS#11. engine_pkcs11 is an OpenSSL -engine which is part of the `OpenSC`_ project. The engine is dynamically -loaded into OpenSSL and the HSM is operated indirectly; any -cryptographic operations not supported by the HSM can be carried out by -OpenSSL instead. +BIND 9 access PKCS#11 libraries via OpenSSL extensions. The extension for +OpenSSL 3 and newer is `pkcs11-provider`_. And for the older OpenSSL versions +engine_pkcs11 from the `OpenSC`_ project can be used. +.. _`pkcs11-provider`: https://github.com/latchset/pkcs11-provider .. _OpenSC: https://github.com/OpenSC/libp11 +In both cases the extension is dynamically loaded into OpenSSL and the HSM is +operated indirectly; any cryptographic operations not supported by the HSM can +be carried out by OpenSSL instead. + Prerequisites ^^^^^^^^^^^^^ @@ -64,10 +67,10 @@ with BIND. $ make install $ /opt/pkcs11/usr/bin/softhsm-util --init-token 0 --slot 0 --label softhsmv2 -OpenSSL-based PKCS#11 -^^^^^^^^^^^^^^^^^^^^^ +OpenSSL 1.x.x with engine_pkcs11 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -OpenSSL-based PKCS#11 uses engine_pkcs11 OpenSSL engine from libp11 project. +OpenSSL engine-based PKCS#11 uses engine_pkcs11 OpenSSL engine from libp11 project. engine_pkcs11 tries to fit the PKCS#11 API within the engine API of OpenSSL. That is, it provides a gateway between PKCS#11 modules and the OpenSSL engine @@ -82,8 +85,14 @@ For more detailed howto including the examples, we recommend reading: https://gitlab.isc.org/isc-projects/bind9/-/wikis/BIND-9-PKCS11 -Using the HSM -^^^^^^^^^^^^^ +When using engine_pkcs11, all BIND binaries potentially need the keys require +'-E pkcs11' argument to activate the engine support. + +Even though OpenSSL 3 has compatibility support for Engine API it is not +recommended to be used due to bugs in OpenSSL and libp11. + +Configuring engine_pkcs11 +^^^^^^^^^^^^^^^^^^^^^^^^^ The canonical documentation for configuring engine_pkcs11 is in the `libp11/README.md`_, but here's copy of working configuration for @@ -106,7 +115,7 @@ and export the environment variable: export OPENSSL_CONF=/opt/bind9/etc/openssl.cnf -Now add following line at the top of file, before any sections (in square +Now add the following line at the top of file, before any sections (in square brackets) are defined: :: @@ -129,8 +138,104 @@ Add following lines at the bottom of the file: engine_id = pkcs11 dynamic_path = /pkcs11.so MODULE_PATH = + # if automatic logging to the token is needed, PIN can be specified as below + #PIN = 1234 init = 0 +Enabling the OpenSSL Engine in BIND commands +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When using OpenSSL Engine-based PKCS#11, the "engine" to be used by OpenSSL can be +specified in :iscman:`named` and all of the BIND ``dnssec-*`` tools by using the ``-E +`` command line option. This engine name matches the 'engine_id' in the +``openssl.cnf`` created in previous section. + +The zone signing commences as usual, with only one small difference. We need to +provide the name of the OpenSSL engine using the -E command line option. + +:: + + dnssec-signzone -E pkcs11 -S -o example.net example.net + + +OpenSSL 3 with pkcs11-provider +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +OpenSSL provider-based PKCS#11 uses pkcs11-provider project. + +pkcs11-provider tries to fit the PKCS#11 API within the Provider API of OpenSSL. +That is, it provides a gateway between PKCS#11 modules and the OpenSSL Provider +API. One has to register the engine with OpenSSL and one has to provide the +path to the PKCS#11 module which should be gatewayed to. This can be done by +editing the OpenSSL configuration file, by engine specific controls, or by using +the p11-kit proxy module. + +It is recommended that pkcs11-provider git commit 8672b98d2558aecb49f173df97b1463c7697b540 +from August 15, 2023 or later is used. + +BIND support for pkcs11-provider is built in and the -E command line option +explained above should not be used. + +Configuring pkcs11-provider +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The canonical documentation for configuring pkcs11-provider is in the +`provider-pkcs11.7`_ manual page, but here's copy of working configuration for +your convenience: + +.. _`provider-pkcs11.7`: https://github.com/latchset/pkcs11-provider/blob/main/docs/provider-pkcs11.7.md + +We are going to use our own custom copy of OpenSSL configuration, again it's +driven by an environment variable, this time called OPENSSL_CONF. We are +going to copy the global OpenSSL configuration (often found in +``etc/ssl/openssl.conf``) and customize it to use pkcs11-provider. + +:: + + cp /etc/ssl/openssl.cnf /opt/bind9/etc/openssl.cnf + +and export the environment variable: + +:: + + export OPENSSL_CONF=/opt/bind9/etc/openssl.cnf + +Now add the following line at the top of file, before any sections (in square +brackets) are defined: + +:: + + openssl_conf = openssl_init + +And make sure there are no other 'openssl_conf = ...' lines in the file. + +Add following lines at the bottom of the file: + +:: + + [openssl_init] + providers = provider_init + + [provider_init] + default = default_init + pkcs11 = pkcs11_init + + [default_init] + activate = 1 + + [pkcs11_init] + module = /pkcs11.so + pkcs11-module-path = + # bind uses the digest+sign api. this is broken with the default load behaviour, + # but works with early load. see: https://github.com/latchset/pkcs11-provider/issues/266 + pkcs11-module-load-behavior = early + # no-deinit quirk is needed if you use softhsm2 + #pkcs11-module-quirks = no-deinit + # if automatic logging to the token is needed, PIN can be specified as below + # the file referenced should contain just the PIN + #pkcs11-module-token-pin = file:/etc/pki/pin.txt + activate = 1 + Key Generation ^^^^^^^^^^^^^^ @@ -154,23 +259,27 @@ label to reference the private key. Convert the RSA keys stored in the HSM into a format that BIND 9 understands. The :iscman:`dnssec-keyfromlabel` tool from BIND 9 can link the raw keys stored in the -HSM with the ``K++`` files. You'll need to provide the OpenSSL -engine name (``pkcs11``), the algorithm (``RSASHA256``) and the PKCS#11 label -that specify the token (we asume that it has been initialized as bind9), the -name of the PKCS#11 object (called label when generating the keys using -``pkcs11-tool``) and the HSM PIN. +HSM with the ``K++`` files. + +You'll need to provide the OpenSSL engine name (``pkcs11``) if using the engine and +the algorithm (``RSASHA256``). The key is referenced with the PKCS#11 URI scheme and it +can contain the PKCS#11 token label (we asume that it has been initialized as bind9), +and the PKCS#11 object label (called label when generating the keys using ``pkcs11-tool``) +and the HSM PIN. Refer to `RFC7512`_ for the full PKCS#11 URI specification. + +.. _`RFC7512`: https://www.rfc-editor.org/rfc/rfc7512.html Convert the KSK: :: - dnssec-keyfromlabel -E pkcs11 -a RSASHA256 -l "token=bind9;object=example.net-ksk;pin-value=0000" -f KSK example.net + dnssec-keyfromlabel -E pkcs11 -a RSASHA256 -l "pkcs11:token=bind9;object=example.net-ksk;pin-value=0000" -f KSK example.net and ZSK: :: - dnssec-keyfromlabel -E pkcs11 -a RSASHA256 -l "token=bind9;object=example.net-zsk;pin-value=0000" example.net + dnssec-keyfromlabel -E pkcs11 -a RSASHA256 -l "pkcs11:token=bind9;object=example.net-zsk;pin-value=0000" example.net NOTE: you can use PIN stored on disk, by specifying ``pin-source=/``, f.e.: @@ -212,26 +321,12 @@ this is when creating ECDSA keys, you should specify a unique ID: pkcs11-tool --module -l -k --key-type EC:prime256v1 --id $zsk --label example.net-zsk --pin -Specifying the Engine on the Command Line -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When using OpenSSL-based PKCS#11, the "engine" to be used by OpenSSL can be -specified in :iscman:`named` and all of the BIND ``dnssec-*`` tools by using the ``-E -`` command line option. Specifying the engine is generally not necessary -unless a different OpenSSL engine is used. - -The zone signing commences as usual, with only one small difference. We need to -provide the name of the OpenSSL engine using the -E command line option. - -:: - - dnssec-signzone -E pkcs11 -S -o example.net example.net - Running :iscman:`named` With Automatic Zone Re-signing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The zone can also be signed automatically by named. Again, we need to provide -the name of the OpenSSL engine using the :option:`-E ` command line option. +the name of the OpenSSL engine using the :option:`-E ` command line option, +if using OpenSSL 1.x.x with engine_pkcs11, and this is not needed when using OpenSSL 3.x.x providers. :: @@ -254,21 +349,7 @@ have access to the HSM PIN. In OpenSSL-based PKCS#11, this is accomplished by placing the PIN into the ``openssl.cnf`` file (in the above examples, ``/opt/pkcs11/usr/ssl/openssl.cnf``). -The location of the openssl.cnf file can be overridden by setting the -``OPENSSL_CONF`` environment variable before running :iscman:`named`. - -Here is a sample ``openssl.cnf``: - -:: - - openssl_conf = openssl_def - [ openssl_def ] - engines = engine_section - [ engine_section ] - pkcs11 = pkcs11_section - [ pkcs11_section ] - PIN = - -This also allows the ``dnssec-\*`` tools to access the HSM without PIN -entry. (The ``pkcs11-\*`` tools access the HSM directly, not via OpenSSL, so -a PIN is still required to use them.) +See OpenSSL extension specific documentation on how to configure the PIN on +global level. Doing so allows the ``dnssec-\*`` tools to access the HSM without +PIN entry. (The ``pkcs11-\*`` tools access the HSM directly, not via OpenSSL, +so a PIN is still required to use them.)