Skip to content
Open
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6c23670
lint about the encoding of qcstatements for PSD2
Feb 4, 2020
4666bb7
Revert "lint about the encoding of qcstatements for PSD2"
Feb 4, 2020
01996c6
Merge https://github.com/zmap/zlint
Aug 26, 2020
28481cc
Merge https://github.com/zmap/zlint
Sep 1, 2021
749d896
Merge https://github.com/zmap/zlint
Oct 21, 2021
e56e2a0
util: gtld_map autopull updates for 2021-10-21T07:25:20 UTC
web-flow Oct 21, 2021
8600050
Merge pull request #1 from mtgag/zlint-gtld-update
mtgag Oct 21, 2021
30b096e
Merge https://github.com/zmap/zlint
mtgag Apr 19, 2023
92e659c
always check and perform the operation in the execution
mtgag Apr 27, 2023
351a379
Merge branch 'master' into master
christopher-henderson May 14, 2023
b52111b
Merge https://github.com/zmap/zlint
mtgag May 16, 2023
526f9be
Merge https://github.com/zmap/zlint
mtgag Jun 9, 2023
92902fc
Merge https://github.com/zmap/zlint
mtgag Jul 1, 2023
1652cfa
synchronised with project
mtgag Jul 5, 2023
d4f2f9f
synchronised with project
mtgag Aug 30, 2023
88c933e
Merge https://github.com/zmap/zlint
mtgag Aug 30, 2023
cee805f
Merge https://github.com/zmap/zlint
mtgag Dec 3, 2023
2408543
synchronised with project
mtgag Dec 14, 2023
67537e9
synchronised with project
mtgag Dec 14, 2023
e77fae1
synchronised with project
mtgag Jan 24, 2024
51d498f
synchronised with project
mtgag Feb 13, 2024
31e1845
Merge https://github.com/zmap/zlint
mtgag Feb 25, 2024
d10444e
Merge https://github.com/zmap/zlint
mtgag Mar 4, 2024
53b911e
fixed merge error
mtgag Mar 5, 2024
f1a66db
Merge https://github.com/zmap/zlint
mtgag Mar 10, 2024
795d206
Merge https://github.com/zmap/zlint
mtgag Apr 5, 2024
bad73ee
synchronised with project
mtgag Apr 5, 2024
2cd7d08
synchronised with project
mtgag Apr 9, 2024
63cf8e8
Revert "synchronised with project"
mtgag Apr 9, 2024
b3a86b3
Revert "synchronised with project"
mtgag Apr 9, 2024
4d46729
Merge https://github.com/zmap/zlint
mtgag Apr 9, 2024
f0991f9
Merge https://github.com/zmap/zlint
mtgag Jun 6, 2024
6662edf
Merge https://github.com/zmap/zlint
mtgag Jun 18, 2024
d5aec9b
synchronised with project
mtgag Feb 18, 2025
fdc1d36
synchronised with project
mtgag Apr 7, 2025
a694591
synchronised with project
mtgag May 5, 2025
b26ef71
added lint
mtgag May 7, 2025
05f2372
added testdata
mtgag May 7, 2025
cd332f8
added missing date
mtgag May 7, 2025
96060e5
with main project
mtgag May 7, 2025
e1e43ff
addressing review comments
mtgag May 12, 2025
636623a
addressing review comments
mtgag May 12, 2025
1036f73
addressing lint issues
mtgag May 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,846 changes: 8,846 additions & 0 deletions h

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions v3/cmd/genTestCerts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -40,9 +42,11 @@ github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhu
github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
github.com/zmap/zcertificate v0.0.1/go.mod h1:q0dlN54Jm4NVSSuzisusQY0hqDWvu92C+TWveAxiVWk=
github.com/zmap/zcrypto v0.0.0-20201128221613-3719af1573cf/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ=
github.com/zmap/zcrypto v0.0.0-20201211161100-e54a5822fb7e/go.mod h1:aPM7r+JOkfL+9qSB4KbYjtoEzJqUK50EXkkJabeNJDQ=
github.com/zmap/zcrypto v0.0.0-20250129210703-03c45d0bae98 h1:Qp98bmMm9JHPPOaLi2Nb6oWoZ+1OyOMWI7PPeJrirI0=
github.com/zmap/zcrypto v0.0.0-20250129210703-03c45d0bae98/go.mod h1:YTUyN/U1oJ7RzCEY5hUweYxbVUu7X+11wB7OXZT15oE=
github.com/zmap/zlint/v3 v3.0.0/go.mod h1:paGwFySdHIBEMJ61YjoqT4h7Ge+fdYG4sUQhnTb1lJ8=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
Expand Down Expand Up @@ -83,13 +87,13 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -101,6 +105,7 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
Expand All @@ -113,9 +118,9 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
Expand Down
1 change: 1 addition & 0 deletions v3/integration/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,7 @@
},
"e_qcstatem_qctype_smime": { },
"e_qcstatem_pds_must_have_https_only": { },
"e_qcstatem_correct_national_scheme": { },
"n_ca_digital_signature_not_set": {
"NoticeCount": 1405
},
Expand Down
144 changes: 144 additions & 0 deletions v3/lints/etsi/lint_qcstatem_etsi_national_scheme.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package etsi

/*
* ZLint Copyright 2025 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"
"regexp"

"github.com/zmap/zcrypto/x509"
"github.com/zmap/zlint/v3/lint"
"github.com/zmap/zlint/v3/util"
)

type qcStatemNationalScheme struct{}

/************************************************************************
ETSI EN 319 412-2 V2.2.1 (2020-07)
https://www.etsi.org/deliver/etsi_en/319400_319499/31941202/02.02.01_60/en_31941202v020201p.pdf
4.2.4 Certificates may include one or more semantics identifiers as specified in ETSI
EN 319 412-1 [i.4], clause 5 which defines the semantics for the organizationIdentifier attribute.

Certificates may include one or more semantics identifiers as specified in ETSI EN 319 412-1 [i.4],
clause 5 which define the semantics for the serialNumber attribute.

ETSI EN 319 412-1 V1.4.1 (2020-06)
https://www.etsi.org/deliver/etsi_en/319400_319499/31941201/01.04.01_60/en_31941201v010401p.pdf
5.1.3 Natural person semantics identifier
The semantics of id-etsi-qcs-SemanticsId-Natural shall be as follows.
When the natural person semantics identifier is included, any present serialNumber attribute in the subject field shall
contain information using the following structure in the presented order:
The three initial characters shall have one of the following defined values:
1) "PAS" for identification based on passport number.
2) "IDC" for identification based on national identity card number.
3) "PNO" for identification based on (national) personal number (national civic registration number).
4) "TAX" for identification based on a personal tax reference number issued by a national tax authority. This
value is deprecated. The value "TIN" should be used instead.
5) "TIN" Tax Identification Number according to the European Commission – Tax and Customs Union
(https://ec.europa.eu/taxation_customs/tin/tinByCountry.html).
6) Two characters according to local definition within the specified country and name registration authority,
identifying a national scheme that is considered appropriate for national and European level, followed by the
character ":" (colon).

5.1.4 Legal person semantics identifier
The semantics of id-etsi-qcs-SemanticsId-Legal shall be as follows.
When the legal person semantics identifier is included, any present organizationIdentifier attribute in the subject
field shall contain information using the following structure in the presented order:
• 3 character legal person identity type reference;
• 2 character ISO 3166 [2] country code;
• hyphen-minus "-" (0x2D (ASCII), U+002D (UTF-8)); and
• identifier (according to country and identity type reference).
The three initial characters shall have one of the following defined values:
1) "VAT" for identification based on a national value added tax identification number.
2) "NTR" for identification based on an identifier from a national trade register.
3) "PSD" for identification based on national authorization number of a payment service provider under
Payments Services Directive (EU) 2015/2366 [i.13]. This shall use the extended structure as defined in ETSI
TS 119 495 [3], clause 5.2.1.
4) "LEI" for a global Legal Entity Identifier as specified in ISO 17442 [4]. The 2 character ISO 3166 [2] country
code shall be set to 'XG'.
5) Two characters according to local definition within the specified country and name registration authority,
identifying a national scheme that is considered appropriate for national and European level, followed by the
character ":" (colon)
*************************************************************************/

func init() {
lint.RegisterCertificateLint(&lint.CertificateLint{
LintMetadata: lint.LintMetadata{
Name: "e_qcstatem_correct_national_scheme",
Description: "This lint checks that the national scheme is well-formed when used in the serialNumber or organizationIdentifier attribute in the subject field, provided that either the natural person semantics identifier or the legal person semantics identifier is present.",
Citation: "ETSI EN 319 412-1 V1.4.1, 5.1.3 Natural person semantics identifier and 5.1.4 Legal person semantics identifier",
Source: lint.EtsiEsi,
EffectiveDate: util.ETSI_EN_319_412_1_V1_4_1_DATE,
},
Lint: NewQcStatemNationalScheme,
})
}

func NewQcStatemNationalScheme() lint.LintInterface {
return &qcStatemNationalScheme{}
}

func (l *qcStatemNationalScheme) CheckApplies(c *x509.Certificate) bool {
_, isPresent := util.IsQcStatemPresent(c, &util.IdQcsPkixQCSyntaxV2)

if !isPresent {
return false
}

qcs2Generic := util.ParseQcStatem(util.GetQcStatemExtValue(c), util.IdQcsPkixQCSyntaxV2)

qcs2 := qcs2Generic.(util.DecodedQcS2)
semanticsId := qcs2.Decoded.SemanticsId
re := regexp.MustCompile(`^.{2}:`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
re := regexp.MustCompile(`^.{2}:`)
re := regexp.MustCompile(`^[a-zA-Z]{2}:`)

I am not 100% certain of this, but do at least consider making this a bit more precise (if possible).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good. Changed.


if semanticsId.Equal(util.IdEtsiQcsSemanticsIdNatural) {
serialNumber := c.Subject.SerialNumber
return re.MatchString(serialNumber)
}

if semanticsId.Equal(util.IdEtsiQcsSemanticsIdLegal) {
for _, orgId := range c.Subject.OrganizationIDs {
if re.MatchString(orgId) {
return true
}
}
}
return false
}

func (l *qcStatemNationalScheme) Execute(c *x509.Certificate) *lint.LintResult {

qcs2Generic := util.ParseQcStatem(util.GetQcStatemExtValue(c), util.IdQcsPkixQCSyntaxV2)

qcs2 := qcs2Generic.(util.DecodedQcS2)
semanticsId := qcs2.Decoded.SemanticsId

if semanticsId.Equal(util.IdEtsiQcsSemanticsIdNatural) {
serialNumber := c.Subject.SerialNumber
if !util.CheckNationalScheme(serialNumber) {
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("invalid format of subject:serialNumber %s for national scheme", serialNumber)}
}
}

if semanticsId.Equal(util.IdEtsiQcsSemanticsIdLegal) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am unsure of this block. The psuedo-code that describes it is...

[ (legal person semantics identifier is included) AND (two characters according to local ... are present in organizationIdentifier) ]

However, it will also succeed if there are simply no orgIDs or if none of the orgIDs that are present match the ^.{2}: regex. Are you expecting both of these scenarios to also generate a PASS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CheckApplies should cover this. If the certificate does not have any orgIDs or none of the orgIDs that are present match the regexp then it is an NA.

re := regexp.MustCompile(`^.{2}:`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind placing this regex in the global context so that CheckApplies and Execute use the precise same object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

for _, orgId := range c.Subject.OrganizationIDs {
if re.MatchString(orgId) && !util.CheckNationalScheme(orgId) {
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("invalid format of subject:organizationIdentifier %s for national scheme", orgId)}
}
}
}
return &lint.LintResult{Status: lint.Pass}
}
69 changes: 69 additions & 0 deletions v3/lints/etsi/lint_qcstatem_etsi_national_scheme_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package etsi

/*
* ZLint Copyright 2025 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 (
"testing"

"github.com/zmap/zlint/v3/lint"
"github.com/zmap/zlint/v3/test"
)

func TestQcStatemNationalScheme(t *testing.T) {
testCases := []struct {
Name string
InputFilename string
ExpectedResult lint.LintStatus
}{
{
Name: "NA - certificate has the natural person semantics identifier and no national scheme value",
InputFilename: "qcNaturalNoNationalScheme.pem",
ExpectedResult: lint.NA,
},
{
Name: "Pass - certificate has the natural person semantics identifier and a correct national scheme value",
InputFilename: "qcNaturalCorrectNationalScheme.pem",
ExpectedResult: lint.Pass,
},
{
Name: "Error - certificate has the natural person semantics identifier and a wrong national scheme value",
InputFilename: "qcNaturalNotCorrectScheme.pem",
ExpectedResult: lint.Error,
},
{
Name: "NA - certificate has the legal person semantics identifier and no national scheme value",
InputFilename: "qcLegalNoNationalScheme.pem",
ExpectedResult: lint.NA,
},
{
Name: "Pass - certificate has the legal person semantics identifier and a correct national scheme value",
InputFilename: "qcLegalCorrectNationalScheme.pem",
ExpectedResult: lint.Pass,
},
{
Name: "Error - certificate has the legal person semantics identifier and a wrong national scheme value",
InputFilename: "qcLegalNotCorrectScheme.pem",
ExpectedResult: lint.Error,
},
}
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
result := test.TestLint("e_qcstatem_correct_national_scheme", tc.InputFilename)
if result.Status != tc.ExpectedResult {
t.Errorf("expected result %v was %v - details: %v", tc.ExpectedResult, result.Status, result.Details)
}
})
}
}
40 changes: 40 additions & 0 deletions v3/testdata/qcLegalCorrectNationalScheme.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
3e:40:85:f1:1f:4f:d3:c8:50:3f:5b:dc
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Lint CA, O = Lint, C = DE
Validity
Not Before: Feb 18 00:00:00 2025 GMT
Not After : Feb 18 00:00:00 2026 GMT
Subject: organizationIdentifier = EI:SE-5567971433
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:8c:5e:3f:b1:9b:cb:61:f6:56:fe:06:f2:26:06:
93:00:d4:6f:5a:ac:72:d7:3f:3c:f4:8e:72:73:71:
6f:2e:e0:af:93:2f:57:42:58:50:ef:47:f4:b2:ab:
58:d5:d5:7a:c9:d0:cd:46:1f:8e:b1:c5:19:28:5f:
ea:c1:d4:49:3e
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
qcStatements:
0.0...+.......0.......I..
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:49:36:0b:d5:cc:db:c9:d2:2a:81:19:3f:11:3a:
01:e3:34:fd:66:65:c7:05:e2:76:2e:36:cf:17:bb:91:90:ca:
02:20:4d:e5:9e:45:32:d5:c8:99:c3:0f:4d:aa:2b:b8:a0:34:
2d:a6:d5:11:76:63:5a:09:3b:0d:7d:ad:ed:f4:14:ae
-----BEGIN CERTIFICATE-----
MIIBazCCARKgAwIBAgIMPkCF8R9P08hQP1vcMAoGCCqGSM49BAMCMC4xEDAOBgNV
BAMMB0xpbnQgQ0ExDTALBgNVBAoMBExpbnQxCzAJBgNVBAYTAkRFMB4XDTI1MDIx
ODAwMDAwMFoXDTI2MDIxODAwMDAwMFowGzEZMBcGA1UEYQwQRUk6U0UtNTU2Nzk3
MTQzMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIxeP7Gby2H2Vv4G8iYGkwDU
b1qsctc/PPSOcnNxby7gr5MvV0JYUO9H9LKrWNXVesnQzUYfjrHFGShf6sHUST6j
KTAnMCUGCCsGAQUFBwEDBBkwFzAVBggrBgEFBQcLAjAJBgcEAIvsSQECMAoGCCqG
SM49BAMCA0cAMEQCIEk2C9XM28nSKoEZPxE6AeM0/WZlxwXidi42zxe7kZDKAiBN
5Z5FMtXImcMPTaoruKA0LabVEXZjWgk7DX2t7fQUrg==
-----END CERTIFICATE-----
40 changes: 40 additions & 0 deletions v3/testdata/qcLegalNoNationalScheme.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
43:f4:da:2d:d7:7e:4f:67:7f:3c:0e:2a
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Lint CA, O = Lint, C = DE
Validity
Not Before: Feb 18 00:00:00 2025 GMT
Not After : Feb 18 00:00:00 2026 GMT
Subject: organizationIdentifier = PASSK-P3000180
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:8c:5e:3f:b1:9b:cb:61:f6:56:fe:06:f2:26:06:
93:00:d4:6f:5a:ac:72:d7:3f:3c:f4:8e:72:73:71:
6f:2e:e0:af:93:2f:57:42:58:50:ef:47:f4:b2:ab:
58:d5:d5:7a:c9:d0:cd:46:1f:8e:b1:c5:19:28:5f:
ea:c1:d4:49:3e
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
qcStatements:
0.0...+.......0.......I..
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:35:22:18:10:bc:e0:55:ca:df:5d:c1:14:de:07:
68:f0:70:59:22:23:99:da:0e:1a:15:df:d1:4b:f3:c4:36:16:
02:20:24:40:37:4f:d7:b4:61:df:75:60:97:22:c2:63:d7:9d:
88:4f:5f:be:5f:9b:88:27:80:3c:ab:60:e9:75:1d:25
-----BEGIN CERTIFICATE-----
MIIBaTCCARCgAwIBAgIMQ/TaLdd+T2d/PA4qMAoGCCqGSM49BAMCMC4xEDAOBgNV
BAMMB0xpbnQgQ0ExDTALBgNVBAoMBExpbnQxCzAJBgNVBAYTAkRFMB4XDTI1MDIx
ODAwMDAwMFoXDTI2MDIxODAwMDAwMFowGTEXMBUGA1UEYQwOUEFTU0stUDMwMDAx
ODAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASMXj+xm8th9lb+BvImBpMA1G9a
rHLXPzz0jnJzcW8u4K+TL1dCWFDvR/Syq1jV1XrJ0M1GH46xxRkoX+rB1Ek+oykw
JzAlBggrBgEFBQcBAwQZMBcwFQYIKwYBBQUHCwIwCQYHBACL7EkBAjAKBggqhkjO
PQQDAgNHADBEAiA1IhgQvOBVyt9dwRTeB2jwcFkiI5naDhoV39FL88Q2FgIgJEA3
T9e0Yd91YJciwmPXnYhPX75fm4gngDyrYOl1HSU=
-----END CERTIFICATE-----
Loading