Skip to content

Commit

Permalink
Check tbsCertificate signature algorithm matches certificate (#436)
Browse files Browse the repository at this point in the history
* Check tbsCertificate signature algorithm matches certificate

Per RFC 5280 section 4.1.1.2, couldn't find an existing lint.

* Add ignore to integration + reuse tbsCert

Co-authored-by: Daniel McCarney <daniel@binaryparadox.net>
  • Loading branch information
rolandshoemaker and cpu committed Jun 1, 2020
1 parent 82e1f43 commit de9eafb
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 1 deletion.
5 changes: 4 additions & 1 deletion v2/integration/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,9 @@
},
"w_subject_dn_trailing_whitespace": {
"WarnCount": 64
},
"e_cert_sig_alg_not_match_tbs_sig_alg": {
"ErrCount": 10
}
}
}
}
88 changes: 88 additions & 0 deletions v2/lints/rfc/lint_tbs_signature_alg_matches_cert_signature_alg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* ZLint Copyright 2020 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.
*/

/*******************************************************************
RFC 5280: 4.1.1.2
[the Certificate signatureAlgorithm] field MUST contain the same
algorithm identifier as the signature field in the sequence
tbsCertificate
********************************************************************/

package rfc

import (
"bytes"

"github.com/zmap/zcrypto/x509"
"github.com/zmap/zlint/v2/lint"
"github.com/zmap/zlint/v2/util"
"golang.org/x/crypto/cryptobyte"
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
)

type mismatchingSigAlg struct{}

func (l *mismatchingSigAlg) Initialize() error {
return nil
}

func (l *mismatchingSigAlg) CheckApplies(_ *x509.Certificate) bool {
return true
}

func (l *mismatchingSigAlg) Execute(c *x509.Certificate) *lint.LintResult {
// parse out certificate signatureAlgorithm
input := cryptobyte.String(c.Raw)
var cert cryptobyte.String
if !input.ReadASN1(&cert, cryptobyte_asn1.SEQUENCE) {
return &lint.LintResult{Status: lint.Fatal, Details: "error reading certificate"}
}
var tbsCert cryptobyte.String
if !cert.ReadASN1(&tbsCert, cryptobyte_asn1.SEQUENCE) {
return &lint.LintResult{Status: lint.Fatal, Details: "error reading certificate.tbsCertificate"}
}
var certSigAlg cryptobyte.String
if !cert.ReadASN1(&certSigAlg, cryptobyte_asn1.SEQUENCE) {
return &lint.LintResult{Status: lint.Fatal, Details: "error reading certificate.signatureAlgorithm"}
}

// parse out tbsCertificate signature
if !tbsCert.SkipOptionalASN1(cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.version"}
}
if !tbsCert.SkipASN1(cryptobyte_asn1.INTEGER) {
return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.serialNumber"}
}
var tbsSigAlg cryptobyte.String
if !tbsCert.ReadASN1(&tbsSigAlg, cryptobyte_asn1.SEQUENCE) {
return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.signature"}
}

if !bytes.Equal(certSigAlg, tbsSigAlg) {
return &lint.LintResult{Status: lint.Error}
}

return &lint.LintResult{Status: lint.Pass}
}

func init() {
lint.RegisterLint(&lint.Lint{
Name: "e_cert_sig_alg_not_match_tbs_sig_alg",
Description: "Certificate signature field must match TBSCertificate signature field",
Citation: "RFC 5280, Section 4.1.1.2",
Source: lint.RFC5280,
EffectiveDate: util.RFC5280Date,
Lint: &mismatchingSigAlg{},
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* ZLint Copyright 2020 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 rfc

import (
"testing"

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

func TestSigAlgMismatch(t *testing.T) {
testCases := []struct {
name string
filepath string
expectedStatus lint.LintStatus
}{
{
name: "error cert with mismatching signature algorithms (bad OID)",
filepath: "mismatchingSigAlgsBadOID.pem",
expectedStatus: lint.Error,
},
{
name: "error cert with mismatching signature algorithms (bad parameters)",
filepath: "mismatchingSigAlgsBadParams.pem",
expectedStatus: lint.Error,
},
{
name: "pass cert with matching signature algorithms",
filepath: "ecdsaP256.pem",
expectedStatus: lint.Pass,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := test.TestLint("e_cert_sig_alg_not_match_tbs_sig_alg", tc.filepath)
if result.Status != tc.expectedStatus {
t.Errorf("expected result %v was %v", tc.expectedStatus, result.Status)
}
})
}
}
37 changes: 37 additions & 0 deletions v2/testdata/mismatchingSigAlgsBadOID.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: ecdsa-with-SHA384
Issuer:
Validity
Not Before: Nov 10 23:00:00 2009 GMT
Not After : Aug 10 23:00:00 2019 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:27:0c:60:cf:ca:31:8a:91:db:8f:67:c7:95:04:
6d:df:18:31:99:2c:97:8a:71:8d:7b:c2:b9:79:3d:
02:86:21:a9:1b:5a:0c:55:03:cc:cc:18:2c:1b:96:
52:81:dc:70:62:7f:c9:f4:67:cd:d3:f4:43:31:b4:
a5:75:0b:19:3b
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Subject Alternative Name: critical
DNS:asd
Signature Algorithm: ecdsa-with-SHA384
30:44:02:20:3b:b7:b6:5d:a4:13:a1:f2:d8:42:5e:36:b9:e5:
41:7a:90:1c:ea:45:3f:11:6e:b7:b0:7d:b0:f7:bc:22:8b:35:
02:20:25:7a:88:77:4c:8a:fd:9d:e8:93:33:93:6d:f7:c3:80:
ba:a1:1c:51:3e:04:b6:7f:c1:ff:a2:3a:c4:87:ac:f9
-----BEGIN CERTIFICATE-----
MIIBAjCBqqADAgECAgEAMAoGCCqGSM49BAMCMAAwHhcNMDkxMTEwMjMwMDAwWhcN
MTkwODEwMjMwMDAwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJwxgz8ox
ipHbj2fHlQRt3xgxmSyXinGNe8K5eT0ChiGpG1oMVQPMzBgsG5ZSgdxwYn/J9GfN
0/RDMbSldQsZO6MVMBMwEQYDVR0RAQH/BAcwBYIDYXNkMAoGCCqGSM49BAMDA0cA
MEQCIDu3tl2kE6Hy2EJeNrnlQXqQHOpFPxFut7B9sPe8Ios1AiAleoh3TIr9neiT
M5Nt98OAuqEcUT4Etn/B/6I6xIes+Q==
-----END CERTIFICATE-----
37 changes: 37 additions & 0 deletions v2/testdata/mismatchingSigAlgsBadParams.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: ecdsa-with-SHA256
Issuer:
Validity
Not Before: Nov 10 23:00:00 2009 GMT
Not After : Aug 10 23:00:00 2019 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:27:0c:60:cf:ca:31:8a:91:db:8f:67:c7:95:04:
6d:df:18:31:99:2c:97:8a:71:8d:7b:c2:b9:79:3d:
02:86:21:a9:1b:5a:0c:55:03:cc:cc:18:2c:1b:96:
52:81:dc:70:62:7f:c9:f4:67:cd:d3:f4:43:31:b4:
a5:75:0b:19:3b
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Subject Alternative Name: critical
DNS:asd
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:3b:b7:b6:5d:a4:13:a1:f2:d8:42:5e:36:b9:e5:
41:7a:90:1c:ea:45:3f:11:6e:b7:b0:7d:b0:f7:bc:22:8b:35:
02:20:25:7a:88:77:4c:8a:fd:9d:e8:93:33:93:6d:f7:c3:80:
ba:a1:1c:51:3e:04:b6:7f:c1:ff:a2:3a:c4:87:ac:f9
-----BEGIN CERTIFICATE-----
MIIBBDCBqqADAgECAgEAMAoGCCqGSM49BAMCMAAwHhcNMDkxMTEwMjMwMDAwWhcN
MTkwODEwMjMwMDAwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJwxgz8ox
ipHbj2fHlQRt3xgxmSyXinGNe8K5eT0ChiGpG1oMVQPMzBgsG5ZSgdxwYn/J9GfN
0/RDMbSldQsZO6MVMBMwEQYDVR0RAQH/BAcwBYIDYXNkMAwGCCqGSM49BAMCBQAD
RwAwRAIgO7e2XaQTofLYQl42ueVBepAc6kU/EW63sH2w97wiizUCICV6iHdMiv2d
6JMzk233w4C6oRxRPgS2f8H/ojrEh6z5
-----END CERTIFICATE-----

0 comments on commit de9eafb

Please sign in to comment.