Skip to content

Commit

Permalink
Fix issue with other types of SAN values
Browse files Browse the repository at this point in the history
The testcases did not take in account that there could be other types of otherName attributes, like the class 2, tag 2 alternative host name. This commit fixes that issue.
  • Loading branch information
rolandgroen committed Nov 6, 2024
1 parent ca6da44 commit 8570569
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 21 deletions.
29 changes: 16 additions & 13 deletions vdr/didx509/x509_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,24 @@ func findOtherNameValues(cert *x509.Certificate) ([]string, error) {
// findSanValues extracts the SAN values from a given pkix.Extension, returning the resulting values or an error.
func findSanValues(extension pkix.Extension) ([]string, error) {
var values []string
err := forEachSan(extension.Value, func(data []byte) error {
var other OtherName
_, err := asn1.UnmarshalWithParams(data, &other, "tag:0")
if err != nil {
return err
}
if other.TypeID.Equal(OtherNameType) {
var value string
_, err = asn1.Unmarshal(other.Value.Bytes, &value)
err := forEachSan(extension.Value, func(v *asn1.RawValue) error {
if v.Class == asn1.ClassContextSpecific && v.Tag == 0 {
var other OtherName
_, err := asn1.UnmarshalWithParams(v.FullBytes, &other, "tag:0")
if err != nil {
return err
}
values = append(values, value)
if other.TypeID.Equal(OtherNameType) {
var value string
_, err = asn1.Unmarshal(other.Value.Bytes, &value)
if err != nil {
return err
}
values = append(values, value)
}
}
return nil

})
if err != nil {
return make([]string, 0), err
Expand All @@ -127,7 +130,7 @@ func findSanValues(extension pkix.Extension) ([]string, error) {
}

// forEachSan processes each SAN extension in the certificate
func forEachSan(extension []byte, callback func(data []byte) error) error {
func forEachSan(extension []byte, callback func(data *asn1.RawValue) error) error {
var seq asn1.RawValue
rest, err := asn1.Unmarshal(extension, &seq)
if err != nil {
Expand All @@ -150,7 +153,7 @@ func isSANSequence(seq asn1.RawValue) bool {
}

// processSANSequence processes the SAN sequence and invokes the callback on each element
func processSANSequence(rest []byte, callback func(data []byte) error) error {
func processSANSequence(rest []byte, callback func(data *asn1.RawValue) error) error {
for len(rest) > 0 {
var v asn1.RawValue
var err error
Expand All @@ -160,7 +163,7 @@ func processSANSequence(rest []byte, callback func(data []byte) error) error {
return err
}

if err := callback(v.FullBytes); err != nil {
if err := callback(&v); err != nil {
return err
}
}
Expand Down
22 changes: 14 additions & 8 deletions vdr/didx509/x509_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func SigningCertTemplate(serialNumber *big.Int, identifiers []string) (*x509.Cer
// Either the ExtraExtensions SubjectAlternativeNameType is set, or the Subject Alternate Name values are set,
// both don't mix
if len(identifiers) > 0 {
err := setSanAlternativeName(&tmpl, identifiers)
err := setSanAlternativeName(&tmpl, identifiers, "testhost.example.com")
if err != nil {
return nil, err
}
Expand All @@ -193,8 +193,14 @@ func SigningCertTemplate(serialNumber *big.Int, identifiers []string) (*x509.Cer
return &tmpl, nil
}

func setSanAlternativeName(tmpl *x509.Certificate, identifiers []string) error {
func setSanAlternativeName(tmpl *x509.Certificate, identifiers []string, altHostName string) error {
var list []asn1.RawValue
// Add the alternative host name first
value, err := toRawValue(altHostName, "tag:2")
if err != nil {
return err
}
list = append(list, *value)

for _, identifier := range identifiers {
raw, err := toRawValue(identifier, "ia5")
Expand Down Expand Up @@ -230,8 +236,8 @@ func setSanAlternativeName(tmpl *x509.Certificate, identifiers []string) error {
}

// toRawValue marshals an ASN.1 identifier with a given tag, then unmarshals it into a RawValue structure.
func toRawValue(identifier any, tag string) (*asn1.RawValue, error) {
b, err := asn1.MarshalWithParams(identifier, tag)
func toRawValue(value any, tag string) (*asn1.RawValue, error) {
b, err := asn1.MarshalWithParams(value, tag)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -493,8 +499,8 @@ func TestProcessSANSequence(t *testing.T) {
panic(err)
}
wrongValueErr := errors.New("wrong value")
callback := func(data []byte) error {
if !bytes.Equal(data, testRawValue.FullBytes) {
callback := func(v *asn1.RawValue) error {
if !bytes.Equal(v.FullBytes, testRawValue.FullBytes) {
return wrongValueErr
}
return nil
Expand Down Expand Up @@ -552,8 +558,8 @@ func TestForEachSan(t *testing.T) {
panic(err)
}
wrongValueErr := errors.New("wrong value")
callback := func(data []byte) error {
if !bytes.Equal(data, testEncapsulatedValue.FullBytes) {
callback := func(v *asn1.RawValue) error {
if !bytes.Equal(v.FullBytes, testEncapsulatedValue.FullBytes) {
return wrongValueErr
}
return nil
Expand Down

0 comments on commit 8570569

Please sign in to comment.