Skip to content

Commit

Permalink
add PutCertificate and GetCertificate to store x509 certificates on t…
Browse files Browse the repository at this point in the history
…he HSM
  • Loading branch information
MagicalTux committed May 21, 2019
1 parent 0377a47 commit f7b33d8
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
8 changes: 7 additions & 1 deletion intf.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package hsm

import "crypto"
import (
"crypto"
"crypto/x509"
)

type HSM interface {
Ready() bool
ListKeys() ([]Key, error)
ListKeysByName(name string) ([]Key, error)

PutCertificate(name string, cert *x509.Certificate) error
GetCertificate(name string) (*x509.Certificate, error)
}

type Key interface {
Expand Down
9 changes: 9 additions & 0 deletions software.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hsm

import (
"crypto/x509"
"log"
"os"
"path/filepath"
Expand Down Expand Up @@ -41,3 +42,11 @@ func (h *SoftwareHSM) ListKeysByName(name string) ([]Key, error) {
// TODO
return nil, nil
}

func (h *SoftwareHSM) PutCertificate(name string, cert *x509.Certificate) error {
return nil // TODO
}

func (h *SoftwareHSM) GetCertificate(name string) (*x509.Certificate, error) {
return nil, nil // TODO
}
35 changes: 35 additions & 0 deletions yubihsm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"crypto/x509"
"errors"
"fmt"
"io"
"log"
"math/big"
"os"
"sync"
"syscall"

Expand Down Expand Up @@ -85,6 +87,39 @@ func (h *YubiHSM2) ListKeysByName(name string) ([]Key, error) {
return f, nil
}

func (h *YubiHSM2) PutCertificate(name string, cert *x509.Certificate) error {
res, err := h.sm.ListObjects(yubihsm2.TypeOpaque, yubihsm2.Label(name))
if err != nil {
return err
}
var id yubihsm2.ObjectID

if len(res) > 0 {
id = res[0].ObjectID
}

// send certificate
_, err = h.sm.PutOpaque(id, []byte(name), 1, 0, yubihsm2.OpaqueX509Cert, cert.Raw)
return err
}

func (h *YubiHSM2) GetCertificate(name string) (*x509.Certificate, error) {
res, err := h.sm.ListObjects(yubihsm2.TypeOpaque, yubihsm2.Label(name))
if err != nil {
return nil, err
}
if len(res) == 0 {
return nil, os.ErrNotExist
}

// grab data
der, err := h.sm.GetOpaque(res[0].ObjectID)
if err != nil {
return nil, err
}
return x509.ParseCertificate(der)
}

func (k *YubiHSM2Key) Public() crypto.PublicKey {
key, err := k.parent.sm.GetPubKey(k.kid)
if err != nil {
Expand Down
39 changes: 39 additions & 0 deletions yubihsm2/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,42 @@ func (call CommandHandler) PutAsymmetricKey(keyID uint16, label []byte, domains
res.ReadValue(&keyID)
return keyID, nil
}

func (call CommandHandler) PutOpaque(id ObjectID, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, data []byte) (ObjectID, error) {
if len(label) > LabelLength {
return 0, errors.New("label is too long")
}
if len(label) < LabelLength {
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
}

command := CmdPutOpaque.New()
command.WriteValue(id)
command.Write(label)
command.WriteValue(domains)
command.WriteValue(capabilities)
command.WriteValue(algorithm)
command.Write(data)

res, err := call(command)
if err != nil {
return 0, err
}
if res.Len() != 2 {
return 0, errors.New("invalid response payload length")
}
res.ReadValue(&id)
return id, nil
}

func (call CommandHandler) GetOpaque(id ObjectID) ([]byte, error) {
command := CmdGetOpaque.New()
command.WriteValue(id)

res, err := call(command)
if err != nil {
return nil, err
}

return res.Payload, nil
}

0 comments on commit f7b33d8

Please sign in to comment.