implement GetLogs, SetLogIndex commands
This commit is contained in:
parent
dac1fd2bba
commit
8d65b759ea
|
@ -22,6 +22,8 @@ Currently the following commands are implemented:
|
||||||
* SignAttestationCertificate
|
* SignAttestationCertificate
|
||||||
* Authentication & Session related commands
|
* Authentication & Session related commands
|
||||||
* GetPseudoRandom
|
* GetPseudoRandom
|
||||||
|
* GetLogs
|
||||||
|
* SetLogIndex
|
||||||
|
|
||||||
Implementing new commands is really easy. Please consult `commands/constructors.go` and `commands/response.go` for reference.
|
Implementing new commands is really easy. Please consult `commands/constructors.go` and `commands/response.go` for reference.
|
||||||
|
|
||||||
|
|
|
@ -459,3 +459,23 @@ func CreateImportWrappedCommand(wrapObjID uint16, nonce, data []byte) (*CommandM
|
||||||
|
|
||||||
return command, nil
|
return command, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateGetLogsCommand() *CommandMessage {
|
||||||
|
command := &CommandMessage{
|
||||||
|
CommandType: CommandTypeGetLogs,
|
||||||
|
}
|
||||||
|
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSetLogIndexCommand(index uint16) *CommandMessage {
|
||||||
|
command := &CommandMessage{
|
||||||
|
CommandType: CommandTypeSetLogIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := bytes.NewBuffer([]byte{})
|
||||||
|
_ = binary.Write(payload, binary.BigEndian, index)
|
||||||
|
command.Data = payload.Bytes()
|
||||||
|
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
|
@ -127,6 +127,24 @@ type (
|
||||||
ObjectType uint8
|
ObjectType uint8
|
||||||
ObjectID uint16
|
ObjectID uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetLogsResponse struct {
|
||||||
|
UnloggedBootEvents uint16
|
||||||
|
UnloggedAuthenticationEvents uint16
|
||||||
|
Elements []LogElement
|
||||||
|
}
|
||||||
|
|
||||||
|
LogElement struct {
|
||||||
|
CommandNumber uint16
|
||||||
|
CommandType CommandType
|
||||||
|
CommandLength uint16
|
||||||
|
SessionID uint16
|
||||||
|
KeyID uint16
|
||||||
|
SecondaryKeyID uint16
|
||||||
|
Result ErrorCode
|
||||||
|
SysTick uint32
|
||||||
|
Digest []byte
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseResponse parses the binary response from the card to the relevant Response type.
|
// ParseResponse parses the binary response from the card to the relevant Response type.
|
||||||
|
@ -201,6 +219,10 @@ func ParseResponse(data []byte) (Response, error) {
|
||||||
return parseExportWrappedResponse(payload)
|
return parseExportWrappedResponse(payload)
|
||||||
case CommandTypeImportWrapped:
|
case CommandTypeImportWrapped:
|
||||||
return parseImportWrappedResponse(payload)
|
return parseImportWrappedResponse(payload)
|
||||||
|
case CommandTypeGetLogs:
|
||||||
|
return parseGetLogsResponse(payload)
|
||||||
|
case CommandTypeSetLogIndex:
|
||||||
|
return nil, nil
|
||||||
case ErrorResponseCode:
|
case ErrorResponseCode:
|
||||||
return nil, parseErrorResponse(payload)
|
return nil, parseErrorResponse(payload)
|
||||||
default:
|
default:
|
||||||
|
@ -473,6 +495,115 @@ func parseImportWrappedResponse(payload []byte) (Response, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
LogElementDataLength = 16
|
||||||
|
LogElementDigestLength = 16
|
||||||
|
LogElementLength = LogElementDataLength + LogElementDigestLength
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LogCommandTypeBoot = CommandType(0x00)
|
||||||
|
LogCommandTypeReset = CommandType(0xff)
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseGetLogsResponse(payload []byte) (Response, error) {
|
||||||
|
if len(payload) < 5 {
|
||||||
|
return nil, errors.New("invalid response payload length")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
unloggedBootEvents uint16
|
||||||
|
unloggedAuthenticationEvents uint16
|
||||||
|
numberOfElements uint8
|
||||||
|
elements []LogElement
|
||||||
|
)
|
||||||
|
|
||||||
|
r := bytes.NewReader(payload)
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &unloggedBootEvents); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &unloggedAuthenticationEvents); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &numberOfElements); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(payload) != 5+int(numberOfElements)*LogElementLength {
|
||||||
|
return nil, errors.New("invalid response payload length")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(numberOfElements); i++ {
|
||||||
|
var (
|
||||||
|
commandNumber uint16
|
||||||
|
commandType CommandType
|
||||||
|
commandLength uint16
|
||||||
|
sessionID uint16
|
||||||
|
keyID uint16
|
||||||
|
secondaryKeyID uint16
|
||||||
|
result ErrorCode
|
||||||
|
sysTick uint32
|
||||||
|
digest = make([]byte, 16)
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &commandNumber); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &commandType); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &commandLength); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &sessionID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &keyID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &secondaryKeyID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &sysTick); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n, err := r.Read(digest); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if n != 16 {
|
||||||
|
return nil, errors.New("incomplete log entry digest")
|
||||||
|
}
|
||||||
|
|
||||||
|
elements = append(elements, LogElement{
|
||||||
|
CommandNumber: commandNumber,
|
||||||
|
CommandType: commandType,
|
||||||
|
CommandLength: commandLength,
|
||||||
|
SessionID: sessionID,
|
||||||
|
KeyID: keyID,
|
||||||
|
SecondaryKeyID: secondaryKeyID,
|
||||||
|
Result: result,
|
||||||
|
SysTick: sysTick,
|
||||||
|
Digest: digest,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GetLogsResponse{
|
||||||
|
UnloggedBootEvents: unloggedBootEvents,
|
||||||
|
UnloggedAuthenticationEvents: unloggedAuthenticationEvents,
|
||||||
|
Elements: elements,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (le LogElement) IsBoot() bool {
|
||||||
|
return le.CommandType == LogCommandTypeBoot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (le LogElement) IsReset() bool {
|
||||||
|
return le.CommandType == LogCommandTypeReset
|
||||||
|
}
|
||||||
|
|
||||||
// Error formats a card error message into a human readable format
|
// Error formats a card error message into a human readable format
|
||||||
func (e *Error) Error() string {
|
func (e *Error) Error() string {
|
||||||
message := ""
|
message := ""
|
||||||
|
|
Loading…
Reference in New Issue