Skip to content

Commit

Permalink
lints: disallow reserved iPAddresses in NCs (#414)
Browse files Browse the repository at this point in the history
Co-authored-by: Zakir Durumeric <zakird@gmail.com>
  • Loading branch information
zakird authored Mar 5, 2020
1 parent 48bf6ee commit 1968515
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 0 deletions.
63 changes: 63 additions & 0 deletions v2/lints/cabf_br/lint_ext_nc_intersects_reserved_ip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package cabf_br

/*
* 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.
*/

/************************************************
BRs: 7.1.5
(b) For each iPAddress range in permittedSubtrees, the CA MUST confirm that the
Applicant has been assigned the iPAddress range or has been authorized by the
assigner to act on the assignee's behalf.
BRs: 7.1.4.2.1
CAs SHALL NOT issue certificates with a subjectAlternativeName extension or
Subject commonName field containing a Reserved IP Address or Internal Name.
************************************************/

import (
"github.com/zmap/zcrypto/x509"
"github.com/zmap/zlint/v2/lint"
"github.com/zmap/zlint/v2/util"
)

type NCReservedIPNet struct{}

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

func (l *NCReservedIPNet) CheckApplies(c *x509.Certificate) bool {
return c.NotAfter.After(util.NoReservedIP) && util.IsExtInCert(c, util.NameConstOID)
}

func (l *NCReservedIPNet) Execute(c *x509.Certificate) *lint.LintResult {
for _, constraint := range c.PermittedIPAddresses {
if util.IntersectsIANAReserved(constraint.Data) {
return &lint.LintResult{Status: lint.Error}
}
}

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

func init() {
lint.RegisterLint(&lint.Lint{
Name: "e_ext_nc_intersects_reserved_ip",
Description: "iPAddress name constraint intersects an IANA reserved network",
Citation: "BRs: 7.1.5 / 7.1.4.2.1",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.CABEffectiveDate,
Lint: &NCReservedIPNet{},
})
}
40 changes: 40 additions & 0 deletions v2/lints/cabf_br/lint_ext_nc_intersects_reserved_ip_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cabf_br

/*
* 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.
*/

import (
"testing"

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

func TestNCIPNetReserved(t *testing.T) {
inputPath := "NCReservedIPNet.pem"
expected := lint.Error
out := test.TestLint("e_ext_nc_intersects_reserved_ip", inputPath)
if out.Status != expected {
t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status)
}
}

func TestNCIPNetNotReserved(t *testing.T) {
inputPath := "NCValidIPNet.pem"
expected := lint.Pass
out := test.TestLint("e_ext_nc_intersects_reserved_ip", inputPath)
if out.Status != expected {
t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status)
}
}
9 changes: 9 additions & 0 deletions v2/testdata/NCReservedIPNet.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE-----
MIIBIDCBy6ADAgECAgEBMA0GCSqGSIb3DQEBCwUAMAAwHhcNMTcxMTAxMDAwMDAw
WhcNMTcxMTAxMDAwMDAwWjAAMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPUKHIBE
9vJNmpMGGEDSjq6BURlG4bNwRy/JyTZaHlj7MfTraCuYgKT7NDLe/7byDZ3UQnL6
BeYQ7zBl6A8n6ysCAwEAAaMwMC4wEwYDVR0lBAwwCgYIKwYBBQUHAwEwFwYDVR0e
BBAwDqAMMAqHCMAAAAD//wAAMA0GCSqGSIb3DQEBCwUAA0EARpmi5GqWaFxCvP3J
CyGWDCROHOqx5qVSXCKp2tL1B2/hxoQ8H7ZkniF1T7Q0Ty2Mivpdn1iINXSR1vsv
vYP+Aw==
-----END CERTIFICATE-----
9 changes: 9 additions & 0 deletions v2/testdata/NCValidIPNet.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN CERTIFICATE-----
MIIBIDCBy6ADAgECAgEBMA0GCSqGSIb3DQEBCwUAMAAwHhcNMTcxMTAxMDAwMDAw
WhcNMTcxMTAxMDAwMDAwWjAAMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANtrQxdO
RIczJZR48zbQi6Q5GUOc9zZGSYqfjnoXE96N+CERx+PaYkHsRCPlZkqJ57dAfEao
/l2ZyAR31jk8ysECAwEAAaMwMC4wEwYDVR0lBAwwCgYIKwYBBQUHAwEwFwYDVR0e
BBAwDqAMMAqHCKYAAAD///8AMA0GCSqGSIb3DQEBCwUAA0EAmrW2tFHXgQzONqcq
qdNEZyHLRhAoxw0egu4kKd+q1vWKyszzmNwP8V+euxwkW6RZm0MBR/po0fGVSvfv
LlHuUQ==
-----END CERTIFICATE-----
13 changes: 13 additions & 0 deletions v2/util/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ func IsIANAReserved(ip net.IP) bool {
return false
}

// IntersectsIANAReserved checks if a CIDR intersects any IANA reserved CIDRs
func IntersectsIANAReserved(net net.IPNet) bool {
if !net.IP.IsGlobalUnicast() {
return true
}
for _, reserved := range reservedNetworks {
if reserved.Contains(net.IP) || net.Contains(reserved.IP) {
return true
}
}
return false
}

func init() {
var networks = map[subnetCategory][]string{
privateUse: {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"},
Expand Down

0 comments on commit 1968515

Please sign in to comment.