forked from getlantern/http-proxy-archived
/
tls.go
83 lines (73 loc) · 2.22 KB
/
tls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
import (
"crypto/tls"
"fmt"
"net"
"os"
"time"
"github.com/getlantern/keyman"
"github.com/getlantern/tlsdefaults"
)
var (
tenYearsFromToday = time.Now().AddDate(10, 0, 0)
processStart = time.Now()
)
func listenTLS(addr string) (net.Listener, error) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, fmt.Errorf("Unable to split host and port for %v: %v\n", addr, err)
}
ctx := CertContext{
PKFile: "key.pem",
ServerCertFile: "cert.pem",
}
err = ctx.InitServerCert(host)
if err != nil {
return nil, fmt.Errorf("Unable to init server cert: %s\n", err)
}
tlsConfig := tlsdefaults.Server()
cert, err := tls.LoadX509KeyPair(ctx.ServerCertFile, ctx.PKFile)
if err != nil {
return nil, fmt.Errorf("Unable to load certificate and key from %s and %s: %s\n", ctx.ServerCertFile, ctx.PKFile, err)
}
tlsConfig.Certificates = []tls.Certificate{cert}
listener, err := tls.Listen("tcp", addr, tlsConfig)
if err != nil {
return nil, fmt.Errorf("Unable to listen for tls connections at %s: %s\n", addr, err)
}
return listener, err
}
// CertContext encapsulates the certificates used by a Server
type CertContext struct {
PKFile string
ServerCertFile string
PK *keyman.PrivateKey
ServerCert *keyman.Certificate
}
// InitServerCert initializes a PK + cert for use by a server proxy, signed by
// the CA certificate. We always generate a new certificate just in case.
func (ctx *CertContext) InitServerCert(host string) (err error) {
if ctx.PK, err = keyman.LoadPKFromFile(ctx.PKFile); err != nil {
if os.IsNotExist(err) {
fmt.Printf("Creating new PK at: %s\n", ctx.PKFile)
if ctx.PK, err = keyman.GeneratePK(2048); err != nil {
return
}
if err = ctx.PK.WriteToFile(ctx.PKFile); err != nil {
return fmt.Errorf("Unable to save private key: %s\n", err)
}
} else {
return fmt.Errorf("Unable to read private key, even though it exists: %s\n", err)
}
}
fmt.Printf("Creating new server cert at: %s\n", ctx.ServerCertFile)
ctx.ServerCert, err = ctx.PK.TLSCertificateFor("Lantern", host, tenYearsFromToday, true, nil)
if err != nil {
return
}
err = ctx.ServerCert.WriteToFile(ctx.ServerCertFile)
if err != nil {
return
}
return nil
}