Skip to content

Commit

Permalink
Populate ExtraNames from Names
Browse files Browse the repository at this point in the history
This commit will populate the subject ExtraNames in a certificate
request from the information present in Names as long as it is not
one of the default fields. This way, we can extract non-default fields
as well as populate them in the final certificate if necessary.

It also uses the proper type for the deprecated email address
attribute in the subject.

Related to smallstep/certificates#916
  • Loading branch information
maraino committed May 16, 2022
1 parent a7692cc commit 005d309
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 20 deletions.
1 change: 0 additions & 1 deletion x509util/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ func newExtensions(extensions []pkix.Extension) []Extension {
ret[i] = newExtension(e)
}
return ret

}

// Set adds the extension to the given X509 certificate.
Expand Down
56 changes: 47 additions & 9 deletions x509util/name.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ import (
"github.com/pkg/errors"
)

// attributeTypeNames are the subject attributes managed by Go and this package.
// newDistinguisedNames will populate .Insecure.CR.ExtraNames with the
// attributes not present on this map.
var attributeTypeNames = map[string]string{
"2.5.4.6": "C",
"2.5.4.10": "O",
"2.5.4.11": "OU",
"2.5.4.3": "CN",
"2.5.4.5": "SERIALNUMBER",
"2.5.4.7": "L",
"2.5.4.8": "ST",
"2.5.4.9": "STREET",
"2.5.4.17": "POSTALCODE",
}

// oidEmailAddress is the oid of the deprecated emailAddress in the subject.
var oidEmailAddress = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}

// Name is the JSON representation of X.501 type Name, used in the X.509 subject
// and issuer fields.
type Name struct {
Expand All @@ -35,7 +53,7 @@ func newName(n pkix.Name) Name {
PostalCode: n.PostalCode,
SerialNumber: n.SerialNumber,
CommonName: n.CommonName,
ExtraNames: newDistinguisedNames(n.ExtraNames),
ExtraNames: newDistinguisedNames(n.Names),
}
}

Expand Down Expand Up @@ -131,24 +149,44 @@ type DistinguishedName struct {
Value interface{} `json:"value"`
}

// newDistinguisedNames returns a list of DistinguishedName with the attributes not
// present in attributeTypeNames.
func newDistinguisedNames(atvs []pkix.AttributeTypeAndValue) []DistinguishedName {
var extraNames []DistinguishedName
for _, atv := range atvs {
extraNames = append(extraNames, DistinguishedName{
Type: ObjectIdentifier(atv.Type),
Value: atv.Value,
})
if _, ok := attributeTypeNames[atv.Type.String()]; !ok {
extraNames = append(extraNames, DistinguishedName{
Type: ObjectIdentifier(atv.Type),
Value: atv.Value,
})
}
}
return extraNames
}

// fromDistinguisedNames converts a list of DistinguisedName to
// []pkix.AttributeTypeAndValue. Note that this method has a special case to
// encode the emailAddress deprecated field (1.2.840.113549.1.9.1).
func fromDistinguisedNames(dns []DistinguishedName) []pkix.AttributeTypeAndValue {
var atvs []pkix.AttributeTypeAndValue
for _, dn := range dns {
atvs = append(atvs, pkix.AttributeTypeAndValue{
Type: asn1.ObjectIdentifier(dn.Type),
Value: dn.Value,
})
typ := asn1.ObjectIdentifier(dn.Type)
v, isString := dn.Value.(string)
if typ.Equal(oidEmailAddress) && isString {
atvs = append(atvs, pkix.AttributeTypeAndValue{
Type: typ,
Value: asn1.RawValue{
Class: asn1.ClassUniversal,
Tag: asn1.TagIA5String,
Bytes: []byte(v),
},
})
} else {
atvs = append(atvs, pkix.AttributeTypeAndValue{
Type: typ,
Value: dn.Value,
})
}
}
return atvs
}
28 changes: 18 additions & 10 deletions x509util/name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ func Test_newName(t *testing.T) {
PostalCode: []string{"The postalCode"},
SerialNumber: "The serialNumber",
CommonName: "The commonName",
ExtraNames: []pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
Names: []pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{2, 5, 4, 3}, Value: "The commonName"},
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
},
}}, Name{
Country: []string{"The country"},
Expand All @@ -41,7 +42,7 @@ func Test_newName(t *testing.T) {
SerialNumber: "The serialNumber",
CommonName: "The commonName",
ExtraNames: []DistinguishedName{
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
},
}},
}
Expand Down Expand Up @@ -127,8 +128,8 @@ func Test_newSubject(t *testing.T) {
PostalCode: []string{"The postalCode"},
SerialNumber: "The serialNumber",
CommonName: "The commonName",
ExtraNames: []pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
Names: []pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
},
}}, Subject{
Country: []string{"The country"},
Expand All @@ -141,7 +142,7 @@ func Test_newSubject(t *testing.T) {
SerialNumber: "The serialNumber",
CommonName: "The commonName",
ExtraNames: []DistinguishedName{
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
},
}},
}
Expand Down Expand Up @@ -405,6 +406,7 @@ func TestIssuer_Set(t *testing.T) {
CommonName: "The commonName",
ExtraNames: []DistinguishedName{
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: ObjectIdentifier{1, 2, 3, 4}, Value: "custom@example.com"},
},
}, args{&x509.Certificate{}}, &x509.Certificate{
Issuer: pkix.Name{
Expand All @@ -418,7 +420,8 @@ func TestIssuer_Set(t *testing.T) {
SerialNumber: "The serialNumber",
CommonName: "The commonName",
ExtraNames: []pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
{Type: asn1.ObjectIdentifier{1, 2, 3, 4}, Value: "custom@example.com"},
},
},
}},
Expand Down Expand Up @@ -462,9 +465,12 @@ func Test_newDistinguisedNames(t *testing.T) {
want []DistinguishedName
}{
{"ok", args{[]pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: asn1.ObjectIdentifier{2, 5, 4, 3}, Value: "The commonName"},
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
{Type: asn1.ObjectIdentifier{1, 2, 3, 4}, Value: "custom@example.com"},
}}, []DistinguishedName{
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
{Type: ObjectIdentifier{1, 2, 3, 4}, Value: "custom@example.com"},
}},
{"ok nil", args{nil}, nil},
}
Expand All @@ -488,8 +494,10 @@ func Test_fromDistinguisedNames(t *testing.T) {
}{
{"ok", args{[]DistinguishedName{
{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: ObjectIdentifier{1, 2, 3, 4}, Value: "custom@example.com"},
}}, []pkix.AttributeTypeAndValue{
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "jane@example.com"},
{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: asn1.RawValue{Class: asn1.ClassUniversal, Tag: asn1.TagIA5String, Bytes: []byte("jane@example.com")}},
{Type: asn1.ObjectIdentifier{1, 2, 3, 4}, Value: "custom@example.com"},
}},
{"ok nil", args{nil}, nil},
}
Expand Down

0 comments on commit 005d309

Please sign in to comment.