Skip to content

Commit 553d7fa

Browse files
committed
Bump the maximum OID component to 2^64-1
1 parent bd344e5 commit 553d7fa

7 files changed

Lines changed: 77 additions & 66 deletions

File tree

cmd/ascii2der/encoder.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"github.com/google/der-ascii/internal"
2222
)
2323

24-
func appendBase128(dst []byte, value uint32) []byte {
24+
func appendBase128(dst []byte, value uint64) []byte {
2525
dst, err := appendBase128WithLength(dst, value, 0)
2626
if err != nil {
2727
// Only a length override can fail.
@@ -30,7 +30,7 @@ func appendBase128(dst []byte, value uint32) []byte {
3030
return dst
3131
}
3232

33-
func appendBase128WithLength(dst []byte, value uint32, length int) ([]byte, error) {
33+
func appendBase128WithLength(dst []byte, value uint64, length int) ([]byte, error) {
3434
// Count how many bytes are needed.
3535
var l int
3636
for n := value; n != 0; n >>= 7 {
@@ -73,7 +73,7 @@ func appendTag(dst []byte, tag internal.Tag) ([]byte, error) {
7373
// High-tag-number form.
7474
b |= 0x1f
7575
dst = append(dst, b)
76-
return appendBase128WithLength(dst, tag.Number, tag.LongFormOverride)
76+
return appendBase128WithLength(dst, uint64(tag.Number), tag.LongFormOverride)
7777
}
7878

7979
// appendLength marshals the given length in DER and appends the result to dst,
@@ -120,7 +120,7 @@ func appendInteger(dst []byte, value int64) []byte {
120120
return dst
121121
}
122122

123-
func appendObjectIdentifier(dst []byte, value []uint32) ([]byte, bool) {
123+
func appendObjectIdentifier(dst []byte, value []uint64) ([]byte, bool) {
124124
// Validate the input before anything is written.
125125
if len(value) < 2 || value[0] > 2 || (value[0] < 2 && value[1] > 39) {
126126
return dst, false
@@ -136,7 +136,7 @@ func appendObjectIdentifier(dst []byte, value []uint32) ([]byte, bool) {
136136
return dst, true
137137
}
138138

139-
func appendRelativeOID(dst []byte, value []uint32) []byte {
139+
func appendRelativeOID(dst []byte, value []uint64) []byte {
140140
for _, v := range value {
141141
dst = appendBase128(dst, v)
142142
}

cmd/ascii2der/encoder_test.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,22 @@ func TestAppendInteger(t *testing.T) {
143143
}
144144

145145
var appendObjectIdentifierTests = []struct {
146-
value []uint32
146+
value []uint64
147147
encoded []byte
148148
ok bool
149149
}{
150-
{[]uint32{0, 1}, []byte{1}, true},
151-
{[]uint32{1, 2, 3, 4, 0, 127, 128, 129}, []byte{42, 3, 4, 0, 0x7f, 0x81, 0x00, 0x81, 0x01}, true},
152-
{[]uint32{2, 1}, []byte{81}, true},
153-
{[]uint32{2, math.MaxUint32 - 80}, []byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, true},
150+
{[]uint64{0, 1}, []byte{1}, true},
151+
{[]uint64{1, 2, 3, 4, 0, 127, 128, 129}, []byte{42, 3, 4, 0, 0x7f, 0x81, 0x00, 0x81, 0x01}, true},
152+
{[]uint64{2, 1}, []byte{81}, true},
153+
{[]uint64{2, math.MaxUint32 - 80}, []byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, true},
154+
{[]uint64{2, math.MaxUint64 - 80}, []byte{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, true},
154155
// Invalid OIDs.
155-
{[]uint32{}, nil, false},
156-
{[]uint32{1}, nil, false},
157-
{[]uint32{1, 40}, nil, false},
158-
{[]uint32{0, 40}, nil, false},
159-
{[]uint32{3, 1}, nil, false},
160-
{[]uint32{2, math.MaxUint32 - 79}, nil, false},
156+
{[]uint64{}, nil, false},
157+
{[]uint64{1}, nil, false},
158+
{[]uint64{1, 40}, nil, false},
159+
{[]uint64{0, 40}, nil, false},
160+
{[]uint64{3, 1}, nil, false},
161+
{[]uint64{2, math.MaxUint64 - 79}, nil, false},
161162
}
162163

163164
func TestAppendObjectIdentifier(t *testing.T) {
@@ -188,14 +189,15 @@ func TestAppendObjectIdentifier(t *testing.T) {
188189
}
189190

190191
var appendRelativeOIDTests = []struct {
191-
value []uint32
192+
value []uint64
192193
encoded []byte
193194
}{
194-
{[]uint32{1}, []byte{1}},
195-
{[]uint32{1, 2, 3, 4, 0, 127, 128, 129}, []byte{1, 2, 3, 4, 0, 0x7f, 0x81, 0x00, 0x81, 0x01}},
196-
{[]uint32{math.MaxUint32}, []byte{0x8f, 0xff, 0xff, 0xff, 0x7f}},
195+
{[]uint64{1}, []byte{1}},
196+
{[]uint64{1, 2, 3, 4, 0, 127, 128, 129}, []byte{1, 2, 3, 4, 0, 0x7f, 0x81, 0x00, 0x81, 0x01}},
197+
{[]uint64{math.MaxUint32}, []byte{0x8f, 0xff, 0xff, 0xff, 0x7f}},
198+
{[]uint64{math.MaxUint64}, []byte{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}},
197199
// This is not actually valid, but the tokenizer will never try to serialize it.
198-
{[]uint32{}, []byte{}},
200+
{[]uint64{}, []byte{}},
199201
}
200202

201203
func TestAppendRelativeOID(t *testing.T) {

cmd/ascii2der/scanner.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,13 @@ loop:
420420

421421
if regexpOID.MatchString(symbol) {
422422
oidStr := strings.Split(symbol, ".")
423-
var oid []uint32
423+
var oid []uint64
424424
for _, s := range oidStr {
425-
u, err := strconv.ParseUint(s, 10, 32)
425+
u, err := strconv.ParseUint(s, 10, 64)
426426
if err != nil {
427427
return token{}, &parseError{start, err}
428428
}
429-
oid = append(oid, uint32(u))
429+
oid = append(oid, u)
430430
}
431431
der, ok := appendObjectIdentifier(nil, oid)
432432
if !ok {
@@ -437,13 +437,13 @@ loop:
437437

438438
if regexpRelativeOID.MatchString(symbol) {
439439
oidStr := strings.Split(symbol[1:], ".")
440-
var oid []uint32
440+
var oid []uint64
441441
for _, s := range oidStr {
442-
u, err := strconv.ParseUint(s, 10, 32)
442+
u, err := strconv.ParseUint(s, 10, 64)
443443
if err != nil {
444444
return token{}, &parseError{start, err}
445445
}
446-
oid = append(oid, uint32(u))
446+
oid = append(oid, u)
447447
}
448448
der := appendRelativeOID(nil, oid)
449449
return token{Kind: tokenBytes, Value: der, Pos: s.pos}, nil

cmd/ascii2der/scanner_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@ SEQUENCE[0]{}SEQUENCE}1}-1}1.2}#comment
4242
` + "`AABBCC`" + `
4343
4444
# Length modifiers
45-
indefinite long-form:2 adjust-length:10 adjust-length:-10`,
45+
indefinite long-form:2 adjust-length:10 adjust-length:-10
46+
47+
# Maximally large OIDs and relative-OIDs.
48+
# 2.(MaxUint64-81).MaxUint64
49+
2.18446744073709551535.18446744073709551615
50+
# .MaxUint64.MaxUint64
51+
.18446744073709551615.18446744073709551615`,
4652
[]token{
4753
{Kind: tokenBytes, Value: []byte{0x30}},
4854
{Kind: tokenBytes, Value: []byte{0x30}},
@@ -74,6 +80,8 @@ indefinite long-form:2 adjust-length:10 adjust-length:-10`,
7480
{Kind: tokenLongForm, Length: 2},
7581
{Kind: tokenAdjustLength, Length: 10},
7682
{Kind: tokenAdjustLength, Length: -10},
83+
{Kind: tokenBytes, Value: []byte{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}},
84+
{Kind: tokenBytes, Value: []byte{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}},
7785
{Kind: tokenEOF},
7886
},
7987
true,
@@ -93,8 +101,12 @@ indefinite long-form:2 adjust-length:10 adjust-length:-10`,
93101
{"999999999999999999999999999999999999999999999999999999999999999", nil, false},
94102
// Invalid OID.
95103
{"1.99.1", nil, false},
96-
// OID component overflow.
104+
// OID and relative-OID component overflow.
97105
{"1.1.99999999999999999999999999999999999999999999999999999999999999999", nil, false},
106+
{"1.1.18446744073709551616", nil, false},
107+
{"2.18446744073709551536", nil, false}, // 2^64 - 80
108+
{".99999999999999999999999999999999999999999999999999999999999999999", nil, false},
109+
{".18446744073709551616", nil, false},
98110
// Bad tag string.
99111
{"[THIS IS NOT A VALID TAG]", nil, false},
100112
{"[]", nil, false},

cmd/der2ascii/decoder.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414

1515
package main
1616

17-
import "github.com/google/der-ascii/internal"
17+
import (
18+
"math"
1819

19-
func parseBase128(bytes []byte) (ret uint32, rest []byte, ok bool) {
20+
"github.com/google/der-ascii/internal"
21+
)
22+
23+
func parseBase128(bytes []byte) (ret uint64, rest []byte, ok bool) {
2024
rest = bytes
2125
// There must be at least one byte, and the value must be minimally-encoded.
2226
if len(rest) == 0 || rest[0] == 0x80 {
@@ -28,7 +32,7 @@ func parseBase128(bytes []byte) (ret uint32, rest []byte, ok bool) {
2832
return
2933
}
3034
b := rest[0]
31-
ret = (ret << 7) | uint32(b&0x7f)
35+
ret = (ret << 7) | uint64(b&0x7f)
3236
rest = rest[1:]
3337
if b&0x80 == 0 {
3438
ok = true
@@ -37,7 +41,7 @@ func parseBase128(bytes []byte) (ret uint32, rest []byte, ok bool) {
3741
}
3842
}
3943

40-
func parseBase128Lax(bytes []byte) (ret uint32, lengthOverride int, rest []byte, ok bool) {
44+
func parseBase128Lax(bytes []byte) (ret uint64, lengthOverride int, rest []byte, ok bool) {
4145
rest = bytes
4246
// Tolerate non-minimal inputs.
4347
isMinimal := true
@@ -77,7 +81,7 @@ func parseTag(bytes []byte) (tag internal.Tag, rest []byte, ok bool) {
7781
}
7882

7983
n, lengthOverride, rest, base128Ok := parseBase128Lax(rest)
80-
if !base128Ok {
84+
if !base128Ok || n > math.MaxUint32 {
8185
// Parse error.
8286
rest = bytes
8387
return
@@ -86,7 +90,7 @@ func parseTag(bytes []byte) (tag internal.Tag, rest []byte, ok bool) {
8690
// Non-minimal encoding.
8791
lengthOverride = len(bytes) - len(rest) - 1
8892
}
89-
number = n
93+
number = uint32(n)
9094

9195
tag = internal.Tag{class, number, constructed, lengthOverride}
9296
ok = true
@@ -202,13 +206,13 @@ func decodeInteger(bytes []byte) (int64, bool) {
202206

203207
// decodeObjectIdentifier decodes bytes as the contents of a DER OBJECT IDENTIFIER. It
204208
// returns the value on success and false otherwise.
205-
func decodeObjectIdentifier(bytes []byte) (oid []uint32, ok bool) {
209+
func decodeObjectIdentifier(bytes []byte) (oid []uint64, ok bool) {
206210
// Reserve a space as the first component is split.
207-
oid = []uint32{0}
211+
oid = []uint64{0}
208212

209213
// Decode each component.
210214
for len(bytes) != 0 {
211-
var c uint32
215+
var c uint64
212216
c, bytes, ok = parseBase128(bytes)
213217
if !ok {
214218
return nil, false
@@ -235,10 +239,10 @@ func decodeObjectIdentifier(bytes []byte) (oid []uint32, ok bool) {
235239

236240
// decodeRelativeOID decodes bytes as the contents of a DER RELATIVE-OID. It
237241
// returns the value on success and false otherwise.
238-
func decodeRelativeOID(bytes []byte) (oid []uint32, ok bool) {
242+
func decodeRelativeOID(bytes []byte) (oid []uint64, ok bool) {
239243
// Decode each component.
240244
for len(bytes) != 0 {
241-
var c uint32
245+
var c uint64
242246
c, bytes, ok = parseBase128(bytes)
243247
if !ok {
244248
return nil, false

cmd/der2ascii/decoder_test.go

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"bytes"
1919
"math"
2020
"reflect"
21+
"slices"
2122
"testing"
2223

2324
"github.com/google/der-ascii/internal"
@@ -231,33 +232,23 @@ func TestDecodeInteger(t *testing.T) {
231232
}
232233
}
233234

234-
func eqUint32s(a, b []uint32) bool {
235-
if len(a) != len(b) {
236-
return false
237-
}
238-
for i := range a {
239-
if a[i] != b[i] {
240-
return false
241-
}
242-
}
243-
return true
244-
}
245-
246235
var decodeObjectIdentifierTests = []struct {
247236
in []byte
248-
out []uint32
237+
out []uint64
249238
ok bool
250239
}{
251-
{[]byte{1}, []uint32{0, 1}, true},
252-
{[]byte{42, 3, 4, 0x7f, 0x81, 0x00, 0x81, 0x01}, []uint32{1, 2, 3, 4, 127, 128, 129}, true},
253-
{[]byte{81}, []uint32{2, 1}, true},
254-
{[]byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, []uint32{2, math.MaxUint32 - 80}, true},
240+
{[]byte{1}, []uint64{0, 1}, true},
241+
{[]byte{42, 3, 4, 0x7f, 0x81, 0x00, 0x81, 0x01}, []uint64{1, 2, 3, 4, 127, 128, 129}, true},
242+
{[]byte{81}, []uint64{2, 1}, true},
243+
{[]byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, []uint64{2, math.MaxUint32 - 80}, true},
244+
{[]byte{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, []uint64{2, math.MaxUint64 - 80}, true},
255245
// Empty.
256246
{[]byte{}, nil, false},
257247
// Incomplete component.
258248
{[]byte{0xff}, nil, false},
259249
// Overflow.
260-
{[]byte{0x9f, 0xff, 0xff, 0xff, 0x7f}, nil, false},
250+
{[]byte{0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}, nil, false},
251+
{[]byte{0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, nil, false},
261252
}
262253

263254
func TestDecodeObjectIdentifier(t *testing.T) {
@@ -269,26 +260,28 @@ func TestDecodeObjectIdentifier(t *testing.T) {
269260
}
270261
} else if !ok {
271262
t.Errorf("%d. decodeObjectIdentifier(%v) unexpectedly failed.", i, tt.in)
272-
} else if !eqUint32s(out, tt.out) {
263+
} else if !slices.Equal(out, tt.out) {
273264
t.Errorf("%d. decodeObjectIdentifier(%v) = %v wanted %v.", i, tt.in, out, tt.out)
274265
}
275266
}
276267
}
277268

278269
var decodeRelativeOIDTests = []struct {
279270
in []byte
280-
out []uint32
271+
out []uint64
281272
ok bool
282273
}{
283-
{[]byte{1}, []uint32{1}, true},
284-
{[]byte{1, 2, 3, 4, 0x7f, 0x81, 0x00, 0x81, 0x01}, []uint32{1, 2, 3, 4, 127, 128, 129}, true},
285-
{[]byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, []uint32{math.MaxUint32}, true},
274+
{[]byte{1}, []uint64{1}, true},
275+
{[]byte{1, 2, 3, 4, 0x7f, 0x81, 0x00, 0x81, 0x01}, []uint64{1, 2, 3, 4, 127, 128, 129}, true},
276+
{[]byte{0x8f, 0xff, 0xff, 0xff, 0x7f}, []uint64{math.MaxUint32}, true},
277+
{[]byte{0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, []uint64{math.MaxUint64}, true},
286278
// Empty.
287279
{[]byte{}, nil, false},
288280
// Incomplete component.
289281
{[]byte{0xff}, nil, false},
290282
// Overflow.
291-
{[]byte{0x9f, 0xff, 0xff, 0xff, 0x7f}, nil, false},
283+
{[]byte{0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00}, nil, false},
284+
{[]byte{0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, nil, false},
292285
}
293286

294287
func TestDecodeRelativeOID(t *testing.T) {
@@ -300,7 +293,7 @@ func TestDecodeRelativeOID(t *testing.T) {
300293
}
301294
} else if !ok {
302295
t.Errorf("%d. decodeRelativeOID(%v) unexpectedly failed.", i, tt.in)
303-
} else if !eqUint32s(out, tt.out) {
296+
} else if !slices.Equal(out, tt.out) {
304297
t.Errorf("%d. decodeRelativeOID(%v) = %v wanted %v.", i, tt.in, out, tt.out)
305298
}
306299
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/google/der-ascii
22

3-
go 1.12
3+
go 1.27

0 commit comments

Comments
 (0)