-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtls.go
107 lines (99 loc) · 2.85 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
openssl "github.com/lunixbochs/go-openssl"
"io/ioutil"
"log"
"net"
"os"
"path"
"time"
)
func MakeRSAKey(keyPath string) error {
key := try(openssl.GenerateRSAKey(2048))
pubKey := try(key.MarshalPKIXPublicKeyPEM())
privKey := try(key.MarshalPKCS1PrivateKeyPEM())
err = os.Mkdir(path.Dir(keyPath), os.ModeDir|0700)
if err != nil && !os.IsExist(err) {
return err
}
try(ioutil.WriteFile(keyPath+".pub", pubKey, 0400))
try(ioutil.WriteFile(keyPath, privKey, 0400))
return nil
}
func MakeCA(caPath string) error {
err = os.Mkdir(path.Dir(caPath), os.ModeDir|0700)
if !os.IsExist(err) {
return err
}
info := &openssl.CertificateInfo{
Serial: 1,
Issued: 0,
Expires: 10 * 365 * 24 * time.Hour,
Country: "US",
Organization: "poxd Root CA",
CommonName: "poxd Root CA",
}
ca := try(openssl.NewCertificate(info, state.CAKey))
try(ca.AddExtensions(map[openssl.NID]string{
openssl.NID_basic_constraints: "critical,CA:TRUE",
openssl.NID_key_usage: "critical,keyCertSign,cRLSign",
openssl.NID_subject_key_identifier: "hash",
openssl.NID_netscape_cert_type: "sslCA",
}))
try(ca.Sign(state.CAKey, openssl.EVP_SHA256))
pem := try(ca.MarshalPEM())
try(ioutil.WriteFile(caPath, pem, 0400))
return nil
}
func MakeCert(hostname string) (*openssl.Certificate, error) {
info := &openssl.CertificateInfo{
Serial: 1,
Issued: 0,
Expires: 24 * time.Hour,
Country: "US",
Organization: "poxd",
CommonName: hostname,
}
cert := try(openssl.NewCertificate(info, state.CAKey))
try(cert.AddExtensions(map[openssl.NID]string{
openssl.NID_basic_constraints: "critical,CA:FALSE",
openssl.NID_key_usage: "keyEncipherment",
openssl.NID_ext_key_usage: "serverAuth",
}))
try(cert.SetIssuer(state.CA))
try(cert.Sign(state.CAKey, openssl.EVP_SHA256))
return cert, nil
}
func IsTLS(c Conn) bool {
p, err := c.Peek(6)
if err != nil {
return false
}
// leading byte == 22, version > 3.0, length > 20, message type = ClientHello
return (len(p) > 5 && p[0] == 22 &&
p[1] >= 3 && (p[3] > 0 || p[4] > 20) &&
p[5] == 1)
}
func WrapTLSServer(c net.Conn) net.Conn {
ctx := try(openssl.NewCtx())
conn := try(openssl.Client(c, ctx))
return conn
}
func WrapTLSClient(c net.Conn, hostname string) net.Conn {
log.Println("Wrapping TLS with hostname:", hostname)
ctx := try(openssl.NewCtx())
cert := try(MakeCert(hostname))
ctx.UseCertificate(cert)
ctx.UsePrivateKey(state.CAKey)
ctx.SetTLSExtServernameCallback(func(ssl *openssl.SSL) openssl.SSLTLSExtErr {
log.Println("Using SNI to switch hostname:", ssl.GetServername())
ctx := try(openssl.NewCtx())
cert := try(MakeCert(ssl.GetServername()))
ctx.UseCertificate(cert)
ctx.UsePrivateKey(state.CAKey)
ssl.SetSSLCtx(ctx)
return openssl.SSLTLSExtErrOK
})
conn := try(openssl.Server(c, ctx))
return conn
}