293 lines
7.4 KiB
Go
293 lines
7.4 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 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 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 CreateGetPseudoRandomCommand(numBytes uint16) *CommandMessage {
|
|
command := &CommandMessage{
|
|
CommandType: CommandTypeGetPseudoRandom,
|
|
}
|
|
|
|
payload := bytes.NewBuffer([]byte{})
|
|
binary.Write(payload, binary.BigEndian, numBytes)
|
|
command.Data = payload.Bytes()
|
|
|
|
return command
|
|
}
|
|
|
|
func CreatePutWrapkeyCommand(objID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, delegated uint64, wrapkey []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))...)
|
|
}
|
|
switch algorithm {
|
|
case AlgorithmAES128CCMWrap:
|
|
if keyLen := len(wrapkey); keyLen != 16 {
|
|
return nil, errors.New("wrapkey is wrong length")
|
|
}
|
|
case AlgorithmAES192CCMWrap:
|
|
if keyLen := len(wrapkey); keyLen != 24 {
|
|
return nil, errors.New("wrapkey is wrong length")
|
|
}
|
|
case AlgorithmAES256CCMWrap:
|
|
if keyLen := len(wrapkey); keyLen != 32 {
|
|
return nil, errors.New("wrapkey is wrong length")
|
|
}
|
|
default:
|
|
return nil, errors.New("invalid algorithm")
|
|
}
|
|
|
|
command := &CommandMessage{
|
|
CommandType: CommandTypePutWrapKey,
|
|
}
|
|
|
|
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, algorithm)
|
|
binary.Write(payload, binary.BigEndian, delegated)
|
|
payload.Write(wrapkey)
|
|
|
|
command.Data = payload.Bytes()
|
|
|
|
return command, nil
|
|
}
|