mirror of
https://github.com/golang/go
synced 2024-11-13 16:50:23 -07:00
encoding/asn1: check bounds when parsing tag and length
This was found while fuzzing another program, triggering a panic in x509.ParseECPrivateKey. Fixes #11154 Change-Id: Ief35ead38adf14caec4d37b9eacf8a92e67cd1e6 Reviewed-on: https://go-review.googlesource.com/10712 Reviewed-by: Adam Langley <agl@golang.org> Run-TryBot: Adam Langley <agl@golang.org>
This commit is contained in:
parent
a1fe3b5046
commit
38e3427b2f
@ -20,6 +20,7 @@ package asn1
|
||||
// everything by any means.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
@ -389,6 +390,12 @@ type RawContent []byte
|
||||
// don't distinguish between ordered and unordered objects in this code.
|
||||
func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
|
||||
offset = initOffset
|
||||
// parseTagAndLength should not be called without at least a single
|
||||
// byte to read. Thus this check is for robustness:
|
||||
if offset >= len(bytes) {
|
||||
err = errors.New("asn1: internal error in parseTagAndLength")
|
||||
return
|
||||
}
|
||||
b := bytes[offset]
|
||||
offset++
|
||||
ret.class = int(b >> 6)
|
||||
@ -611,6 +618,10 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
|
||||
if params.application {
|
||||
expectedClass = classApplication
|
||||
}
|
||||
if offset == len(bytes) {
|
||||
err = StructuralError{"explicit tag has no child"}
|
||||
return
|
||||
}
|
||||
if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
|
||||
if t.length > 0 {
|
||||
t, offset, err = parseTagAndLength(bytes, offset)
|
||||
|
@ -867,3 +867,22 @@ func TestImplicitTaggedTime(t *testing.T) {
|
||||
t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
|
||||
}
|
||||
}
|
||||
|
||||
type truncatedExplicitTagTest struct {
|
||||
Test int `asn1:"explicit,tag:0"`
|
||||
}
|
||||
|
||||
func TestTruncatedExplicitTag(t *testing.T) {
|
||||
// This crashed Unmarshal in the past. See #11154.
|
||||
der := []byte{
|
||||
0x30, // SEQUENCE
|
||||
0x02, // two bytes long
|
||||
0xa0, // context-specific, tag 0
|
||||
0x30, // 48 bytes long
|
||||
}
|
||||
|
||||
var result truncatedExplicitTagTest
|
||||
if _, err := Unmarshal(der, &result); err == nil {
|
||||
t.Error("Unmarshal returned without error")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user