diff --git a/attest/attest_test.go b/attest/attest_test.go index fb248b3..f618fa2 100644 --- a/attest/attest_test.go +++ b/attest/attest_test.go @@ -18,6 +18,8 @@ import ( "bytes" "crypto" "flag" + "fmt" + "reflect" "testing" ) @@ -163,3 +165,13 @@ func TestBug139(t *testing.T) { t.Errorf("ParseAKPublic() err = %v, want %v", err, msg) } } + +func TestBug142(t *testing.T) { + // Tests ParseEKCertificate() with a malformed size prefix which would overflow + // an int16, ensuring an error is returned rather than a panic occurring. + input := []byte{0x10, 0x01, 0x00, 0xff, 0xff, 0x20} + wantErr := fmt.Errorf("parsing nvram header: ekCert size %d smaller than specified cert length %d", len(input), 65535) + if _, err := ParseEKCertificate(input); !reflect.DeepEqual(err, wantErr) { + t.Errorf("ParseEKCertificate() = %v, want %v", err, wantErr) + } +} diff --git a/attest/tpm.go b/attest/tpm.go index 404f328..ca5fbb9 100644 --- a/attest/tpm.go +++ b/attest/tpm.go @@ -158,8 +158,8 @@ func ParseEKCertificate(ekCert []byte) (*x509.Certificate, error) { // a prefix when storing a certificate in NVRAM. We look // for and unwrap the certificate if its present. if len(ekCert) > 5 && bytes.Equal(ekCert[:3], []byte{0x10, 0x01, 0x00}) { - certLen := binary.BigEndian.Uint16(ekCert[3:5]) - if len(ekCert) < int(certLen+5) { + certLen := int(binary.BigEndian.Uint16(ekCert[3:5])) + if len(ekCert) < certLen+5 { return nil, fmt.Errorf("parsing nvram header: ekCert size %d smaller than specified cert length %d", len(ekCert), certLen) } ekCert = ekCert[5 : 5+certLen]