]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/asn1: allow Marshaling and Unmarshaling private tag class
authorHAMANO Tsukasa <hamano@osstech.co.jp>
Wed, 2 May 2018 05:54:12 +0000 (05:54 +0000)
committerFilippo Valsorda <filippo@golang.org>
Thu, 17 May 2018 18:06:38 +0000 (18:06 +0000)
ASN.1 has an private class, but current implementation does not support it.

Change-Id: I3ebf07a048831869572f75223cb17d4c115caef7
GitHub-Last-Rev: b3c69ad091218acfa0bb0e34111cceae69586eb9
GitHub-Pull-Request: golang/go#25195
Reviewed-on: https://go-review.googlesource.com/110561
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
src/encoding/asn1/asn1.go
src/encoding/asn1/asn1_test.go
src/encoding/asn1/common.go
src/encoding/asn1/marshal.go
src/encoding/asn1/marshal_test.go

index 26868a3bd7f79a0aa1e627e1624e7341c070a06d..ae382ee6bf52e08906d21f1d38fcf8c9cc941bd3 100644 (file)
@@ -793,6 +793,12 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
                matchAnyClassAndTag = false
        }
 
+       if !params.explicit && params.private && params.tag != nil {
+               expectedClass = ClassPrivate
+               expectedTag = *params.tag
+               matchAnyClassAndTag = false
+       }
+
        // We have unwrapped any explicit tagging at this point.
        if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
                (!matchAny && t.isCompound != compoundType) {
@@ -1028,6 +1034,7 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
 // The following tags on struct fields have special meaning to Unmarshal:
 //
 //     application specifies that an APPLICATION tag is used
+//     private     specifies that a PRIVATE tag is used
 //     default:x   sets the default value for optional integer fields (only used if optional is also present)
 //     explicit    specifies that an additional, explicit tag wraps the implicit one
 //     optional    marks the field as ASN.1 OPTIONAL
index 5e67dc5ee4dddac67cc3540e76c218db7758dc92..185349773f5937edf388600c1ab8cf4f4fd77d05 100644 (file)
@@ -428,11 +428,12 @@ var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParame
        {"optional", fieldParameters{optional: true}},
        {"explicit", fieldParameters{explicit: true, tag: new(int)}},
        {"application", fieldParameters{application: true, tag: new(int)}},
+       {"private", fieldParameters{private: true, tag: new(int)}},
        {"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
        {"default:42", fieldParameters{defaultValue: newInt64(42)}},
        {"tag:17", fieldParameters{tag: newInt(17)}},
        {"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
-       {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, 0, false, false}},
+       {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{optional: true, explicit: true, application: false, defaultValue: newInt64(42), tag: newInt(17), stringType: 0, timeType: 0, set: false, omitEmpty: false}},
        {"set", fieldParameters{set: true}},
 }
 
@@ -1079,6 +1080,7 @@ func TestTaggedRawValue(t *testing.T) {
                {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
                {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
                {false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
+               {false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}},
        }
 
        for i, test := range tests {
index a6589a521af4610f810c663c1aa5cfef7b73cf04..255d1ebfa8990eff81c997a098c1c6d849c64e44 100644 (file)
@@ -75,6 +75,7 @@ type fieldParameters struct {
        optional     bool   // true iff the field is OPTIONAL
        explicit     bool   // true iff an EXPLICIT tag is in use.
        application  bool   // true iff an APPLICATION tag is in use.
+       private      bool   // true iff a PRIVATE tag is in use.
        defaultValue *int64 // a default value for INTEGER typed fields (maybe nil).
        tag          *int   // the EXPLICIT or IMPLICIT tag (maybe nil).
        stringType   int    // the string tag to use when marshaling.
@@ -130,6 +131,11 @@ func parseFieldParameters(str string) (ret fieldParameters) {
                        if ret.tag == nil {
                                ret.tag = new(int)
                        }
+               case part == "private":
+                       ret.private = true
+                       if ret.tag == nil {
+                               ret.tag = new(int)
+                       }
                case part == "omitempty":
                        ret.omitEmpty = true
                }
index 3e85651ffd0027484ca15a250c1397a5eb74b095..c9ae2ca33e5244130f0d8417033ed605c45e5fa2 100644 (file)
@@ -631,6 +631,8 @@ func makeField(v reflect.Value, params fieldParameters) (e encoder, err error) {
        if params.tag != nil {
                if params.application {
                        class = ClassApplication
+               } else if params.private {
+                       class = ClassPrivate
                } else {
                        class = ClassContextSpecific
                }
index 4f755a1f39f6b49be0407aa34a5e1662aa97064f..f20ccdc8e98c56cc32b3787331fc7ec356d2c397 100644 (file)
@@ -80,6 +80,13 @@ type applicationTest struct {
        B int `asn1:"application,tag:1,explicit"`
 }
 
+type privateTest struct {
+       A int `asn1:"private,tag:0"`
+       B int `asn1:"private,tag:1,explicit"`
+       C int `asn1:"private,tag:31"`  // tag size should be 2 octet
+       D int `asn1:"private,tag:128"` // tag size should be 3 octet
+}
+
 type numericStringTest struct {
        A string `asn1:"numeric"`
 }
@@ -169,6 +176,7 @@ var marshalTests = []marshalTest{
        {defaultTest{1}, "3000"},
        {defaultTest{2}, "3003020102"},
        {applicationTest{1, 2}, "30084001016103020102"},
+       {privateTest{1, 2, 3, 4}, "3011c00101e103020102df1f0103df81000104"},
        {numericStringTest{"1 9"}, "30051203312039"},
 }
 
@@ -195,6 +203,7 @@ type marshalWithParamsTest struct {
 var marshalWithParamsTests = []marshalWithParamsTest{
        {intStruct{10}, "set", "310302010a"},
        {intStruct{10}, "application", "600302010a"},
+       {intStruct{10}, "private", "e00302010a"},
 }
 
 func TestMarshalWithParams(t *testing.T) {