1
0
mirror of https://github.com/golang/go synced 2024-11-23 16:20:04 -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:
Kyle Isom 2015-06-04 13:23:25 -07:00 committed by Adam Langley
parent a1fe3b5046
commit 38e3427b2f
2 changed files with 30 additions and 0 deletions

View File

@ -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)

View File

@ -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")
}
}