-
Notifications
You must be signed in to change notification settings - Fork 12
/
common.go
180 lines (155 loc) · 3.4 KB
/
common.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package dtls
import (
"crypto"
"crypto/rand"
"crypto/x509"
"io"
"sync"
"time"
)
const (
VersionDTLS10 = 0x0301
VersionDTLS12 = 0x0303
)
const (
signatureRSA uint8 = 1
signatureECDSA uint8 = 3
)
const (
maxDatagramLength = 1463
maxPlaintext = 16384
maxCiphertext = 16384 + 2048
recordHeaderLen = 13
recordEpochStart = 4
recordSequenceEnd = 12
maxHandshake = 65536
)
const (
compressionNone uint8 = 0
)
type recordType uint8
const (
recordTypeChangeCipherSpec recordType = 20
recordTypeAlert recordType = 21
recordTypeHandshake recordType = 22
recordTypeApplicationData recordType = 23
)
const (
typeClientHello uint8 = 1
typeServerHello uint8 = 2
typeHelloVerifyRequest uint8 = 3
typeNewSessionTicket uint8 = 4
typeCertificate uint8 = 11
typeServerKeyExchange uint8 = 12
typeCertificateRequest uint8 = 13
typeServerHelloDone uint8 = 14
typeCertificateVerify uint8 = 15
typeClientKeyExchange uint8 = 16
typeFinished uint8 = 20
typeCertificateStatus uint8 = 22
typeNextProtocol uint8 = 67 // Not IANA assigned
)
const (
minVersion = VersionDTLS10
maxVersion = VersionDTLS12
)
type ClientAuthType int
const (
NoClientCert ClientAuthType = iota
RequestClientCert
RequireAnyClientCert
VerifyClientCertIfGiven
RequireAndVerifyClientCert
)
type record struct {
contentType recordType
major, minor uint8
epoch uint16
sequenceNumber [6]byte
payload []byte
}
type Config struct {
Rand io.Reader
Time func() time.Time
Certificates []Certificate
NameToCertificate map[string]*Certificate
RootCAs *x509.CertPool
NextProtos []string
ServerName string
ClientAuth ClientAuthType
ClientCAs *x509.CertPool
InsecureSkipVerify bool
CipherSuites []uint16
PreferServerCipherSuites bool
SessionTicketsDisabled bool
SessionTicketKey [32]byte
MinVersion uint16
MaxVersion uint16
serverInitOnce sync.Once
}
func (c *Config) serverInit() {
if c.SessionTicketsDisabled {
return
}
for _, b := range c.SessionTicketKey {
if b != 0 {
return
}
}
if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
c.SessionTicketsDisabled = true
}
}
func (c *Config) rand() io.Reader {
r := c.Rand
if r == nil {
return rand.Reader
}
return r
}
func (c *Config) time() time.Time {
t := c.Time
if t == nil {
t = time.Now
}
return t()
}
func (c *Config) cipherSuites() []uint16 {
s := c.CipherSuites
if s == nil {
s = defaultCipherSuites()
}
return s
}
func (c *Config) minVersion() uint16 {
if c == nil || c.MinVersion == 0 {
return minVersion
}
return c.MinVersion
}
func (c *Config) maxVersion() uint16 {
if c == nil || c.MaxVersion == 0 {
return maxVersion
}
return c.MaxVersion
}
type Certificate struct {
Certificate [][]byte
PrivateKey crypto.PrivateKey
OCSPStaple []byte
Leaf *x509.Certificate
}
var (
once sync.Once
varDefaultCipherSuites []uint16
)
func defaultCipherSuites() []uint16 {
once.Do(initDefaultCipherSuites)
return varDefaultCipherSuites
}
func initDefaultCipherSuites() {
varDefaultCipherSuites = make([]uint16, len(cipherSuites))
for i, suite := range cipherSuites {
varDefaultCipherSuites[i] = suite.id
}
}