func testConnState(t *testing.T, certPath, keyPath, rootCertPath string) tls.ConnectionState { cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { t.Fatalf("err: %v", err) } rootCAs, err := api.LoadCACert(rootCertPath) if err != nil { t.Fatalf("err: %v", err) } listenConf := &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequestClientCert, InsecureSkipVerify: false, RootCAs: rootCAs, } dialConf := new(tls.Config) *dialConf = *listenConf list, err := tls.Listen("tcp", "127.0.0.1:0", listenConf) if err != nil { t.Fatalf("err: %v", err) } defer list.Close() go func() { addr := list.Addr().String() conn, err := tls.Dial("tcp", addr, dialConf) if err != nil { t.Fatalf("err: %v", err) } defer conn.Close() // Write ping conn.Write([]byte("ping")) }() serverConn, err := list.Accept() if err != nil { t.Fatalf("err: %v", err) } defer serverConn.Close() // Read the pign buf := make([]byte, 4) serverConn.Read(buf) // Grab the current state connState := serverConn.(*tls.Conn).ConnectionState() return connState }
// NewVaultService creates a new VaultService and loads its configuration from the given settings. func NewVaultService(log *logging.Logger, srvCfg VaultServiceConfig) (*VaultService, error) { // Create a vault client var serverName, address string if srvCfg.VaultAddr != "" { address = srvCfg.VaultAddr log.Debugf("Setting vault address to %s", address) url, err := url.Parse(address) if err != nil { return nil, maskAny(err) } host, _, err := net.SplitHostPort(url.Host) if err != nil { return nil, maskAny(err) } serverName = host } var newCertPool *x509.CertPool if srvCfg.VaultCACert != "" || srvCfg.VaultCAPath != "" { var err error if srvCfg.VaultCACert != "" { log.Debugf("Loading CA cert: %s", srvCfg.VaultCACert) newCertPool, err = api.LoadCACert(srvCfg.VaultCACert) } else { log.Debugf("Loading CA certs from: %s", srvCfg.VaultCAPath) newCertPool, err = api.LoadCAPath(srvCfg.VaultCAPath) } if err != nil { return nil, maskAny(err) } } var token string if srvCfg.TokenPath != "" { log.Debugf("Loading token from %s", srvCfg.TokenPath) var err error token, err = readID(srvCfg.TokenPath) if err != nil { return nil, maskAny(err) } } return &VaultService{ log: log, address: address, serverName: serverName, initialToken: token, certPool: newCertPool, }, nil }
// Client returns the API client to a Vault server given the configured // flag settings for this command. func (m *Meta) Client() (*api.Client, error) { config := api.DefaultConfig() err := config.ReadEnvironment() if err != nil { return nil, errwrap.Wrapf("error reading environment: {{err}}", err) } if m.flagAddress != "" { config.Address = m.flagAddress } if m.ForceAddress != "" { config.Address = m.ForceAddress } // If we need custom TLS configuration, then set it if m.flagCACert != "" || m.flagCAPath != "" || m.flagClientCert != "" || m.flagClientKey != "" || m.flagInsecure { // We may have set items from the environment so start with the // 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) } if err != nil { return nil, errwrap.Wrapf("Error setting up CA path: {{err}}", err) } if certPool != nil { tlsConfig.RootCAs = certPool } if m.flagInsecure { tlsConfig.InsecureSkipVerify = true } if m.flagClientCert != "" && m.flagClientKey != "" { tlsCert, err := tls.LoadX509KeyPair(m.flagClientCert, m.flagClientKey) if err != nil { return nil, err } tlsConfig.Certificates = []tls.Certificate{tlsCert} } else if m.flagClientCert != "" || m.flagClientKey != "" { return nil, fmt.Errorf("Both client cert and client key must be provided") } } // Build the client client, err := api.NewClient(config) if err != nil { return nil, err } // If we have a token directly, then set that token := m.ClientToken // Try to set the token to what is already stored if token == "" { token = client.Token() } // If we don't have a token, check the token helper if token == "" { if m.TokenHelper != nil { // If we have a token, then set that tokenHelper, err := m.TokenHelper() if err != nil { return nil, err } token, err = tokenHelper.Get() if err != nil { return nil, err } } } // Set the token if token != "" { client.SetToken(token) } return client, nil }
// Unlike testConnState, this method does not use the same 'tls.Config' objects for // both dialing and listening. Instead, it runs the server without specifying its CA. // But the client, presents the CA cert of the server to trust the server. // The client can present a cert and key which is completely independent of server's CA. // The connection state returned will contain the certificate presented by the client. func connectionState(t *testing.T, serverCAPath, serverCertPath, serverKeyPath, clientCertPath, clientKeyPath string) tls.ConnectionState { serverKeyPair, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath) if err != nil { t.Fatal(err) } // Prepare the listener configuration with server's key pair listenConf := &tls.Config{ Certificates: []tls.Certificate{serverKeyPair}, ClientAuth: tls.RequestClientCert, } clientKeyPair, err := tls.LoadX509KeyPair(clientCertPath, clientKeyPath) if err != nil { t.Fatal(err) } // Load the CA cert required by the client to authenticate the server. serverCAs, err := api.LoadCACert(serverCAPath) if err != nil { t.Fatal(err) } // Prepare the dial configuration that the client uses to establish the connection. dialConf := &tls.Config{ Certificates: []tls.Certificate{clientKeyPair}, RootCAs: serverCAs, } // Start the server. list, err := tls.Listen("tcp", "127.0.0.1:0", listenConf) if err != nil { t.Fatal(err) } defer list.Close() // Establish a connection from the client side and write a few bytes. go func() { addr := list.Addr().String() conn, err := tls.Dial("tcp", addr, dialConf) if err != nil { t.Fatalf("err: %v", err) } defer conn.Close() // Write ping conn.Write([]byte("ping")) }() // Accept the connection on the server side. serverConn, err := list.Accept() if err != nil { t.Fatal(err) } defer serverConn.Close() // Read the ping buf := make([]byte, 4) serverConn.Read(buf) // Grab the current state connState := serverConn.(*tls.Conn).ConnectionState() return connState }