github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/certpool.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package api 5 6 import ( 7 "crypto/x509" 8 "os" 9 "path/filepath" 10 11 "github.com/juju/errors" 12 "github.com/juju/utils/v3/cert" 13 14 "github.com/juju/juju/core/paths" 15 ) 16 17 var certDir = filepath.FromSlash(paths.CertDir(paths.CurrentOS())) 18 19 // CreateCertPool creates a new x509.CertPool and adds in the caCert passed 20 // in. All certs from the cert directory (/etc/juju/cert.d on ubuntu) are 21 // also added. 22 func CreateCertPool(caCert string) (*x509.CertPool, error) { 23 24 pool := x509.NewCertPool() 25 if caCert != "" { 26 xcert, err := cert.ParseCert(caCert) 27 if err != nil { 28 return nil, errors.Annotatef(err, "cannot parse certificate %q", caCert) 29 } 30 pool.AddCert(xcert) 31 } 32 33 count := processCertDir(pool) 34 if count >= 0 { 35 logger.Debugf("added %d certs to the pool from %s", count, certDir) 36 } 37 38 return pool, nil 39 } 40 41 // processCertDir iterates through the certDir looking for *.pem files. 42 // Each pem file is read in turn and added to the pool. A count of the number 43 // of successful certificates processed is returned. 44 func processCertDir(pool *x509.CertPool) (count int) { 45 fileInfo, err := os.Stat(certDir) 46 if os.IsNotExist(err) { 47 logger.Tracef("cert dir %q does not exist", certDir) 48 return -1 49 } 50 if err != nil { 51 logger.Infof("unexpected error reading cert dir: %s", err) 52 return -1 53 } 54 if !fileInfo.IsDir() { 55 logger.Infof("cert dir %q is not a directory", certDir) 56 return -1 57 } 58 59 matches, err := filepath.Glob(filepath.Join(certDir, "*.pem")) 60 if err != nil { 61 logger.Infof("globbing files failed: %s", err) 62 return -1 63 } 64 65 for _, match := range matches { 66 data, err := os.ReadFile(match) 67 if err != nil { 68 logger.Infof("error reading %q: %v", match, err) 69 continue 70 } 71 certificate, err := cert.ParseCert(string(data)) 72 if err != nil { 73 logger.Infof("error parsing cert %q: %v", match, err) 74 continue 75 } 76 pool.AddCert(certificate) 77 count++ 78 } 79 return count 80 }