2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

Update PKCS#11 section in the ARM

Add instructions for pkcs11-provider and generalize common sections.
This commit is contained in:
Timo Teräs 2023-08-31 14:24:15 +03:00 committed by Matthijs Mekking
parent 6f53d34201
commit 38df202cdb

View File

@ -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 = <PATHTO>/pkcs11.so
MODULE_PATH = <FULL_PATH_TO_HSM_MODULE>
# 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
<engine>`` 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 = <PATHTO>/pkcs11.so
pkcs11-module-path = <FULL_PATH_TO_HSM_MODULE>
# 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<zone>+<alg>+<id>`` 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<zone>+<alg>+<id>`` 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=<path_to>/<file>``, f.e.:
@ -212,26 +321,12 @@ this is when creating ECDSA keys, you should specify a unique ID:
pkcs11-tool --module <FULL_PATH_TO_HSM_MODULE> -l -k --key-type EC:prime256v1 --id $zsk --label example.net-zsk --pin <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
<engine>`` 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 <named -E>` command line option.
the name of the OpenSSL engine using the :option:`-E <named -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 = <PLACE PIN HERE>
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.)