github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/x509/chain.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package x509
     6  
     7  import (
     8  	"bytes"
     9  	"strings"
    10  )
    11  
    12  // CertificateChain is a slice of certificates. The 0'th element is the leaf,
    13  // and the last element is a root. Successive elements have a child-parent
    14  // relationship.
    15  type CertificateChain []*Certificate
    16  
    17  // Range runs a function on each element of chain. It can modify each
    18  // certificate in place.
    19  func (chain CertificateChain) Range(f func(int, *Certificate)) {
    20  	for i, c := range chain {
    21  		f(i, c)
    22  	}
    23  }
    24  
    25  // SubjectAndKeyInChain returns true if the given SubjectAndKey is found in any
    26  // certificate in the chain.
    27  func (chain CertificateChain) SubjectAndKeyInChain(sk *SubjectAndKey) bool {
    28  	for _, cert := range chain {
    29  		if bytes.Equal(sk.RawSubject, cert.RawSubject) && bytes.Equal(sk.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
    30  			return true
    31  		}
    32  	}
    33  	return false
    34  }
    35  
    36  // CertificateSubjectAndKeyInChain returns true if the SubjectAndKey from c is
    37  // found in any certificate in the chain.
    38  func (chain CertificateChain) CertificateSubjectAndKeyInChain(c *Certificate) bool {
    39  	for _, cert := range chain {
    40  		if bytes.Equal(c.RawSubject, cert.RawSubject) && bytes.Equal(c.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
    41  			return true
    42  		}
    43  	}
    44  	return false
    45  }
    46  
    47  // CertificateInChain returns true if c is in the chain.
    48  func (chain CertificateChain) CertificateInChain(c *Certificate) bool {
    49  	for _, cert := range chain {
    50  		if bytes.Equal(c.Raw, cert.Raw) {
    51  			return true
    52  		}
    53  	}
    54  	return false
    55  }
    56  
    57  func (chain CertificateChain) AppendToFreshChain(c *Certificate) CertificateChain {
    58  	n := make([]*Certificate, len(chain)+1)
    59  	copy(n, chain)
    60  	n[len(chain)] = c
    61  	return n
    62  }
    63  
    64  func (chain CertificateChain) chainID() string {
    65  	var parts []string
    66  	for _, c := range chain {
    67  		parts = append(parts, string(c.FingerprintSHA256))
    68  	}
    69  	return strings.Join(parts, "")
    70  }