forked from pion/dtls
/
cipher_suite.go
82 lines (70 loc) · 2.27 KB
/
cipher_suite.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
package dtls
import (
"encoding/binary"
"hash"
)
type cipherSuiteID uint16
type cipherSuite interface {
ID() cipherSuiteID
certificateType() clientCertificateType
hashFunc() func() hash.Hash
// Generate the internal encryption state
init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error
encrypt(pkt *recordLayer, raw []byte) ([]byte, error)
decrypt(in []byte) ([]byte, error)
}
// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
// A cipherSuite is a specific combination of key agreement, cipher and MAC
// function.
func cipherSuiteForID(id cipherSuiteID) cipherSuite {
switch id {
case cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{}.ID():
return &cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{}
case cipherSuiteTLSEcdheRsaWithAes128GcmSha256{}.ID():
return &cipherSuiteTLSEcdheRsaWithAes128GcmSha256{}
case cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{}.ID():
return &cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{}
case cipherSuiteTLSEcdheRsaWithAes256CbcSha{}.ID():
return &cipherSuiteTLSEcdheRsaWithAes256CbcSha{}
}
return nil
}
// CipherSuites we support as a client
// Preferred at the bottom
func clientCipherSuites() []cipherSuite {
return []cipherSuite{
&cipherSuiteTLSEcdheRsaWithAes256CbcSha{},
&cipherSuiteTLSEcdheEcdsaWithAes256CbcSha{},
&cipherSuiteTLSEcdheRsaWithAes128GcmSha256{},
&cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{},
}
}
// CipherSuites we support as a server
// func serverCipherSuites() []cipherSuite {
// return []cipherSuite{
// &cipherSuiteTLSEcdheEcdsaWithAes128GcmSha256{},
// }
// }
func decodeCipherSuites(buf []byte) ([]cipherSuite, error) {
if len(buf) < 2 {
return nil, errDTLSPacketInvalidLength
}
cipherSuitesCount := int(binary.BigEndian.Uint16(buf[0:])) / 2
rtrn := []cipherSuite{}
for i := 0; i < cipherSuitesCount; i++ {
id := cipherSuiteID(binary.BigEndian.Uint16(buf[(i*2)+2:]))
if c := cipherSuiteForID(id); c != nil {
rtrn = append(rtrn, c)
}
}
return rtrn, nil
}
func encodeCipherSuites(c []cipherSuite) []byte {
out := []byte{0x00, 0x00}
binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(c)*2))
for i := len(c); i > 0; i-- {
out = append(out, []byte{0x00, 0x00}...)
binary.BigEndian.PutUint16(out[len(out)-2:], uint16(c[i-1].ID()))
}
return out
}