Created
January 1, 2018 17:18
-
-
Save cprima/37aa9090092c277f9e3af727a0dcbe8a to your computer and use it in GitHub Desktop.
Initializing the Nitrokey HSM (Ubuntu 16.04)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% 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