1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
package agent
import (
"errors"
keyfile "github.com/foxboron/go-tpm-keyfiles"
"github.com/foxboron/ssh-tpm-agent/key"
"golang.org/x/crypto/ssh"
sshagent "golang.org/x/crypto/ssh/agent"
)
// type AddedKey struct {
// PrivateKey *keyfile.TPMKey
// Certificate *ssh.Certificate
// Comment string
// LifetimeSecs uint32
// ConfirmBeforeUse bool
// ConstraintExtensions []sshagent.ConstraintExtension
// }
type TPMKeyMsg struct {
Type string `sshtype:"17|25"`
PrivateKey []byte
CertBytes []byte
Constraints []byte `ssh:"rest"`
}
func MarshalTPMKeyMsg(cert *sshagent.AddedKey) []byte {
var req []byte
var constraints []byte
if secs := cert.LifetimeSecs; secs != 0 {
constraints = append(constraints, ssh.Marshal(constrainLifetimeAgentMsg{secs})...)
}
if cert.ConfirmBeforeUse {
constraints = append(constraints, agentConstrainConfirm)
}
var certBytes []byte
if cert.Certificate != nil {
certBytes = cert.Certificate.Marshal()
}
switch k := cert.PrivateKey.(type) {
case *keyfile.TPMKey:
req = ssh.Marshal(TPMKeyMsg{
Type: "TPMKEY",
PrivateKey: k.Bytes(),
CertBytes: certBytes,
Constraints: constraints,
})
case *key.SSHTPMKey:
req = ssh.Marshal(TPMKeyMsg{
Type: "TPMKEY",
PrivateKey: k.Bytes(),
CertBytes: certBytes,
Constraints: constraints,
})
}
return req
}
func ParseTPMKeyMsg(req []byte) (*key.SSHTPMKey, error) {
var (
k TPMKeyMsg
tpmkey *key.SSHTPMKey
err error
)
if err := ssh.Unmarshal(req, &k); err != nil {
return nil, err
}
if len(k.PrivateKey) != 0 {
tpmkey, err = key.Decode(k.PrivateKey)
if err != nil {
return nil, err
}
}
if len(k.CertBytes) != 0 {
pubKey, err := ssh.ParsePublicKey(k.CertBytes)
if err != nil {
return nil, err
}
cert, ok := pubKey.(*ssh.Certificate)
if !ok {
return nil, errors.New("agent: bad tpm thing")
}
tpmkey.Certificate = cert
}
return tpmkey, nil
}
|