aboutsummaryrefslogtreecommitdiff
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
parent3399d5538c0fbaa2a175f194b38113e053f3cfb0 (diff)
TLS Solver
-rw-r--r--cmd/acme/main.go13
-rw-r--r--solve_http.go11
-rw-r--r--solve_tls.go73
3 files changed, 49 insertions, 48 deletions
diff --git a/cmd/acme/main.go b/cmd/acme/main.go
index a9d41af..95b1418 100644
--- a/cmd/acme/main.go
+++ b/cmd/acme/main.go
@@ -86,16 +86,21 @@ func main() {
log.Fatal(err)
}
- httpSol := acme.NewHTTPSolver(conf.Defaults.Listen)
- tlsSol := acme.NewTLSSolver(conf.Defaults.ListenTLS)
+ httpSol, err := acme.NewHTTPSolver(conf.Defaults.Listen)
+ if err != nil {
+ log.Fatal(err)
+ }
+ tlsSol, err := acme.NewTLSSolver(conf.Defaults.ListenTLS)
+ if err != nil {
+ log.Fatal(err)
+ }
for k, des := range conf.Desire {
if des.Webroot != "" {
wrSol := acme.NewWebrootSolver(des.Webroot)
des.RegisterSolver(acme.ChallengeHTTP, wrSol)
} else {
- //des.RegisterSolver(acme.ChallengeHTTP, httpSol)
- _ = httpSol
+ des.RegisterSolver(acme.ChallengeHTTP, httpSol)
}
des.RegisterSolver(acme.ChallengeTLS, tlsSol)
diff --git a/solve_http.go b/solve_http.go
index d4f5635..0175760 100644
--- a/solve_http.go
+++ b/solve_http.go
@@ -11,16 +11,17 @@ type httpSolver struct {
http.Server
}
-func NewHTTPSolver(addr string) Solver {
- s := new(httpSolver)
- s.Server = http.Server{Addr: addr}
+func NewHTTPSolver(addr string) (Solver, error) {
+ s := &httpSolver{
+ Server: http.Server{Addr: addr},
+ }
go s.ListenAndServe()
- return s
+ return s, nil
}
func (s *httpSolver) Solve(token, keyAuth string) error {
p := path.Join(WellKnown, token)
- log.Println("solve http", p)
+ log.Println("solve http")
http.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, keyAuth)
})
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)
-}