Skip to content

Instantly share code, notes, and snippets.

@cprima
Created January 1, 2018 17:18
Show Gist options
  • Save cprima/37aa9090092c277f9e3af727a0dcbe8a to your computer and use it in GitHub Desktop.
Save cprima/37aa9090092c277f9e3af727a0dcbe8a to your computer and use it in GitHub Desktop.
Initializing the Nitrokey HSM (Ubuntu 16.04)
#!/usr/bin/env bash
#/**
# * A bash script to initialize a Nitrokey HSM in a basic way.
# * Does nothing on a Nitrokey HSM that was ever initialized before.
# * Its main purpose is to validate user input, especially the -so-pin.
# * I wrote it to make me read the docu carefully. ;)
# *
# * What the script does:
# * - uses readline with plain input, and not "enter twice and compare"
# * -- so "secret input" are visible on the screen
# * - uses the default -so-pin Security Officer PIN if no other is given
# * - asks for the -pin user PIN to initialize
# * - asks for the number of custodians
# * -- to generate DKEK shares for
# * -- writes these in plain text to disk(!)
# * - initializes the Nitrokey HSM with the -so-pin and -pin and number of custodians
# * - and imports the custodian's DKEK shares
# *
# * What the script does NOT:
# * - implement n of M thresholds
# * - generate keys
# * - re-initializes a Nitrokey HSM (although could be adapted)
# *
# * Copyright (c) 2018 Christian Prior
# * Licensed under the MIT License. See LICENSE file in the project root for full license information.
# *
# * @SEE: https://shop.nitrokey.com/de_DE/shop/product/nitrokey-hsm-7
# * @SEE: https://raymii.org/s/articles/Get_Started_With_The_Nitrokey_HSM.html
# *
# *
: <<'sample_output'
./initializing-NitrokeyHSM.sh
Do you want to initialize with a new SO pin(16 chars hex)? [yn]n
SO pin unchanged.
Using -so-pin ending on ************3830
Enter the user PIN to initialize the Nitrokey HSM with (min 4 and max 16 ASCII chars): 12345
Using -pin ending on ****5
The PIN can be changed, but not its length without re-initializing the HSM.
Enter how many custodians to generate: 1
Generating 1 DKEK share for later re-import after the initialiation.
Enter the custodian password to initialize DKEK share (should be > 10 chars): abcdef
Using reader with a card: Nitrokey Nitrokey HSM (010000000000000000000000) 00 00
Enciphering DKEK share, please wait...
DKEK share created and saved to dkek-share-1.pbe
U2FsdGVkX1/uB8Y4t6SR7yrzue47/nzeFixjesMkOgsy662+pFszk8OcjiL0D2Br
DB+WoOd4pdPZ76p6fnWzfg==
Do you want to initialize the Nitrokey HSM? [yn]y
Initializing with ************3830
and 1 DKEK shares.
Using reader with a card: Nitrokey Nitrokey HSM (010000000000000000000000) 00 00
Using reader with a card: Nitrokey Nitrokey HSM (010000000000000000000000) 00 00
Version : 2.5
Config options :
User PIN reset with SO-PIN enabled
SO-PIN tries left : 15
User PIN tries left : 3
DKEK shares : 1
DKEK import pending, 1 share(s) still missing
Using reader with a card: Nitrokey Nitrokey HSM (010000000000000000000000) 00 00
Deciphering DKEK share, please wait...
DKEK share imported
DKEK shares : 1
DKEK key check value : 6790B7958E0D84EE
Using reader with a card: Nitrokey Nitrokey HSM (010000000000000000000000) 00 00
Version : 2.5
Config options :
User PIN reset with SO-PIN enabled
SO-PIN tries left : 15
User PIN tries left : 3
DKEK shares : 1
DKEK key check value : 6790B7958E0D84EE
sample_output
# *
# */
set -o nounset #exit on undeclared variable
_LENGTH_USERPIN_MIN=4
_LENGTH_USERPIN_MAX=16
_COUNT_CUSTODIANS_MIN=0
_COUNT_CUSTODIANS_MAX=9
_COUNT_CUSTODIANS=1
_TMP_PASSWD_CUSTODIAN=
declare -A _CUSTODIANS
_SOPIN_CURRENT=
_SOPIN_FUTURE=
_USERPIN=
answer=
_PRISTINE_HSM=""
if sc-hsm-tool 2>/dev/null | grep -q "SmartCard-HSM has never been initialized. Please use --initialize to set SO-PIN and user PIN."; then
_SOPIN_CURRENT=3537363231383830;
_PRISTINE_HSM="True";
#-e on interactive shells: use Bash's readline interface to read the data
#-r raw input - disables interpretion of backslash escapes and line-continuation in the read data
#-s secure input - don't echo input if on a terminal
while read -e -r -n 1 -s -p "Do you want to initialize with a new SO pin(16 chars hex)? [yn]" answer; do
if [[ $answer = [YyNn] ]]; then
if [[ $answer = [Yy] ]]; then
while true; do
read -e -p "Enter the SO-PIN (16 hex(!) chars and only 15 strikes/lifetime):" _SOPIN_FUTURE;
if ! [[ ${_SOPIN_FUTURE} =~ ^[[:xdigit:]]{16}$ ]]; then
echo "Error: Not valid hex format [A-Fa-f0-9] or wrong length!";
else echo "else"; break 2; fi;
done;
elif [[ $answer = [Nn] ]]; then
echo "SO pin unchanged."
break;
fi
fi
done
echo -e "\n\nUsing -so-pin ending on ${_SOPIN_CURRENT/${_SOPIN_CURRENT:0:12}/************}";
if [ ! -z ${_SOPIN_FUTURE} ]; then
echo -e "Future -so-pin ending on ${_SOPIN_FUTURE/${_SOPIN_FUTURE:0:12}/************}\n";
else echo -e "\n\n";
fi
while true; do read -e -p "Enter the user PIN to initialize the Nitrokey HSM with (min ${_LENGTH_USERPIN_MIN} and max ${_LENGTH_USERPIN_MAX} ASCII chars): " -i "12345" _USERPIN;
if [[ ${#_USERPIN} -lt ${_LENGTH_USERPIN_MIN} ]]; then
echo "Too short (min ${_LENGTH_USERPIN_MIN} chars).";
elif [[ ${#_USERPIN} -gt ${_LENGTH_USERPIN_MAX} ]]; then
echo "Too long (min ${_LENGTH_USERPIN_MAX} chars).";
elif ! [[ ${_USERPIN} =~ ^[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]{${_LENGTH_USERPIN_MIN},${_LENGTH_USERPIN_MAX}}$ ]]; then
echo "Error: Not valid ASCII format [0-9a-zA-Z] or wrong length!";
else break; fi;
done;
echo -e "\n\nUsing -pin ending on ${_USERPIN/${_USERPIN:0:4}/****}\nThe PIN can be changed, but not its length without re-initializing the HSM.\n\n"
while true; do read -e -p "Enter how many custodians to generate: " -i "1" _COUNT_CUSTODIANS;
if [[ ${_COUNT_CUSTODIANS} -lt ${_COUNT_CUSTODIANS_MIN} ]]; then
echo "Too short (min ${_COUNT_CUSTODIANS_MIN} chars).";
elif [[ ${_COUNT_CUSTODIANS} -gt ${_COUNT_CUSTODIANS_MAX} ]]; then
echo "Too long (min ${_COUNT_CUSTODIANS_MAX} chars).";
else break; fi;
done;
echo -e "\n\nGenerating ${_COUNT_CUSTODIANS} DKEK share for later re-import after the initialiation.\n\n"
######################################################################
#/**
# * Main part
# *
# */
for (( COUNTER=1; COUNTER<=${_COUNT_CUSTODIANS}; COUNTER+=1 )); do
while true; do read -e -p "Enter the custodian password to initialize DKEK share (should be > 10 chars): " -i "abcdef" _TMP_PASSWD_CUSTODIAN;
if [[ ${#_TMP_PASSWD_CUSTODIAN} -le 4 ]]; then
echo "Really? This is too short, methinks.";
else
set +o nounset
_CUSTODIANS[${COUNTER}]=${_TMP_PASSWD_CUSTODIAN}
set -o nounset
break;
fi;
done;
\sc-hsm-tool --create-dkek-share dkek-share-${COUNTER}.pbe --password ${_TMP_PASSWD_CUSTODIAN}
\openssl base64 -in dkek-share-${COUNTER}.pbe | tee dkek-share-${COUNTER}.pbe.txt
done
#\sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 648219 --dkek-shares 1
while read -e -r -n 1 -s -p "Do you want to initialize the Nitrokey HSM? [yn]" answer; do
if [[ $answer = [YyNn] ]]; then
if [[ $answer = [Yy] ]]; then
if [ ! -z ${_SOPIN_FUTURE} ]; then
echo -e "Initializing with ${_SOPIN_FUTURE/${_SOPIN_FUTURE:0:12}/************}\nand ${_COUNT_CUSTODIANS} DKEK shares.\n";
\sc-hsm-tool --initialize --so-pin ${_SOPIN_FUTURE} --pin ${_USERPIN} --dkek-shares ${_COUNT_CUSTODIANS};
else
echo -e "Initializing with ${_SOPIN_CURRENT/${_SOPIN_CURRENT:0:12}/************}\nand ${_COUNT_CUSTODIANS} DKEK shares.\n";
\sc-hsm-tool --initialize --so-pin ${_SOPIN_CURRENT} --pin ${_USERPIN} --dkek-shares ${_COUNT_CUSTODIANS};
fi
\sc-hsm-tool
for i in "${!_CUSTODIANS[@]}"; do
\sc-hsm-tool --import-dkek-share dkek-share-${i}.pbe --password ${_CUSTODIANS[$i]}
done
\sc-hsm-tool
_PRISTINE_HSM="False";
break;
elif [[ $answer = [Nn] ]]; then
echo "Nothing done. Extiting."
exit 0;
fi
fi
done
else
echo "Nitrokey HSM already initialized. This script does nothing."
fi; #
exit 0
{% for item in ['pcscd', 'pcsc-tools', 'libccid', 'libpcsclite-dev', 'libssl-dev', 'libreadline-dev', 'autoconf', 'automake', 'build-essential', 'docbook-xsl', 'xsltproc', 'libtool', 'pkg-config'] %}
{{ item }}:
pkg.installed
{% endfor %}
opensc_sources:
archive.extracted:
- name: /tmp/
- source: https://github.com/OpenSC/OpenSC/releases/download/0.17.0/opensc-0.17.0.tar.gz
- source_hash: fc502ed7753f950b8e2a18a476d0cd52
#- source_hash: 724d128f23cd7a74b28d04300ce7bcbd
- archive_format: tar
opensc_installations:
cmd.run:
- name: |
cd /tmp/opensc-0.17.0
./bootstrap
./configure --prefix=/usr --sysconfdir=/etc/opensc
make
make install
libssl-dev_again:
pkg.installed:
- name: libssl-dev
#https://github.com/OpenSC/libp11/releases/download/libp11-0.4.7/libp11-0.4.7.tar.gz
libp11_sources:
archive.extracted:
- name: /tmp/
- source: https://github.com/OpenSC/libp11/releases/download/libp11-0.4.7/libp11-0.4.7.tar.gz
- source_hash: 0902e692c7a5d2b96505913240b33220
- archive_format: tar
libp11_installations:
cmd.run:
- name: |
cd /tmp/libp11-0.4.7
./configure && make && sudo make install
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment