Просмотр исходного кода

Add documentation for a secret

tags/v2.0.0-rc1
9seconds 5 лет назад
Родитель
Сommit
e6d444546f
1 измененных файлов: 40 добавлений и 1 удалений
  1. 40
    1
      mtglib/secret.go

+ 40
- 1
mtglib/secret.go Просмотреть файл

11
 
11
 
12
 var secretEmptyKey [SecretKeyLength]byte
12
 var secretEmptyKey [SecretKeyLength]byte
13
 
13
 
14
+// Secret is a data structure that presents a secret.
15
+//
16
+// Telegram secret is not a simple string like
17
+// "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d".
18
+// Actually, this is a serialized datastructure of 2 parts: key and host.
19
+//
20
+//     ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d
21
+//     |-|-------------------------------|-------------------------------------------
22
+//     p key                             hostname
23
+//
24
+// Serialized secret starts with 'ee'. Actually, in the past we also had
25
+// 'dd' secrets and prefixless ones. But this is history. Currently,
26
+// we do have only 'ee' secrets which mean faketls + protection from
27
+// statistical attacks on a length. 'ee' is a byte 238 (0xee).
28
+//
29
+// After that, we have 16 bytes of the key. This is a random generated
30
+// secret data of the proxy and this data is used to derive
31
+// authentication schemas. These secrets are mixed into hmacs and sha256
32
+// checksums which are used to build AEAD ciphers for obfuscated2
33
+// protocol and ensure faketls handshake.
34
+//
35
+// Host is a domain fronting hostname in latin1 (ASCII) encoding. This
36
+// hostname should be used for SNI in faketls and MTG verifies it. Also,
37
+// this is when mtg gets about a domain fronting hostname.
38
+//
39
+// Secrets can be serialized into 2 forms: hex and base64. If
40
+// you decode both forms into bytes, you'll get the same byte array.
41
+// Telegram clients nowadays accept all forms.
14
 type Secret struct {
42
 type Secret struct {
15
-	Key  [SecretKeyLength]byte
43
+	// Key is a set of bytes used for traffic authentication.
44
+	Key [SecretKeyLength]byte
45
+
46
+	// Host is a domain fronting hostname.
16
 	Host string
47
 	Host string
17
 }
48
 }
18
 
49
 
50
+// MarshalText is to support text.Marshaller interface.
19
 func (s Secret) MarshalText() ([]byte, error) {
51
 func (s Secret) MarshalText() ([]byte, error) {
20
 	if s.Valid() {
52
 	if s.Valid() {
21
 		return []byte(s.String()), nil
53
 		return []byte(s.String()), nil
24
 	return nil, nil
56
 	return nil, nil
25
 }
57
 }
26
 
58
 
59
+// MarshalText is to support text.Unmarshaller interface.
27
 func (s *Secret) UnmarshalText(data []byte) error {
60
 func (s *Secret) UnmarshalText(data []byte) error {
28
 	text := string(data)
61
 	text := string(data)
29
 	if text == "" {
62
 	if text == "" {
62
 	return nil
95
 	return nil
63
 }
96
 }
64
 
97
 
98
+// Valid checks if this secret is valid and can be used in proxy.
65
 func (s Secret) Valid() bool {
99
 func (s Secret) Valid() bool {
66
 	return s.Key != secretEmptyKey && s.Host != ""
100
 	return s.Key != secretEmptyKey && s.Host != ""
67
 }
101
 }
68
 
102
 
103
+// String is to support fmt.Stringer interface.
69
 func (s Secret) String() string {
104
 func (s Secret) String() string {
70
 	return s.Base64()
105
 	return s.Base64()
71
 }
106
 }
72
 
107
 
108
+// Base64 returns a base64-encoded form of this secret.
73
 func (s Secret) Base64() string {
109
 func (s Secret) Base64() string {
74
 	return base64.RawURLEncoding.EncodeToString(s.makeBytes())
110
 	return base64.RawURLEncoding.EncodeToString(s.makeBytes())
75
 }
111
 }
76
 
112
 
113
+// Hex returns a hex-encoded form of this secret (ee-secret).
77
 func (s Secret) Hex() string {
114
 func (s Secret) Hex() string {
78
 	return hex.EncodeToString(s.makeBytes())
115
 	return hex.EncodeToString(s.makeBytes())
79
 }
116
 }
85
 	return data
122
 	return data
86
 }
123
 }
87
 
124
 
125
+// GenerateSecret makes a new secret with a given hostname.
88
 func GenerateSecret(hostname string) Secret {
126
 func GenerateSecret(hostname string) Secret {
89
 	s := Secret{
127
 	s := Secret{
90
 		Host: hostname,
128
 		Host: hostname,
97
 	return s
135
 	return s
98
 }
136
 }
99
 
137
 
138
+// ParseSecret parses a secret (both hex and base64 forms).
100
 func ParseSecret(secret string) (Secret, error) {
139
 func ParseSecret(secret string) (Secret, error) {
101
 	s := Secret{}
140
 	s := Secret{}
102
 
141
 

Загрузка…
Отмена
Сохранить