@@ -264,36 +264,35 @@ func (s *String) ReadASN1Boolean(out *bool) bool {
264
264
return true
265
265
}
266
266
267
- var bigIntType = reflect .TypeOf ((* big .Int )(nil )).Elem ()
268
-
269
267
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
270
- // not point to an integer or to a big.Int, it panics. It reports whether the
271
- // read was successful.
268
+ // not point to an integer, to a big.Int, or to a []byte it panics. Only
269
+ // positive and zero values can be decoded into []byte, and they are returned as
270
+ // big-endian binary values that share memory with s. Positive values will have
271
+ // no leading zeroes, and zero will be returned as a single zero byte.
272
+ // ReadASN1Integer reports whether the read was successful.
272
273
func (s * String ) ReadASN1Integer (out interface {}) bool {
273
- if reflect .TypeOf (out ).Kind () != reflect .Ptr {
274
- panic ("out is not a pointer" )
275
- }
276
- switch reflect .ValueOf (out ).Elem ().Kind () {
277
- case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
274
+ switch out := out .(type ) {
275
+ case * int , * int8 , * int16 , * int32 , * int64 :
278
276
var i int64
279
277
if ! s .readASN1Int64 (& i ) || reflect .ValueOf (out ).Elem ().OverflowInt (i ) {
280
278
return false
281
279
}
282
280
reflect .ValueOf (out ).Elem ().SetInt (i )
283
281
return true
284
- case reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uint64 :
282
+ case * uint , * uint8 , * uint16 , * uint32 , * uint64 :
285
283
var u uint64
286
284
if ! s .readASN1Uint64 (& u ) || reflect .ValueOf (out ).Elem ().OverflowUint (u ) {
287
285
return false
288
286
}
289
287
reflect .ValueOf (out ).Elem ().SetUint (u )
290
288
return true
291
- case reflect .Struct :
292
- if reflect .TypeOf (out ).Elem () == bigIntType {
293
- return s .readASN1BigInt (out .(* big.Int ))
294
- }
289
+ case * big.Int :
290
+ return s .readASN1BigInt (out )
291
+ case * []byte :
292
+ return s .readASN1Bytes (out )
293
+ default :
294
+ panic ("out does not point to an integer type" )
295
295
}
296
- panic ("out does not point to an integer type" )
297
296
}
298
297
299
298
func checkASN1Integer (bytes []byte ) bool {
@@ -333,6 +332,21 @@ func (s *String) readASN1BigInt(out *big.Int) bool {
333
332
return true
334
333
}
335
334
335
+ func (s * String ) readASN1Bytes (out * []byte ) bool {
336
+ var bytes String
337
+ if ! s .ReadASN1 (& bytes , asn1 .INTEGER ) || ! checkASN1Integer (bytes ) {
338
+ return false
339
+ }
340
+ if bytes [0 ]& 0x80 == 0x80 {
341
+ return false
342
+ }
343
+ for len (bytes ) > 1 && bytes [0 ] == 0 {
344
+ bytes = bytes [1 :]
345
+ }
346
+ * out = bytes
347
+ return true
348
+ }
349
+
336
350
func (s * String ) readASN1Int64 (out * int64 ) bool {
337
351
var bytes String
338
352
if ! s .ReadASN1 (& bytes , asn1 .INTEGER ) || ! checkASN1Integer (bytes ) || ! asn1Signed (out , bytes ) {
@@ -654,34 +668,27 @@ func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
654
668
return s .ReadASN1 (& unused , tag )
655
669
}
656
670
657
- // ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
658
- // explicitly tagged with tag into out and advances. If no element with a
659
- // matching tag is present, it writes defaultValue into out instead. If out
660
- // does not point to an integer or to a big.Int, it panics. It reports
661
- // whether the read was successful.
671
+ // ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
672
+ // tagged with tag into out and advances. If no element with a matching tag is
673
+ // present, it writes defaultValue into out instead. Otherwise, it behaves like
674
+ // ReadASN1Integer.
662
675
func (s * String ) ReadOptionalASN1Integer (out interface {}, tag asn1.Tag , defaultValue interface {}) bool {
663
- if reflect .TypeOf (out ).Kind () != reflect .Ptr {
664
- panic ("out is not a pointer" )
665
- }
666
676
var present bool
667
677
var i String
668
678
if ! s .ReadOptionalASN1 (& i , & present , tag ) {
669
679
return false
670
680
}
671
681
if ! present {
672
- switch reflect . ValueOf ( out ). Elem (). Kind ( ) {
673
- case reflect . Int , reflect . Int8 , reflect . Int16 , reflect . Int32 , reflect . Int64 ,
674
- reflect . Uint , reflect . Uint8 , reflect . Uint16 , reflect . Uint32 , reflect . Uint64 :
682
+ switch out .( type ) {
683
+ case * int , * int8 , * int16 , * int32 , * int64 ,
684
+ * uint , * uint8 , * uint16 , * uint32 , * uint64 , * [] byte :
675
685
reflect .ValueOf (out ).Elem ().Set (reflect .ValueOf (defaultValue ))
676
- case reflect .Struct :
677
- if reflect .TypeOf (out ).Elem () != bigIntType {
678
- panic ("invalid integer type" )
679
- }
680
- if reflect .TypeOf (defaultValue ).Kind () != reflect .Ptr ||
681
- reflect .TypeOf (defaultValue ).Elem () != bigIntType {
686
+ case * big.Int :
687
+ if defaultValue , ok := defaultValue .(* big.Int ); ok {
688
+ out .(* big.Int ).Set (defaultValue )
689
+ } else {
682
690
panic ("out points to big.Int, but defaultValue does not" )
683
691
}
684
- out .(* big.Int ).Set (defaultValue .(* big.Int ))
685
692
default :
686
693
panic ("invalid integer type" )
687
694
}
0 commit comments