Skip to content

Commit 94aba76

Browse files
enjagl
authored andcommitted
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 <[email protected]> Run-TryBot: Adam Langley <[email protected]>
1 parent 8a2cc22 commit 94aba76

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

src/encoding/asn1/asn1.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package asn1
2222
import (
2323
"errors"
2424
"fmt"
25+
"math"
2526
"math/big"
2627
"reflect"
2728
"strconv"
@@ -293,16 +294,24 @@ type Flag bool
293294
// given byte slice. It returns the value and the new offset.
294295
func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
295296
offset = initOffset
297+
var ret64 int64
296298
for shifted := 0; offset < len(bytes); shifted++ {
297-
if shifted == 4 {
299+
// 5 * 7 bits per byte == 35 bits of data
300+
// Thus the representation is either non-minimal or too large for an int32
301+
if shifted == 5 {
298302
err = StructuralError{"base 128 integer too large"}
299303
return
300304
}
301-
ret <<= 7
305+
ret64 <<= 7
302306
b := bytes[offset]
303-
ret |= int(b & 0x7f)
307+
ret64 |= int64(b & 0x7f)
304308
offset++
305309
if b&0x80 == 0 {
310+
ret = int(ret64)
311+
// Ensure that the returned value fits in an int on all platforms
312+
if ret64 > math.MaxInt32 {
313+
err = StructuralError{"base 128 integer too large"}
314+
}
306315
return
307316
}
308317
}

src/encoding/asn1/asn1_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package asn1
77
import (
88
"bytes"
99
"fmt"
10+
"math"
1011
"math/big"
1112
"reflect"
1213
"strings"
@@ -386,6 +387,8 @@ var tagAndLengthData = []tagAndLengthTest{
386387
{[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}},
387388
// Tag numbers which would overflow int32 are rejected. (The value below is 2^31.)
388389
{[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}},
390+
// Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.)
391+
{[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}},
389392
// Long tag number form may not be used for tags that fit in short form.
390393
{[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}},
391394
}

0 commit comments

Comments
 (0)