...

Source file src/github.com/letsencrypt/boulder/linter/lints/chrome/e_scts_from_same_operator.go

Documentation: github.com/letsencrypt/boulder/linter/lints/chrome

     1  package chrome
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/zmap/zcrypto/x509"
     7  	"github.com/zmap/zcrypto/x509/ct"
     8  	"github.com/zmap/zlint/v3/lint"
     9  	"github.com/zmap/zlint/v3/util"
    10  
    11  	"github.com/letsencrypt/boulder/ctpolicy/loglist"
    12  	"github.com/letsencrypt/boulder/linter/lints"
    13  )
    14  
    15  type sctsFromSameOperator struct {
    16  	logList loglist.List
    17  }
    18  
    19  func init() {
    20  	lint.RegisterLint(&lint.Lint{
    21  		Name:          "e_scts_from_same_operator",
    22  		Description:   "Let's Encrypt Subscriber Certificates have two SCTs from logs run by different operators",
    23  		Citation:      "Chrome CT Policy",
    24  		Source:        lints.ChromeCTPolicy,
    25  		EffectiveDate: time.Date(2022, time.April, 15, 0, 0, 0, 0, time.UTC),
    26  		Lint:          NewSCTsFromSameOperator,
    27  	})
    28  }
    29  
    30  func NewSCTsFromSameOperator() lint.LintInterface {
    31  	return &sctsFromSameOperator{logList: loglist.GetLintList()}
    32  }
    33  
    34  func (l *sctsFromSameOperator) CheckApplies(c *x509.Certificate) bool {
    35  	return util.IsSubscriberCert(c) && !util.IsExtInCert(c, util.CtPoisonOID)
    36  }
    37  
    38  func (l *sctsFromSameOperator) Execute(c *x509.Certificate) *lint.LintResult {
    39  	if len(l.logList) == 0 {
    40  		return &lint.LintResult{
    41  			Status:  lint.NE,
    42  			Details: "Failed to load log list, unable to check Certificate SCTs.",
    43  		}
    44  	}
    45  
    46  	if len(c.SignedCertificateTimestampList) < 2 {
    47  		return &lint.LintResult{
    48  			Status:  lint.Error,
    49  			Details: "Certificate had too few embedded SCTs; browser policy requires 2.",
    50  		}
    51  	}
    52  
    53  	logIDs := make(map[ct.SHA256Hash]struct{})
    54  	for _, sct := range c.SignedCertificateTimestampList {
    55  		logIDs[sct.LogID] = struct{}{}
    56  	}
    57  
    58  	if len(logIDs) < 2 {
    59  		return &lint.LintResult{
    60  			Status:  lint.Error,
    61  			Details: "Certificate SCTs from too few distinct logs; browser policy requires 2.",
    62  		}
    63  	}
    64  
    65  	operatorNames := make(map[string]struct{})
    66  	for logID := range logIDs {
    67  		operator, err := l.logList.OperatorForLogID(logID.Base64String())
    68  		if err != nil {
    69  			// This certificate *may* have more than 2 SCTs, so missing one now isn't
    70  			// a problem.
    71  			continue
    72  		}
    73  		operatorNames[operator] = struct{}{}
    74  	}
    75  
    76  	if len(operatorNames) < 2 {
    77  		return &lint.LintResult{
    78  			Status:  lint.Error,
    79  			Details: "Certificate SCTs from too few distinct log operators; browser policy requires 2.",
    80  		}
    81  	}
    82  
    83  	return &lint.LintResult{
    84  		Status: lint.Pass,
    85  	}
    86  }
    87  

View as plain text