...

Source file src/github.com/google/certificate-transparency-go/loglist3/logfilter.go

Documentation: github.com/google/certificate-transparency-go/loglist3

     1  // Copyright 2022 Google LLC. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package loglist3
    16  
    17  import (
    18  	"github.com/google/certificate-transparency-go/x509"
    19  	"github.com/google/certificate-transparency-go/x509util"
    20  	"k8s.io/klog/v2"
    21  )
    22  
    23  // LogRoots maps Log-URLs (stated at LogList) to the pools of their accepted
    24  // root-certificates.
    25  type LogRoots map[string]*x509util.PEMCertPool
    26  
    27  // Compatible creates a new LogList containing only Logs matching the temporal,
    28  // root-acceptance and Log-status conditions.
    29  func (ll *LogList) Compatible(cert *x509.Certificate, certRoot *x509.Certificate, roots LogRoots) LogList {
    30  	active := ll.TemporallyCompatible(cert)
    31  	return active.RootCompatible(certRoot, roots)
    32  }
    33  
    34  // SelectByStatus creates a new LogList containing only logs with status
    35  // provided from the original.
    36  func (ll *LogList) SelectByStatus(lstats []LogStatus) LogList {
    37  	var active LogList
    38  	for _, op := range ll.Operators {
    39  		activeOp := *op
    40  		activeOp.Logs = []*Log{}
    41  		for _, l := range op.Logs {
    42  			for _, lstat := range lstats {
    43  				if l.State.LogStatus() == lstat {
    44  					activeOp.Logs = append(activeOp.Logs, l)
    45  					break
    46  				}
    47  			}
    48  		}
    49  		if len(activeOp.Logs) > 0 {
    50  			active.Operators = append(active.Operators, &activeOp)
    51  		}
    52  	}
    53  	return active
    54  }
    55  
    56  // RootCompatible creates a new LogList containing only the logs of original
    57  // LogList that are compatible with the provided cert, according to
    58  // the passed in collection of per-log roots. Logs that are missing from
    59  // the collection are treated as always compatible and included, even if
    60  // an empty cert root is passed in.
    61  // Cert-root when provided is expected to be CA-cert.
    62  func (ll *LogList) RootCompatible(certRoot *x509.Certificate, roots LogRoots) LogList {
    63  	var compatible LogList
    64  
    65  	// Check whether root is a CA-cert.
    66  	if certRoot != nil && !certRoot.IsCA {
    67  		klog.Warningf("Compatible method expects fully rooted chain, while last cert of the chain provided is not root")
    68  		return compatible
    69  	}
    70  
    71  	for _, op := range ll.Operators {
    72  		compatibleOp := *op
    73  		compatibleOp.Logs = []*Log{}
    74  		for _, l := range op.Logs {
    75  			// If root set is not defined, we treat Log as compatible assuming no
    76  			// knowledge of its roots.
    77  			if _, ok := roots[l.URL]; !ok {
    78  				compatibleOp.Logs = append(compatibleOp.Logs, l)
    79  				continue
    80  			}
    81  
    82  			if certRoot == nil {
    83  				continue
    84  			}
    85  
    86  			// Check root is accepted.
    87  			if roots[l.URL].Included(certRoot) {
    88  				compatibleOp.Logs = append(compatibleOp.Logs, l)
    89  			}
    90  		}
    91  		if len(compatibleOp.Logs) > 0 {
    92  			compatible.Operators = append(compatible.Operators, &compatibleOp)
    93  		}
    94  	}
    95  	return compatible
    96  }
    97  
    98  // TemporallyCompatible creates a new LogList containing only the logs of
    99  // original LogList that are compatible with the provided cert, according to
   100  // NotAfter and TemporalInterval matching.
   101  // Returns empty LogList if nil-cert is provided.
   102  func (ll *LogList) TemporallyCompatible(cert *x509.Certificate) LogList {
   103  	var compatible LogList
   104  	if cert == nil {
   105  		return compatible
   106  	}
   107  
   108  	for _, op := range ll.Operators {
   109  		compatibleOp := *op
   110  		compatibleOp.Logs = []*Log{}
   111  		for _, l := range op.Logs {
   112  			if l.TemporalInterval == nil {
   113  				compatibleOp.Logs = append(compatibleOp.Logs, l)
   114  				continue
   115  			}
   116  			if cert.NotAfter.Before(l.TemporalInterval.EndExclusive) && (cert.NotAfter.After(l.TemporalInterval.StartInclusive) || cert.NotAfter.Equal(l.TemporalInterval.StartInclusive)) {
   117  				compatibleOp.Logs = append(compatibleOp.Logs, l)
   118  			}
   119  		}
   120  		if len(compatibleOp.Logs) > 0 {
   121  			compatible.Operators = append(compatible.Operators, &compatibleOp)
   122  		}
   123  	}
   124  	return compatible
   125  }
   126  

View as plain text