mirror of
https://github.com/google/go-attestation.git
synced 2025-06-18 23:18:19 +00:00
Pay attention to digest size information in the headers
Crypto agile logs may contain digest types that we don't currently handle. However, we still need to know how long each digest is in order to read over the appropriate amount of the buffer. This information is provided to us as part of the spec header - make use of it rather than hardcoding the set of digests and lengths we know about.
This commit is contained in:
@ -343,20 +343,21 @@ const eventTypeNoAction = 0x03
|
|||||||
|
|
||||||
// ParseEventLog parses an unverified measurement log.
|
// ParseEventLog parses an unverified measurement log.
|
||||||
func ParseEventLog(measurementLog []byte) (*EventLog, error) {
|
func ParseEventLog(measurementLog []byte) (*EventLog, error) {
|
||||||
|
var specID *specIDEvent
|
||||||
r := bytes.NewBuffer(measurementLog)
|
r := bytes.NewBuffer(measurementLog)
|
||||||
parseFn := parseRawEvent
|
parseFn := parseRawEvent
|
||||||
var el EventLog
|
var el EventLog
|
||||||
e, err := parseFn(r)
|
e, err := parseFn(r, specID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse first event: %v", err)
|
return nil, fmt.Errorf("parse first event: %v", err)
|
||||||
}
|
}
|
||||||
if e.typ == eventTypeNoAction {
|
if e.typ == eventTypeNoAction {
|
||||||
specID, err := parseSpecIDEvent(e.data)
|
specID, err = parseSpecIDEvent(e.data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse spec ID event: %v", err)
|
return nil, fmt.Errorf("failed to parse spec ID event: %v", err)
|
||||||
}
|
}
|
||||||
for _, alg := range specID.algs {
|
for _, alg := range specID.algs {
|
||||||
switch tpm2.Algorithm(alg) {
|
switch tpm2.Algorithm(alg.ID) {
|
||||||
case tpm2.AlgSHA1:
|
case tpm2.AlgSHA1:
|
||||||
el.Algs = append(el.Algs, HashSHA1)
|
el.Algs = append(el.Algs, HashSHA1)
|
||||||
case tpm2.AlgSHA256:
|
case tpm2.AlgSHA256:
|
||||||
@ -378,7 +379,7 @@ func ParseEventLog(measurementLog []byte) (*EventLog, error) {
|
|||||||
}
|
}
|
||||||
sequence := 1
|
sequence := 1
|
||||||
for r.Len() != 0 {
|
for r.Len() != 0 {
|
||||||
e, err := parseFn(r)
|
e, err := parseFn(r, specID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -390,7 +391,7 @@ func ParseEventLog(measurementLog []byte) (*EventLog, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type specIDEvent struct {
|
type specIDEvent struct {
|
||||||
algs []uint16
|
algs []specAlgSize
|
||||||
}
|
}
|
||||||
|
|
||||||
type specAlgSize struct {
|
type specAlgSize struct {
|
||||||
@ -450,7 +451,7 @@ func parseSpecIDEvent(b []byte) (*specIDEvent, error) {
|
|||||||
if err := binary.Read(r, binary.LittleEndian, &specAlg); err != nil {
|
if err := binary.Read(r, binary.LittleEndian, &specAlg); err != nil {
|
||||||
return nil, fmt.Errorf("reading algorithm: %v", err)
|
return nil, fmt.Errorf("reading algorithm: %v", err)
|
||||||
}
|
}
|
||||||
e.algs = append(e.algs, specAlg.ID)
|
e.algs = append(e.algs, specAlg)
|
||||||
}
|
}
|
||||||
|
|
||||||
var vendorInfoSize uint8
|
var vendorInfoSize uint8
|
||||||
@ -489,7 +490,7 @@ func (e *eventSizeErr) Error() string {
|
|||||||
return fmt.Sprintf("event data size (%d bytes) is greater than remaining measurement log (%d bytes)", e.eventSize, e.logSize)
|
return fmt.Sprintf("event data size (%d bytes) is greater than remaining measurement log (%d bytes)", e.eventSize, e.logSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRawEvent(r *bytes.Buffer) (event rawEvent, err error) {
|
func parseRawEvent(r *bytes.Buffer, specID *specIDEvent) (event rawEvent, err error) {
|
||||||
var h rawEventHeader
|
var h rawEventHeader
|
||||||
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
|
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
|
||||||
return event, err
|
return event, err
|
||||||
@ -516,7 +517,7 @@ type rawEvent2Header struct {
|
|||||||
Type uint32
|
Type uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseRawEvent2(r *bytes.Buffer) (event rawEvent, err error) {
|
func parseRawEvent2(r *bytes.Buffer, specID *specIDEvent) (event rawEvent, err error) {
|
||||||
var h rawEvent2Header
|
var h rawEvent2Header
|
||||||
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
|
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
|
||||||
return event, err
|
return event, err
|
||||||
@ -529,20 +530,24 @@ func parseRawEvent2(r *bytes.Buffer) (event rawEvent, err error) {
|
|||||||
if err := binary.Read(r, binary.LittleEndian, &numDigests); err != nil {
|
if err := binary.Read(r, binary.LittleEndian, &numDigests); err != nil {
|
||||||
return event, err
|
return event, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < int(numDigests); i++ {
|
for i := 0; i < int(numDigests); i++ {
|
||||||
var algID uint16
|
var algID uint16
|
||||||
if err := binary.Read(r, binary.LittleEndian, &algID); err != nil {
|
if err := binary.Read(r, binary.LittleEndian, &algID); err != nil {
|
||||||
return event, err
|
return event, err
|
||||||
}
|
}
|
||||||
var digest []byte
|
var digest []byte
|
||||||
switch algID {
|
for _, alg := range specID.algs {
|
||||||
case algSHA1:
|
if alg.ID != algID {
|
||||||
digest = make([]byte, crypto.SHA1.Size())
|
continue
|
||||||
case algSHA256:
|
}
|
||||||
digest = make([]byte, crypto.SHA256.Size())
|
if uint16(r.Len()) < alg.Size {
|
||||||
default:
|
return event, fmt.Errorf("reading digest: %v", io.ErrUnexpectedEOF)
|
||||||
// ignore signatures that aren't SHA1 or SHA256
|
}
|
||||||
continue
|
digest = make([]byte, alg.Size)
|
||||||
|
}
|
||||||
|
if len(digest) == 0 {
|
||||||
|
return event, fmt.Errorf("unknown algorithm ID %x", algID)
|
||||||
}
|
}
|
||||||
if _, err := io.ReadFull(r, digest); err != nil {
|
if _, err := io.ReadFull(r, digest); err != nil {
|
||||||
return event, err
|
return event, err
|
||||||
|
@ -232,13 +232,14 @@ func TestParseSpecIDEvent(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
spec, err := parseSpecIDEvent(test.data)
|
spec, err := parseSpecIDEvent(test.data)
|
||||||
|
var algs []uint16
|
||||||
if (err != nil) != test.wantErr {
|
if (err != nil) != test.wantErr {
|
||||||
t.Fatalf("parsing spec, wantErr=%t, got=%v", test.wantErr, err)
|
t.Fatalf("parsing spec, wantErr=%t, got=%v", test.wantErr, err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
algsEq := func(got, want []uint16) bool {
|
algsEq := func(want, got []uint16) bool {
|
||||||
if len(got) != len(want) {
|
if len(got) != len(want) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -250,7 +251,11 @@ func TestParseSpecIDEvent(t *testing.T) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !algsEq(test.want, spec.algs) {
|
for _, alg := range(spec.algs) {
|
||||||
|
algs = append(algs, alg.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !algsEq(test.want, algs) {
|
||||||
t.Errorf("algorithms, got=%x, want=%x", spec.algs, test.want)
|
t.Errorf("algorithms, got=%x, want=%x", spec.algs, test.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user