1
0
mirror of https://github.com/golang/go synced 2024-09-29 19:34:38 -06:00

encoding/asn1: support 31 bit identifiers with OID

The current implementation uses a max of 28 bits when decoding an
ObjectIdentifier.  This change makes it so that an int64 is used to
accumulate up to 35 bits.  If the resulting data would not overflow
an int32, it is used as an int.  Thus up to 31 bits may be used to
represent each subidentifier of an ObjectIdentifier.

Fixes #19933

Change-Id: I95d74b64b24cdb1339ff13421055bce61c80243c
Reviewed-on: https://go-review.googlesource.com/40436
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>
This commit is contained in:
Monis Khan 2017-04-12 16:00:58 -04:00 committed by Adam Langley
parent 8a2cc22209
commit 94aba76639
2 changed files with 15 additions and 3 deletions

View File

@ -22,6 +22,7 @@ package asn1
import (
"errors"
"fmt"
"math"
"math/big"
"reflect"
"strconv"
@ -293,16 +294,24 @@ type Flag bool
// given byte slice. It returns the value and the new offset.
func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
offset = initOffset
var ret64 int64
for shifted := 0; offset < len(bytes); shifted++ {
if shifted == 4 {
// 5 * 7 bits per byte == 35 bits of data
// Thus the representation is either non-minimal or too large for an int32
if shifted == 5 {
err = StructuralError{"base 128 integer too large"}
return
}
ret <<= 7
ret64 <<= 7
b := bytes[offset]
ret |= int(b & 0x7f)
ret64 |= int64(b & 0x7f)
offset++
if b&0x80 == 0 {
ret = int(ret64)
// Ensure that the returned value fits in an int on all platforms
if ret64 > math.MaxInt32 {
err = StructuralError{"base 128 integer too large"}
}
return
}
}

View File

@ -7,6 +7,7 @@ package asn1
import (
"bytes"
"fmt"
"math"
"math/big"
"reflect"
"strings"
@ -386,6 +387,8 @@ var tagAndLengthData = []tagAndLengthTest{
{[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}},
// Tag numbers which would overflow int32 are rejected. (The value below is 2^31.)
{[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}},
// Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.)
{[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}},
// Long tag number form may not be used for tags that fit in short form.
{[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}},
}