From 7d8389a6ffe3e81ef76a987c8287629f2bc40320 Mon Sep 17 00:00:00 2001 From: Gary Belvin Date: Thu, 4 Mar 2021 15:46:36 +0000 Subject: [PATCH 1/3] PutWrapkeyCommand --- commands/constructors.go | 28 ++++++++++++++++++++++++++++ commands/response.go | 19 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/commands/constructors.go b/commands/constructors.go index 0f3c238..fc1e973 100644 --- a/commands/constructors.go +++ b/commands/constructors.go @@ -248,3 +248,31 @@ func CreateGetPseudoRandomCommand(numBytes uint16) *CommandMessage { return command } + +func CreatePutWrapkeyCommand(objID uint16, label []byte, domains uint16, capabilities, 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))...) + } + if keyLen := len(wrapkey); keyLen != 16 && keyLen != 24 && keyLen != 32 { + return nil, errors.New("wrapkey is wrong length") + } + + 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, delegated) + payload.Write(wrapkey) + + command.Data = payload.Bytes() + + return command, nil +} diff --git a/commands/response.go b/commands/response.go index 276f031..d107205 100644 --- a/commands/response.go +++ b/commands/response.go @@ -83,6 +83,10 @@ type ( ChangeAuthenticationKeyResponse struct { ObjectID uint16 } + + PutWrapkeyResponse struct { + ObjectID uint16 + } ) // ParseResponse parses the binary response from the card to the relevant Response type. @@ -139,6 +143,8 @@ func ParseResponse(data []byte) (Response, error) { return parseChangeAuthenticationKeyResponse(payload) case CommandTypeGetPseudoRandom: return parseGetPseudoRandomResponse(payload), nil + case CommandTypePutWrapKey: + return parsePutWrapkeyResponse(payload) case ErrorResponseCode: return nil, parseErrorResponse(payload) default: @@ -288,6 +294,19 @@ func parseGetPseudoRandomResponse(payload []byte) Response { return payload } +func parsePutWrapkeyResponse(payload []byte) (Response, error) { + if len(payload) != 2 { + return nil, errors.New("invalid response payload length") + } + + var objectID uint16 + err := binary.Read(bytes.NewReader(payload), binary.BigEndian, &objectID) + if err != nil { + return nil, err + } + return &PutWrapkeyResponse{ObjectID: objectID}, nil +} + // Error formats a card error message into a human readable format func (e *Error) Error() string { message := "" From 8ea63b0b208dbb4a450fed45e15ac9a349f8ca09 Mon Sep 17 00:00:00 2001 From: Gary Belvin Date: Thu, 4 Mar 2021 16:12:23 +0000 Subject: [PATCH 2/3] GitIgnore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 78d47ef..899a641 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea *.iml *.swp +*.swo From fe9ad5f86ff06cc298df22455924fac6c15a21c7 Mon Sep 17 00:00:00 2001 From: Gary Belvin Date: Fri, 5 Mar 2021 12:00:28 +0000 Subject: [PATCH 3/3] Wrap Algorithms --- commands/constructors.go | 20 +++++++++++++++++--- commands/types.go | 3 +++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/commands/constructors.go b/commands/constructors.go index fc1e973..dbfdaac 100644 --- a/commands/constructors.go +++ b/commands/constructors.go @@ -249,15 +249,28 @@ func CreateGetPseudoRandomCommand(numBytes uint16) *CommandMessage { return command } -func CreatePutWrapkeyCommand(objID uint16, label []byte, domains uint16, capabilities, delegated uint64, wrapkey []byte) (*CommandMessage, error) { +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))...) } - if keyLen := len(wrapkey); keyLen != 16 && keyLen != 24 && keyLen != 32 { - return nil, errors.New("wrapkey is wrong length") + 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{ @@ -269,6 +282,7 @@ func CreatePutWrapkeyCommand(objID uint16, label []byte, domains uint16, capabil 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) diff --git a/commands/types.go b/commands/types.go index 9194da1..7812a70 100644 --- a/commands/types.go +++ b/commands/types.go @@ -84,6 +84,9 @@ const ( AlgorithmSecp256k1 Algorithm = 15 AlgorithmYubicoAESAuthentication Algorithm = 38 AlgorighmED25519 Algorithm = 46 + AlgorithmAES128CCMWrap Algorithm = 29 + AlgorithmAES192CCMWrap Algorithm = 41 + AlgorithmAES256CCMWrap Algorithm = 42 // Capabilities CapabilityGetOpaque uint64 = 0x0000000000000001