tcp_socket.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package sockets
  2. import (
  3. "crypto/tls"
  4. "crypto/x509"
  5. "fmt"
  6. "io/ioutil"
  7. "net"
  8. "os"
  9. "github.com/docker/docker/pkg/listenbuffer"
  10. )
  11. type TlsConfig struct {
  12. CA string
  13. Certificate string
  14. Key string
  15. Verify bool
  16. }
  17. func NewTlsConfig(tlsCert, tlsKey, tlsCA string, verify bool) *TlsConfig {
  18. return &TlsConfig{
  19. Verify: verify,
  20. Certificate: tlsCert,
  21. Key: tlsKey,
  22. CA: tlsCA,
  23. }
  24. }
  25. func NewTcpSocket(addr string, config *TlsConfig, activate <-chan struct{}) (net.Listener, error) {
  26. l, err := listenbuffer.NewListenBuffer("tcp", addr, activate)
  27. if err != nil {
  28. return nil, err
  29. }
  30. if config != nil {
  31. if l, err = setupTls(l, config); err != nil {
  32. return nil, err
  33. }
  34. }
  35. return l, nil
  36. }
  37. func setupTls(l net.Listener, config *TlsConfig) (net.Listener, error) {
  38. tlsCert, err := tls.LoadX509KeyPair(config.Certificate, config.Key)
  39. if err != nil {
  40. if os.IsNotExist(err) {
  41. return nil, fmt.Errorf("Could not load X509 key pair (%s, %s): %v", config.Certificate, config.Key, err)
  42. }
  43. return nil, fmt.Errorf("Error reading X509 key pair (%s, %s): %q. Make sure the key is encrypted.",
  44. config.Certificate, config.Key, err)
  45. }
  46. tlsConfig := &tls.Config{
  47. NextProtos: []string{"http/1.1"},
  48. Certificates: []tls.Certificate{tlsCert},
  49. // Avoid fallback on insecure SSL protocols
  50. MinVersion: tls.VersionTLS10,
  51. }
  52. if config.CA != "" {
  53. certPool := x509.NewCertPool()
  54. file, err := ioutil.ReadFile(config.CA)
  55. if err != nil {
  56. return nil, fmt.Errorf("Could not read CA certificate: %v", err)
  57. }
  58. certPool.AppendCertsFromPEM(file)
  59. tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
  60. tlsConfig.ClientCAs = certPool
  61. }
  62. return tls.NewListener(l, tlsConfig), nil
  63. }