From 3185360834dc9992c141c84517bdecd3a87312a1 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 21 Aug 2016 12:17:19 -0400 Subject: Scripts demonstrating the OpenSSL engine API with Cryptech Alpha HSM. --- .gitignore | 4 ++++ README.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ basic-signature.sh | 8 ++++++++ create-keys.sh | 11 +++++++++++ delete-keys.sh | 11 +++++++++++ environment.sh | 22 +++++++++++++++++++++ list-keys.sh | 5 +++++ message.txt | 1 + openssl.conf | 46 +++++++++++++++++++++++++++++++++++++++++++ smime-signature.sh | 32 ++++++++++++++++++++++++++++++ 10 files changed, 197 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100755 basic-signature.sh create mode 100755 create-keys.sh create mode 100755 delete-keys.sh create mode 100644 environment.sh create mode 100755 list-keys.sh create mode 120000 message.txt create mode 100644 openssl.conf create mode 100755 smime-signature.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6df164f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.cer +*.sig +*.smime +TAGS diff --git a/README.md b/README.md new file mode 100644 index 0000000..648a565 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Toys to test Cryptech Alpha HSM with OpenSSL engine API + +Packages you need (on Debian Jessie, anyway): + + sudo apt-get install libengine-pkcs11-openssl opensc opensc-pkcs11 cryptech-alpha + +General plan here is to use pkcs11-tool to create keys, then use the +pkcs11 OpenSSL engine and OpenSSL command line tool to do vaguely +useful things with those keys. + +## Configuration + +* `openssl.conf` contains two different kinds of OpenSSL voodoo: the + bits needed to configure the engine, and the bits needed to + construct X.509 certificates. The engine configuration uses + environment variables to minimize the number of places where the + same information needs to be configured. + +* `environment.sh` is where environment variables are configured, + including the PKCS #11 PIN: you would not want to handle the PIN + this way in production! But it's convenient for a test script. + +## Scripts + +* `create-keys.sh` uses `pkcs11-tool` to create several test keys. At + the moment these are all RSA: the HSM is quite capable of using EC + P-256, P-384, and P-521 keys, but the engine seems not to like them. + +* `list-keys.sh` uses `pkcs11-tool` to list keys known to the HSM. + +* `delete-keys.sh` uses `pkcs11-tool` to delete the keys which + `create-keys.sh` created. + +* `basic-signature.sh` performs a basic hash-and-sign of a data file + using the `openssl dgst` command, writing a detached signature out + as a binary file. As a sanity check, it also verifies the resulting + signature using the corresponding public key. + +* `smime-signature.sh` generates a small X.509v3 certificate tree and + uses that to generate a signed S/MIME message. + +## References and notes + +* https://www.nlnetlabs.nl/downloads/publications/hsm/ +* https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM +* https://wiki.openssl.org/index.php/Command_Line_Utilities +* https://www.openssl.org/docs/man1.0.2/apps/ + +Given the overall state of OpenSSL's documentation, it also helps to +be able to read the OpenSSL source code: in this particular case, the +`apps/` directory is most likely to be useful. It turns out that many +(not all) places where one of the OpenSSL command line functions allow +one to specify a key format other than `PEM`, one of the supported +formats is `ENGINE`, in which case the "filename" is interpreted as a +key selector. + + diff --git a/basic-signature.sh b/basic-signature.sh new file mode 100755 index 0000000..16b663a --- /dev/null +++ b/basic-signature.sh @@ -0,0 +1,8 @@ +#!/bin/sh - + +. ./environment.sh + +set -x + +openssl dgst -keyform ENGINE -sha256 -engine pkcs11 -sign label_boris -out message.sig message.txt +openssl dgst -keyform ENGINE -sha256 -engine pkcs11 -verify label_boris -signature message.sig message.txt diff --git a/create-keys.sh b/create-keys.sh new file mode 100755 index 0000000..5cfda45 --- /dev/null +++ b/create-keys.sh @@ -0,0 +1,11 @@ +#!/bin/sh - + +. ./environment.sh + +# Not really sure which silly name to use for the EC curve, doc is not great. prime256v1? ansiX9p256r1? secp256r1? +# If I had to guess, ansiX9p256r1, so try that: --key-type EC:ansiX9p256r1 +# Still having trouble with OpenSSL using this key, so revert to RSA for now, try ECDSA again later. + +pkcs11-tool --module ${PKCS11_MODULE} --login --pin ${PKCS11_PIN} --keypairgen --id 1 --label leader --key-type rsa:2048 +pkcs11-tool --module ${PKCS11_MODULE} --login --pin ${PKCS11_PIN} --keypairgen --id 2 --label boris --key-type rsa:2048 +pkcs11-tool --module ${PKCS11_MODULE} --login --pin ${PKCS11_PIN} --keypairgen --id 3 --label natasha --key-type rsa:2848 diff --git a/delete-keys.sh b/delete-keys.sh new file mode 100755 index 0000000..f615bd7 --- /dev/null +++ b/delete-keys.sh @@ -0,0 +1,11 @@ +#!/bin/sh - + +. ./environment.sh + +for label in leader boris natasha +do + for type in privkey pubkey + do + pkcs11-tool --module ${PKCS11_MODULE} --login --pin ${PKCS11_PIN} --delete-object --label "$label" --type "$type" + done +done diff --git a/environment.sh b/environment.sh new file mode 100644 index 0000000..a842d81 --- /dev/null +++ b/environment.sh @@ -0,0 +1,22 @@ +# This is not a script in its own right, it's included by the other +# scripts to let us keep all the environment variables in a single place. + +# Where the PKCS #11 module lives, usually /usr/lib/libcryptech-pkcs11.so + +export PKCS11_MODULE=/usr/lib/libcryptech-pkcs11.so + +# PIN for user account on the HSM. In production you would NOT +# want this in an environment variable! + +export PKCS11_PIN=fnord + +# Where to find our OpenSSL configuration file. + +export OPENSSL_CONF=`pwd`/openssl.conf + +# If we don't already have the cryptech UART environment variables set, do that now. + +if test "X${CRYPTECH_RPC_CLIENT_SERIAL_DEVICE}" = "X" +then + eval `cryptech_probe` +fi diff --git a/list-keys.sh b/list-keys.sh new file mode 100755 index 0000000..77f24aa --- /dev/null +++ b/list-keys.sh @@ -0,0 +1,5 @@ +#!/bin/sh - + +. ./environment.sh + +pkcs11-tool --module ${PKCS11_MODULE} --login --pin ${PKCS11_PIN} --list-objects 2>/dev/null diff --git a/message.txt b/message.txt new file mode 120000 index 0000000..42061c0 --- /dev/null +++ b/message.txt @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/openssl.conf b/openssl.conf new file mode 100644 index 0000000..7f156ce --- /dev/null +++ b/openssl.conf @@ -0,0 +1,46 @@ +# For details on what can go here, see: +# +# https://github.com/OpenSC/libp11/README.md +# https://www.nlnetlabs.nl/downloads/publications/hsm/hsm_node18.html + +openssl_conf = openssl_def + +[openssl_def] +engines = engine_section + +[engine_section] +pkcs11 = pkcs11_section + +[pkcs11_section] +engine_id = pkcs11 +dynamic_path = /usr/lib/engines/engine_pkcs11.so +init = 0 + +# For convenience while testing, we use environment variables to pass +# in the PIN and the path to the PKCS #11 module. You would NOT +# want to do this in production, particularly with the PIN. + +MODULE_PATH = ${ENV::PKCS11_MODULE} +PIN = ${ENV::PKCS11_PIN} + +# From here down is OpenSSL voodoo for issuing certificates. + +[req] +distinguished_name = dn +default_md = sha256 +x509_extensions = ext_ca + +[dn] +C = PV +O = Pottsylvanian Ministry of Offense + +[ext_ca] +basicConstraints = critical, CA:true +keyUsage = critical, cRLSign, keyCertSign +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always + +[ext_ee] +keyUsage = critical, digitalSignature, nonRepudiation +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always diff --git a/smime-signature.sh b/smime-signature.sh new file mode 100755 index 0000000..fb2f815 --- /dev/null +++ b/smime-signature.sh @@ -0,0 +1,32 @@ +#!/bin/sh - + +. ./environment.sh + +set -x + +openssl req -batch -new -engine pkcs11 -keyform ENGINE -x509 -days 365 \ + -subj "/C=PV/O=Pottsylvanian Ministry of Offense/GN=Fearless/SN=Leader" \ + -key label_leader -out leader.cer + +openssl req -batch -new -engine pkcs11 -keyform ENGINE \ + -subj "/GN=Natasha/SN=Fatale" \ + -key label_natasha | +openssl x509 -req -engine pkcs11 -CAkeyform ENGINE -days 60 \ + -set_serial `date +%s` -extfile $OPENSSL_CONF -extensions ext_ee \ + -CAkey label_leader -CA leader.cer \ + -out natasha.cer + +openssl req -batch -new -engine pkcs11 -keyform ENGINE \ + -subj "/GN=Boris/SN=Badenov" \ + -key label_boris | +openssl x509 -req -engine pkcs11 -CAkeyform ENGINE -days 60 \ + -set_serial `date +%s` -extfile $OPENSSL_CONF -extensions ext_ee \ + -CAkey label_leader -CA leader.cer \ + -out boris.cer + +openssl smime -engine pkcs11 -sign -text -keyform ENGINE \ + -inkey label_natasha -signer natasha.cer -certfile leader.cer \ + -from "Natasha Fatale " \ + -to "Boris Badenov " \ + -subject "Fiendish plot" \ + -in message.txt -out message.smime -- cgit v1.2.3