From d3f55e54bdc6fc736cd5838fa4c74e8f9da2b124 Mon Sep 17 00:00:00 2001 From: Gary Belvin Date: Thu, 17 Jun 2021 07:28:14 -0400 Subject: [PATCH 1/2] ExportWrapped --- commands/constructors.go | 15 ++++++++++++++- commands/response.go | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/commands/constructors.go b/commands/constructors.go index 4ffccfd..129b66e 100644 --- a/commands/constructors.go +++ b/commands/constructors.go @@ -411,7 +411,20 @@ func CreateSignAttestationCertCommand(keyObjID, attestationObjID uint16) (*Comma payload := bytes.NewBuffer([]byte{}) binary.Write(payload, binary.BigEndian, keyObjID) binary.Write(payload, binary.BigEndian, attestationObjID) - + command.Data = payload.Bytes() + + return command, nil +} + +func CreateExportWrappedCommand(wrapObjID uint16, objType uint8, objID uint16) (*CommandMessage, error) { + command := &CommandMessage{ + CommandType: CommandTypeExportWrapped, + } + + payload := bytes.NewBuffer([]byte{}) + binary.Write(payload, binary.BigEndian, wrapObjID) + binary.Write(payload, binary.BigEndian, objType) + binary.Write(payload, binary.BigEndian, objID) command.Data = payload.Bytes() return command, nil diff --git a/commands/response.go b/commands/response.go index c2f6c60..44c9216 100644 --- a/commands/response.go +++ b/commands/response.go @@ -107,6 +107,11 @@ type ( SignAttestationCertResponse struct { Cert []byte } + + ExportWrappedResponse struct { + Nonce []byte + Data []byte + } ) // ParseResponse parses the binary response from the card to the relevant Response type. @@ -175,6 +180,8 @@ func ParseResponse(data []byte) (Response, error) { return parseGetOpaqueResponse(payload) case CommandTypeAttestAsymmetric: return parseAttestationCertResponse(payload) + case CommandTypeExportWrapped: + return parseExportWrappedResponse(payload) case ErrorResponseCode: return nil, parseErrorResponse(payload) default: @@ -397,6 +404,17 @@ func parseAttestationCertResponse(payload []byte) (Response, error) { }, nil } +func parseExportWrappedResponse(payload []byte) (Response, error) { + if len(payload) < 13 { + return nil, errors.New("invalid response payload length") + } + + return &ExportWrappedResponse{ + Nonce: payload[:13], + Data: payload[13:], + }, nil +} + // Error formats a card error message into a human readable format func (e *Error) Error() string { message := "" From 88cd1748238f016d5484485cbafecbe3a1dfb8ee Mon Sep 17 00:00:00 2001 From: Gary Belvin Date: Thu, 17 Jun 2021 13:59:00 -0400 Subject: [PATCH 2/2] ImportWrapped --- commands/constructors.go | 21 +++++++++++++++++++++ commands/response.go | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/commands/constructors.go b/commands/constructors.go index 129b66e..c303b06 100644 --- a/commands/constructors.go +++ b/commands/constructors.go @@ -429,3 +429,24 @@ func CreateExportWrappedCommand(wrapObjID uint16, objType uint8, objID uint16) ( return command, nil } + +// CreateImportWrappedCommand will import a wrapped/encrypted Object that was +// previously exported by an YubiHSM2 device. The imported object will retain +// its metadata (Object ID, Domains, Capabilities …etc), however, the object’s +// origin will be marked as imported instead of generated. +func CreateImportWrappedCommand(wrapObjID uint16, nonce, data []byte) (*CommandMessage, error) { + command := &CommandMessage{ + CommandType: CommandTypeImportWrapped, + } + if len(nonce) != 13 { + return nil, errors.New("invalid nonce length") + } + + payload := bytes.NewBuffer([]byte{}) + binary.Write(payload, binary.BigEndian, wrapObjID) + payload.Write(nonce) + payload.Write(data) + command.Data = payload.Bytes() + + return command, nil +} diff --git a/commands/response.go b/commands/response.go index 44c9216..bd34727 100644 --- a/commands/response.go +++ b/commands/response.go @@ -112,6 +112,11 @@ type ( Nonce []byte Data []byte } + + ImportWrappedResponse struct { + ObjectType uint8 + ObjectID uint16 + } ) // ParseResponse parses the binary response from the card to the relevant Response type. @@ -182,6 +187,8 @@ func ParseResponse(data []byte) (Response, error) { return parseAttestationCertResponse(payload) case CommandTypeExportWrapped: return parseExportWrappedResponse(payload) + case CommandTypeImportWrapped: + return parseImportWrappedResponse(payload) case ErrorResponseCode: return nil, parseErrorResponse(payload) default: @@ -415,6 +422,23 @@ func parseExportWrappedResponse(payload []byte) (Response, error) { }, nil } +func parseImportWrappedResponse(payload []byte) (Response, error) { + if len(payload) != 3 { + return nil, errors.New("invalid response payload length") + } + + var objID uint16 + err := binary.Read(bytes.NewReader(payload[1:3]), binary.BigEndian, &objID) + if err != nil { + return nil, err + } + + return &ImportWrappedResponse{ + ObjectType: uint8(payload[0]), + ObjectID: objID, + }, nil +} + // Error formats a card error message into a human readable format func (e *Error) Error() string { message := ""