-
Notifications
You must be signed in to change notification settings - Fork 498
/
ssl.go
152 lines (122 loc) · 3.26 KB
/
ssl.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
Copyright 2017 Authors All rights reserved
*/
package ssl
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
)
// ClientTSLConfNoVerity get a empty tls.Config with insecure skip verify for client side.
func ClientTSLConfNoVerity() *tls.Config {
return &tls.Config{
InsecureSkipVerify: true,
}
}
// ClientTSLConfVerityServer get a new tls.Config and will check given ca for client side.
func ClientTSLConfVerityServer(caFile string) (*tls.Config, error) {
caPool, err := loadCa(caFile)
if err != nil {
return nil, err
}
conf := &tls.Config{
RootCAs: caPool,
}
return conf, nil
}
// ClientTSLConfVerity receive certs files and return a tls.Config for client side.
func ClientTSLConfVerity(caFile, certFile, keyFile, passwd string) (*tls.Config, error) {
caPool, err := loadCa(caFile)
if err != nil {
return nil, err
}
cert, err := loadCertificates(certFile, keyFile, passwd)
if err != nil {
return nil, err
}
conf := &tls.Config{
InsecureSkipVerify: true,
RootCAs: caPool,
Certificates: []tls.Certificate{*cert},
}
return conf, nil
}
// ServerTSLConf receive certs files and return a tls.Config for server side.
func ServerTSLConf(caFile, certFile, keyFile, passwd string) (*tls.Config, error) {
if "" == caFile {
return ServerTSLConfVerity(certFile, keyFile, passwd)
}
return ServerTSLConfVerityClient(caFile, certFile, keyFile, passwd)
}
// ServerTSLConfVerity receive certs files without ca and return a tls.Config for server side.
func ServerTSLConfVerity(certFile, keyFile, passwd string) (*tls.Config, error) {
cert, err := loadCertificates(certFile, keyFile, passwd)
if err != nil {
return nil, err
}
conf := &tls.Config{
Certificates: []tls.Certificate{*cert},
}
return conf, nil
}
// ServerTSLConfVerityClient receive certs files with ca and return a tls.Config for server side.
func ServerTSLConfVerityClient(caFile, certFile, keyFile, passwd string) (*tls.Config, error) {
caPool, err := loadCa(caFile)
if err != nil {
return nil, err
}
cert, err := loadCertificates(certFile, keyFile, passwd)
if err != nil {
return nil, err
}
conf := &tls.Config{
ClientCAs: caPool,
Certificates: []tls.Certificate{*cert},
ClientAuth: tls.RequireAndVerifyClientCert,
}
return conf, nil
}
func loadCa(caFile string) (*x509.CertPool, error) {
ca, err := ioutil.ReadFile(caFile)
if err != nil {
return nil, err
}
caPool := x509.NewCertPool()
if ok := caPool.AppendCertsFromPEM(ca); ok != true {
return nil, fmt.Errorf("append ca cert failed")
}
return caPool, nil
}
func loadCertificates(certFile, keyFile, passwd string) (*tls.Certificate, error) {
//key file
priKey, err := ioutil.ReadFile(keyFile)
if err != nil {
return nil, err
}
if "" != passwd {
priPem, _ := pem.Decode(priKey)
if priPem == nil {
return nil, fmt.Errorf("decode private key failed")
}
priDecrPem, err := x509.DecryptPEMBlock(priPem, []byte(passwd))
if err != nil {
return nil, err
}
priKey = pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: priDecrPem,
})
}
//certificate
certData, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, err
}
tlsCert, err := tls.X509KeyPair(certData, priKey)
if err != nil {
return nil, err
}
return &tlsCert, nil
}