aboutsummaryrefslogtreecommitdiff
path: root/solve_tls.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-01-29 01:01:21 +0100
committerDimitri Sokolyuk <demon@dim13.org>2016-01-29 01:01:21 +0100
commit2faf8c5dc46aa6cd45e91eaa74a83f07b227d44d (patch)
tree9670104fd9453fddf2e7060c7390e4233f0c7a75 /solve_tls.go
parent3399d5538c0fbaa2a175f194b38113e053f3cfb0 (diff)
TLS Solver
Diffstat (limited to 'solve_tls.go')
-rw-r--r--solve_tls.go73
1 files changed, 34 insertions, 39 deletions
diff --git a/solve_tls.go b/solve_tls.go
index 6b8869e..00ef6f0 100644
--- a/solve_tls.go
+++ b/solve_tls.go
@@ -8,25 +8,48 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
+ "errors"
"log"
"math/big"
- "net"
"net/http"
"time"
)
+var errNoCert = errors.New("no cert")
+
type tlsSolver struct {
http.Server
+ sni map[string]*tls.Certificate
+}
+
+func (s *tlsSolver) getCert(h *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ if crt, ok := s.sni[h.ServerName]; ok {
+ return crt, nil
+ }
+ return nil, errNoCert
}
-func NewTLSSolver(addr string) Solver {
- s := new(tlsSolver)
- s.Server = http.Server{
- Addr: addr,
- TLSConfig: &tls.Config{},
+func NewTLSSolver(addr string) (Solver, error) {
+ // we need at least one cert
+ dummy, err := newCert(sniName(""))
+ if err != nil {
+ return nil, err
+ }
+
+ config := &tls.Config{
+ Certificates: []tls.Certificate{dummy},
+ //GetCertificate: s.getCert,
}
- go ListenAndServeSNI(&s.Server)
- return s
+ s := &tlsSolver{
+ Server: http.Server{
+ Addr: addr,
+ TLSConfig: config,
+ },
+ sni: make(map[string]*tls.Certificate),
+ }
+ s.Server.TLSConfig.GetCertificate = s.getCert
+ go s.ListenAndServeTLS("", "")
+ return s, nil
}
func newCert(domain string) (tls.Certificate, error) {
@@ -73,43 +96,15 @@ func sniName(keyAuth string) string {
func (s *tlsSolver) Solve(_, keyAuth string) error {
log.Println("solve tls")
- crt, err := newCert(sniName(keyAuth))
+ name := sniName(keyAuth)
+ crt, err := newCert(name)
if err != nil {
return err
}
- s.TLSConfig.Certificates = append(s.TLSConfig.Certificates, crt)
- s.TLSConfig.BuildNameToCertificate()
- log.Printf(">>> %+v\n", s.TLSConfig.NameToCertificate)
+ s.sni[name] = &crt
return nil
}
func (s *tlsSolver) Solved() error {
return nil
}
-
-func ListenAndServeSNI(srv *http.Server) error {
- addr := srv.Addr
- if addr == "" {
- addr = ":https"
- }
- config := &tls.Config{}
- if srv.TLSConfig != nil {
- *config = *srv.TLSConfig
- }
- if config.NextProtos == nil {
- config.NextProtos = []string{"http/1.1"}
- }
- // we need at least one cert
- dummy, err := newCert(sniName(""))
- if err != nil {
- return err
- }
- config.Certificates = []tls.Certificate{dummy}
- config.BuildNameToCertificate()
- conn, err := net.Listen("tcp", addr)
- if err != nil {
- return err
- }
- tlsListener := tls.NewListener(conn, config)
- return srv.Serve(tlsListener)
-}