Skip to content

Commit

Permalink
Refactor PIV, implement direct-to-Yubikey cert creation
Browse files Browse the repository at this point in the history
elonen committed Aug 28, 2024
1 parent aebcfa9 commit 902ff80
Showing 10 changed files with 559 additions and 356 deletions.
48 changes: 39 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -4,26 +4,40 @@

Higher level interactive CLI tool for YubiHSM2 operations, based on a YAML configuration file (see [hsm-conf.yml](hsm-conf.yml)).

The config file approach simplifies planning, setup and daily use while maintaining high security standards.
The config file approach simplifies planning, setup, validity checking and daily use while maintaining high security standards.

Built mostly on top of Yubico's Python APIs and the Cryptography library.

## Highlights

- Centralized configuration in a single YAML file
- Automatic key/cert generation based on the config file
- Authenticate HSM operators by YubiKey 5 hardware tokens to avoid credential theft by malware
- Integrated Yubikey HSM auth (yubihsm-auth) slot setup for operators
- Discourage leaking secrets in process listing, local disk or terminal scrollback
- Fully within one process, does not invoke external CLI tools (except in unit tests)
- Sensible default config with comments
- Authenticate HSM operators by YubiKey 5 hardware tokens
- Integrated Yubikey HSM auth (yubihsm-auth) slot management for operators
- Integrate daily operations under a single tool:
- OpenSSH certificate creation and signing, including hardware token **sk-ed25519** and **sk-ecdsa** keys
- X.509 certificate creationg and signing
- Sanity checks / lint for generated certificates by usage
- TLS server cert creation
- Windows login certs for Yubikey with PIV
- PIV cert generation (e.g. Windows login with YubiKey)
- Store in YubiKey or save to disk
- Password derivation for VMs etc.
- HSM audit logging
- Specify HSM audit policy in config file
- Incrementally fetch and parse log entries from YubiHSM
- from multiple devices (for HA / load balancing)
- store into SQlite database
- convenient "forced logging mode" support (with `log fetch --clear`)
- Show log entries in human-readable
- Verify audit chain integrity
- Export new logs to JSONL, for log server submission
- Improved Secret Sharing ceremony vs. YubiHSM setup util (vs. yubihsm-setup)
- password protected shares (optional)
- better display hygiene
- detailed interactive guiding
- Discourage leaking secrets in process listing, local disk or terminal scrollback
- Fully within one process, does not invoke external CLI tools (except in unit tests)

## Practical Examples

@@ -77,12 +91,22 @@ openssl crl2pkcs7 -nocrl -certfile ./certs/wiki-server.cer.pem | openssl pkcs7
```

In this example, the HTTPS server key was generated and written on local disk, for convenience.

For added separation of concerns, it could also have been created on the web server by a webmaster (perhaps with openssl), and the HSM operator would only have signed the CSR (Certificate Signing Request) with `hsm-secrets tls sign wiki-server.csr.pem`.

## Development status
## Development

**Work in progress**, but usable and useful.

Work-in-progress, but usable and useful.
This rather niche software is being developed to scratch some particular sysops itches, not as a "product".
Even if you don't actually use the tool, I hope this repository shares some knowledge and technical details.
Corrections, improvements and observations are welcome.

## Unit tests

Run `make test` to install requirements and run a test suite.

The tests **do not** use an actual YubiHSM device, but rather a mock
implementation (using `--mock` option) to test the commands with `openssl`, `ssh-keygen` etc.

## Installation and upgrade

@@ -175,6 +199,12 @@ YubiHSM2 devices are easy to reset, so you might want to do a test-run or two be
Airgapped setup is necessary to prevent supply chain attacks from exfiltrating any generated secrets.
You might want to use something like Tails Linux on USB stick, and wipe/destroy the media after setup.

## License

Released under the MIT license

Copyright 2024 by Jarno Elonen

## Disclaimer

The software is provided "as is", the license disclaims any warranties and liabilities. Use at your own risk.
41 changes: 24 additions & 17 deletions doc/setup-workflow.md
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@
This is checklist for setting up YubiHSM2 devices using the hsm-secrets tool.
The process should be performed in an airgapped environment for maximum security.

**TIP:** *You can try these steps withou actual HSM devices, by using `hsm-secrets --mock mock.pickle` instead of plain `hsm-secrets`*

## Initial Setup Workflow

1. `[ ]` Connect all YubiHSM2 devices to the airgapped computer.
@@ -12,56 +14,61 @@ The process should be performed in an airgapped environment for maximum security

3. `[ ]` Set a common wrap key on all devices:
```
hsm-secrets hsm make-wrap-key
hsm-secrets hsm backup make-key
```

4. `[ ]` Host a Secret Sharing Ceremony to add a super admin key:
```
hsm-secrets hsm admin-sharing-ceremony
hsm-secrets hsm admin sharing-ceremony
```
- Follow the prompts to set up the number of shares and threshold.

5. `[ ]` Add user keys (YubiKey auth) to the master device:
5. `[ ]` Add YubiKey auth user keys to the master device:
```
hsm-secrets user add-yubikey --label <user_label>
hsm-secrets user add-yubikey <user_label>
```
- User will need to connect their YubiKey and follow instructions.
- Repeat for each user key.
- Repeat for each user key

6. `[ ]` Add service accounts to master device:
```
hsm-secrets user add-service --all
```

6. `[ ]` Generate keys on the master device:
7. `[ ]` Generate keys and certificates on the master device:
```
hsm-secrets hsm compare --create
hsm-secrets hsm objects create-missing
```

7. `[ ]` Create certificates from the generated keys:
8. `[ ]` Apply audit logging settings to devices:
```
hsm-secrets x509 create --all
hsm-secrets log apply-settings --alldevs
```

8. `[ ]` Verify all configured objects are present on the master device:
9. `[ ]` Verify all configured objects are present on the master device:
```
hsm-secrets hsm compare
```

9. `[ ]` Create a (wrapped) backup of the master device:
10. `[ ]` Create a (wrapped) backup of the master device:
```
hsm-secrets hsm backup
hsm-secrets hsm backup export
```

10. `[ ]` Restore the backup to other devices (for HA):
11. `[ ]` Restore the backup to other devices (for HA):
```
hsm-secrets hsm restore <backup_file>
hsm-secrets --hsmserial <device serial> hsm backup import <backup_file>
```
- Repeat for each additional device.
11. `[ ]` Verify all keys are present on all devices:
12. `[ ]` Verify all keys are present on all devices:
```
hsm-secrets hsm compare --alldevs
```
12. `[ ]` Remove the default admin key from all devices:
13. `[ ]` Remove the default admin key from all devices:
```
hsm-secrets hsm default-admin-disable --alldevs
hsm-secrets hsm admin default-disable --alldevs
```
## Post-Setup Verification
31 changes: 21 additions & 10 deletions hsm-conf.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This is a configuration file for the 'hsm-secrets' tool.
# It is used to generate keys and certificates for the YubiHSM 2.
# It is used to generate keys and certificates for YubiHSM 2 devices.
#
# Most keys are provided in RSA, Ed25519 and NIST EC formats.
# Ed25519 is recommended whenever possible, RSA (super slow on YubiHSM) is for compatibility with older systems.
@@ -14,8 +14,8 @@ general:
}

domains:
# These domain numbers separate different types of objects in the YubiHSM 2.
# The names are used by the hsm-secrets tool for clarity, not by the device itself.
# Domain numbers (1-16) separate different types of objects in the YubiHSM 2.
# These text names are used by the hsm-secrets tool for clarity, not by the device itself.
x509: 1
tls: 2
nac: 3
@@ -26,6 +26,8 @@ general:
password_derivation: 8
encryption: 9

# Default settings for X.509 certificates.
# These are used for all generated certificates when a specific setting is not provided (i.e. is null).
x509_defaults:
validity_days: 3650
basic_constraints:
@@ -61,7 +63,8 @@ general:
- "http://crl2.example.com/all.crl"
authority_info_access: null # OCSP is increasingly deprecated due to security issues, in favor of CRLs again

# Subsystem for YubiHSM 2 device admin auth keys.

# YubiHSM 2 device admin keys and settings
admin:
default_admin_password: 'password'

@@ -131,7 +134,7 @@ admin:
get-log-entries: 'off' # This seems to change after fetch (firmware bug?), so don't log it to avoid digest mismatch
create-session: 'off' # Not much point, as auth session key is included in every other log entry
close-session: 'off' # (--||--)
authenticate-session: 'off' # (--||--)
authenticate-session: 'off' # (--||--)
session-message: 'off' # This is a low-level command, spams the log, not very useful to log


@@ -211,7 +214,7 @@ service_keys:


# Subsystem/domain for root CAs.
# Intermediate CAs in other subsystems (TLS, X.509, ..) are signed by these.
# Intermediate CAs in other subsystems are signed by these.
#
# usages: Generate a root CA with OpenSSL using these as private keys.
# Generate attestation certificates for the root CAs when creating them, and store them
@@ -434,7 +437,8 @@ tls:
sign_by: 0x0131 # ECP384 Root CA


# NAC (Network Access Control) intermediate keys for 802.1X
# NAC (Network Access Control) intermediate keys for 802.1X EAP-TLS.
# NO COMMANDS FOR THIS SECTION IMPLEMENTED YET -- KEYS ARE GENERATED FOR FUTURE USE
nac:
intermediate_certs:
-
@@ -497,9 +501,11 @@ nac:
algorithm: opaque-x509-certificate
sign_by: 0x0131

# PIV (Personal Identity Verification) keys for smartcard login
piv:
# PIV (Personal Identity Verification) keys for smartcard login
default_ca_id: 0x0431
default_piv_domain: '@example.directory' # AD UPN suffix for Windows, rfc822 suffix for Linux/macOS

intermediate_certs:
-
key:
@@ -636,7 +642,9 @@ ssh:


# GPG/OpenPGP keys
# for future use, PKCS#11 support in GPG is not very good atm
# NO COMMANDS FOR THIS SECTION IMPLEMENTED YET -- KEYS ARE GENERATED FOR FUTURE USE
#
# Note: PKCS#11 support in GPG is not very good atm
#
# RSA keys can be used for both SCA (Sign, Certify, Authenticate) and E (Encrypt) operations in GnuPG, but
# it is recommended to use separate keys for these purposes, so make two keys here. Allow both sign & crypt
@@ -689,6 +697,7 @@ gpg:


# Code signing keys for signing software, firmware, etc.
# NO COMMANDS FOR THIS SECTION IMPLEMENTED YET -- KEYS ARE GENERATED FOR FUTURE USE
codesign:
intermediate_certs:
-
@@ -747,6 +756,7 @@ codesign:
algorithm: opaque-x509-certificate
sign_by: 0x0131


# For deriving unique passwords from usernames, hostnames, etc.
password_derivation:
keys:
@@ -776,7 +786,8 @@ password_derivation:


# For generic encryption of secrets, passwords, etc.
# (For limited and infrequent use, YubiHSM is not very fast)
# Limited and infrequent use, YubiHSM is not very fast
# NO COMMANDS FOR THIS SECTION IMPLEMENTED YET -- KEYS ARE GENERATED FOR FUTURE USE
encryption:
keys:
- label: enc-1
1 change: 1 addition & 0 deletions hsm_secrets/config.py
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ class TLS(NoExtraBaseModel):

class PIV(NoExtraBaseModel):
default_ca_id: HSMKeyID
default_piv_domain: str
intermediate_certs: List['X509Cert']
dc_cert_templates: Dict[str, 'X509Info'] # Overrides global defaults
user_cert_templates: Dict[str, 'X509Info']
Loading

0 comments on commit 902ff80

Please sign in to comment.