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