summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2017-07-02 01:58:11 +0200
committerChristian Pointner <equinox@spreadspace.org>2017-07-02 01:58:11 +0200
commit92820f73dc1eaf7869a8656ccafb13c38cdc77d5 (patch)
treee1c1acff908c4107922c637c17bcf013146d1fc3
parentinitial work to make tls parameter configurable (diff)
tls settings con now be fully configured
-rw-r--r--src/daq/s5proxy/sample.json17
-rw-r--r--src/daq/s5proxy/src/s5proxy/config.go284
2 files changed, 284 insertions, 17 deletions
diff --git a/src/daq/s5proxy/sample.json b/src/daq/s5proxy/sample.json
index 8ec6dc1..cd72df2 100644
--- a/src/daq/s5proxy/sample.json
+++ b/src/daq/s5proxy/sample.json
@@ -3,8 +3,21 @@
"protocol": "http+https",
"redirect2https": 301,
"tls": {
- "certificate": "fullchain.pem",
- "certificate-key": "private.key"
+ "certificate": "fullchain.pem",
+ "certificate-key": "private.key",
+ "min-protocol-version": "TLSv1",
+ "ciphers": [
+ "ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ "ECDHE_RSA_WITH_AES_256_CBC_SHA",
+ "RSA_WITH_AES_256_GCM_SHA384",
+ "RSA_WITH_AES_256_CBC_SHA"
+ ],
+ "prefer-server-ciphers": true,
+ "ecdh-curves": [
+ "secp521r1",
+ "secp384r1",
+ "secp256r1"
+ ]
},
"connect": "http://emc01.spreadspace.org:8000",
"request_header": [
diff --git a/src/daq/s5proxy/src/s5proxy/config.go b/src/daq/s5proxy/src/s5proxy/config.go
index d8c61e0..d145393 100644
--- a/src/daq/s5proxy/src/s5proxy/config.go
+++ b/src/daq/s5proxy/src/s5proxy/config.go
@@ -34,6 +34,7 @@ package main
import (
"crypto/tls"
+ "encoding/hex"
"encoding/json"
"errors"
"fmt"
@@ -44,6 +45,11 @@ import (
"time"
)
+//*********************************************
+//********** HTTP/HTTPS Proxy Configuration
+
+//********** ProtocolType
+
type ProtocolType string
const (
@@ -79,6 +85,8 @@ func (p *ProtocolType) UnmarshalText(data []byte) (err error) {
return p.fromString(string(data))
}
+//********** RedirectCode
+
type RedirectCode int
func (r RedirectCode) String() string {
@@ -116,6 +124,8 @@ func (r *RedirectCode) UnmarshalJSON(data []byte) (err error) {
return r.fromString(string(data))
}
+//********** Operation
+
type Operation string
const (
@@ -154,6 +164,8 @@ func (o *Operation) UnmarshalText(data []byte) (err error) {
return o.fromString(string(data))
}
+//********** HeaderOperation
+
type HeaderOperation struct {
Operation Operation `json:"op"`
Header string `json:"header"`
@@ -171,23 +183,256 @@ func (h *HeaderOperation) Parse() (err error) {
return nil
}
+//*********************************************
+//********** TLS Configuration
+
+//********** ProtocolType
+
type TLSProtocolVersion uint16
-type TLSCipher uint16
+func (pv TLSProtocolVersion) String() string {
+ switch pv {
+ case tls.VersionSSL30:
+ return "SSLv3"
+ case tls.VersionTLS10:
+ return "TLSv1"
+ case tls.VersionTLS11:
+ return "TLSv1.1"
+ case tls.VersionTLS12:
+ return "TLSv1.2"
+ }
+ return "unknown tls protocol"
+}
+
+func (pv *TLSProtocolVersion) fromString(str string) (err error) {
+ switch strings.ToUpper(str) {
+ case "SSLV3":
+ *pv = tls.VersionSSL30
+ case "TLSV1":
+ *pv = tls.VersionTLS10
+ case "TLSV1.1":
+ *pv = tls.VersionTLS11
+ case "TLSV1.2":
+ *pv = tls.VersionTLS12
+ default:
+ return fmt.Errorf("invalid tls protocol version: '" + str + "'")
+ }
+ return
+}
+
+func (pv TLSProtocolVersion) MarshalText() (data []byte, err error) {
+ data = []byte(pv.String())
+ return
+}
+
+func (pv *TLSProtocolVersion) UnmarshalText(data []byte) (err error) {
+ return pv.fromString(string(data))
+}
+
+//********** CipherSuite
+
+type TLSCipherSuite uint16
+
+func (cs TLSCipherSuite) String() string {
+ switch uint16(cs) {
+ case tls.TLS_RSA_WITH_RC4_128_SHA:
+ return "RSA_WITH_RC4_128_SHA"
+ case tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "RSA_WITH_3DES_EDE_CBC_SHA"
+ case tls.TLS_RSA_WITH_AES_128_CBC_SHA:
+ return "RSA_WITH_AES_128_CBC_SHA"
+ case tls.TLS_RSA_WITH_AES_256_CBC_SHA:
+ return "RSA_WITH_AES_256_CBC_SHA"
+ case tls.TLS_RSA_WITH_AES_128_CBC_SHA256:
+ return "RSA_WITH_AES_128_CBC_SHA256"
+ case tls.TLS_RSA_WITH_AES_128_GCM_SHA256:
+ return "RSA_WITH_AES_128_GCM_SHA256"
+ case tls.TLS_RSA_WITH_AES_256_GCM_SHA384:
+ return "RSA_WITH_AES_256_GCM_SHA384"
+ case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+ return "ECDHE_ECDSA_WITH_RC4_128_SHA"
+ case tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+ return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
+ case tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+ return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
+ case tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+ return "ECDHE_RSA_WITH_RC4_128_SHA"
+ case tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+ return "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"
+ case tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ return "ECDHE_RSA_WITH_AES_128_CBC_SHA"
+ case tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+ return "ECDHE_RSA_WITH_AES_256_CBC_SHA"
+ case tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+ return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
+ case tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ return "ECDHE_RSA_WITH_AES_128_CBC_SHA256"
+ case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ return "ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ case tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ return "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
+ case tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ return "ECDHE_RSA_WITH_AES_256_GCM_SHA384"
+ case tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+ return "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
+ case tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:
+ return "ECDHE_RSA_WITH_CHACHA20_POLY1305"
+ case tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
+ return "ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
+ }
+ return "unknown tls cipher suite"
+}
+
+func (cs *TLSCipherSuite) fromString(str string) (err error) {
+ switch strings.Replace(strings.ToUpper(str), "-", "_", -1) {
+ case "RSA_WITH_RC4_128_SHA":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_RC4_128_SHA)
+ case "RSA_WITH_3DES_EDE_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA)
+ case "RSA_WITH_AES_128_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA)
+ case "RSA_WITH_AES_256_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_AES_256_CBC_SHA)
+ case "RSA_WITH_AES_128_CBC_SHA256":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_AES_128_CBC_SHA256)
+ case "RSA_WITH_AES_128_GCM_SHA256":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_AES_128_GCM_SHA256)
+ case "RSA_WITH_AES_256_GCM_SHA384":
+ *cs = TLSCipherSuite(tls.TLS_RSA_WITH_AES_256_GCM_SHA384)
+ case "ECDHE_ECDSA_WITH_RC4_128_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA)
+ case "ECDHE_ECDSA_WITH_AES_128_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
+ case "ECDHE_ECDSA_WITH_AES_256_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
+ case "ECDHE_RSA_WITH_RC4_128_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA)
+ case "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA)
+ case "ECDHE_RSA_WITH_AES_128_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
+ case "ECDHE_RSA_WITH_AES_256_CBC_SHA":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
+ case "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
+ case "ECDHE_RSA_WITH_AES_128_CBC_SHA256":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
+ case "ECDHE_RSA_WITH_AES_128_GCM_SHA256":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
+ case "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
+ case "ECDHE_RSA_WITH_AES_256_GCM_SHA384":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
+ case "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
+ case "ECDHE_RSA_WITH_CHACHA20_POLY1305":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305)
+ case "ECDHE_ECDSA_WITH_CHACHA20_POLY1305":
+ *cs = TLSCipherSuite(tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)
+ default:
+ return fmt.Errorf("invalid tls cipher suite: '" + str + "'")
+ }
+ return
+}
+
+func (cs TLSCipherSuite) MarshalText() (data []byte, err error) {
+ data = []byte(cs.String())
+ return
+}
+
+func (cs *TLSCipherSuite) UnmarshalText(data []byte) (err error) {
+ return cs.fromString(string(data))
+}
+
+//********** TLSCurve
type TLSCurve tls.CurveID
+func (c TLSCurve) String() string {
+ switch tls.CurveID(c) {
+ case tls.CurveP256:
+ return "secp256r1"
+ case tls.CurveP384:
+ return "secp384r1"
+ case tls.CurveP521:
+ return "secp521r1"
+ case tls.X25519:
+ return "x25519"
+ }
+ return "unknown tls echd curve"
+}
+
+func (c *TLSCurve) fromString(str string) (err error) {
+ switch strings.ToLower(str) {
+ case "prime256v1":
+ fallthrough
+ case "secp256r1":
+ *c = TLSCurve(tls.CurveP256)
+ case "prime384v1":
+ fallthrough
+ case "secp384r1":
+ *c = TLSCurve(tls.CurveP384)
+ case "prime521v1":
+ fallthrough
+ case "secp521r1":
+ *c = TLSCurve(tls.CurveP521)
+ case "x25519":
+ *c = TLSCurve(tls.X25519)
+ default:
+ return fmt.Errorf("invalid tls ecdh curve: '" + str + "'")
+ }
+ return
+}
+
+func (c TLSCurve) MarshalText() (data []byte, err error) {
+ data = []byte(c.String())
+ return
+}
+
+func (c *TLSCurve) UnmarshalText(data []byte) (err error) {
+ return c.fromString(string(data))
+}
+
+//********** TLSSessionTicketKey
+
type TLSSessionTicketKey [32]byte
+func (stk TLSSessionTicketKey) String() string {
+ return hex.EncodeToString([]byte(stk[:]))
+}
+
+func (stk *TLSSessionTicketKey) fromString(str string) error {
+ key, err := hex.DecodeString(str)
+ if err != nil {
+ return fmt.Errorf("invalid tls session ticket key: %v", err)
+ }
+ if len(key) != len(stk) {
+ return fmt.Errorf("invalid tls session ticket key length: got %d bytes, expected %d bytes", len(key), len(stk))
+ }
+ copy(stk[:], key)
+ return nil
+}
+
+func (stk TLSSessionTicketKey) MarshalText() (data []byte, err error) {
+ data = []byte(stk.String())
+ return
+}
+
+func (stk *TLSSessionTicketKey) UnmarshalText(data []byte) (err error) {
+ return stk.fromString(string(data))
+}
+
+//********** TLSConfig
+
type TLSConfig struct {
CertFile string `json:"certificate"`
KeyFile string `json:"certificate-key"`
MinVersion TLSProtocolVersion `json:"min-protocol-version"`
MaxVersion TLSProtocolVersion `json:"max-protocol-version"`
- CipherSuites []TLSCipher `json:"ciphers"`
+ CipherSuites []TLSCipherSuite `json:"ciphers"`
PreferServerCipherSuites bool `json:"prefer-server-ciphers"`
CurvePreferences []TLSCurve `json:"ecdh-curves"`
- SessionTicketsDisabled bool `json:"session-tickets"`
+ SessionTickets bool `json:"session-tickets"`
SessionTicketKey TLSSessionTicketKey `json:"session-ticket-key"`
}
@@ -197,23 +442,27 @@ func (t TLSConfig) ToGoTLSConfig() (*tls.Config, error) {
return nil, err
}
- // TODO: generate cfg from t
- cfg := &tls.Config{
- Certificates: []tls.Certificate{cert},
- MinVersion: tls.VersionTLS10,
- CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
- PreferServerCipherSuites: true,
- CipherSuites: []uint16{
- tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
- tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
- tls.TLS_RSA_WITH_AES_256_CBC_SHA,
- },
+ cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
+ cfg.MinVersion = uint16(t.MinVersion)
+ cfg.MaxVersion = uint16(t.MaxVersion)
+ for _, cs := range t.CipherSuites {
+ cfg.CipherSuites = append(cfg.CipherSuites, uint16(cs))
+ }
+ cfg.PreferServerCipherSuites = t.PreferServerCipherSuites
+ for _, cp := range t.CurvePreferences {
+ cfg.CurvePreferences = append(cfg.CurvePreferences, tls.CurveID(cp))
}
+ cfg.SessionTicketsDisabled = !t.SessionTickets
+ cfg.SessionTicketKey = [32]byte(t.SessionTicketKey)
return cfg, nil
}
+//*********************************************
+//********** SFive Statistics
+
+//********** SFiveDuration
+
type SFiveDuration int64
func (d *SFiveDuration) UnmarshalText(data []byte) error {
@@ -228,6 +477,8 @@ func (d *SFiveDuration) UnmarshalText(data []byte) error {
return nil
}
+//********** SFiveConf
+
type SFiveConf struct {
Sock string `json:"socket"`
Hostname string `json:"hostname"`
@@ -237,6 +488,9 @@ type SFiveConf struct {
Stream []string `json:"stream"`
}
+//*********************************************
+//********** Configuration
+
type Config struct {
ListenAddr string `json:"listen"`
Protocol ProtocolType `json:"protocol"`