Skip to content

Commit 12debf4

Browse files
committed
crypto/x509/pkix: print non-standard parsed Names at the end
This doesn't change how ExtraNames are printed, so as not to cause unnecessary churn of current outputs. Switched the ExtraNames check to a nil check as we are checking for just-parsed values. Fixes #39924 Fixes #39873 Change-Id: Ifa07cfc1a057d73643710a774ef8a154222db187 Reviewed-on: https://go-review.googlesource.com/c/go/+/240543 Run-TryBot: Filippo Valsorda <[email protected]> Reviewed-by: Katie Hockman <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 6ba3e6a commit 12debf4

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

doc/go1.15.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,11 +553,11 @@ <h3 id="minor_library_changes">Minor changes to the library</h3>
553553

554554
<dl id="crypto/x509/pkix"><dt><a href="/pkg/crypto/x509/pkix/">crypto/x509/pkix</a></dt>
555555
<dd>
556-
<p><!-- CL 229864 -->
556+
<p><!-- CL 229864, CL 240543 -->
557557
<a href="/pkg/crypto/x509/pkix/#Name.String"><code>Name.String</code></a>
558558
now prints non-standard attributes from
559559
<a href="/pkg/crypto/x509/pkix/#Name.Names"><code>Names</code></a> if
560-
<a href="/pkg/crypto/x509/pkix/#Name.ExtraNames"><code>ExtraNames</code></a> is empty.
560+
<a href="/pkg/crypto/x509/pkix/#Name.ExtraNames"><code>ExtraNames</code></a> is nil.
561561
</p>
562562
</dd>
563563
</dl><!-- crypto/x509/pkix -->

src/crypto/x509/pkix/pkix.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,20 +247,26 @@ func (n Name) ToRDNSequence() (ret RDNSequence) {
247247
// String returns the string form of n, roughly following
248248
// the RFC 2253 Distinguished Names syntax.
249249
func (n Name) String() string {
250-
if len(n.ExtraNames) == 0 {
250+
var rdns RDNSequence
251+
// If there are no ExtraNames, surface the parsed value (all entries in
252+
// Names) instead.
253+
if n.ExtraNames == nil {
251254
for _, atv := range n.Names {
252255
t := atv.Type
253256
if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
254257
switch t[3] {
255258
case 3, 5, 6, 7, 8, 9, 10, 11, 17:
256-
// These attributes are already parsed into named fields.
259+
// These attributes were already parsed into named fields.
257260
continue
258261
}
259262
}
260-
n.ExtraNames = append(n.ExtraNames, atv)
263+
// Place non-standard parsed values at the beginning of the sequence
264+
// so they will be at the end of the string. See Issue 39924.
265+
rdns = append(rdns, []AttributeTypeAndValue{atv})
261266
}
262267
}
263-
return n.ToRDNSequence().String()
268+
rdns = append(rdns, n.ToRDNSequence()...)
269+
return rdns.String()
264270
}
265271

266272
// oidInAttributeTypeAndValue reports whether a type with the given OID exists

src/crypto/x509/x509_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,10 +2076,31 @@ func TestPKIXNameString(t *testing.T) {
20762076
t.Fatal(err)
20772077
}
20782078

2079+
// Check that parsed non-standard attributes are printed.
2080+
rdns := pkix.Name{
2081+
Locality: []string{"Gophertown"},
2082+
ExtraNames: []pkix.AttributeTypeAndValue{
2083+
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
2084+
}.ToRDNSequence()
2085+
nn := pkix.Name{}
2086+
nn.FillFromRDNSequence(&rdns)
2087+
2088+
// Check that zero-length non-nil ExtraNames hide Names.
2089+
extra := []pkix.AttributeTypeAndValue{
2090+
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "backing array"}}
2091+
extraNotNil := pkix.Name{
2092+
Locality: []string{"Gophertown"},
2093+
ExtraNames: extra[:0],
2094+
Names: []pkix.AttributeTypeAndValue{
2095+
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
2096+
}
2097+
20792098
tests := []struct {
20802099
dn pkix.Name
20812100
want string
20822101
}{
2102+
{nn, "L=Gophertown,1.2.3.4.5=#130a676f6c616e672e6f7267"},
2103+
{extraNotNil, "L=Gophertown"},
20832104
{pkix.Name{
20842105
CommonName: "Steve Kille",
20852106
Organization: []string{"Isode Limited"},
@@ -2108,13 +2129,31 @@ func TestPKIXNameString(t *testing.T) {
21082129
ExtraNames: []pkix.AttributeTypeAndValue{
21092130
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
21102131
}, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"},
2132+
// If there are no ExtraNames, the Names are printed instead.
2133+
{pkix.Name{
2134+
Locality: []string{"Gophertown"},
2135+
Names: []pkix.AttributeTypeAndValue{
2136+
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
2137+
}, "L=Gophertown,1.2.3.4.5=#130a676f6c616e672e6f7267"},
2138+
// If there are both, print only the ExtraNames.
2139+
{pkix.Name{
2140+
Locality: []string{"Gophertown"},
2141+
ExtraNames: []pkix.AttributeTypeAndValue{
2142+
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 5}), Value: "golang.org"}},
2143+
Names: []pkix.AttributeTypeAndValue{
2144+
{Type: asn1.ObjectIdentifier([]int{1, 2, 3, 4, 6}), Value: "example.com"}},
2145+
}, "1.2.3.4.5=#130a676f6c616e672e6f7267,L=Gophertown"},
21112146
}
21122147

21132148
for i, test := range tests {
21142149
if got := test.dn.String(); got != test.want {
21152150
t.Errorf("#%d: String() = \n%s\n, want \n%s", i, got, test.want)
21162151
}
21172152
}
2153+
2154+
if extra[0].Value != "backing array" {
2155+
t.Errorf("the backing array of an empty ExtraNames got modified by String")
2156+
}
21182157
}
21192158

21202159
func TestRDNSequenceString(t *testing.T) {

0 commit comments

Comments
 (0)