Skip to content

Commit

Permalink
added opencryptoki as another trustmanager
Browse files Browse the repository at this point in the history
resolves notaryproject#1289
Signed-off-by: Florian Eichin <florian.eichin@gmail.com>
  • Loading branch information
florianeichin authored and jschintag committed Jun 6, 2019
1 parent f5a27e9 commit 86194a0
Show file tree
Hide file tree
Showing 14 changed files with 1,530 additions and 33 deletions.
3 changes: 3 additions & 0 deletions cmd/notary/integration_pkcs11_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/passphrase"
"github.com/theupdateframework/notary/trustmanager/pkcs11/common"
"github.com/theupdateframework/notary/trustmanager/pkcs11/opencryptoki"
"github.com/theupdateframework/notary/trustmanager/pkcs11/yubikey"
"github.com/theupdateframework/notary/tuf/data"
)
Expand All @@ -18,6 +19,8 @@ var _retriever notary.PassRetriever

func init() {
yubikey.SetYubikeyKeyMode(yubikey.KeymodeNone)
opencryptoki.SetPin("12345670")
opencryptoki.SetSlot(4)
regRetriver := passphrase.PromptRetriever()
_retriever := func(k, a string, c bool, n int) (string, bool, error) {
if k == "Yubikey" {
Expand Down
4 changes: 0 additions & 4 deletions cmd/notary/keys_pkcs11.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import (
"github.com/theupdateframework/notary/trustmanager/pkcs11/common"
)

func init() {
pkcs11.Setup()
}

func getHardwareStore(fileKeyStore trustmanager.KeyStore, ret notary.PassRetriever) (*common.HardwareStore, error) {
return common.NewHardwareStore(fileKeyStore, ret)
}
Expand Down
Binary file added cmd/notary/notary
Binary file not shown.
15 changes: 8 additions & 7 deletions trustmanager/pkcs11/common/hardwareprivatekey.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package common
import (
"crypto"
"crypto/x509"
"errors"
"fmt"
"io"

Expand All @@ -15,6 +14,7 @@ import (
)

const (
// SigAttempts defines maximum attempts to sign an artifact before aborting
SigAttempts = 5
)

Expand All @@ -31,7 +31,7 @@ type hardwareSigner struct {
HardwarePrivateKey
}

// NewHwrdwarePrivateKey returns a HwardwarePrivateKey, which implements the data.PrivateKey
// NewHardwarePrivateKey returns a HwardwarePrivateKey, which implements the data.PrivateKey
// interface except that the private material is inaccessible
func NewHardwarePrivateKey(slot HardwareSlot, pubKey data.ECDSAPublicKey, passRetriever notary.PassRetriever) *HardwarePrivateKey {
return &HardwarePrivateKey{
Expand All @@ -43,20 +43,21 @@ func NewHardwarePrivateKey(slot HardwareSlot, pubKey data.ECDSAPublicKey, passRe
}

// Public is a required method of the crypto.Signer interface
func (ys *hardwareSigner) Public() crypto.PublicKey {
publicKey, err := x509.ParsePKIXPublicKey(ys.HardwarePrivateKey.Public())
func (hs *hardwareSigner) Public() crypto.PublicKey {
publicKey, err := x509.ParsePKIXPublicKey(hs.HardwarePrivateKey.Public())
if err != nil {
return nil
}

return publicKey
}

// SetLibLoader sets up the pkcs library for further usage
func (hpk *HardwarePrivateKey) SetLibLoader(loader Pkcs11LibLoader) {
hpk.libLoader = loader
}

// CryptoSigner returns a crypto.Signer tha wraps the HardwarePrivateKey. Needed for
// CryptoSigner returns a crypto.Signer that wraps the HardwarePrivateKey. Needed for
// Certificate generation only
func (hpk *HardwarePrivateKey) CryptoSigner() crypto.Signer {
return &hardwareSigner{HardwarePrivateKey: *hpk}
Expand All @@ -69,7 +70,7 @@ func (hpk *HardwarePrivateKey) Private() []byte {

// SignatureAlgorithm returns which algorithm this key uses to sign - currently
// hardcoded to ECDSA
func (y HardwarePrivateKey) SignatureAlgorithm() data.SigAlgorithm {
func (hpk HardwarePrivateKey) SignatureAlgorithm() data.SigAlgorithm {
return data.ECDSASignature
}

Expand All @@ -92,5 +93,5 @@ func (hpk *HardwarePrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.Sign
return sig, nil
}
}
return nil, errors.New(fmt.Sprintln("failed to generate signature on %s", hardwareName))
return nil, fmt.Errorf("failed to generate signature on %s", hardwareName)
}
4 changes: 3 additions & 1 deletion trustmanager/pkcs11/common/hardwarestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/theupdateframework/notary/tuf/data"
)

// HardwareStore defines a datastructure with the corresponding pkcs11 library,
// all keys inside, the given passretirever and the backup store in the filesystem
type HardwareStore struct {
PassRetriever notary.PassRetriever
Keys map[string]HardwareSlot
Expand All @@ -38,6 +40,7 @@ func (s HardwareStore) Name() string {
return hardwareName
}

// SetLibLoader sets up the libloader for further usage
func (s *HardwareStore) SetLibLoader(loader Pkcs11LibLoader) {
s.LibLoader = loader
}
Expand Down Expand Up @@ -114,7 +117,6 @@ func (s *HardwareStore) addKey(keyID string, role data.RoleName, privKey data.Pr
SlotID: slot,
KeyID: keyID,
}
//err = hardwareKeyStore.AddECDSAKey(ctx, session, privKey, slot, s.PassRetriever, role)
err = hardwareKeyStore.AddECDSAKey(ctx, session, privKey, key, s.PassRetriever, role)
if err == nil {
s.Keys[privKey.ID()] = key
Expand Down
13 changes: 9 additions & 4 deletions trustmanager/pkcs11/common/universal.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ var (
hardwareKeyStore HardwareSpecificStore
)

// SetKeyStore sets up the to be used keystore
func SetKeyStore(ks HardwareSpecificStore) {
hardwareKeyStore = ks
hardwareName = hardwareKeyStore.Name()
}

// IPKCS11 is an interface for wrapping github.com/miekg/pkcs11
// Pkcs11LibLoader defines IPKCS11 which is an interface for wrapping github.com/miekg/pkcs11
type Pkcs11LibLoader func(module string) IPKCS11Ctx

// DefaultLoader returns pkcs11 witha given module
func DefaultLoader(module string) IPKCS11Ctx {
return pkcs11.New(module)
}
Expand Down Expand Up @@ -59,13 +61,14 @@ type IPKCS11Ctx interface {

//Common Functions and Structs that may be used by different PKCS11 Implementations

// HardwareSlot defines and connects the keyrole, slotid and keyid
type HardwareSlot struct {
Role data.RoleName
SlotID []byte
KeyID string
}

// An error indicating that the HSM is not present (as opposed to failing),
// ErrHSMNotPresent is an error indicating that the HSM is not present (as opposed to failing),
// i.e. that we can confidently claim that the key is not stored in the HSM
// without notifying the user about a missing or failing HSM.
type ErrHSMNotPresent struct {
Expand All @@ -76,6 +79,7 @@ func (err ErrHSMNotPresent) Error() string {
return err.Err
}

// HardwareSpecificStore is an interface that defines all the functions, a hardwarespecific keystore needs to implement to work with pkcs11
type HardwareSpecificStore interface {
Name() string
AddECDSAKey(IPKCS11Ctx, pkcs11.SessionHandle, data.PrivateKey, HardwareSlot, notary.PassRetriever, data.RoleName) error
Expand Down Expand Up @@ -158,6 +162,7 @@ func FinalizeAndDestroy(ctx IPKCS11Ctx) {
ctx.Destroy()
}

// BuildKeyMap maps all the keys of a slot according to its info
func BuildKeyMap(keys map[string]HardwareSlot) map[string]trustmanager.KeyInfo {
res := make(map[string]trustmanager.KeyInfo)
for k, v := range keys {
Expand All @@ -166,8 +171,8 @@ func BuildKeyMap(keys map[string]HardwareSlot) map[string]trustmanager.KeyInfo {
return res
}

// If a byte array is less than the number of bytes specified by
// ecdsaPrivateKeySize, left-zero-pad the byte array until
// EnsurePrivateKeySize checks if a byte array is less than the number of bytes specified by
// ecdsaPrivateKeySize. If, left-zero-pad the byte array until
// it is the required size.
func EnsurePrivateKeySize(payload []byte) []byte {
final := payload
Expand Down
10 changes: 9 additions & 1 deletion trustmanager/pkcs11/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/trustmanager"
"github.com/theupdateframework/notary/trustmanager/pkcs11/common"
"github.com/theupdateframework/notary/trustmanager/pkcs11/opencryptoki"
"github.com/theupdateframework/notary/trustmanager/pkcs11/yubikey"
"github.com/theupdateframework/notary/tuf/data"
"github.com/theupdateframework/notary/tuf/utils"
Expand All @@ -23,9 +24,16 @@ func Setup() {
return
}
hardwareKeyStore = yubikey.NewKeyStore()
ctx, session, err := hardwareKeyStore.SetupHSMEnv(common.DefaultLoader)
if err == nil {
common.SetKeyStore(hardwareKeyStore)
defer common.Cleanup(ctx, session)
return
}

hardwareKeyStore = opencryptoki.NewKeyStore()
common.SetKeyStore(hardwareKeyStore)
return

}

// HardwareImport is a wrapper around the HardwareStore that allows us to import private
Expand Down
9 changes: 9 additions & 0 deletions trustmanager/pkcs11/opencryptoki/non_pkcs11.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// go list ./... and go test ./... will not pick up this package without this
// file, because go ? ./... does not honor build tags.

// e.g. "go list -tags pkcs11 ./..." will not list this package if all the
// files in it have a build tag.

// See https://github.com/golang/go/issues/11246

package opencryptoki
Loading

0 comments on commit 86194a0

Please sign in to comment.