mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
package server
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io/ioutil"
|
|
)
|
|
|
|
// TLSInfo holds the SSL certificates paths.
|
|
type TLSInfo struct {
|
|
CertFile string `json:"CertFile"`
|
|
KeyFile string `json:"KeyFile"`
|
|
CAFile string `json:"CAFile"`
|
|
}
|
|
|
|
// Generates a TLS configuration from the given files.
|
|
func (info TLSInfo) Config() (TLSConfig, error) {
|
|
var t TLSConfig
|
|
t.Scheme = "http"
|
|
|
|
// If the user do not specify key file, cert file and CA file, the type will be HTTP
|
|
if info.KeyFile == "" && info.CertFile == "" && info.CAFile == "" {
|
|
return t, nil
|
|
}
|
|
|
|
// Both the key and cert must be present.
|
|
if info.KeyFile == "" || info.CertFile == "" {
|
|
return t, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile)
|
|
}
|
|
|
|
tlsCert, err := tls.LoadX509KeyPair(info.CertFile, info.KeyFile)
|
|
if err != nil {
|
|
return t, err
|
|
}
|
|
|
|
t.Scheme = "https"
|
|
t.Server.ClientAuth, t.Server.ClientCAs, err = newCertPool(info.CAFile)
|
|
if err != nil {
|
|
return t, err
|
|
}
|
|
|
|
// The client should trust the RootCA that the Server uses since
|
|
// everyone is a peer in the network.
|
|
t.Client.Certificates = []tls.Certificate{tlsCert}
|
|
t.Client.RootCAs = t.Server.ClientCAs
|
|
|
|
return t, nil
|
|
}
|
|
|
|
// newCertPool creates x509 certPool and corresponding Auth Type.
|
|
// If the given CAfile is valid, add the cert into the pool and verify the clients'
|
|
// certs against the cert in the pool.
|
|
// If the given CAfile is empty, do not verify the clients' cert.
|
|
// If the given CAfile is not valid, fatal.
|
|
func newCertPool(CAFile string) (tls.ClientAuthType, *x509.CertPool, error) {
|
|
if CAFile == "" {
|
|
return tls.NoClientCert, nil, nil
|
|
}
|
|
pemByte, err := ioutil.ReadFile(CAFile)
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
|
|
block, pemByte := pem.Decode(pemByte)
|
|
cert, err := x509.ParseCertificate(block.Bytes)
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
|
|
certPool := x509.NewCertPool()
|
|
certPool.AddCert(cert)
|
|
|
|
return tls.RequireAndVerifyClientCert, certPool, nil
|
|
}
|