forked from refraction-networking/utls
-
Notifications
You must be signed in to change notification settings - Fork 3
/
u_handshake_messages.go
133 lines (114 loc) · 3.53 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
// 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 {
if m.raw != nil {
return m.raw
}
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)
})
})
m.raw = b.BytesOrPanic()
return m.raw
}
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
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)
}
return true // success/unknown extension
}
type utlsClientEncryptedExtensionsMsg struct {
raw []byte
applicationSettings []byte
hasApplicationSettings bool
customExtension []byte
}
func (m *utlsClientEncryptedExtensionsMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
}
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 = builder.BytesOrPanic()
return m.raw
}
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
}