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 }