Implements the KES api(s) required by Minio in KES mode. It uses then github.com/ThalesIgnite/crypto11
by Thales that uses pkcs#11
to interface to HSM (SoftHSM or Thales Luna).
The following is a toy created to explore the possibility to connect Minio (in GW mode, and a rather old version circa 2020 I believe) directly to an HSM. At the time I had the possibility to play with a Thales HSM so the support is for that and SoftHSM.Given my limited knowledge of encryption, it might contains subtle (or not so subtle) errors, so don't use it.
Also:
- No unit/integration tests.
- No crypto engineering analysis on how this was implemented.
- No crypto engineering analysis done to be 100% sure of 3rd party libraries (altough it is a Thales official library).
- No analysis of failure modes (since there are no tests); the code uses a fail-fast approach.
If you want to use a software HSM install the SoftHSM
library https://github.com/opendnssec/SoftHSMv2
If you want to use Thales Luna HSM you need to install and configure the Luna network Client and the SDK on the same machine.
Install and configure GO Sdk, then make
will generate the executable
Execute the binary with the relevant env variables
The service is configured via ENV variables and config files that modify the behaviour.
All the ENV variables must be placed in .env
file passed as argument to the executable with -env
.
KES_MODE
put the web server indebug
orproduction
mode, default is:debug
KES_HTTP_PORT
port for HTTP endpoint, default8080
, format:8080
KES_HTTP_DISABLE
disable HTTP localhost server, default isno
KES_HTTPS
if set the port for HTTPS endpoint, format:0.0.0.0:3000
KES_HTTPS_CA
path to ca pem (optional indebug
mode)KES_HTTPS_CA_CLIENTS
path to client ca pem (optional indebug
mode)KES_HTTPS_CA_SELFSIGNED
specify if ca is selfsigned (cannot verify client certs of a selfsigned CA), default isno
selfsignedKES_HTTPS_CERT
path to certificate pemKES_HTTPS_KEY
path to key pemKES_HTTPS_FIPS_CYPHERS
ifon
the HTTPS endpoint will use only FIPS approved algorithms for TLS 1.2 and 1.3KES_HTTPS_AUTH_DISABLED
(ONLY INdebug
) ifon
disable authentication based on mTLS certificatesKES_METRICS
ifon
Prometheus metrics are available on/metrics
(on any web server port)KES_CONFIG_AUTH
path to json containing auth mapsKES_CONFIG_HSM
path to json containing HSM config (crypto11
library config file )KES_CONFIG_HSM_PIN
pin for the HSM config to override the json content (useful for fast debug)KES_CONFIG_KEYS
path to json containing keys id to internal id config
When started with KES_MODE=production
the following behaviour is enforced by default:
- The HTTP server will not have the KES api endpoints
- The HTTPS server will always use authentication for the KES api endpoints
- No system CA will be used, only the one provided in the
KES_HTTPS_CA
variable - No system CA will be used, only the one provided in the
KES_HTTPS_CA_CLIENTS
variable KES_CONFIG_HSM_PIN
will not be used
They can be anywhere, we've three types:
Controlled by KES_CONFIG_HSM
This is the config directly read by the Thales library, refer to https://github.com/ThalesIgnite/crypto11 for details
{
"Path": "/usr/safenet/lunaclient/lib/libCryptoki2_64.so",
"TokenSerial": "", // Token slot serial
"Pin": "", // Pin
"MaxSessions": 0 // Number of sessions, 0 means unlimited
}
Controlled by KES_CONFIG_KEYS
This is the config to define the relation between the key id requested by Minio and the id of the key on the HSM. It supports many aliases and keys to make rotation easily.
{
"keys": [
{
"name": "", // The key id requested by minio
"data": [
{
"id": "", // A unique name for the key, saved in minio headers
"internalid": "1994ce294ee025ace83271abc8a62257741eb6e7", // The id in HSM (a string of bytes in string form)
"valid": true // This is to mark this key for current encryption use
},
{
"id": "",
"internalid": "",
"valid": false // This mark the key for decryption use only, you can have one encryption key, but many decryption (rotation)
},
...
]
}
]
}
Controlled by KES_CONFIG_AUTH
This is the config to define the relation between the key id requested by Minio and the id of the certificate requesting it.
{
"certificates": [
{
"id": "", // The "Signature" parth of the client certificate, you can get it via openssl x509 -in key.pem -text -noout
"name": "", // Friendly name for this certificate
"keys": [
{
"id": "", // The key id requested by minio ("NAME" field in the keys config file)
"encrypt": true, // Can call encrypt endpoint for this key
"decrypt": true, // Can call decrypt endpoint for this key
"generate": true // Can call generate endpoint for this key
},
... // The list of object key requested by minio, for this client
]
}
],
"tlsproxy": {
"enabled": false,
"fingerprint": "----",
"header": "X-SSL-Client-Certificate",
"caverifier": "/home/furio/git/kes-hsm-go/self-signed-keys/chain.pem"
}
}
The TLS proxy section is used if reverse HTTPS proxy is being used.
In this case you must setup the reverse proxy to verify the certificates and send the public one over the header (in base64) specified in the header
section: it will be loaded and verified against the caverifier
root certificate, if valid it's fingerprint will be used as usual in the certificates
section.
Since Minio in KES mode allows only mTLS connections also the reverse proxy should have a valid client certificate and it's fingerprint will be checked against the one in the field fingerprint
.