mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-24 07:39:07 +02:00
62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
package tpm
|
|
|
|
import (
|
|
"crypto"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
|
|
"go.step.sm/crypto/tpm/tss2"
|
|
)
|
|
|
|
// KeyPEMType is the PEM block type of a TPM 2.0 key file as defined by
|
|
// draft-bottomley-tpm2-keys and written by tpm2-openssl and tpm2-tss-engine.
|
|
const KeyPEMType = "TSS2 PRIVATE KEY"
|
|
|
|
var ErrKeyNeedsAuth = errors.New("TPM key requires an authorization value")
|
|
|
|
// ParseKey reads a TSS2 key file and returns a signer that produces every signature
|
|
// inside the TPM; only the digest goes in and only the signature comes out. A key with
|
|
// a persistent parent is loaded under it, a key whose parent is a hierarchy under the
|
|
// TCG default ECC primary that tpm2-openssl and tpm2-tss-engine derive as well. Keys
|
|
// guarded by an authorization value are rejected, since nothing can supply it without
|
|
// prompting.
|
|
func ParseKey(der []byte) (crypto.Signer, error) {
|
|
key, err := tss2.ParsePrivateKey(der)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parse TSS2 key: %w", err)
|
|
}
|
|
if !key.EmptyAuth {
|
|
return nil, ErrKeyNeedsAuth
|
|
}
|
|
public, err := key.Public()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("decode TSS2 public key: %w", err)
|
|
}
|
|
return &keySigner{key: key, public: public}, nil
|
|
}
|
|
|
|
type keySigner struct {
|
|
key *tss2.TPMKey
|
|
public crypto.PublicKey
|
|
}
|
|
|
|
func (s *keySigner) Public() crypto.PublicKey {
|
|
return s.public
|
|
}
|
|
|
|
func (s *keySigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
|
rwc, err := Open()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() { _ = rwc.Close() }()
|
|
|
|
signer, err := tss2.CreateSigner(rwc, s.key)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load TSS2 key: %w", err)
|
|
}
|
|
signer.SetSRKTemplate(tss2.ECCSRKTemplate)
|
|
return signer.Sign(rand, digest, opts)
|
|
}
|