-
Notifications
You must be signed in to change notification settings - Fork 257
/
u_handshake_messages.go
141 lines (122 loc) · 3.76 KB
/
u_handshake_messages.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
// Copyright 2022 uTLS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tls
import (
"golang.org/x/crypto/cryptobyte"
)
// Only implemented client-side, for server certificates.
// Alternate certificate message formats (https://datatracker.ietf.org/doc/html/rfc7250) are not
// supported.
// https://datatracker.ietf.org/doc/html/rfc8879
type utlsCompressedCertificateMsg struct {
raw []byte
algorithm uint16
uncompressedLength uint32 // uint24
compressedCertificateMessage []byte
}
func (m *utlsCompressedCertificateMsg) marshal() ([]byte, error) {
if m.raw != nil {
return m.raw, nil
}
var b cryptobyte.Builder
b.AddUint8(utlsTypeCompressedCertificate)
b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16(m.algorithm)
b.AddUint24(m.uncompressedLength)
b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.compressedCertificateMessage)
})
})
var err error
m.raw, err = b.Bytes()
return m.raw, err
}
func (m *utlsCompressedCertificateMsg) unmarshal(data []byte) bool {
*m = utlsCompressedCertificateMsg{raw: data}
s := cryptobyte.String(data)
if !s.Skip(4) || // message type and uint24 length field
!s.ReadUint16(&m.algorithm) ||
!s.ReadUint24(&m.uncompressedLength) ||
!readUint24LengthPrefixed(&s, &m.compressedCertificateMessage) {
return false
}
return true
}
type utlsEncryptedExtensionsMsgExtraFields struct {
hasApplicationSettings bool
applicationSettings []byte
echRetryConfigs []ECHConfig
customExtension []byte
}
func (m *encryptedExtensionsMsg) utlsUnmarshal(extension uint16, extData cryptobyte.String) bool {
switch extension {
case utlsExtensionApplicationSettings:
m.utls.hasApplicationSettings = true
m.utls.applicationSettings = []byte(extData)
case utlsExtensionECH:
var err error
m.utls.echRetryConfigs, err = UnmarshalECHConfigs([]byte(extData))
if err != nil {
return false
}
}
return true // success/unknown extension
}
type utlsClientEncryptedExtensionsMsg struct {
raw []byte
applicationSettings []byte
hasApplicationSettings bool
customExtension []byte
}
func (m *utlsClientEncryptedExtensionsMsg) marshal() (x []byte, err error) {
if m.raw != nil {
return m.raw, nil
}
var builder cryptobyte.Builder
builder.AddUint8(typeEncryptedExtensions)
builder.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
body.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
if m.hasApplicationSettings {
extensions.AddUint16(utlsExtensionApplicationSettings)
extensions.AddUint16LengthPrefixed(func(msg *cryptobyte.Builder) {
msg.AddBytes(m.applicationSettings)
})
}
if len(m.customExtension) > 0 {
extensions.AddUint16(utlsFakeExtensionCustom)
extensions.AddUint16LengthPrefixed(func(msg *cryptobyte.Builder) {
msg.AddBytes(m.customExtension)
})
}
})
})
m.raw, err = builder.Bytes()
return m.raw, err
}
func (m *utlsClientEncryptedExtensionsMsg) unmarshal(data []byte) bool {
*m = utlsClientEncryptedExtensionsMsg{raw: data}
s := cryptobyte.String(data)
var extensions cryptobyte.String
if !s.Skip(4) || // message type and uint24 length field
!s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
return false
}
for !extensions.Empty() {
var extension uint16
var extData cryptobyte.String
if !extensions.ReadUint16(&extension) ||
!extensions.ReadUint16LengthPrefixed(&extData) {
return false
}
switch extension {
case utlsExtensionApplicationSettings:
m.hasApplicationSettings = true
m.applicationSettings = []byte(extData)
default:
// Unknown extensions are illegal in EncryptedExtensions.
return false
}
}
return true
}