Преглед изворни кода

Add documentation for a secret

tags/v2.0.0-rc1
9seconds пре 5 година
родитељ
комит
e6d444546f
1 измењених фајлова са 40 додато и 1 уклоњено
  1. 40
    1
      mtglib/secret.go

+ 40
- 1
mtglib/secret.go Прегледај датотеку

@@ -11,11 +11,43 @@ const secretFakeTLSFirstByte byte = 0xee
11 11
 
12 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 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 47
 	Host string
17 48
 }
18 49
 
50
+// MarshalText is to support text.Marshaller interface.
19 51
 func (s Secret) MarshalText() ([]byte, error) {
20 52
 	if s.Valid() {
21 53
 		return []byte(s.String()), nil
@@ -24,6 +56,7 @@ func (s Secret) MarshalText() ([]byte, error) {
24 56
 	return nil, nil
25 57
 }
26 58
 
59
+// MarshalText is to support text.Unmarshaller interface.
27 60
 func (s *Secret) UnmarshalText(data []byte) error {
28 61
 	text := string(data)
29 62
 	if text == "" {
@@ -62,18 +95,22 @@ func (s *Secret) UnmarshalText(data []byte) error {
62 95
 	return nil
63 96
 }
64 97
 
98
+// Valid checks if this secret is valid and can be used in proxy.
65 99
 func (s Secret) Valid() bool {
66 100
 	return s.Key != secretEmptyKey && s.Host != ""
67 101
 }
68 102
 
103
+// String is to support fmt.Stringer interface.
69 104
 func (s Secret) String() string {
70 105
 	return s.Base64()
71 106
 }
72 107
 
108
+// Base64 returns a base64-encoded form of this secret.
73 109
 func (s Secret) Base64() string {
74 110
 	return base64.RawURLEncoding.EncodeToString(s.makeBytes())
75 111
 }
76 112
 
113
+// Hex returns a hex-encoded form of this secret (ee-secret).
77 114
 func (s Secret) Hex() string {
78 115
 	return hex.EncodeToString(s.makeBytes())
79 116
 }
@@ -85,6 +122,7 @@ func (s *Secret) makeBytes() []byte {
85 122
 	return data
86 123
 }
87 124
 
125
+// GenerateSecret makes a new secret with a given hostname.
88 126
 func GenerateSecret(hostname string) Secret {
89 127
 	s := Secret{
90 128
 		Host: hostname,
@@ -97,6 +135,7 @@ func GenerateSecret(hostname string) Secret {
97 135
 	return s
98 136
 }
99 137
 
138
+// ParseSecret parses a secret (both hex and base64 forms).
100 139
 func ParseSecret(secret string) (Secret, error) {
101 140
 	s := Secret{}
102 141
 

Loading…
Откажи
Сачувај