]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: don't include empty additional primes in PKCS#1 private key.
authorAdam Langley <agl@golang.org>
Mon, 5 Mar 2012 17:04:18 +0000 (12:04 -0500)
committerAdam Langley <agl@golang.org>
Mon, 5 Mar 2012 17:04:18 +0000 (12:04 -0500)
asn1 didn't have an omitempty tag, so the list of additional primes in
an RSA private key was serialised as an empty SEQUENCE, even for
version 1 structures. This tripped up external code that didn't handle
v2.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5729062

src/pkg/crypto/x509/pkcs1.go
src/pkg/encoding/asn1/asn1_test.go
src/pkg/encoding/asn1/common.go
src/pkg/encoding/asn1/marshal.go
src/pkg/encoding/asn1/marshal_test.go

index 3aaa8c5832a26aac09c6d353efa7868269d7557b..873d3966eb55cf51488d2e14ec6013d17ccda157 100644 (file)
@@ -24,7 +24,7 @@ type pkcs1PrivateKey struct {
        Dq   *big.Int `asn1:"optional"`
        Qinv *big.Int `asn1:"optional"`
 
-       AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional"`
+       AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"`
 }
 
 type pkcs1AdditionalRSAPrime struct {
index 92c9eb62d2c6b373bbdb94e233cf07254e7abc6d..93803f43532938bf27894d714651646b04236498 100644 (file)
@@ -321,7 +321,7 @@ var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParame
        {"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, false}},
+       {"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false, false}},
        {"set", fieldParameters{set: true}},
 }
 
index f7cb3acbb8693b919389caa74ba66565264c8b3b..03856bc55c5ab41e3e95a0686c5ff314d0e160e6 100644 (file)
@@ -75,6 +75,7 @@ type fieldParameters struct {
        tag          *int   // the EXPLICIT or IMPLICIT tag (maybe nil).
        stringType   int    // the string tag to use when marshaling.
        set          bool   // true iff this should be encoded as a SET
+       omitEmpty    bool   // true iff this should be omitted if empty when marshaling.
 
        // Invariants:
        //   if explicit is set, tag is non-nil.
@@ -116,6 +117,8 @@ func parseFieldParameters(str string) (ret fieldParameters) {
                        if ret.tag == nil {
                                ret.tag = new(int)
                        }
+               case part == "omitempty":
+                       ret.omitEmpty = true
                }
        }
        return
index 774bee74baacbd67ce8eff74523afdd5fca41c6a..163bca575de1c0e6dca78f3883cc9ff6119e7f72 100644 (file)
@@ -463,6 +463,10 @@ func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters)
                return marshalField(out, v.Elem(), params)
        }
 
+       if v.Kind() == reflect.Slice && v.Len() == 0 && params.omitEmpty {
+               return
+       }
+
        if params.optional && reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) {
                return
        }
index a7447f978127c3362c1cf4691f63d6a63abf84d6..f43bcae681a503bdf674ce971a2f9c590baa25ff 100644 (file)
@@ -54,6 +54,10 @@ type optionalRawValueTest struct {
        A RawValue `asn1:"optional"`
 }
 
+type omitEmptyTest struct {
+       A []string `asn1:"omitempty"`
+}
+
 type testSET []int
 
 var PST = time.FixedZone("PST", -8*60*60)
@@ -116,6 +120,8 @@ var marshalTests = []marshalTest{
        {rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"},
        {RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"},
        {testSET([]int{10}), "310302010a"},
+       {omitEmptyTest{[]string{}}, "3000"},
+       {omitEmptyTest{[]string{"1"}}, "30053003130131"},
 }
 
 func TestMarshal(t *testing.T) {