github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/config/clouds/tls.go (about) 1 package clouds 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "crypto/x509" 7 "fmt" 8 "os" 9 "path" 10 "strings" 11 ) 12 13 func computeTLSConfig(cloud Cloud, options cloudOpts) (*tls.Config, error) { 14 tlsConfig := new(tls.Config) 15 if caCertPath := coalesce(options.caCertPath, os.Getenv("OS_CACERT"), cloud.CACertFile); caCertPath != "" { 16 caCertPath, err := resolveTilde(caCertPath) 17 if err != nil { 18 return nil, fmt.Errorf("failed to resolve user home directory: %w", err) 19 } 20 21 caCert, err := os.ReadFile(caCertPath) 22 if err != nil { 23 return nil, fmt.Errorf("failed to open the CA cert file: %w", err) 24 } 25 26 caCertPool := x509.NewCertPool() 27 if ok := caCertPool.AppendCertsFromPEM(bytes.TrimSpace(caCert)); !ok { 28 return nil, fmt.Errorf("failed to parse the CA Cert from %q", caCertPath) 29 } 30 tlsConfig.RootCAs = caCertPool 31 } 32 33 tlsConfig.InsecureSkipVerify = func() bool { 34 if options.insecure != nil { 35 return *options.insecure 36 } 37 if cloud.Verify != nil { 38 return !*cloud.Verify 39 } 40 return false 41 }() 42 43 if clientCertPath, clientKeyPath := coalesce(options.clientCertPath, os.Getenv("OS_CERT"), cloud.ClientCertFile), coalesce(options.clientKeyPath, os.Getenv("OS_KEY"), cloud.ClientKeyFile); clientCertPath != "" && clientKeyPath != "" { 44 clientCertPath, err := resolveTilde(clientCertPath) 45 if err != nil { 46 return nil, fmt.Errorf("failed to resolve user home directory in client cert path: %w", err) 47 } 48 clientKeyPath, err := resolveTilde(clientKeyPath) 49 if err != nil { 50 return nil, fmt.Errorf("failed to resolve user home directory in client cert key path: %w", err) 51 } 52 53 clientCert, err := os.ReadFile(clientCertPath) 54 if err != nil { 55 return nil, fmt.Errorf("failed to read the client cert file: %w", err) 56 } 57 58 clientKey, err := os.ReadFile(clientKeyPath) 59 if err != nil { 60 return nil, fmt.Errorf("failed to read the client cert key file: %w", err) 61 } 62 63 cert, err := tls.X509KeyPair(clientCert, clientKey) 64 if err != nil { 65 return nil, err 66 } 67 68 tlsConfig.Certificates = []tls.Certificate{cert} 69 } else if clientCertPath != "" && clientKeyPath == "" { 70 return nil, fmt.Errorf("client cert is set, but client cert key is missing") 71 } else if clientCertPath == "" && clientKeyPath != "" { 72 return nil, fmt.Errorf("client cert key is set, but client cert is missing") 73 } 74 75 return tlsConfig, nil 76 } 77 78 func resolveTilde(p string) (string, error) { 79 if after := strings.TrimPrefix(p, "~/"); after != p { 80 h, err := os.UserHomeDir() 81 if err != nil { 82 return "", fmt.Errorf("failed to resolve user home directory: %w", err) 83 } 84 return path.Join(h, after), nil 85 } 86 return p, nil 87 }