Compare commits

...

3 Commits

Author SHA1 Message Date
Leopold Schabel 43f6e607f2
Merge pull request #16 from gdbelvin/import
ImportWrapped
2021-11-02 16:31:04 +01:00
Gary Belvin 88cd174823 ImportWrapped 2021-06-17 13:59:00 -04:00
Gary Belvin d3f55e54bd ExportWrapped 2021-06-17 07:28:14 -04:00
2 changed files with 77 additions and 1 deletions

View File

@ -411,7 +411,41 @@ 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
}
// 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 objects
// 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

View File

@ -107,6 +107,16 @@ type (
SignAttestationCertResponse struct {
Cert []byte
}
ExportWrappedResponse struct {
Nonce []byte
Data []byte
}
ImportWrappedResponse struct {
ObjectType uint8
ObjectID uint16
}
)
// ParseResponse parses the binary response from the card to the relevant Response type.
@ -175,6 +185,10 @@ func ParseResponse(data []byte) (Response, error) {
return parseGetOpaqueResponse(payload)
case CommandTypeAttestAsymmetric:
return parseAttestationCertResponse(payload)
case CommandTypeExportWrapped:
return parseExportWrappedResponse(payload)
case CommandTypeImportWrapped:
return parseImportWrappedResponse(payload)
case ErrorResponseCode:
return nil, parseErrorResponse(payload)
default:
@ -397,6 +411,34 @@ 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
}
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 := ""