yubihsm-go/commands/constructors.go

351 lines
9.1 KiB
Go

package commands
import (
"bytes"
"encoding/binary"
"errors"
"io"
"github.com/certusone/yubihsm-go/authkey"
)
func CreateCreateSessionCommand(keySetID uint16, hostChallenge []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeCreateSession,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keySetID)
payload.Write(hostChallenge)
command.Data = payload.Bytes()
return command, nil
}
func CreateAuthenticateSessionCommand(hostCryptogram []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeAuthenticateSession,
Data: hostCryptogram,
}
return command, nil
}
// Authenticated
func CreateResetCommand() (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeReset,
}
return command, nil
}
func CreateGenerateAsymmetricKeyCommand(keyID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm) (*CommandMessage, error) {
if len(label) > LabelLength {
return nil, errors.New("label is too long")
}
if len(label) < LabelLength {
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
}
command := &CommandMessage{
CommandType: CommandTypeGenerateAsymmetricKey,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyID)
payload.Write(label)
binary.Write(payload, binary.BigEndian, domains)
binary.Write(payload, binary.BigEndian, capabilities)
binary.Write(payload, binary.BigEndian, algorithm)
command.Data = payload.Bytes()
return command, nil
}
func CreateSignDataEddsaCommand(keyID uint16, data []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeSignDataEddsa,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyID)
payload.Write(data)
command.Data = payload.Bytes()
return command, nil
}
func CreateSignDataEcdsaCommand(keyID uint16, data []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeSignDataEcdsa,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyID)
payload.Write(data)
command.Data = payload.Bytes()
return command, nil
}
func CreatePutAsymmetricKeyCommand(keyID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, keyPart1 []byte, keyPart2 []byte) (*CommandMessage, error) {
if len(label) > LabelLength {
return nil, errors.New("label is too long")
}
if len(label) < LabelLength {
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
}
command := &CommandMessage{
CommandType: CommandTypePutAsymmetric,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyID)
payload.Write(label)
binary.Write(payload, binary.BigEndian, domains)
binary.Write(payload, binary.BigEndian, capabilities)
binary.Write(payload, binary.BigEndian, algorithm)
payload.Write(keyPart1)
if keyPart2 != nil {
payload.Write(keyPart2)
}
command.Data = payload.Bytes()
return command, nil
}
type ListCommandOption func(w io.Writer)
func NewObjectTypeOption(objectType uint8) ListCommandOption {
return func(w io.Writer) {
binary.Write(w, binary.BigEndian, ListObjectParamType)
binary.Write(w, binary.BigEndian, objectType)
}
}
func NewIDOption(id uint16) ListCommandOption {
return func(w io.Writer) {
binary.Write(w, binary.BigEndian, ListObjectParamID)
binary.Write(w, binary.BigEndian, id)
}
}
func NewDomainOption(domain uint16) ListCommandOption {
return func(w io.Writer) {
binary.Write(w, binary.BigEndian, ListObjectParamDomains)
binary.Write(w, binary.BigEndian, domain)
}
}
func NewLabelOption(label []byte) (ListCommandOption, error) {
if len(label) > LabelLength {
return nil, errors.New("label is too long")
}
if len(label) < LabelLength {
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
}
return func(w io.Writer) {
binary.Write(w, binary.BigEndian, ListObjectParamLabel)
binary.Write(w, binary.BigEndian, label)
}, nil
}
func CreateListObjectsCommand(options ...ListCommandOption) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeListObjects,
}
payload := bytes.NewBuffer([]byte{})
for _, opt := range options {
opt(payload)
}
command.Data = payload.Bytes()
return command, nil
}
func CreateGetObjectInfoCommand(keyID uint16, objectType uint8) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeGetObjectInfo,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyID)
binary.Write(payload, binary.BigEndian, objectType)
command.Data = payload.Bytes()
return command, nil
}
func CreateCloseSessionCommand() (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeCloseSession,
}
return command, nil
}
func CreateGetPubKeyCommand(keyID uint16) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeGetPubKey,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyID)
command.Data = payload.Bytes()
return command, nil
}
func CreateDeleteObjectCommand(objID uint16, objType uint8) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeDeleteObject,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, objID)
binary.Write(payload, binary.BigEndian, objType)
command.Data = payload.Bytes()
return command, nil
}
func CreateEchoCommand(data []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeEcho,
Data: data,
}
return command, nil
}
func CreateDeriveEcdhCommand(objID uint16, pubkey []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeDeriveEcdh,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, objID)
payload.Write(pubkey)
command.Data = payload.Bytes()
return command, nil
}
func CreatePutAuthenticationKeyCommand(objID uint16, label []byte, domains uint16, capabilities uint64, delegated uint64, password string) (*CommandMessage, error) {
if len(label) > LabelLength {
return nil, errors.New("label is too long")
}
if len(label) < LabelLength {
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
}
command := &CommandMessage{
CommandType: CommandTypePutAuthKey,
}
authKey := authkey.NewFromPassword(password)
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, objID)
payload.Write(label)
binary.Write(payload, binary.BigEndian, domains)
binary.Write(payload, binary.BigEndian, capabilities)
binary.Write(payload, binary.BigEndian, AlgorithmYubicoAESAuthentication)
binary.Write(payload, binary.BigEndian, delegated)
payload.Write(authKey.GetEncKey())
payload.Write(authKey.GetMacKey())
command.Data = payload.Bytes()
return command, nil
}
func CreateChangeAuthenticationKeyCommand(objID uint16, newPassword string) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeChangeAuthenticationKey,
}
authKey := authkey.NewFromPassword(newPassword)
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, objID)
binary.Write(payload, binary.BigEndian, AlgorithmYubicoAESAuthentication)
payload.Write(authKey.GetEncKey())
payload.Write(authKey.GetMacKey())
command.Data = payload.Bytes()
return command, nil
}
func CreatePutOpaqueCommand(objID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, data []byte) (*CommandMessage, error) {
if len(label) > LabelLength {
return nil, errors.New("label is too long")
}
if len(label) < LabelLength {
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
}
command := &CommandMessage{
CommandType: CommandTypePutOpaque,
}
payload := bytes.NewBuffer(nil)
binary.Write(payload, binary.BigEndian, objID)
payload.Write(label)
binary.Write(payload, binary.BigEndian, domains)
binary.Write(payload, binary.BigEndian, capabilities)
binary.Write(payload, binary.BigEndian, algorithm)
payload.Write(data)
command.Data = payload.Bytes()
return command, nil
}
func CreateGetOpaqueCommand(objID uint16) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeGetOpaque,
}
payload := bytes.NewBuffer(nil)
binary.Write(payload, binary.BigEndian, objID)
command.Data = payload.Bytes()
return command, nil
}
func CreateSignDataPkcs1Command(objID uint16, data []byte) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeSignDataPkcs1,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, objID)
payload.Write(data)
command.Data = payload.Bytes()
return command, nil
}
func CreateSignAttestationCertCommand(keyObjID, attestationObjID uint16) (*CommandMessage, error) {
command := &CommandMessage{
CommandType: CommandTypeAttestAsymmetric,
}
payload := bytes.NewBuffer([]byte{})
binary.Write(payload, binary.BigEndian, keyObjID)
binary.Write(payload, binary.BigEndian, attestationObjID)
command.Data = payload.Bytes()
return command, nil
}