Skip to content

Commit

Permalink
Merge pull request hashicorp#1370 from hashicorp/go-rootcerts
Browse files Browse the repository at this point in the history
Switch our tri-copy ca loading code to go-rootcerts
  • Loading branch information
jefferai committed May 3, 2016
2 parents e2091c3 + d3f1176 commit 78a2831
Show file tree
Hide file tree
Showing 20 changed files with 780 additions and 182 deletions.
4 changes: 4 additions & 0 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 12 additions & 89 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@ package api

import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"time"

"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-rootcerts"
)

const EnvVaultAddress = "VAULT_ADDR"
Expand Down Expand Up @@ -84,9 +81,9 @@ func (c *Config) ReadEnvironment() error {
var foundInsecure bool
var envTLSServerName string

var newCertPool *x509.CertPool
var clientCert tls.Certificate
var foundClientCert bool
var err error

if v := os.Getenv(EnvVaultAddress); v != "" {
envAddress = v
Expand Down Expand Up @@ -116,16 +113,6 @@ func (c *Config) ReadEnvironment() error {
}
// If we need custom TLS configuration, then set it
if envCACert != "" || envCAPath != "" || envClientCert != "" || envClientKey != "" || envInsecure {
var err error
if envCACert != "" {
newCertPool, err = LoadCACert(envCACert)
} else if envCAPath != "" {
newCertPool, err = LoadCAPath(envCAPath)
}
if err != nil {
return fmt.Errorf("Error setting up CA path: %s", err)
}

if envClientCert != "" && envClientKey != "" {
clientCert, err = tls.LoadX509KeyPair(envClientCert, envClientKey)
if err != nil {
Expand All @@ -145,16 +132,23 @@ func (c *Config) ReadEnvironment() error {
if foundInsecure {
clientTLSConfig.InsecureSkipVerify = envInsecure
}
if newCertPool != nil {
clientTLSConfig.RootCAs = newCertPool
}

if foundClientCert {
clientTLSConfig.Certificates = []tls.Certificate{clientCert}
}
if envTLSServerName != "" {
clientTLSConfig.ServerName = envTLSServerName
}

rootConfig := &rootcerts.Config{
CAFile: envCACert,
CAPath: envCAPath,
}
err = rootcerts.ConfigureTLS(clientTLSConfig, rootConfig)
if err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -310,74 +304,3 @@ START:

return result, nil
}

// Loads the certificate from given path and creates a certificate pool from it.
func LoadCACert(path string) (*x509.CertPool, error) {
certs, err := loadCertFromPEM(path)
if err != nil {
return nil, err
}

result := x509.NewCertPool()
for _, cert := range certs {
result.AddCert(cert)
}

return result, nil
}

// Loads the certificates present in the given directory and creates a
// certificate pool from it.
func LoadCAPath(path string) (*x509.CertPool, error) {
result := x509.NewCertPool()
fn := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

certs, err := loadCertFromPEM(path)
if err != nil {
return err
}

for _, cert := range certs {
result.AddCert(cert)
}
return nil
}

return result, filepath.Walk(path, fn)
}

// Creates a certificate from the given path
func loadCertFromPEM(path string) ([]*x509.Certificate, error) {
pemCerts, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}

certs := make([]*x509.Certificate, 0, 5)
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}

cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}

certs = append(certs, cert)
}

return certs, nil
}
12 changes: 5 additions & 7 deletions api/ssh_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-rootcerts"
"github.com/hashicorp/hcl"
"github.com/hashicorp/hcl/hcl/ast"
"github.com/mitchellh/mapstructure"
Expand Down Expand Up @@ -85,17 +86,14 @@ func (c *SSHHelperConfig) NewClient() (*Client, error) {

// Check if certificates are provided via config file.
if c.CACert != "" || c.CAPath != "" || c.TLSSkipVerify {
var certPool *x509.CertPool
var err error
if c.CACert != "" {
certPool, err = LoadCACert(c.CACert)
} else if c.CAPath != "" {
certPool, err = LoadCAPath(c.CAPath)
rootConfig := &rootcerts.Config{
CAFile: c.CACert,
CAPath: c.CAPath,
}
certPool, err := rootcerts.LoadCACerts(rootConfig)
if err != nil {
return nil, err
}

// Enable TLS on the HTTP client information
c.SetTLSParameters(clientConfig, certPool)
}
Expand Down
12 changes: 9 additions & 3 deletions builtin/credential/cert/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"testing"
"time"

"github.com/hashicorp/vault/api"
"github.com/hashicorp/go-rootcerts"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
logicaltest "github.com/hashicorp/vault/logical/testing"
Expand Down Expand Up @@ -52,7 +52,10 @@ func connectionState(t *testing.T, serverCAPath, serverCertPath, serverKeyPath,
t.Fatal(err)
}
// Load the CA cert required by the client to authenticate the server.
serverCAs, err := api.LoadCACert(serverCAPath)
rootConfig := &rootcerts.Config{
CAFile: serverCAPath,
}
serverCAs, err := rootcerts.LoadCACerts(rootConfig)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -569,7 +572,10 @@ func testConnState(t *testing.T, certPath, keyPath, rootCertPath string) tls.Con
if err != nil {
t.Fatalf("err: %v", err)
}
rootCAs, err := api.LoadCACert(rootCertPath)
rootConfig := &rootcerts.Config{
CAFile: rootCertPath,
}
rootCAs, err := rootcerts.LoadCACerts(rootConfig)
if err != nil {
t.Fatalf("err: %v", err)
}
Expand Down
89 changes: 6 additions & 83 deletions meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@ package meta
import (
"bufio"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-rootcerts"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/command/token"
"github.com/mitchellh/cli"
Expand Down Expand Up @@ -74,20 +70,14 @@ func (m *Meta) Client() (*api.Client, error) {
// existing TLS config
tlsConfig := config.HttpClient.Transport.(*http.Transport).TLSClientConfig

var certPool *x509.CertPool
var err error
if m.flagCACert != "" {
certPool, err = api.LoadCACert(m.flagCACert)
} else if m.flagCAPath != "" {
certPool, err = api.LoadCAPath(m.flagCAPath)
rootConfig := &rootcerts.Config{
CAFile: m.flagCACert,
CAPath: m.flagCAPath,
}
if err != nil {
return nil, errwrap.Wrapf("Error setting up CA path: {{err}}", err)
if err := rootcerts.ConfigureTLS(tlsConfig, rootConfig); err != nil {
return nil, err
}

if certPool != nil {
tlsConfig.RootCAs = certPool
}
if m.flagInsecure {
tlsConfig.InsecureSkipVerify = true
}
Expand Down Expand Up @@ -175,73 +165,6 @@ func (m *Meta) FlagSet(n string, fs FlagSetFlags) *flag.FlagSet {
return f
}

func (m *Meta) loadCACert(path string) (*x509.CertPool, error) {
certs, err := m.loadCertFromPEM(path)
if err != nil {
return nil, fmt.Errorf("Error loading %s: %s", path, err)
}

result := x509.NewCertPool()
for _, cert := range certs {
result.AddCert(cert)
}

return result, nil
}

func (m *Meta) loadCAPath(path string) (*x509.CertPool, error) {
result := x509.NewCertPool()
fn := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

certs, err := m.loadCertFromPEM(path)
if err != nil {
return fmt.Errorf("Error loading %s: %s", path, err)
}

for _, cert := range certs {
result.AddCert(cert)
}
return nil
}

return result, filepath.Walk(path, fn)
}

func (m *Meta) loadCertFromPEM(path string) ([]*x509.Certificate, error) {
pemCerts, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}

certs := make([]*x509.Certificate, 0, 5)
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}

cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}

certs = append(certs, cert)
}

return certs, nil
}

// GeneralOptionsUsage returns the usage documenation for commonly
// available options
func GeneralOptionsUsage() string {
Expand Down
12 changes: 12 additions & 0 deletions vendor/github.com/hashicorp/go-rootcerts/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 78a2831

Please sign in to comment.