NetHSM Command Line Interface
A command line interface (CLI) for the Nitrokey NetHSM based on the nethsm crate.
Installation
This crate can be installed using cargo:
cargo install nethsm-cli
Afterwards the nethsm executable is available.
It is recommended to refer to the extensive --help output of the executable and its subcommands.
Usage
The following assumes a recent version of openssl and podman.
Start a test container
podman run --rm -ti --network=pasta:-t,auto,-u,auto,-T,auto,-U,auto docker.io/nitrokey/nethsm:testing
Configuration file
The configuration file uses the TOML format.
By default an Operating System specific, well-defined configuration file location is chosen.
Using -c / --config / the NETHSM_CONFIG environment variable it is possible to provide a custom configuration file location.
nethsm_tmpdir="$(mktemp --directory --suffix '.nethsm-test')"
export NETHSM_CONFIG="$(mktemp --tmpdir="$nethsm_tmpdir" --suffix '-nethsm.toml' --dry-run)"
To be able to interact with a NetHSM (or the testing container), each device must be added to the configuration file.
nethsm env add device --label test https://localhost:8443/api/v1 Unsafe
If only one device environment is configured, it is used by default when issuing nethsm commands.
If more than one environment is configured, the target device must be selected using the global -l/ --label option.
The handling of credentials is flexible: Credentials can be stored in the configuration file with or without passphrases or not at all.
If credentials are not configured, they are prompted for interactively.
nethsm_admin_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.admin-passphrase.txt')"
export NETHSM_PASSPHRASE_FILE="$nethsm_admin_passphrase_file"
printf 'my-very-unsafe-admin-passphrase' > "$NETHSM_PASSPHRASE_FILE"
nethsm env add credentials admin Administrator
Provisioning
Before using a device for the first time, it must be provisioned.
This includes setting the passphrase for the initial "admin" user, the unlock passphrase and the system time of the device.
export NETHSM_UNLOCK_PASSPHRASE_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.unlock-passphrase.txt')"
printf 'my-very-unsafe-unlock-passphrase' > "$NETHSM_UNLOCK_PASSPHRASE_FILE"
export NETHSM_ADMIN_PASSPHRASE_FILE="$nethsm_admin_passphrase_file"
nethsm provision
Users
Each user may be in exactly one role ("Administrator", "Operator", "Metrics" or "Backup").
Users either exist system-wide or in a "Namespace".
Users in a Namespace only have access to users and keys in their own Namespace and are not able to interact with system-wide facilities.
System-wide users on the other hand are not able to access keys or manipulate users in a Namespace, but can interact with other system-wide facilities, as well as system-wide users and keys.
- "Administrator": for adjusting system configuration, managing users and keys (may exist in a Namespace or system-wide)
- R-Administrator: a system-wide Administrator which is able to interact with all system-wide facilities, as well as managing system-wide users and keys
- N-Administrator: a namespace Administrator, which is only able to operate on users and keys in their own namespace
- "Operator": for using cryptographic keys and getting random bytes (may exist in a Namespace or system-wide)
- "Metrics": for retrieving metrics of a device (may only exist system-wide)
- "Backup": for creating and downloading backups of a device (may only exist system-wide)
System-wide and namespace users are easily distinguishable: While system-wide user names consist only of characters in the set [a-z0-9] (e.g. admin1), namespace user names consist of characters in the set [a-z0-9~] and start with the namespace name (e.g. namespace1~admin1).
nethsm_admin1_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.admin1-passphrase.txt')"
printf 'my-very-unsafe-admin1-passphrase' > "$nethsm_admin1_passphrase_file"
nethsm_operator1_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.operator1-passphrase.txt')"
printf 'my-very-unsafe-operator1-passphrase' > "$nethsm_operator1_passphrase_file"
nethsm_backup1_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.backup1-passphrase.txt')"
printf 'my-very-unsafe-backup1-passphrase' > "$nethsm_backup1_passphrase_file"
nethsm_metrics1_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.metrics1-passphrase.txt')"
printf 'my-very-unsafe-metrics1-passphrase' > "$nethsm_metrics1_passphrase_file"
nethsm_namespace1_admin1_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.namespace1-admin1-passphrase.txt')"
printf 'my-very-unsafe-namespace1-admin1-passphrase' > "$nethsm_namespace1_admin1_passphrase_file"
nethsm_namespace1_operator1_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.namespace1-operator1-passphrase.txt')"
printf 'my-very-unsafe-namespace1-operator1-passphrase' > "$nethsm_namespace1_operator1_passphrase_file"
export NETHSM_PASSPHRASE_FILE="$nethsm_admin1_passphrase_file"
nethsm user add "Some Admin1" Administrator admin1
nethsm env add credentials admin1 Administrator
export NETHSM_PASSPHRASE_FILE="$nethsm_operator1_passphrase_file"
nethsm user add "Some Operator1" Operator operator1
nethsm env add credentials operator1 Operator
export NETHSM_PASSPHRASE_FILE="$nethsm_backup1_passphrase_file"
nethsm user add "Some Backup1" Backup backup1
nethsm env add credentials backup1 Backup
export NETHSM_PASSPHRASE_FILE="$nethsm_metrics1_passphrase_file"
nethsm user add "Some Metrics1" Metrics metrics1
nethsm env add credentials metrics1 Metrics
export NETHSM_PASSPHRASE_FILE="$nethsm_namespace1_admin1_passphrase_file"
nethsm user add "Namespace1 Admin1" Administrator namespace1~admin1
nethsm env add credentials namespace1~admin1 Administrator
nethsm --user admin namespace add namespace1
export NETHSM_PASSPHRASE_FILE="$nethsm_operator1_passphrase_file"
nethsm --user namespace1~admin1 user add "Namespace1 Operator1" Operator namespace1~operator1
nethsm env add credentials namespace1~operator1 Operator
nethsm env list
The user names and accompanying information can be queried:
while read -r user; do
nethsm --user admin1 user get "$user"
done < <(nethsm --user admin1 user list)
while read -r user; do
nethsm --user namespace1~admin1 user get "$user"
done < <(nethsm --user namespace1~admin1 user list)
Tags for users can only be created once keys with those tags exists.
Keys
Keys on the device are managed using users in the "Administrator" role.
Depending on restrictions (tags), the keys may then be used by users in the "Operator" role.
NOTE: Keys created by an N-Administrator are only visible within their namespace and only available to Operator users in that namespace.
Generating keys
Below, we are generating keys of all available types (Curve25519, EcP224, EcP256, EcP384, EcP521, Generic and Rsa).
When generating a key, the unique ID for it may be set manually (else it is auto-generated).
Tags, which later on allow users access to the keys may also be set during key generation.
Note that some keys require to set the key bit length (i.e. Generic and Rsa).
nethsm --user admin1 key generate --key-id signing1 --tags tag1 Curve25519 EdDsaSignature
nethsm --user admin1 key generate --key-id signing2 --tags tag2 EcP224 EcdsaSignature
nethsm --user admin1 key generate --key-id signing3 --tags tag2 EcP256 EcdsaSignature
nethsm --user admin1 key generate --key-id signing4 --tags tag2 EcP384 EcdsaSignature
nethsm --user admin1 key generate --key-id signing5 --tags tag2 EcP521 EcdsaSignature
nethsm --user admin1 key generate --key-id encdec1 --tags tag3 --length 128 Generic AesDecryptionCbc AesEncryptionCbc
nethsm --user admin1 key generate --key-id dec1 --tags tag4 --length 2048 Rsa RsaDecryptionPkcs1
nethsm --user admin1 key generate --key-id signing6 --tags tag5 --length 2048 Rsa RsaSignaturePssSha512
nethsm --user admin1 key generate --key-id signing8 --tags tag6 --length 2048 Rsa RsaSignaturePkcs1
nethsm --user namespace1~admin1 key generate --key-id signing1 --tags tag1 Curve25519 EdDsaSignature
nethsm --user namespace1~admin1 key generate --key-id signing2 --tags tag2 EcP224 EcdsaSignature
nethsm --user namespace1~admin1 key generate --key-id signing3 --tags tag2 EcP256 EcdsaSignature
nethsm --user namespace1~admin1 key generate --key-id signing4 --tags tag2 EcP384 EcdsaSignature
nethsm --user namespace1~admin1 key generate --key-id signing5 --tags tag2 EcP521 EcdsaSignature
nethsm --user namespace1~admin1 key generate --key-id encdec1 --length 128 --tags tag3 Generic AesDecryptionCbc AesEncryptionCbc
nethsm --user namespace1~admin1 key generate --key-id dec1 --length 2048 --tags tag4 Rsa RsaDecryptionPkcs1
nethsm --user namespace1~admin1 key generate --key-id signing6 --length 2048 --tags tag5 Rsa RsaSignaturePssSha512
nethsm --user namespace1~admin1 key generate --key-id signing8 --length 2048 --tags tag6 Rsa RsaSignaturePkcs1
All key IDs on the device and info about them can be listed:
while read -r key; do
nethsm key get "$key"
done < <(nethsm --user admin1 key list)
while read -r key; do
nethsm key get "$key"
done < <(nethsm --user namespace1~admin1 key list)
Importing keys
Keys can also be imported:
ed25519_cert_pem="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.ed25519_cert.pem')"
ed25519_cert_der="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.ed25519_cert.pkcs8.der')"
openssl genpkey -algorithm ed25519 -out "$ed25519_cert_pem"
openssl pkcs8 -topk8 -inform pem -in "$ed25519_cert_pem" -outform der -nocrypt -out "$ed25519_cert_der"
nethsm --user admin1 key import --key-id signing7 Curve25519 "$ed25519_cert_der" EdDsaSignature
nethsm --user admin1 key import --format PEM --key-id signing9 Curve25519 "$ed25519_cert_pem" EdDsaSignature
nethsm --user admin1 key tag signing7 tag1
nethsm --user operator1 key get signing7
nethsm --user namespace1~admin1 key import --key-id signing7 Curve25519 "$ed25519_cert_der" EdDsaSignature
nethsm --user namespace1~admin1 key import --format PEM --key-id signing9 Curve25519 "$ed25519_cert_pem" EdDsaSignature
nethsm --user namespace1~admin1 key tag signing7 tag1
nethsm --user namespace1~operator1 key get signing7
Access to keys
To provide access to keys for users, the users have to be tagged with the same tags as the keys.
nethsm --user admin1 user tag operator1 tag1
nethsm --user namespace1~admin1 user tag namespace1~operator1 tag1
Signing messages
export NETHSM_KEY_SIGNATURE_OUTPUT_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.readme.signature.sig')"
export NETHSM_KEY_PUBKEY_OUTPUT_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.pubkey.pem')"
message_digest="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.message.dgst')"
nethsm --user admin1 user tag operator1 tag2
nethsm --user admin1 user tag operator1 tag5
nethsm --user admin1 user tag operator1 tag6
nethsm --user namespace1~admin1 user tag namespace1~operator1 tag2
nethsm --user namespace1~admin1 user tag namespace1~operator1 tag5
nethsm --user namespace1~admin1 user tag namespace1~operator1 tag6
nethsm --user operator1 key sign --force signing1 EdDsa README.md
nethsm --user operator1 key public-key --force signing1
openssl pkeyutl -verify -in README.md -rawin -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user operator1 key sign --force signing2 EcdsaP224 README.md
nethsm --user operator1 key public-key --force signing2
openssl dgst -sha224 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user operator1 key sign --force signing3 EcdsaP256 README.md
nethsm --user operator1 key public-key --force signing3
openssl dgst -sha256 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user operator1 key sign --force signing4 EcdsaP384 README.md
nethsm --user operator1 key public-key --force signing4
openssl dgst -sha384 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user operator1 key sign --force signing5 EcdsaP521 README.md
nethsm --user operator1 key public-key --force signing5
openssl dgst -sha512 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user operator1 key sign --force signing6 PssSha512 README.md
nethsm --user operator1 key public-key --force signing6
openssl dgst -sha512 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:-1
nethsm --user operator1 key sign --force signing7 EdDsa README.md
nethsm --user operator1 key public-key --force signing7
openssl pkeyutl -verify -in README.md -rawin -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user namespace1~operator1 key sign --force signing1 EdDsa README.md
nethsm --user namespace1~operator1 key public-key --force signing1
openssl pkeyutl -verify -in README.md -rawin -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user namespace1~operator1 key sign --force signing2 EcdsaP224 README.md
nethsm --user namespace1~operator1 key public-key --force signing2
openssl dgst -sha224 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user namespace1~operator1 key sign --force signing3 EcdsaP256 README.md
nethsm --user namespace1~operator1 key public-key --force signing3
openssl dgst -sha256 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user namespace1~operator1 key sign --force signing4 EcdsaP384 README.md
nethsm --user namespace1~operator1 key public-key --force signing4
openssl dgst -sha384 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user namespace1~operator1 key sign --force signing5 EcdsaP521 README.md
nethsm --user namespace1~operator1 key public-key --force signing5
openssl dgst -sha512 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user namespace1~operator1 key sign --force signing6 PssSha512 README.md
nethsm --user namespace1~operator1 key public-key --force signing6
openssl dgst -sha512 -binary README.md > "$message_digest"
openssl pkeyutl -verify -in "$message_digest" -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin -pkeyopt rsa_padding_mode:pss -pkeyopt digest:sha512 -pkeyopt rsa_pss_saltlen:-1
nethsm --user namespace1~operator1 key sign --force signing7 EdDsa README.md
nethsm --user namespace1~operator1 key public-key --force signing7
openssl pkeyutl -verify -in README.md -rawin -sigfile "$NETHSM_KEY_SIGNATURE_OUTPUT_FILE" -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin
nethsm --user admin1 user untag operator1 tag5
nethsm --user namespace1~admin1 user untag namespace1~operator1 tag5
OpenPGP
The CLI can also create OpenPGP certificates for keys stored in the HSM:
export GNUPGHOME="$(mktemp --directory --tmpdir="$nethsm_tmpdir" --suffix 'gnupghome')"
export NETHSM_KEY_CERT_OUTPUT_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.openpgp-cert.pgp')"
nethsm --user admin1 --user operator1 openpgp add --can-sign signing1 "Test signing1 key <test@example.org>"
nethsm --user operator1 key cert get --force signing1
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing1 key"
nethsm --user admin1 --user operator1 openpgp add signing3 "Test signing3 key <test@example.org>"
nethsm --user operator1 key cert get --force signing3
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing3 key"
nethsm --user admin1 --user operator1 openpgp add signing4 "Test signing4 key <test@example.org>"
nethsm --user operator1 key cert get --force signing4
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing4 key"
nethsm --user admin1 --user operator1 openpgp add signing5 "Test signing5 key <test@example.org>"
nethsm --user operator1 key cert get --force signing5
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing5 key"
nethsm --user admin1 --user operator1 openpgp add signing8 "Test signing8 key <test@example.org>"
nethsm --user operator1 key cert get --force signing8
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing8 key"
nethsm --user namespace1~admin1 --user namespace1~operator1 openpgp add --can-sign signing1 "Test signing1 key <test@example.org>"
nethsm --user namespace1~operator1 key cert get --force signing1
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing1 key"
nethsm --user namespace1~admin1 --user namespace1~operator1 openpgp add signing3 "Test signing3 key <test@example.org>"
nethsm --user namespace1~operator1 key cert get --force signing3
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing3 key"
nethsm --user namespace1~admin1 --user namespace1~operator1 openpgp add signing4 "Test signing4 key <test@example.org>"
nethsm --user namespace1~operator1 key cert get --force signing4
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing4 key"
nethsm --user namespace1~admin1 --user namespace1~operator1 openpgp add signing5 "Test signing5 key <test@example.org>"
nethsm --user namespace1~operator1 key cert get --force signing5
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing5 key"
nethsm --user namespace1~admin1 --user namespace1~operator1 openpgp add signing8 "Test signing8 key <test@example.org>"
nethsm --user namespace1~operator1 key cert get --force signing8
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing8 key"
Importing new keys:
export NETHSM_OPENPGP_TSK_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.openpgp-private-key.tsk')"
rsop generate-key --no-armor --signing-only "Test signing10 key <test@example.org>" > "$NETHSM_OPENPGP_TSK_FILE"
nethsm --user admin1 openpgp import --key-id signing10 --tags tag1
nethsm --user operator1 key cert get --force signing10
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing10 key"
nethsm --user namespace1~admin1 openpgp import --key-id signing10 --tags tag1
nethsm --user namespace1~operator1 key cert get --force signing10
gpg --import "$NETHSM_KEY_CERT_OUTPUT_FILE"
sq inspect "$NETHSM_KEY_CERT_OUTPUT_FILE" | grep "Test signing10 key"
Signing messages:
export NETHSM_OPENPGP_SIGNATURE_OUTPUT_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.openpgp-message.txt.sig')"
export NETHSM_OPENPGP_SIGNATURE_MESSAGE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.openpgp-message.txt')"
printf "I like strawberries\n" > "$NETHSM_OPENPGP_SIGNATURE_MESSAGE"
for key in signing1 signing3 signing4 signing5 signing8 signing10; do
nethsm --user operator1 openpgp sign --force "$key"
gpg --verify "$NETHSM_OPENPGP_SIGNATURE_OUTPUT_FILE" "$NETHSM_OPENPGP_SIGNATURE_MESSAGE"
nethsm --user operator1 key cert get --force "$key"
rsop verify "$NETHSM_OPENPGP_SIGNATURE_OUTPUT_FILE" "$NETHSM_KEY_CERT_OUTPUT_FILE" < "$NETHSM_OPENPGP_SIGNATURE_MESSAGE"
nethsm --user namespace1~operator1 openpgp sign --force "$key"
gpg --verify "$NETHSM_OPENPGP_SIGNATURE_OUTPUT_FILE" "$NETHSM_OPENPGP_SIGNATURE_MESSAGE"
nethsm --user namespace1~operator1 key cert get --force "$key"
rsop verify "$NETHSM_OPENPGP_SIGNATURE_OUTPUT_FILE" "$NETHSM_KEY_CERT_OUTPUT_FILE" < "$NETHSM_OPENPGP_SIGNATURE_MESSAGE"
done
Encrypting messages
Messages can be encrypted using keys that offer the key mechanisms for this operation.
message="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.message.txt')"
printf "Hello World! This is a message!!" > "$message"
export NETHSM_KEY_ENCRYPT_IV="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.iv.txt')"
printf "This is unsafe!!" > "$NETHSM_KEY_ENCRYPT_IV"
export NETHSM_KEY_ENCRYPT_OUTPUT="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.symmetric-encrypted-message.txt.enc')"
export NETHSM_KEY_DECRYPT_IV="$NETHSM_KEY_ENCRYPT_IV"
export NETHSM_KEY_DECRYPT_OUTPUT="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.decrypted-message.txt')"
nethsm --user admin1 user tag operator1 tag3
nethsm --user operator1 key encrypt --force encdec1 "$message"
nethsm --user operator1 key decrypt --force encdec1 "$NETHSM_KEY_ENCRYPT_OUTPUT" AesCbc
cat "$NETHSM_KEY_DECRYPT_OUTPUT"
[[ "$(b2sum "$NETHSM_KEY_DECRYPT_OUTPUT" | cut -d ' ' -f1)" == "$(b2sum "$message" | cut -d ' ' -f1)" ]]
nethsm --user namespace1~admin1 user tag namespace1~operator1 tag3
nethsm --user namespace1~operator1 key encrypt --force encdec1 "$message"
nethsm --user namespace1~operator1 key decrypt --force encdec1 "$NETHSM_KEY_ENCRYPT_OUTPUT" AesCbc
cat "$NETHSM_KEY_DECRYPT_OUTPUT"
[[ "$(b2sum "$NETHSM_KEY_DECRYPT_OUTPUT" | cut -d ' ' -f1)" == "$(b2sum "$message" | cut -d ' ' -f1)" ]]
The same works for asymmetric keys as well:
unset NETHSM_KEY_DECRYPT_IV NETHSM_KEY_ENCRYPT_IV
asymmetric_enc_message="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.asymmetric-encrypted-message.txt.enc')"
nethsm --user admin1 user tag operator1 tag4
nethsm --user operator1 key public-key --force dec1
openssl pkeyutl -encrypt -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin -in "$message" -out "$asymmetric_enc_message"
nethsm --user operator1 key decrypt --force dec1 "$asymmetric_enc_message" Pkcs1
cat "$NETHSM_KEY_DECRYPT_OUTPUT"
[[ "$(b2sum "$NETHSM_KEY_DECRYPT_OUTPUT" | cut -d ' ' -f1)" == "$(b2sum "$message" | cut -d ' ' -f1)" ]]
nethsm --user namespace1~admin1 user tag namespace1~operator1 tag4
nethsm --user namespace1~operator1 key public-key --force dec1
openssl pkeyutl -encrypt -inkey "$NETHSM_KEY_PUBKEY_OUTPUT_FILE" -pubin -in "$message" -out "$asymmetric_enc_message"
nethsm --user namespace1~operator1 key decrypt --force dec1 "$asymmetric_enc_message" Pkcs1
cat "$NETHSM_KEY_DECRYPT_OUTPUT"
[[ "$(b2sum "$NETHSM_KEY_DECRYPT_OUTPUT" | cut -d ' ' -f1)" == "$(b2sum "$message" | cut -d ' ' -f1)" ]]
Public key
Administrators and operators can retrieve the public key of any key:
unset NETHSM_KEY_PUBKEY_OUTPUT_FILE
for key in signing{1..8} dec1; do
nethsm --user operator1 key public-key --force "$key"
nethsm --user namespace1~operator1 key public-key --force "$key"
done
Certificate Signing Requests for keys
Certificate Signing Requests for a particular target can be issued using the keys.
nethsm --user operator1 key csr signing7 example.com
nethsm --user namespace1~operator1 key csr signing7 example.com
Random bytes
The device can generate an arbitrary number of random bytes on demand.
All users in the "Operator" role have access to this functionality!
export NETHSM_RANDOM_OUTPUT_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.random.txt')"
nethsm random 200
[[ -f "$NETHSM_RANDOM_OUTPUT_FILE" ]]
Metrics
The metrics for a device can only be retrieved by a system-wide user in the "Metrics" role.
nethsm metrics
Device configuration
Several aspects of the device configuration can be retrieved and modified.
The device configuration is only available to "R-Administrators" (system-wide users in the "Administrator" role).
Boot mode
The boot mode defines whether the system starts into "Locked" or "Operational" state (the former requiring to supply the unlock passphrase to get to "Operational" state).
nethsm --user admin1 config get boot-mode
nethsm --user admin1 config set boot-mode Unattended
nethsm --user admin1 config get boot-mode
Logging
Each device may send syslog to a remote host.
nethsm --user admin1 config get logging
Network
The devices have a unique and static network configuration.
nethsm --user admin1 config get network
System Time
The device's system time can be queried and set.
nethsm --user admin1 config get time
nethsm --user admin1 config set time
nethsm --user admin1 config get time
TLS certificate
We can get and set the TLS certificate used for the device.
nethsm --user admin1 config get tls-certificate
nethsm --user admin1 config set tls-generate Rsa 4096
nethsm --user admin1 config get tls-certificate
We can also receive only the public key for the TLS certificate:
nethsm --user admin1 config get tls-public-key
Or generate a Certificate Signing Request for the TLS certificate:
nethsm --user admin1 config get tls-csr example.com
Setting passphrases
The backup passphrase is used to decrypt a backup created for the device, when importing. By default it is the empty string ("").
nethsm_backup_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.backup-passphrase.txt')"
printf 'my-very-unsafe-backup-passphrase' > "$nethsm_backup_passphrase_file"
export NETHSM_NEW_PASSPHRASE_FILE="$nethsm_backup_passphrase_file"
nethsm_initial_backup_passphrase_file="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.initial-backup-passphrase.txt')"
touch "$nethsm_initial_backup_passphrase_file"
export NETHSM_OLD_PASSPHRASE_FILE="$nethsm_initial_backup_passphrase_file"
nethsm --user admin1 config set backup-passphrase
The unlock passphrase is set during initial provisioning and is used to unlock the device when it is locked.
export NETHSM_OLD_PASSPHRASE_FILE="$NETHSM_UNLOCK_PASSPHRASE_FILE"
export NETHSM_NEW_PASSPHRASE_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.unlock-passphrase.txt')"
printf 'my-new-unsafe-unlock-passphrase' > "$NETHSM_NEW_PASSPHRASE_FILE"
nethsm --user admin1 config set unlock-passphrase
Locking
The device can be locked and unlocked, which puts it into state "Locked" and "Operational", respectively.
nethsm --user admin1 lock
nethsm --user admin1 health state
nethsm --user admin1 health alive
export NETHSM_UNLOCK_PASSPHRASE_FILE="$NETHSM_NEW_PASSPHRASE_FILE"
nethsm unlock
nethsm --user admin1 health state
nethsm --user admin1 health ready
System modifications
The devices offer various system level actions, e.g.:
nethsm --user admin1 system factory-reset
nethsm --user admin1 system reboot
nethsm --user admin1 system shutdown
nethsm --user admin1 system info
Backups
The device offers backing up of keys and user data.
Backup retrieval is only available to system-wide users in the "Backup" role!
export NETHSM_BACKUP_OUTPUT_FILE="$(mktemp --tmpdir="$nethsm_tmpdir" --dry-run --suffix '-nethsm.backup-file.bkp')"
nethsm system backup
A backup can later on be used to restore a device, using an "R-Administrator":
export NETHSM_BACKUP_PASSPHRASE_FILE="$nethsm_backup_passphrase_file"
nethsm --user admin1 system restore "$NETHSM_BACKUP_OUTPUT_FILE"
Updates
Updates for the operating system/ firmware of the device are uploaded to the device and then applied or aborted.
nethsm --user admin1 system upload-update my-update-file.bin
nethsm --user admin1 system commit-update
nethsm --user admin1 system cancel-update
Contributing
Please refer to the contributing guidelines to learn how to contribute to this project.
License
This project may be used under the terms of the Apache-2.0 or MIT license.
Changes to this project - unless stated otherwise - automatically fall under the terms of both of the aforementioned licenses.