Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: pkcs11-tool based HSM support for factory #278

Merged
merged 17 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/test-pki.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Test PKI
on:
pull_request:

jobs:
test-pki:
name: test-pki
runs-on: ubuntu-latest
steps:
- name: Setup Go
uses: actions/setup-go@v4.1.0
with:
go-version: '~1.19'
- name: Clone the code
uses: actions/checkout@v4
- name: Setup test deps
run: sudo make install-test-pki-deps
- name: Run tests
run: make test-pki
vkhoroz marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ build: fioctl-linux-amd64 fioctl-linux-arm64 fioctl-windows-amd64 fioctl-darwin-
fioctl-static:
CGO_ENABLED=0 go build -a -ldflags '-w -extldflags "-static"' -o ./bin/fioctl-static ./main.go

# Allows building a dyn-linked fioctl on platforms without pkcs11-tool (not built by default)
fioctl-cgo-pkcs11:
CGO_ENABLED=1 go build -tags cgopki $(LDFLAGS) -o bin/$@ ./main.go

vkhoroz marked this conversation as resolved.
Show resolved Hide resolved
fioctl-linux-amd64:
fioctl-linux-arm64:
fioctl-linux-armv7:
Expand All @@ -33,6 +37,9 @@ has-linter:

linter-check: has-linter
$(linter) run ${EXTRA_LINTER_FLAGS}
$(linter) run --build-tags bashpki ${EXTRA_LINTER_FLAGS}
$(linter) run --build-tags cgopki ${EXTRA_LINTER_FLAGS}
$(linter) run --build-tags testhsm ${EXTRA_LINTER_FLAGS}

linter: has-linter
$(linter) run --fix ${EXTRA_LINTER_FLAGS}
Expand All @@ -46,6 +53,15 @@ format:
check: format-check linter-check
@true

install-test-pki-deps:
apt install openssl softhsm2 opensc libengine-pkcs11-openssl

# This needs the following packages on Ubuntu: openssl softhsm2 opensc libengine-pkcs11-openssl
test-pki:
mike-sul marked this conversation as resolved.
Show resolved Hide resolved
go test ./x509/... -v -tags testhsm
go test ./x509/... -v -tags testhsm,bashpki
go test ./x509/... -v -tags testhsm,cgopki

# Use the image for Dockerfile.build to build and install the tool.
container-init:
docker build -t fioctl-build -f Dockerfile.build .
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@ export PATH=$PATH:`pwd`/bin

After making changes be sure to run `make format` which will run the go-fmt
tool against the source code.

## HSM support

The HSM support (for some commands) is provided via the OpenSC pkcs11-tool application,
which needs to be installed separately.
It is not needed if you do not plan to use HSM devices.
5 changes: 0 additions & 5 deletions client/foundries_pki.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ type CaCerts struct {
TlsCsr string `json:"tls-csr"`

ChangeMeta ChangeMeta `json:"change-meta"`

CreateCaScript *string `json:"create_ca"`
mike-sul marked this conversation as resolved.
Show resolved Hide resolved
CreateDeviceCaScript *string `json:"create_device_ca"`
SignCaScript *string `json:"sign_ca_csr"`
SignTlsScript *string `json:"sign_tls_csr"`
}

func (a *Api) FactoryGetCA(factory string) (CaCerts, error) {
Expand Down
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.19

require (
cloud.google.com/go/pubsub v1.33.0
github.com/ThalesIgnite/crypto11 v1.2.5
github.com/cheynewallace/tabby v1.1.1
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c
github.com/fatih/color v1.15.0
Expand All @@ -16,6 +17,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4
github.com/theupdateframework/go-tuf v0.6.1
github.com/theupdateframework/notary v0.7.0
golang.org/x/exp v0.0.0-20221204150635-6dcec336b2bb
Expand All @@ -30,6 +32,7 @@ require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand All @@ -42,15 +45,19 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/thales-e-security/pool v0.0.2 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/net v0.10.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E=
github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw=
Expand Down Expand Up @@ -228,6 +230,8 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f h1:eVB9ELsoq5ouItQBr5Tj334bhPJG/MX+m7rTchmzVUQ=
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
Expand All @@ -246,6 +250,7 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down Expand Up @@ -300,8 +305,11 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gtvVDbmPg=
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
github.com/theupdateframework/go-tuf v0.6.1 h1:6J89fGjQf7s0mLmTG7p7pO/MbKOg+bIXhaLyQdmbKuE=
github.com/theupdateframework/go-tuf v0.6.1/go.mod h1:LAFusuQsFNBnEyYoTuA5zZrF7iaQ4TEgBXm8lb6Vj18=
github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
Expand Down
33 changes: 11 additions & 22 deletions subcommands/keys/ca_create.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keys

import (
"errors"
"fmt"
"os"

Expand Down Expand Up @@ -60,14 +61,7 @@ This is optional.`,
cmd.Flags().BoolVarP(&createLocalCA, "local-ca", "", true, "Create a local CA that you can use for signing your own device certificates")
cmd.Flags().StringVarP(&hsmModule, "hsm-module", "", "", "Create key on an PKCS#11 compatible HSM using this module")
cmd.Flags().StringVarP(&hsmPin, "hsm-pin", "", "", "The PKCS#11 PIN to set up on the HSM, if using one")
cmd.Flags().StringVarP(&hsmTokenLabel, "hsm-token-label", "", "device-gateway-root", "The label of the HSM token created for this")
}

func writeFile(filename, contents string, mode os.FileMode) {
if err := os.WriteFile(filename, []byte(contents), mode); err != nil {
fmt.Printf("ERROR: Creating %s: %s", filename, err)
os.Exit(1)
}
cmd.Flags().StringVarP(&hsmTokenLabel, "hsm-token-label", "", "", "The label of the HSM token created for this")
}

func getDeviceCaCommonName(factory string) string {
Expand All @@ -84,35 +78,30 @@ func doCreateCA(cmd *cobra.Command, args []string) {

if len(hsmModule) > 0 {
if len(hsmPin) == 0 {
fmt.Println("ERROR: --hsm-pin is required with --hsm-module")
os.Exit(1)
subcommands.DieNotNil(errors.New("--hsm-pin is required with --hsm-module"))
vkhoroz marked this conversation as resolved.
Show resolved Hide resolved
}
os.Setenv("HSM_MODULE", hsmModule)
os.Setenv("HSM_PIN", hsmPin)
os.Setenv("HSM_TOKEN_LABEL", hsmTokenLabel)
if len(hsmTokenLabel) == 0 {
subcommands.DieNotNil(errors.New("--hsm-token-label is required with --hsm-module"))
}
x509.InitHsm(x509.HsmInfo{
Module: hsmModule,
Pin: hsmPin,
TokenLabel: hsmTokenLabel,
})
}

resp, err := api.FactoryCreateCA(factory)
subcommands.DieNotNil(err)

writeFile(x509.OnlineCaCsrFile, resp.CaCsr, 0400)
writeFile(x509.TlsCsrFile, resp.TlsCsr, 0400)
writeFile(x509.CreateCaScript, *resp.CreateCaScript, 0700)
writeFile(x509.CreateDeviceCaScript, *resp.CreateDeviceCaScript, 0700)
writeFile(x509.SignCaScript, *resp.SignCaScript, 0700)
writeFile(x509.SignTlsScript, *resp.SignTlsScript, 0700)

fmt.Println("Creating offline root CA for Factory")
resp.RootCrt = x509.CreateFactoryCa(factory)

fmt.Println("Signing Foundries TLS CSR")
resp.TlsCrt = x509.SignTlsCsr(resp.TlsCsr)
writeFile(x509.TlsCertFile, resp.TlsCrt, 0400)

if createOnlineCA {
fmt.Println("Signing Foundries CSR for online use")
resp.CaCrt = x509.SignCaCsr(resp.CaCsr)
writeFile(x509.OnlineCaCertFile, resp.CaCrt, 0400)
}

if createLocalCA {
Expand Down
Loading
Loading