Skip to content

Commit 202c43b

Browse files
committed
crypto/x509/pkix: improve docs and Name.String()
Previously, non-standard attributes in Name.Names were being omitted when printed using Name.String(). Now, any non-standard attributes that would not already be printed in Name.String() are being added temporarily to Name.ExtraNames to be printed. Fixes #33094 Fixes #23069 Change-Id: Id9829c20968e16db7194549f69c0eb5985044944 Reviewed-on: https://go-review.googlesource.com/c/go/+/229864 Run-TryBot: Katie Hockman <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
1 parent 3dc4d37 commit 202c43b

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

src/crypto/x509/pkix/pkix.go

+40-4
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,30 @@ type Extension struct {
117117
}
118118

119119
// Name represents an X.509 distinguished name. This only includes the common
120-
// elements of a DN. When parsing, all elements are stored in Names and
121-
// non-standard elements can be extracted from there. When marshaling, elements
122-
// in ExtraNames are appended and override other values with the same OID.
120+
// elements of a DN. Note that Name is only an approximation of the X.509
121+
// structure. If an accurate representation is needed, asn1.Unmarshal the raw
122+
// subject or issuer as an RDNSequence.
123123
type Name struct {
124124
Country, Organization, OrganizationalUnit []string
125125
Locality, Province []string
126126
StreetAddress, PostalCode []string
127127
SerialNumber, CommonName string
128128

129-
Names []AttributeTypeAndValue
129+
// Names contains all parsed attributes. When parsing distinguished names,
130+
// this can be used to extract non-standard attributes that are not parsed
131+
// by this package. When marshaling to RDNSequences, the Names field is
132+
// ignored, see ExtraNames.
133+
Names []AttributeTypeAndValue
134+
135+
// ExtraNames contains attributes to be copied, raw, into any marshaled
136+
// distinguished names. Values override any attributes with the same OID.
137+
// The ExtraNames field is not populated when parsing, see Names.
130138
ExtraNames []AttributeTypeAndValue
131139
}
132140

141+
// FillFromRDNSequence populates n from the provided RDNSequence.
142+
// Multi-entry RDNs are flattened, all entries are added to the
143+
// relevant n fields, and the grouping is not preserved.
133144
func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
134145
for _, rdn := range *rdns {
135146
if len(rdn) == 0 {
@@ -200,6 +211,18 @@ func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentif
200211
return append(in, s)
201212
}
202213

214+
// ToRDNSequence converts n into a single RDNSequence. The following
215+
// attributes are encoded as multi-value RDNs:
216+
//
217+
// - Country
218+
// - Organization
219+
// - OrganizationalUnit
220+
// - Locality
221+
// - Province
222+
// - StreetAddress
223+
// - PostalCode
224+
//
225+
// Each ExtraNames entry is encoded as an individual RDN.
203226
func (n Name) ToRDNSequence() (ret RDNSequence) {
204227
ret = n.appendRDNs(ret, n.Country, oidCountry)
205228
ret = n.appendRDNs(ret, n.Province, oidProvince)
@@ -224,6 +247,19 @@ func (n Name) ToRDNSequence() (ret RDNSequence) {
224247
// String returns the string form of n, roughly following
225248
// the RFC 2253 Distinguished Names syntax.
226249
func (n Name) String() string {
250+
if len(n.ExtraNames) == 0 {
251+
for _, atv := range n.Names {
252+
t := atv.Type
253+
if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
254+
switch t[3] {
255+
case 3, 5, 6, 7, 8, 9, 10, 11, 17:
256+
// These attributes are already parsed into named fields.
257+
continue
258+
}
259+
}
260+
n.ExtraNames = append(n.ExtraNames, atv)
261+
}
262+
}
227263
return n.ToRDNSequence().String()
228264
}
229265

0 commit comments

Comments
 (0)