-
Notifications
You must be signed in to change notification settings - Fork 0
/
handshake_message_server_key_exchange.go
71 lines (57 loc) · 1.93 KB
/
handshake_message_server_key_exchange.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
package dtls
import (
"encoding/binary"
)
// Structure only supports ECDH
type handshakeMessageServerKeyExchange struct {
ellipticCurveType ellipticCurveType
namedCurve namedCurve
publicKey []byte
hashAlgorithm HashAlgorithm
signatureAlgorithm signatureAlgorithm
signature []byte
}
func (h handshakeMessageServerKeyExchange) handshakeType() handshakeType {
return handshakeTypeServerKeyExchange
}
func (h *handshakeMessageServerKeyExchange) Marshal() ([]byte, error) {
out := []byte{byte(h.ellipticCurveType), 0x00, 0x00}
binary.BigEndian.PutUint16(out[1:], uint16(h.namedCurve))
out = append(out, byte(len(h.publicKey)))
out = append(out, h.publicKey...)
out = append(out, []byte{byte(h.hashAlgorithm), byte(h.signatureAlgorithm), 0x00, 0x00}...)
binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(h.signature)))
out = append(out, h.signature...)
return out, nil
}
func (h *handshakeMessageServerKeyExchange) Unmarshal(data []byte) error {
if _, ok := ellipticCurveTypes[ellipticCurveType(data[0])]; ok {
h.ellipticCurveType = ellipticCurveType(data[0])
} else {
return errInvalidEllipticCurveType
}
h.namedCurve = namedCurve(binary.BigEndian.Uint16(data[1:]))
if _, ok := namedCurves[h.namedCurve]; !ok {
return errInvalidNamedCurve
}
publicKeyLength := int(data[3])
offset := 4 + publicKeyLength
if len(data) <= publicKeyLength {
return errBufferTooSmall
}
h.publicKey = append([]byte{}, data[4:offset]...)
h.hashAlgorithm = HashAlgorithm(data[offset])
if _, ok := hashAlgorithms[h.hashAlgorithm]; !ok {
return errInvalidHashAlgorithm
}
offset++
h.signatureAlgorithm = signatureAlgorithm(data[offset])
if _, ok := signatureAlgorithms[h.signatureAlgorithm]; !ok {
return errInvalidSignatureAlgorithm
}
offset++
signatureLength := int(binary.BigEndian.Uint16(data[offset:]))
offset += 2
h.signature = append([]byte{}, data[offset:offset+signatureLength]...)
return nil
}