...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package x509util
16
17 import (
18 "crypto/sha256"
19 "encoding/pem"
20 "errors"
21 "fmt"
22 "os"
23
24 "github.com/google/certificate-transparency-go/x509"
25 "k8s.io/klog/v2"
26 )
27
28
29 const pemCertificateBlockType string = "CERTIFICATE"
30
31
32
33
34
35 type PEMCertPool struct {
36
37 fingerprintToCertMap map[[sha256.Size]byte]x509.Certificate
38 rawCerts []*x509.Certificate
39 certPool *x509.CertPool
40 }
41
42
43 func NewPEMCertPool() *PEMCertPool {
44 return &PEMCertPool{fingerprintToCertMap: make(map[[sha256.Size]byte]x509.Certificate), certPool: x509.NewCertPool()}
45 }
46
47
48
49 func (p *PEMCertPool) AddCert(cert *x509.Certificate) {
50 fingerprint := sha256.Sum256(cert.Raw)
51 _, ok := p.fingerprintToCertMap[fingerprint]
52
53 if !ok {
54 p.fingerprintToCertMap[fingerprint] = *cert
55 p.certPool.AddCert(cert)
56 p.rawCerts = append(p.rawCerts, cert)
57 }
58 }
59
60
61 func (p *PEMCertPool) Included(cert *x509.Certificate) bool {
62 fingerprint := sha256.Sum256(cert.Raw)
63 _, ok := p.fingerprintToCertMap[fingerprint]
64 return ok
65 }
66
67
68
69
70 func (p *PEMCertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
71 for len(pemCerts) > 0 {
72 var block *pem.Block
73 block, pemCerts = pem.Decode(pemCerts)
74 if block == nil {
75 break
76 }
77 if block.Type != pemCertificateBlockType || len(block.Headers) != 0 {
78 continue
79 }
80
81 cert, err := x509.ParseCertificate(block.Bytes)
82 if x509.IsFatal(err) {
83 klog.Warningf("error parsing PEM certificate: %v", err)
84 return false
85 }
86
87 p.AddCert(cert)
88 ok = true
89 }
90
91 return
92 }
93
94
95 func (p *PEMCertPool) AppendCertsFromPEMFile(pemFile string) error {
96 pemData, err := os.ReadFile(pemFile)
97 if err != nil {
98 return fmt.Errorf("failed to load PEM certs file: %v", err)
99 }
100
101 if !p.AppendCertsFromPEM(pemData) {
102 return errors.New("failed to parse PEM certs file")
103 }
104 return nil
105 }
106
107
108 func (p *PEMCertPool) Subjects() (res [][]byte) {
109 return p.certPool.Subjects()
110 }
111
112
113 func (p *PEMCertPool) CertPool() *x509.CertPool {
114 return p.certPool
115 }
116
117
118 func (p *PEMCertPool) RawCertificates() []*x509.Certificate {
119 return p.rawCerts
120 }
121
View as plain text