-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
36 changed files
with
1,758 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package cabf_br | ||
|
||
/* | ||
* ZLint Copyright 2024 Regents of the University of Michigan | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
* use this file except in compliance with the License. You may obtain a copy | ||
* of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
import ( | ||
"fmt" | ||
"github.com/zmap/zcrypto/encoding/asn1" | ||
"github.com/zmap/zcrypto/x509" | ||
"github.com/zmap/zlint/v3/lint" | ||
"github.com/zmap/zlint/v3/util" | ||
) | ||
|
||
type subjectRdnsCorrectEncoding struct{} | ||
|
||
func init() { | ||
lint.RegisterCertificateLint(&lint.CertificateLint{ | ||
LintMetadata: lint.LintMetadata{ | ||
Name: "e_subject_rdns_correct_encoding", | ||
Description: "CAs that include attributes in the Certificate subject field that are listed in the Tables 77 and 78 of BR 2.0.0 SHALL follow the specified encoding requirements for the attribute", | ||
Citation: "BRs 2.0.0: 7.1.4.2, Table 77 and Table 78", | ||
Source: lint.CABFBaselineRequirements, | ||
EffectiveDate: util.SC62EffectiveDate, | ||
}, | ||
Lint: NewSubjectRdnsCorrectEncoding, | ||
}) | ||
} | ||
|
||
func NewSubjectRdnsCorrectEncoding() lint.LintInterface { | ||
return &subjectRdnsCorrectEncoding{} | ||
} | ||
|
||
func (l *subjectRdnsCorrectEncoding) CheckApplies(c *x509.Certificate) bool { | ||
return true | ||
} | ||
|
||
func (l *subjectRdnsCorrectEncoding) Execute(c *x509.Certificate) *lint.LintResult { | ||
rdnSequence := util.RawRDNSequence{} | ||
if rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence); err != nil || len(rest) > 0 { | ||
return &lint.LintResult{Status: lint.Fatal} | ||
} | ||
|
||
for _, attrTypeAndValueSet := range rdnSequence { | ||
for _, attrTypeAndValue := range attrTypeAndValueSet { | ||
oid := attrTypeAndValue.Type.String() | ||
tag := attrTypeAndValue.Value.Tag | ||
|
||
if "0.9.2342.19200300.100.1.25" == oid && tag != 22 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute domainComponent in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.6" == oid && tag != 19 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute countryName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.8" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute stateOrProvinceName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.7" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute localityName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.17" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute postalCode in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.9" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute streetAddress in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.10" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute organizationName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.4" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute surname in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.42" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute givenName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.11" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute organizationalUnitName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.3" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute commonName in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.15" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute businessCategory in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "1.3.6.1.4.1.311.60.2.1.3" == oid && tag != 19 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute jurisdictionCountry in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "1.3.6.1.4.1.311.60.2.1.2" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute jurisdictionStateOrProvince in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "1.3.6.1.4.1.311.60.2.1.1" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute jurisdictionLocality in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.5" == oid && tag != 19 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute serialNumber in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
if "2.5.4.97" == oid && tag != 19 && tag != 12 { | ||
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Attribute organizationIdentifier in subjectDN has the wrong encoding %s.", getEncodingName(tag))} | ||
} | ||
} | ||
} | ||
return &lint.LintResult{Status: lint.Pass} | ||
} | ||
|
||
//Tag BMPString: 0x1e = 30 | ||
//Tag UTF8String: 0x0c = 12 | ||
//Tag TeletexString: 0x14 = 20 | ||
//Tag UniversalString: 0x1c = 28 | ||
//Tag PrintableString: 0x13 = 19 | ||
//Tag IA5String: 0x16 = 22 | ||
|
||
func getEncodingName(tag int) string { | ||
if tag == 12 { | ||
return "UTF8String" | ||
} | ||
if tag == 19 { | ||
return "PrintableString" | ||
} | ||
if tag == 20 { | ||
return "TeletexString" | ||
} | ||
if tag == 22 { | ||
return "IA5String" | ||
} | ||
if tag == 28 { | ||
return "UniversalString" | ||
} | ||
if tag == 30 { | ||
return "BMPString" | ||
} | ||
return "Unknown" | ||
} |
221 changes: 221 additions & 0 deletions
221
v3/lints/cabf_br/lint_subject_rdns_correct_encoding_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
/* | ||
* ZLint Copyright 2024 Regents of the University of Michigan | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
* use this file except in compliance with the License. You may obtain a copy | ||
* of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
package cabf_br | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/zmap/zlint/v3/lint" | ||
"github.com/zmap/zlint/v3/test" | ||
) | ||
|
||
func TestSubjectRdnsCorrectEncoding(t *testing.T) { | ||
data := []struct { | ||
file string | ||
want lint.LintStatus | ||
details string | ||
}{ | ||
{ | ||
"subjectDCWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute domainComponent in subjectDN has the wrong encoding UTF8String", | ||
}, | ||
{ | ||
"subjectCWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute countryName in subjectDN has the wrong encoding UTF8String", | ||
}, | ||
{ | ||
"subjectSTWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute stateOrProvinceName in subjectDN has the wrong encoding TeletexString", | ||
}, | ||
{ | ||
"subjectLWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute localityName in subjectDN has the wrong encoding IA5String", | ||
}, | ||
{ | ||
"subjectPostalCodeWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute postalCode in subjectDN has the wrong encoding UniversalString", | ||
}, | ||
{ | ||
"subjectStreetWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute streetAddress in subjectDN has the wrong encoding BMPString", | ||
}, | ||
{ | ||
"subjectOWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute organizationName in subjectDN has the wrong encoding TeletexString", | ||
}, | ||
{ | ||
"subjectSurnameWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute surname in subjectDN has the wrong encoding IA5String", | ||
}, | ||
{ | ||
"subjectGivenNameWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute givenName in subjectDN has the wrong encoding BMPString", | ||
}, | ||
{ | ||
"subjectOUWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute organizationalUnitName in subjectDN has the wrong encoding BMPString", | ||
}, | ||
{ | ||
"subjectCNWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute commonName in subjectDN has the wrong encoding UniversalString", | ||
}, | ||
{ | ||
"subjectBusinessCategoryWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute businessCategory in subjectDN has the wrong encoding TeletexString", | ||
}, | ||
{ | ||
"subjectjurCWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute jurisdictionCountry in subjectDN has the wrong encoding BMPString", | ||
}, | ||
{ | ||
"subjectjurSTWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute jurisdictionStateOrProvince in subjectDN has the wrong encoding IA5String", | ||
}, | ||
{ | ||
"subjectjurLWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute jurisdictionLocality in subjectDN has the wrong encoding BMPString", | ||
}, | ||
{ | ||
"subjectSerialNumberWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute serialNumber in subjectDN has the wrong encoding UniversalString", | ||
}, | ||
{ | ||
"subjectOrganizationIdentifierWrongEncoding.pem", | ||
lint.Error, | ||
"Attribute organizationIdentifier in subjectDN has the wrong encoding TeletexString", | ||
}, | ||
{ | ||
"subjectDCCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectCCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectSTCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectLCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectPostalCodeCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectStreetCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectOCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectSurnameCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectGivenNameCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectOUCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectCNCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectBusinessCategoryCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectjurCCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectjurSTCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectjurLCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectSerialNumberCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectOrganizationIdentifierCorrectEncoding.pem", | ||
lint.Pass, | ||
"", | ||
}, | ||
{ | ||
"subjectValidCountry.pem", | ||
lint.NE, | ||
"", | ||
}, | ||
} | ||
for _, d := range data { | ||
file := d.file | ||
want := d.want | ||
details := d.details | ||
t.Run(file, func(t *testing.T) { | ||
got := test.TestLint("e_subject_rdns_correct_encoding", file) | ||
if got.Status != want { | ||
t.Errorf("expected %v got %v", want, got) | ||
} | ||
if !strings.Contains(got.Details, details) { | ||
t.Errorf("expected the returned details to contain '%s' but got %s", details, got.Details) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.