mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-25 19:04:57 -05:00
309 lines
12 KiB
Text
309 lines
12 KiB
Text
|
|
BIND 9 PKCS #11 (Cryptoki) support
|
|
|
|
INTRODUCTION
|
|
|
|
PKCS #11 (Public Key Cryptography Standard #11) defines a platform-
|
|
independent API for the control of hardware security modules (HSMs)
|
|
and other cryptographic support devices.
|
|
|
|
BIND 9 is known to work with two HSMs: The Sun SCA 6000 cryptographic
|
|
acceleration board, tested under Solaris x86, and the AEP Keyper
|
|
network-attached key storage device, tested with Debian Linux,
|
|
Solaris x86 and Windows Server 2003.
|
|
|
|
PREREQUISITES
|
|
|
|
See the HSM vendor documentation for information about installing,
|
|
initializing, testing and troubleshooting the HSM.
|
|
|
|
BIND 9 uses OpenSSL for cryptography, but stock OpenSSL does not
|
|
yet fully support PKCS #11. However, a PKCS #11 engine for OpenSSL
|
|
is available from the OpenSolaris project. It has been modified by
|
|
ISC to work with with BIND 9, and to provide new features such as
|
|
PIN management and key by reference.
|
|
|
|
The patched OpenSSL depends on a "PKCS #11 provider". This is a shared
|
|
library object, providing a low-level PKCS #11 interface to the HSM
|
|
hardware. It is dynamically loaded by OpenSSL at runtime. The PKCS #11
|
|
provider comes from the HSM vendor, and and is specific to the HSM to be
|
|
controlled.
|
|
|
|
There are two "flavors" of PKCS #11 support provided by the patched
|
|
OpenSSL, one of which must be chosen at configuration time. The correct
|
|
choice depends on the HSM hardware:
|
|
|
|
- Use 'crypto-accelerator' with HSMs that have hardware cryptographic
|
|
acceleration features, such as the SCA 6000 board. This causes OpenSSL
|
|
to run all supported cryptographic operations in the HSM.
|
|
|
|
- Use 'sign-only' with HSMs that are designed to function primarily as
|
|
secure key storage devices, but lack hardware acceleration. These
|
|
devices are highly secure, but are not necessarily any faster at
|
|
cryptography than the system CPU--often, they are slower. It is
|
|
therefore most efficient to use them only for those cryptographic
|
|
functions that require access to the secured private key, such as
|
|
zone signing, and to use the system CPU for all other computationally-
|
|
intensive operations. The AEP Keyper is an example of such a device.
|
|
|
|
The modified OpenSSL code is included in the BIND 9.7.0b1 release, in the
|
|
form of a context diff against OpenSSL 0.9.8l. Before building BIND 9
|
|
with PKCS #11 support, it will be necessary to build OpenSSL with this
|
|
patch in place and inform it of the path to the HSM-specific PKCS #11
|
|
provider library.
|
|
|
|
Obtain OpenSSL 0.9.8l:
|
|
|
|
wget http://www.openssl.org/source/openssl-0.9.8l.tar.gz
|
|
|
|
Extract the tarball:
|
|
|
|
tar zxf openssl-0.9.8l.tar.gz
|
|
|
|
Apply the patch from the BIND 9 release:
|
|
|
|
patch -p1 -d openssl-0.9.8l \
|
|
< bind-9.7.0b1/bin/pkcs11/openssl-0.9.8l-patch
|
|
|
|
(Note that the patch file may not be compatible with the "patch"
|
|
utility on all operating systems. You may need to install GNU patch.)
|
|
|
|
When building OpenSSL, place it in a non-standard location so that it
|
|
does not interfere with OpenSSL libraries elsewhere on the system.
|
|
In the following examples, we choose to install into "/opt/pkcs11/usr".
|
|
We will use this location when we configure BIND 9.
|
|
|
|
EXAMPLE 1--BUILDING OPENSSL FOR THE AEP KEYPER ON LINUX:
|
|
|
|
The AEP Keyper is a highly secure key storage device, but does
|
|
not provide hardware cryptographic acceleration. It can carry out
|
|
cryptographic operations, but it is probably slower than your
|
|
system's CPU. Therefore, we choose the 'sign-only' flavor when
|
|
building OpenSSL.
|
|
|
|
The Keyper-specific PKCS #11 provider library is delivered with the
|
|
Keyper software. In this example, we place it /opt/pkcs11/usr/lib:
|
|
|
|
cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so
|
|
|
|
This library is only available for Linux as a 32-bit binary. If we are
|
|
compiling on a 64-bit Linux system, it is necessary to force a 32-bit
|
|
build, by specifying -m32 in the build options.
|
|
|
|
Finally, the Keyper library requires threads, so we must specify -pthread.
|
|
|
|
cd openssl-0.9.8l
|
|
./Configure linux-generic32 -m32 -pthread \
|
|
--pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \
|
|
--pk11-flavor=sign-only \
|
|
--prefix=/opt/pkcs11/usr
|
|
|
|
After configuring, run "make" and "make test". If "make test" fails
|
|
with "pthread_atfork() not found", you forgot to add the -pthread
|
|
above.
|
|
|
|
EXAMPLE 2--BUILDING OPENSSL FOR THE SCA 6000 ON SOLARIS:
|
|
|
|
The SCA-6000 PKCS #11 provider is installed as a system library,
|
|
libpkcs11. It is a true crypto accelerator, up to 4 times faster
|
|
than any CPU, so the flavor shall be 'crypto-accelerator'.
|
|
|
|
In this example, we are building on Solaris x86 on an AMD64 system.
|
|
|
|
cd openssl-0.9.8l
|
|
./Configure solaris64-x86_64-cc \
|
|
--pk11-libname=/usr/lib/64/libpkcs11.so \
|
|
--pk11-flavor=crypto-accelerator \
|
|
--prefix=/opt/pkcs11/usr
|
|
|
|
(For a 32-bit build, use "solaris-x86-cc" and /usr/lib/libpkcs11.so.)
|
|
|
|
After configuring, run "make" and "make test".
|
|
|
|
Once you have built OpenSSL, run "apps/openssl engine pkcs11" to confirm
|
|
that PKCS #11 support was compiled in correctly. The output should be
|
|
one of the following lines, depending on the flavor selected:
|
|
|
|
(pkcs11) PKCS #11 engine support (sign only)
|
|
|
|
Or:
|
|
|
|
(pkcs11) PKCS #11 engine support (crypto accelerator)
|
|
|
|
Next, run "apps/openssl engine pkcs11 -t". This will attempt to initialize
|
|
the PKCS #11 engine. If it is able to do so successfully, it will report
|
|
"[ available ]".
|
|
|
|
If the output is correct, run "make install".
|
|
|
|
BUILDING BIND 9
|
|
|
|
When building BIND 9, the location of the custom-built OpenSSL
|
|
library must be specified via configure.
|
|
|
|
EXAMPLE 3--CONFIGURING BIND 9 FOR LINUX
|
|
|
|
To link with the PKCS #11 provider, threads must be enabled in the
|
|
BIND 9 build.
|
|
|
|
The PKCS #11 library for the AEP Keyper is currently only available as
|
|
a 32-bit binary. If we are building on a 64-bit host, we must force a
|
|
32-bit build by adding "-m32" to the CC options on the "configure"
|
|
command line.
|
|
|
|
cd ../bind-9.7.0b1
|
|
./configure CC="gcc -m32" --enable-threads \
|
|
--with-openssl=/opt/pkcs11/usr \
|
|
--with-pkcs11=/opt/pkcs11/usr/lib/libpkcs11.so
|
|
|
|
EXAMPLE 4--CONFIGURING BIND 9 FOR SOLARIS
|
|
|
|
To link with the PKCS #11 provider, threads must be enabled in the
|
|
BIND 9 build.
|
|
|
|
cd ../bind-9.7.0b1
|
|
./configure CC="cc -xarch=amd64" --enable-threads \
|
|
--with-openssl=/opt/pkcs11/usr \
|
|
--with-pkcs11=/usr/lib/64/libpkcs11.so
|
|
|
|
(For a 32-bit build, omit CC="cc -xarch=amd64".)
|
|
|
|
If configure complains about OpenSSL not working, you may have a 32/64-bit
|
|
architecture mismatch. Or, you may have incorrectly specified the path to
|
|
OpenSSL (it should be the same as the --prefix argument to the OpenSSL
|
|
Configure).
|
|
|
|
After configuring, run "make", "make test" and "make install".
|
|
|
|
PKCS #11 TOOLS
|
|
|
|
BIND 9 includes a minimal set of tools to operate the HSM, including
|
|
"pkcs11-keygen" to generate a new key pair within the HSM, "pkcs11-list"
|
|
to list objects currently available, and "pkcs11-destroy" to remove
|
|
objects.
|
|
|
|
In UNIX/Linux builds, these tools are built only if BIND 9 is configured
|
|
with the --with-pkcs11 option. (NOTE: If --with-pkcs11 is set to "yes",
|
|
rather than to the path of the PKCS #11 provider, then the tools will be
|
|
built but the provider will be left undefined. Use the -m option or the
|
|
PKCS11_PROVIDER environment variable to specify the path to the provider.)
|
|
|
|
USING THE HSM
|
|
|
|
First, we must set up the runtime environment so the OpenSSL and PKCS #11
|
|
libraries can be loaded:
|
|
|
|
export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH}
|
|
|
|
When operating an AEP Keyper, it is also necessary to specify the
|
|
location of the "machine" file, which stores information about the Keyper
|
|
for use by PKCS #11 provider library. If the machine file is in
|
|
/opt/Keyper/PKCS11Provider/machine, use:
|
|
|
|
export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider
|
|
|
|
These environment variables must be set whenever running any tool
|
|
that uses the HSM, including pkcs11-keygen, pkcs11-list, pkcs11-destroy,
|
|
dnssec-keyfromlabel, dnssec-signzone, dnssec-keygen (which will use
|
|
the HSM for random number generation), and named.
|
|
|
|
We can now create and use keys in the HSM. In this case, we will
|
|
create a 2048 bit key and give it the label "sample-ksk":
|
|
|
|
pkcs11-keygen -b 2048 -l sample-ksk
|
|
|
|
To confirm that the key exists:
|
|
|
|
pkcs11-list
|
|
Enter PIN:
|
|
object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0]
|
|
object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0]
|
|
|
|
Before using this key to sign a zone, we must create a pair of BIND 9
|
|
key files. The "dnssec-keyfromlabel" utility does this. In this case,
|
|
we will be using the HSM key "sample-ksk" as the key-signing key for
|
|
"example.net":
|
|
|
|
dnssec-keyfromlabel -l sample-ksk -f KSK example.net
|
|
|
|
The resulting K*.key and K*.private files can now be used to sign the
|
|
zone. Unlike normal K* files, which contain both public and private
|
|
key data, these files will contain only the public key data, plus an
|
|
identifier for the private key which remains stored within the HSM.
|
|
The HSM handles signing with the private key.
|
|
|
|
If you wish to generate a second key in the HSM for use as a zone-signing
|
|
key, follow the same procedure above, using a different keylabel, a
|
|
smaller key size, and omitting "-f KSK" from the dnssec-keyfromlabel
|
|
arguments:
|
|
|
|
pkcs11-keygen -b 1024 -l sample-zsk
|
|
dnssec-keyfromlabel -l sample-zsk example.net
|
|
|
|
Alternatively, you may prefer to generate a conventional on-disk key,
|
|
using dnssec-keygen:
|
|
|
|
dnssec-keygen example.net
|
|
|
|
This provides less security than an HSM key, but since HSMs can be
|
|
slow or cumbersome to use for security reasons, it may be more
|
|
efficient to reserve HSM keys for use in the less frequent
|
|
key-signing operation. The zone-signing key can be rolled more
|
|
frequently, if you wish, to compensate for a reduction in key
|
|
security.
|
|
|
|
Now you can sign the zone. (Note: If not using the -S option to
|
|
dnssec-signzone, it will be necessary to add the contents of both
|
|
K*.key files to the zone master file before signing it.)
|
|
|
|
dnssec-signzone -S example.net
|
|
Enter PIN:
|
|
Verifying the zone using the following algorithms: NSEC3RSASHA1.
|
|
Zone signing complete:
|
|
Algorithm: NSEC3RSASHA1: ZSKs: 1, KSKs: 1 active, 0 revoked, 0 stand-by
|
|
example.net.signed
|
|
|
|
SPECIFYING THE ENGINE ON THE COMMAND LINE
|
|
|
|
The OpenSSL engine can be specified in named and all of the dnssec-*
|
|
tools by using the "-E <engine>" command line option. If BIND 9 is built
|
|
with the --with-pkcs11 option, this option defaults to "pkcs11".
|
|
Specifying the engine will generally not be necessary unless for
|
|
some reason you wish to use a different OpenSSL engine.
|
|
|
|
If you wish to disable use of the "pkcs11" engine--for troubleshooting
|
|
purposes, or because the HSM is unavailable--set the engine to the empty
|
|
string. For example:
|
|
|
|
dnssec-signzone -E '' -S example.net
|
|
|
|
This causes dnssec-signzone to run as if it were compiled without the
|
|
--with-pkcs11 option.
|
|
|
|
RUNNING NAMED WITH AUTOMATIC ZONE RE-SIGNING
|
|
|
|
If you want named to dynamically re-sign zones using HSM keys, and/or to
|
|
to sign new records inserted via nsupdate, then named must have access
|
|
to the HSM PIN. This can be 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 named.
|
|
|
|
Sample openssl.cnf:
|
|
|
|
openssl_conf = openssl_def
|
|
[ openssl_def ]
|
|
engines = engine_section
|
|
[ engine_section ]
|
|
pkcs11 = pkcs11_section
|
|
[ pkcs11_section ]
|
|
PIN = <PLACE PIN HERE>
|
|
|
|
This will also allow the dnssec-* tools to access the HSM without
|
|
PIN entry. (The pkcs11-* tools access the HSM directly, not via
|
|
OpenSSL, so a PIN will still be required to use them.)
|
|
|
|
PLEASE NOTE: Placing the HSM's PIN in a text file in this manner
|
|
may reduce the security advantage of using an HSM. Be sure this
|
|
is what you want to do before configuring BIND 9 in this way.
|