-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension_server_name.go
70 lines (61 loc) · 1.7 KB
/
extension_server_name.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
package dtls
import (
"strings"
"golang.org/x/crypto/cryptobyte"
)
const extensionServerNameTypeDNSHostName = 0
type extensionServerName struct {
serverName string
}
func (e extensionServerName) extensionValue() extensionValue {
return extensionServerNameValue
}
func (e *extensionServerName) Marshal() ([]byte, error) {
var b cryptobyte.Builder
b.AddUint16(uint16(e.extensionValue()))
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8(extensionServerNameTypeDNSHostName)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte(e.serverName))
})
})
})
return b.Bytes()
}
func (e *extensionServerName) Unmarshal(data []byte) error {
s := cryptobyte.String(data)
var extension uint16
s.ReadUint16(&extension)
if extensionValue(extension) != e.extensionValue() {
return errInvalidExtensionType
}
var extData cryptobyte.String
s.ReadUint16LengthPrefixed(&extData)
var nameList cryptobyte.String
if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
return errInvalidSNIFormat
}
for !nameList.Empty() {
var nameType uint8
var serverName cryptobyte.String
if !nameList.ReadUint8(&nameType) ||
!nameList.ReadUint16LengthPrefixed(&serverName) ||
serverName.Empty() {
return errInvalidSNIFormat
}
if nameType != extensionServerNameTypeDNSHostName {
continue
}
if len(e.serverName) != 0 {
// Multiple names of the same name_type are prohibited.
return errInvalidSNIFormat
}
e.serverName = string(serverName)
// An SNI value may not include a trailing dot.
if strings.HasSuffix(e.serverName, ".") {
return errInvalidSNIFormat
}
}
return nil
}