Skip to content

Commit

Permalink
Merge pull request #278 from foundriesio/vkhoroz-pkcs11-tool
Browse files Browse the repository at this point in the history
Feature: pkcs11-tool based HSM support for factory PKI
  • Loading branch information
vkhoroz authored Oct 5, 2023
2 parents d2fc303 + 48a08f5 commit 92cd99b
Show file tree
Hide file tree
Showing 15 changed files with 841 additions and 99 deletions.
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
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

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:
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"`
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"))
}
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

0 comments on commit 92cd99b

Please sign in to comment.