tls_info.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // +build ignore
  2. package server
  3. import (
  4. "crypto/tls"
  5. "crypto/x509"
  6. "encoding/pem"
  7. "fmt"
  8. "io/ioutil"
  9. )
  10. // TLSInfo holds the SSL certificates paths.
  11. type TLSInfo struct {
  12. CertFile string `json:"CertFile"`
  13. KeyFile string `json:"KeyFile"`
  14. CAFile string `json:"CAFile"`
  15. }
  16. func (info TLSInfo) Scheme() string {
  17. if info.KeyFile != "" && info.CertFile != "" {
  18. return "https"
  19. } else {
  20. return "http"
  21. }
  22. }
  23. // Generates a tls.Config object for a server from the given files.
  24. func (info TLSInfo) ServerConfig() (*tls.Config, error) {
  25. // Both the key and cert must be present.
  26. if info.KeyFile == "" || info.CertFile == "" {
  27. return nil, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile)
  28. }
  29. var cfg tls.Config
  30. tlsCert, err := tls.LoadX509KeyPair(info.CertFile, info.KeyFile)
  31. if err != nil {
  32. return nil, err
  33. }
  34. cfg.Certificates = []tls.Certificate{tlsCert}
  35. if info.CAFile != "" {
  36. cfg.ClientAuth = tls.RequireAndVerifyClientCert
  37. cp, err := newCertPool(info.CAFile)
  38. if err != nil {
  39. return nil, err
  40. }
  41. cfg.RootCAs = cp
  42. cfg.ClientCAs = cp
  43. } else {
  44. cfg.ClientAuth = tls.NoClientCert
  45. }
  46. return &cfg, nil
  47. }
  48. // Generates a tls.Config object for a client from the given files.
  49. func (info TLSInfo) ClientConfig() (*tls.Config, error) {
  50. var cfg tls.Config
  51. if info.KeyFile == "" || info.CertFile == "" {
  52. return &cfg, nil
  53. }
  54. tlsCert, err := tls.LoadX509KeyPair(info.CertFile, info.KeyFile)
  55. if err != nil {
  56. return nil, err
  57. }
  58. cfg.Certificates = []tls.Certificate{tlsCert}
  59. if info.CAFile != "" {
  60. cp, err := newCertPool(info.CAFile)
  61. if err != nil {
  62. return nil, err
  63. }
  64. cfg.RootCAs = cp
  65. }
  66. return &cfg, nil
  67. }
  68. // newCertPool creates x509 certPool with provided CA file
  69. func newCertPool(CAFile string) (*x509.CertPool, error) {
  70. certPool := x509.NewCertPool()
  71. pemByte, err := ioutil.ReadFile(CAFile)
  72. if err != nil {
  73. return nil, err
  74. }
  75. for {
  76. var block *pem.Block
  77. block, pemByte = pem.Decode(pemByte)
  78. if block == nil {
  79. return certPool, nil
  80. }
  81. cert, err := x509.ParseCertificate(block.Bytes)
  82. if err != nil {
  83. return nil, err
  84. }
  85. certPool.AddCert(cert)
  86. }
  87. }