aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/asn1
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/asn1')
-rw-r--r--libgo/go/asn1/asn1.go84
-rw-r--r--libgo/go/asn1/asn1_test.go14
-rw-r--r--libgo/go/asn1/common.go12
-rw-r--r--libgo/go/asn1/marshal.go64
-rw-r--r--libgo/go/asn1/marshal_test.go24
5 files changed, 116 insertions, 82 deletions
diff --git a/libgo/go/asn1/asn1.go b/libgo/go/asn1/asn1.go
index c531451..5f470ae 100644
--- a/libgo/go/asn1/asn1.go
+++ b/libgo/go/asn1/asn1.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The asn1 package implements parsing of DER-encoded ASN.1 data structures,
+// Package asn1 implements parsing of DER-encoded ASN.1 data structures,
// as defined in ITU-T Rec X.690.
//
// See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
@@ -373,7 +373,7 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
// a number of ASN.1 values from the given byte array and returns them as a
// slice of Go values of the given type.
-func parseSequenceOf(bytes []byte, sliceType *reflect.SliceType, elemType reflect.Type) (ret *reflect.SliceValue, err os.Error) {
+func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err os.Error) {
expectedTag, compoundType, ok := getUniversalType(elemType)
if !ok {
err = StructuralError{"unknown Go type for slice"}
@@ -409,7 +409,7 @@ func parseSequenceOf(bytes []byte, sliceType *reflect.SliceType, elemType reflec
params := fieldParameters{}
offset := 0
for i := 0; i < numElements; i++ {
- offset, err = parseField(ret.Elem(i), bytes, offset, params)
+ offset, err = parseField(ret.Index(i), bytes, offset, params)
if err != nil {
return
}
@@ -418,13 +418,13 @@ func parseSequenceOf(bytes []byte, sliceType *reflect.SliceType, elemType reflec
}
var (
- bitStringType = reflect.Typeof(BitString{})
- objectIdentifierType = reflect.Typeof(ObjectIdentifier{})
- enumeratedType = reflect.Typeof(Enumerated(0))
- flagType = reflect.Typeof(Flag(false))
- timeType = reflect.Typeof(&time.Time{})
- rawValueType = reflect.Typeof(RawValue{})
- rawContentsType = reflect.Typeof(RawContent(nil))
+ bitStringType = reflect.TypeOf(BitString{})
+ objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
+ enumeratedType = reflect.TypeOf(Enumerated(0))
+ flagType = reflect.TypeOf(Flag(false))
+ timeType = reflect.TypeOf(&time.Time{})
+ rawValueType = reflect.TypeOf(RawValue{})
+ rawContentsType = reflect.TypeOf(RawContent(nil))
)
// invalidLength returns true iff offset + length > sliceLength, or if the
@@ -461,13 +461,12 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
}
result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]}
offset += t.length
- v.(*reflect.StructValue).Set(reflect.NewValue(result).(*reflect.StructValue))
+ v.Set(reflect.ValueOf(result))
return
}
// Deal with the ANY type.
- if ifaceType, ok := fieldType.(*reflect.InterfaceType); ok && ifaceType.NumMethod() == 0 {
- ifaceValue := v.(*reflect.InterfaceValue)
+ if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
var t tagAndLength
t, offset, err = parseTagAndLength(bytes, offset)
if err != nil {
@@ -506,7 +505,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
return
}
if result != nil {
- ifaceValue.Set(reflect.NewValue(result))
+ v.Set(reflect.ValueOf(result))
}
return
}
@@ -536,9 +535,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
err = StructuralError{"Zero length explicit tag was not an asn1.Flag"}
return
}
-
- flagValue := v.(*reflect.BoolValue)
- flagValue.Set(true)
+ v.SetBool(true)
return
}
} else {
@@ -606,23 +603,20 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
switch fieldType {
case objectIdentifierType:
newSlice, err1 := parseObjectIdentifier(innerBytes)
- sliceValue := v.(*reflect.SliceValue)
- sliceValue.Set(reflect.MakeSlice(sliceValue.Type().(*reflect.SliceType), len(newSlice), len(newSlice)))
+ v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
if err1 == nil {
- reflect.Copy(sliceValue, reflect.NewValue(newSlice).(reflect.ArrayOrSliceValue))
+ reflect.Copy(v, reflect.ValueOf(newSlice))
}
err = err1
return
case bitStringType:
- structValue := v.(*reflect.StructValue)
bs, err1 := parseBitString(innerBytes)
if err1 == nil {
- structValue.Set(reflect.NewValue(bs).(*reflect.StructValue))
+ v.Set(reflect.ValueOf(bs))
}
err = err1
return
case timeType:
- ptrValue := v.(*reflect.PtrValue)
var time *time.Time
var err1 os.Error
if universalTag == tagUTCTime {
@@ -631,55 +625,53 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
time, err1 = parseGeneralizedTime(innerBytes)
}
if err1 == nil {
- ptrValue.Set(reflect.NewValue(time).(*reflect.PtrValue))
+ v.Set(reflect.ValueOf(time))
}
err = err1
return
case enumeratedType:
parsedInt, err1 := parseInt(innerBytes)
- enumValue := v.(*reflect.IntValue)
if err1 == nil {
- enumValue.Set(int64(parsedInt))
+ v.SetInt(int64(parsedInt))
}
err = err1
return
case flagType:
- flagValue := v.(*reflect.BoolValue)
- flagValue.Set(true)
+ v.SetBool(true)
return
}
- switch val := v.(type) {
- case *reflect.BoolValue:
+ switch val := v; val.Kind() {
+ case reflect.Bool:
parsedBool, err1 := parseBool(innerBytes)
if err1 == nil {
- val.Set(parsedBool)
+ val.SetBool(parsedBool)
}
err = err1
return
- case *reflect.IntValue:
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch val.Type().Kind() {
case reflect.Int:
parsedInt, err1 := parseInt(innerBytes)
if err1 == nil {
- val.Set(int64(parsedInt))
+ val.SetInt(int64(parsedInt))
}
err = err1
return
case reflect.Int64:
parsedInt, err1 := parseInt64(innerBytes)
if err1 == nil {
- val.Set(parsedInt)
+ val.SetInt(parsedInt)
}
err = err1
return
}
- case *reflect.StructValue:
- structType := fieldType.(*reflect.StructType)
+ case reflect.Struct:
+ structType := fieldType
if structType.NumField() > 0 &&
structType.Field(0).Type == rawContentsType {
bytes := bytes[initOffset:offset]
- val.Field(0).SetValue(reflect.NewValue(RawContent(bytes)))
+ val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
}
innerOffset := 0
@@ -697,11 +689,11 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
// adding elements to the end has been used in X.509 as the
// version numbers have increased.
return
- case *reflect.SliceValue:
- sliceType := fieldType.(*reflect.SliceType)
+ case reflect.Slice:
+ sliceType := fieldType
if sliceType.Elem().Kind() == reflect.Uint8 {
val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
- reflect.Copy(val, reflect.NewValue(innerBytes).(reflect.ArrayOrSliceValue))
+ reflect.Copy(val, reflect.ValueOf(innerBytes))
return
}
newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
@@ -710,7 +702,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
}
err = err1
return
- case *reflect.StringValue:
+ case reflect.String:
var v string
switch universalTag {
case tagPrintableString:
@@ -729,7 +721,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
}
if err == nil {
- val.Set(v)
+ val.SetString(v)
}
return
}
@@ -748,9 +740,9 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
if params.defaultValue == nil {
return
}
- switch val := v.(type) {
- case *reflect.IntValue:
- val.Set(*params.defaultValue)
+ switch val := v; val.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ val.SetInt(*params.defaultValue)
}
return
}
@@ -806,7 +798,7 @@ func Unmarshal(b []byte, val interface{}) (rest []byte, err os.Error) {
// UnmarshalWithParams allows field parameters to be specified for the
// top-level element. The form of the params is the same as the field tags.
func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err os.Error) {
- v := reflect.NewValue(val).(*reflect.PtrValue).Elem()
+ v := reflect.ValueOf(val).Elem()
offset, err := parseField(v, b, 0, parseFieldParameters(params))
if err != nil {
return nil, err
diff --git a/libgo/go/asn1/asn1_test.go b/libgo/go/asn1/asn1_test.go
index b776765..78f5628 100644
--- a/libgo/go/asn1/asn1_test.go
+++ b/libgo/go/asn1/asn1_test.go
@@ -267,11 +267,6 @@ func TestParseFieldParameters(t *testing.T) {
}
}
-type unmarshalTest struct {
- in []byte
- out interface{}
-}
-
type TestObjectIdentifierStruct struct {
OID ObjectIdentifier
}
@@ -290,7 +285,10 @@ type TestElementsAfterString struct {
A, B int
}
-var unmarshalTestData []unmarshalTest = []unmarshalTest{
+var unmarshalTestData = []struct {
+ in []byte
+ out interface{}
+}{
{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
@@ -309,9 +307,7 @@ var unmarshalTestData []unmarshalTest = []unmarshalTest{
func TestUnmarshal(t *testing.T) {
for i, test := range unmarshalTestData {
- pv := reflect.MakeZero(reflect.NewValue(test.out).Type())
- zv := reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem())
- pv.(*reflect.PtrValue).PointTo(zv)
+ pv := reflect.New(reflect.TypeOf(test.out).Elem())
val := pv.Interface()
_, err := Unmarshal(test.in, val)
if err != nil {
diff --git a/libgo/go/asn1/common.go b/libgo/go/asn1/common.go
index f2254a4..1589877 100644
--- a/libgo/go/asn1/common.go
+++ b/libgo/go/asn1/common.go
@@ -133,14 +133,14 @@ func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) {
case enumeratedType:
return tagEnum, false, true
}
- switch t := t.(type) {
- case *reflect.BoolType:
+ switch t.Kind() {
+ case reflect.Bool:
return tagBoolean, false, true
- case *reflect.IntType:
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return tagInteger, false, true
- case *reflect.StructType:
+ case reflect.Struct:
return tagSequence, true, true
- case *reflect.SliceType:
+ case reflect.Slice:
if t.Elem().Kind() == reflect.Uint8 {
return tagOctetString, false, true
}
@@ -148,7 +148,7 @@ func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) {
return tagSet, true, true
}
return tagSequence, true, true
- case *reflect.StringType:
+ case reflect.String:
return tagPrintableString, false, true
}
return 0, false, false
diff --git a/libgo/go/asn1/marshal.go b/libgo/go/asn1/marshal.go
index 57b8f20..a3e1145 100644
--- a/libgo/go/asn1/marshal.go
+++ b/libgo/go/asn1/marshal.go
@@ -125,6 +125,28 @@ func int64Length(i int64) (numBytes int) {
return
}
+func marshalLength(out *forkableWriter, i int) (err os.Error) {
+ n := lengthLength(i)
+
+ for ; n > 0; n-- {
+ err = out.WriteByte(byte(i >> uint((n-1)*8)))
+ if err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+func lengthLength(i int) (numBytes int) {
+ numBytes = 1
+ for i > 255 {
+ numBytes++
+ i >>= 8
+ }
+ return
+}
+
func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err os.Error) {
b := uint8(t.class) << 6
if t.isCompound {
@@ -149,12 +171,12 @@ func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err os.Error) {
}
if t.length >= 128 {
- l := int64Length(int64(t.length))
+ l := lengthLength(t.length)
err = out.WriteByte(0x80 | byte(l))
if err != nil {
return
}
- err = marshalInt64(out, int64(t.length))
+ err = marshalLength(out, t.length)
if err != nil {
return
}
@@ -314,28 +336,28 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter
return marshalObjectIdentifier(out, value.Interface().(ObjectIdentifier))
}
- switch v := value.(type) {
- case *reflect.BoolValue:
- if v.Get() {
+ switch v := value; v.Kind() {
+ case reflect.Bool:
+ if v.Bool() {
return out.WriteByte(255)
} else {
return out.WriteByte(0)
}
- case *reflect.IntValue:
- return marshalInt64(out, int64(v.Get()))
- case *reflect.StructValue:
- t := v.Type().(*reflect.StructType)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return marshalInt64(out, int64(v.Int()))
+ case reflect.Struct:
+ t := v.Type()
startingField := 0
// If the first element of the structure is a non-empty
// RawContents, then we don't bother serialising the rest.
if t.NumField() > 0 && t.Field(0).Type == rawContentsType {
- s := v.Field(0).(*reflect.SliceValue)
+ s := v.Field(0)
if s.Len() > 0 {
bytes := make([]byte, s.Len())
for i := 0; i < s.Len(); i++ {
- bytes[i] = uint8(s.Elem(i).(*reflect.UintValue).Get())
+ bytes[i] = uint8(s.Index(i).Uint())
}
/* The RawContents will contain the tag and
* length fields but we'll also be writing
@@ -357,12 +379,12 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter
}
}
return
- case *reflect.SliceValue:
- sliceType := v.Type().(*reflect.SliceType)
+ case reflect.Slice:
+ sliceType := v.Type()
if sliceType.Elem().Kind() == reflect.Uint8 {
bytes := make([]byte, v.Len())
for i := 0; i < v.Len(); i++ {
- bytes[i] = uint8(v.Elem(i).(*reflect.UintValue).Get())
+ bytes[i] = uint8(v.Index(i).Uint())
}
_, err = out.Write(bytes)
return
@@ -372,17 +394,17 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter
for i := 0; i < v.Len(); i++ {
var pre *forkableWriter
pre, out = out.fork()
- err = marshalField(pre, v.Elem(i), params)
+ err = marshalField(pre, v.Index(i), params)
if err != nil {
return
}
}
return
- case *reflect.StringValue:
+ case reflect.String:
if params.stringType == tagIA5String {
- return marshalIA5String(out, v.Get())
+ return marshalIA5String(out, v.String())
} else {
- return marshalPrintableString(out, v.Get())
+ return marshalPrintableString(out, v.String())
}
return
}
@@ -392,7 +414,7 @@ func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameter
func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err os.Error) {
// If the field is an interface{} then recurse into it.
- if v, ok := v.(*reflect.InterfaceValue); ok && v.Type().(*reflect.InterfaceType).NumMethod() == 0 {
+ if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 {
return marshalField(out, v.Elem(), params)
}
@@ -406,7 +428,7 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters)
return
}
- if params.optional && reflect.DeepEqual(v.Interface(), reflect.MakeZero(v.Type()).Interface()) {
+ if params.optional && reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) {
return
}
@@ -471,7 +493,7 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters)
// Marshal returns the ASN.1 encoding of val.
func Marshal(val interface{}) ([]byte, os.Error) {
var out bytes.Buffer
- v := reflect.NewValue(val)
+ v := reflect.ValueOf(val)
f := newForkableWriter()
err := marshalField(f, v, fieldParameters{})
if err != nil {
diff --git a/libgo/go/asn1/marshal_test.go b/libgo/go/asn1/marshal_test.go
index 85eafc9..cd165d2 100644
--- a/libgo/go/asn1/marshal_test.go
+++ b/libgo/go/asn1/marshal_test.go
@@ -77,6 +77,30 @@ var marshalTests = []marshalTest{
{ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"},
{ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"},
{"test", "130474657374"},
+ {
+ "" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 127 times 'x'
+ "137f" +
+ "7878787878787878787878787878787878787878787878787878787878787878" +
+ "7878787878787878787878787878787878787878787878787878787878787878" +
+ "7878787878787878787878787878787878787878787878787878787878787878" +
+ "78787878787878787878787878787878787878787878787878787878787878",
+ },
+ {
+ "" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 128 times 'x'
+ "138180" +
+ "7878787878787878787878787878787878787878787878787878787878787878" +
+ "7878787878787878787878787878787878787878787878787878787878787878" +
+ "7878787878787878787878787878787878787878787878787878787878787878" +
+ "7878787878787878787878787878787878787878787878787878787878787878",
+ },
{ia5StringTest{"test"}, "3006160474657374"},
{printableStringTest{"test"}, "3006130474657374"},
{printableStringTest{"test*"}, "30071305746573742a"},