cloudflare/cloudflared

Public

mirrored from https://github.com/cloudflare/cloudflaredAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
2019.2.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

tlsconfig/tlsconfig.go

91lines · modecode

1// Package tlsconfig provides convenience functions for configuring TLS connections from the
2// command line.
3package tlsconfig
4
5import (
6 "crypto/tls"
7 "crypto/x509"
8 "io/ioutil"
9
10 "github.com/pkg/errors"
11)
12
13// Config is the user provided parameters to create a tls.Config
14type TLSParameters struct {
15 Cert string
16 Key string
17 GetCertificate *CertReloader
18 ClientCAs []string
19 RootCAs []string
20 ServerName string
21 CurvePreferences []tls.CurveID
22}
23
24// GetConfig returns a TLS configuration according to the Config set by the user.
25func GetConfig(p *TLSParameters) (*tls.Config, error) {
26 tlsconfig := &tls.Config{}
27 if p.Cert != "" && p.Key != "" {
28 cert, err := tls.LoadX509KeyPair(p.Cert, p.Key)
29 if err != nil {
30 return nil, errors.Wrap(err, "Error parsing X509 key pair")
31 }
32 tlsconfig.Certificates = []tls.Certificate{cert}
33 // BuildNameToCertificate parses Certificates and builds NameToCertificate from common name
34 // and SAN fields of leaf certificates
35 tlsconfig.BuildNameToCertificate()
36 }
37
38 if p.GetCertificate != nil {
39 // GetCertificate is called when client supplies SNI info or Certificates is empty.
40 // Order of retrieving certificate is GetCertificate, NameToCertificate and lastly first element of Certificates
41 tlsconfig.GetCertificate = p.GetCertificate.Cert
42 }
43
44 if len(p.ClientCAs) > 0 {
45 // set of root certificate authorities that servers use if required to verify a client certificate
46 // by the policy in ClientAuth
47 clientCAs, err := LoadCert(p.ClientCAs)
48 if err != nil {
49 return nil, errors.Wrap(err, "Error loading client CAs")
50 }
51 tlsconfig.ClientCAs = clientCAs
52 // server's policy for TLS Client Authentication. Default is no client cert
53 tlsconfig.ClientAuth = tls.RequireAndVerifyClientCert
54 }
55
56 if len(p.RootCAs) > 0 {
57 rootCAs, err := LoadCert(p.RootCAs)
58 if err != nil {
59 return nil, errors.Wrap(err, "Error loading root CAs")
60 }
61 tlsconfig.RootCAs = rootCAs
62 }
63
64 if p.ServerName != "" {
65 tlsconfig.ServerName = p.ServerName
66 }
67
68 if len(p.CurvePreferences) > 0 {
69 tlsconfig.CurvePreferences = p.CurvePreferences
70 } else {
71 // Cloudflare optimize CurveP256
72 tlsconfig.CurvePreferences = []tls.CurveID{tls.CurveP256}
73 }
74
75 return tlsconfig, nil
76}
77
78// LoadCert creates a CertPool containing all certificates in a PEM-format file.
79func LoadCert(certPaths []string) (*x509.CertPool, error) {
80 ca := x509.NewCertPool()
81 for _, certPath := range certPaths {
82 caCert, err := ioutil.ReadFile(certPath)
83 if err != nil {
84 return nil, errors.Wrapf(err, "Error reading certificate %s", certPath)
85 }
86 if !ca.AppendCertsFromPEM(caCert) {
87 return nil, errors.Wrapf(err, "Error parsing certificate %s", certPath)
88 }
89 }
90 return ca, nil
91}
92