Merge pull request #5 from ecadlabs/master

Support for SignEcdsa and DeleteObject
This commit is contained in:
Hendrik Hofstadt 2019-06-19 21:11:00 +02:00 committed by GitHub
commit 3601184c8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 166 additions and 7 deletions

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"errors"
"io"
)
func CreateCreateSessionCommand(keySetID uint16, hostChallenge []byte) (*CommandMessage, error) {
@ -77,6 +78,20 @@ func CreateSignDataEddsaCommand(keyID uint16, data []byte) (*CommandMessage, err
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")
@ -104,6 +119,51 @@ func CreatePutAsymmetricKeyCommand(keyID uint16, label []byte, domains uint16, c
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,
@ -124,6 +184,19 @@ func CreateGetPubKeyCommand(keyID uint16) (*CommandMessage, error) {
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,

View File

@ -35,10 +35,37 @@ type (
KeyID uint16
}
ObjectInfoResponse struct {
Capabilities uint64
ObjectID uint16
Length uint16
Domains uint16
Type uint8
Algorithm Algorithm
Sequence uint8
Origin uint8
Label [40]byte
DelegatedCapabilites uint64
}
Object struct {
ObjectID uint16
ObjectType uint8
Sequence uint8
}
ListObjectsResponse struct {
Objects []Object
}
SignDataEddsaResponse struct {
Signature []byte
}
SignDataEcdsaResponse struct {
Signature []byte
}
GetPubKeyResponse struct {
Algorithm Algorithm
// KeyData can contain different formats depending on the algorithm according to the YubiHSM2 documentation.
@ -82,12 +109,20 @@ func ParseResponse(data []byte) (Response, error) {
return parseCreateAsymmetricKeyResponse(payload)
case CommandTypeSignDataEddsa:
return parseSignDataEddsaResponse(payload)
case CommandTypeSignDataEcdsa:
return parseSignDataEcdsaResponse(payload)
case CommandTypePutAsymmetric:
return parsePutAsymmetricKeyResponse(payload)
case CommandTypeListObjects:
return parseListObjectsResponse(payload)
case CommandTypeGetObjectInfo:
return parseGetObjectInfoResponse(payload)
case CommandTypeCloseSession:
return nil, nil
case CommandTypeGetPubKey:
return parseGetPubKeyResponse(payload)
case CommandTypeDeleteObject:
return nil, nil
case CommandTypeEcho:
return parseEchoResponse(payload)
case ErrorResponseCode:
@ -149,6 +184,12 @@ func parseSignDataEddsaResponse(payload []byte) (Response, error) {
}, nil
}
func parseSignDataEcdsaResponse(payload []byte) (Response, error) {
return &SignDataEcdsaResponse{
Signature: payload,
}, nil
}
func parsePutAsymmetricKeyResponse(payload []byte) (Response, error) {
if len(payload) != 2 {
return nil, errors.New("invalid response payload length")
@ -165,6 +206,34 @@ func parsePutAsymmetricKeyResponse(payload []byte) (Response, error) {
}, nil
}
func parseListObjectsResponse(payload []byte) (Response, error) {
if len(payload)%4 != 0 {
return nil, errors.New("invalid response payload length")
}
response := ListObjectsResponse{
Objects: make([]Object, len(payload)/4),
}
err := binary.Read(bytes.NewReader(payload), binary.BigEndian, &response.Objects)
if err != nil {
return nil, err
}
return &response, nil
}
func parseGetObjectInfoResponse(payload []byte) (Response, error) {
response := ObjectInfoResponse{}
err := binary.Read(bytes.NewReader(payload), binary.BigEndian, &response)
if err != nil {
return nil, err
}
return &response, nil
}
func parseGetPubKeyResponse(payload []byte) (Response, error) {
if len(payload) < 1 {
return nil, errors.New("invalid response payload length")

View File

@ -78,7 +78,9 @@ const (
ErrorCodeCommandUnexecuted ErrorCode = 0xff
// Algorithms
AlgorighmED25519 Algorithm = 46
AlgorithmP256 Algorithm = 12
AlgorithmSecp256k1 Algorithm = 15
AlgorighmED25519 Algorithm = 46
// Capabilities
CapabilityGetOpaque uint64 = 0x0000000000000001
@ -145,4 +147,17 @@ const (
Domain14 uint16 = 0x2000
Domain15 uint16 = 0x4000
Domain16 uint16 = 0x8000
// object types
ObjectTypeOpaque uint8 = 0x01
ObjectTypeAuthenticationKey uint8 = 0x02
ObjectTypeAsymmetricKey uint8 = 0x03
ObjectTypeWrapKey uint8 = 0x04
ObjectTypeHmacKey uint8 = 0x05
ObjectTypeTemplate uint8 = 0x06
ObjectTypeOtpAeadKey uint8 = 0x07
// list objects params
ListObjectParamID uint8 = 0x01
ListObjectParamType uint8 = 0x02
)

View File

@ -3,10 +3,11 @@ package connector
import (
"bytes"
"fmt"
"github.com/certusone/yubihsm-go/commands"
"io/ioutil"
"net/http"
"strings"
"github.com/certusone/yubihsm-go/commands"
)
type (

View File

@ -3,11 +3,12 @@ package yubihsm
import (
"bytes"
"errors"
"sync"
"time"
"github.com/certusone/yubihsm-go/commands"
"github.com/certusone/yubihsm-go/connector"
"github.com/certusone/yubihsm-go/securechannel"
"sync"
"time"
)
type (
@ -70,7 +71,6 @@ func (s *SessionManager) pingRoutine() {
}
}
println("pinged")
s.keepAlive.Reset(pingInterval)
}
}

View File

@ -7,10 +7,11 @@ import (
"crypto/rand"
"encoding/binary"
"errors"
"sync"
"github.com/enceve/crypto/cmac"
"github.com/certusone/yubihsm-go/commands"
"github.com/certusone/yubihsm-go/connector"
"github.com/enceve/crypto/cmac"
"sync"
)
type (