github.com/go-graphite/carbonapi@v0.17.0/pkg/tlsconfig/parse.go (about) 1 package tlsconfig 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "os" 7 8 merry2 "github.com/ansel1/merry/v2" 9 ) 10 11 // ParseServerTLSConfig parses server and client TLSConfig struct and returns &tls.Config, list of warnings or error if 12 // parsing has failed. 13 // At this moment warnings are only about insecure ciphers 14 func ParseServerTLSConfig(serverTLSConfig, clientTLSConfig *TLSConfig) (*tls.Config, []string, error) { 15 caCertPool := x509.NewCertPool() 16 17 for _, caCert := range serverTLSConfig.CACertFiles { 18 cert, err := os.ReadFile(caCert) 19 if err != nil { 20 return nil, nil, err 21 } 22 caCertPool.AppendCertsFromPEM(cert) 23 } 24 25 if len(serverTLSConfig.CertificatePairs) == 0 { 26 return nil, nil, merry2.Errorf("no server certificate pairs provided") 27 } 28 29 certificates := make([]tls.Certificate, 0, len(serverTLSConfig.CertificatePairs)) 30 31 for _, certPair := range serverTLSConfig.CertificatePairs { 32 certificate, err := tls.LoadX509KeyPair(certPair.CertFile, certPair.PrivateKeyFile) 33 if err != nil { 34 return nil, nil, err 35 } 36 certificates = append(certificates, certificate) 37 } 38 39 minTLSVersion, err := ParseTLSVersion(serverTLSConfig.MinTLSVersion) 40 if err != nil { 41 return nil, nil, err 42 } 43 maxTLSVersion, err := ParseTLSVersion(serverTLSConfig.MaxTLSVersion) 44 if err != nil { 45 return nil, nil, err 46 } 47 48 curves, err := ParseCurves(serverTLSConfig.Curves) 49 if err != nil { 50 return nil, nil, err 51 } 52 53 ciphers, warns, err := CipherSuitesToUint16(serverTLSConfig.CipherSuites) 54 if err != nil { 55 return nil, nil, err 56 } 57 58 clientAuth, err := ParseClientAuthType(serverTLSConfig.ClientAuth) 59 if err != nil { 60 return nil, nil, err 61 } 62 63 if serverTLSConfig.InsecureSkipVerify { 64 warns = append(warns, "InsecureSkipVerify is set to true, it's not recommended to use that in production") 65 } 66 67 tlsConfig := &tls.Config{ 68 RootCAs: caCertPool, 69 Certificates: certificates, 70 MinVersion: minTLSVersion, 71 MaxVersion: maxTLSVersion, 72 ServerName: serverTLSConfig.ServerName, 73 InsecureSkipVerify: serverTLSConfig.InsecureSkipVerify, 74 CurvePreferences: curves, 75 CipherSuites: ciphers, 76 ClientAuth: clientAuth, 77 } 78 79 if clientAuth == tls.NoClientCert && len(clientTLSConfig.CACertFiles) > 0 { 80 warns = append(warns, "NoClientCert checking specified, but client CAs provided") 81 } 82 83 if clientAuth != tls.NoClientCert { 84 if len(clientTLSConfig.CACertFiles) == 0 { 85 return nil, nil, merry2.Errorf("clientAuth set to '%v', but no client CAs provided", serverTLSConfig.ClientAuth) 86 } 87 clientCACertPool := x509.NewCertPool() 88 89 for _, caCert := range clientTLSConfig.CACertFiles { 90 cert, err := os.ReadFile(caCert) 91 if err != nil { 92 return nil, nil, err 93 } 94 clientCACertPool.AppendCertsFromPEM(cert) 95 } 96 tlsConfig.ClientCAs = clientCACertPool 97 } 98 99 return tlsConfig, warns, nil 100 } 101 102 // ParseClientTLSConfig parses TLSConfig as it should be used for HTTPS client mTLS and returns &tls.Config, list of 103 // warnings or error if parsing has failed. 104 // At this moment warnings are only about insecure ciphers 105 func ParseClientTLSConfig(serverTLSConfig *TLSConfig) (*tls.Config, []string, error) { 106 caCertPool := x509.NewCertPool() 107 108 for _, caCert := range serverTLSConfig.CACertFiles { 109 cert, err := os.ReadFile(caCert) 110 if err != nil { 111 return nil, nil, err 112 } 113 caCertPool.AppendCertsFromPEM(cert) 114 } 115 116 if len(serverTLSConfig.CertificatePairs) == 0 { 117 return nil, nil, merry2.Errorf("no server certificate pairs provided") 118 } 119 120 certificates := make([]tls.Certificate, 0, len(serverTLSConfig.CertificatePairs)) 121 122 for _, certPair := range serverTLSConfig.CertificatePairs { 123 certificate, err := tls.LoadX509KeyPair(certPair.CertFile, certPair.PrivateKeyFile) 124 if err != nil { 125 return nil, nil, err 126 } 127 certificates = append(certificates, certificate) 128 } 129 130 minTLSVersion, err := ParseTLSVersion(serverTLSConfig.MinTLSVersion) 131 if err != nil { 132 return nil, nil, err 133 } 134 maxTLSVersion, err := ParseTLSVersion(serverTLSConfig.MaxTLSVersion) 135 if err != nil { 136 return nil, nil, err 137 } 138 139 curves, err := ParseCurves(serverTLSConfig.Curves) 140 if err != nil { 141 return nil, nil, err 142 } 143 144 ciphers, warns, err := CipherSuitesToUint16(serverTLSConfig.CipherSuites) 145 if err != nil { 146 return nil, nil, err 147 } 148 149 if serverTLSConfig.InsecureSkipVerify { 150 warns = append(warns, "InsecureSkipVerify is set to true, it's not recommended to use that in production") 151 } 152 153 tlsConfig := &tls.Config{ 154 RootCAs: caCertPool, 155 Certificates: certificates, 156 MinVersion: minTLSVersion, 157 MaxVersion: maxTLSVersion, 158 ServerName: serverTLSConfig.ServerName, 159 InsecureSkipVerify: serverTLSConfig.InsecureSkipVerify, 160 CurvePreferences: curves, 161 CipherSuites: ciphers, 162 } 163 164 return tlsConfig, warns, nil 165 }