File: u_handshake_messages.go

package info (click to toggle)
golang-refraction-networking-utls 1.2.1-3.1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 3,072 kB
  • sloc: asm: 67; makefile: 5
file content (133 lines) | stat: -rw-r--r-- 3,615 bytes parent folder | download | duplicates (2)
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
}