• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

cpu/H11-May-2021-

examples/H11-May-2021-

testdata/H11-May-2021-

testenv/H11-May-2021-

.travis.ymlH A D11-May-2021391

CONTRIBUTING.mdH A D11-May-2021968

CONTRIBUTORS_GUIDE.mdH A D11-May-20213.5 KiB

LICENSEH A D11-May-202134.3 KiB

README.mdH A D11-May-20211.6 KiB

README.upstream.mdH A D11-May-202113.1 KiB

alert.goH A D11-May-20212.9 KiB

auth.goH A D11-May-20216.9 KiB

auth_test.goH A D11-May-20214.5 KiB

cipher_suites.goH A D11-May-202115.8 KiB

common.goH A D11-May-202140.6 KiB

conn.goH A D11-May-202142.8 KiB

conn_test.goH A D11-May-202110.7 KiB

example_test.goH A D11-May-20216.3 KiB

generate_cert.goH A D11-May-20214.6 KiB

go.modH A D11-May-2021256

go.sumH A D11-May-20211.9 KiB

handshake_client.goH A D11-May-202130.4 KiB

handshake_client_test.goH A D11-May-202155.1 KiB

handshake_client_tls13.goH A D11-May-202122 KiB

handshake_messages.goH A D11-May-202147.1 KiB

handshake_messages_test.goH A D11-May-202113.2 KiB

handshake_server.goH A D11-May-202122.4 KiB

handshake_server_test.goH A D11-May-202160.3 KiB

handshake_server_tls13.goH A D11-May-202125.6 KiB

handshake_test.goH A D11-May-20216.7 KiB

key_agreement.goH A D11-May-20219.9 KiB

key_schedule.goH A D11-May-20215.9 KiB

key_schedule_test.goH A D11-May-20215.6 KiB

prf.goH A D11-May-202111.3 KiB

prf_test.goH A D11-May-20216.6 KiB

ticket.goH A D11-May-20216.1 KiB

tls.goH A D11-May-20219.7 KiB

tls_test.goH A D11-May-202130 KiB

u_common.goH A D11-May-20218.4 KiB

u_common_test.goH A D11-May-2021687

u_conn.goH A D11-May-202118.5 KiB

u_conn_test.goH A D11-May-202121.2 KiB

u_fingerprinter.goH A D11-May-202113.3 KiB

u_fingerprinter_test.goH A D11-May-202127 KiB

u_parrots.goH A D11-May-202128.5 KiB

u_prng.goH A D11-May-20213.7 KiB

u_public.goH A D11-May-202119.7 KiB

u_roller.goH A D11-May-20212.7 KiB

u_tls_extensions.goH A D11-May-202117 KiB

y_certificate_compression.goH A D11-May-20214 KiB

y_ctaes.goH A D11-May-20211.6 KiB

README.md

1### obfs4proxy/meek_lite utls fork
2#### Yawning Angel (yawning at schwanenlied dot me)
3
4### What?
5
6This is a fork of [utls][1] for the specific purpose of improving
7obfs4proxy's meek_lite transport.
8
9Functional differences:
10 * Go v1.11 module metadata files have been added.
11 * The handshake no longer fails if the remote server selects a curve
12   that is not the 0th preferred curve (X25519).  This issue is primarily
13   observable with the Azure host used for the Tor Browser meek bridge,
14   and the `HelloFirefox_63` profile.
15 * The handshake no longer fails against servers that support the
16   [TLS Certificate Compression][2] draft.
17 * `HelloGolang` is totally busted, and no longer resembles `crypto/tls`.
18 * The AES block cipher and GHASH implementation will be timing
19   side-channel safe on architectures where the `crypto/aes` one is
20   not.
21
22### Why?
23
24I was bored and it was an easy way to make meek_lite less awful.
25
26### Why don't you upstream the changes?
27
28It's a pet project done in my spare time and I want to use a
29[strong/viral][3] copyleft license for the vast majority of my pet
30projects going forward.
31
32I used to have a more liberal view on licensing but certain entities have
33ruined it for everybody.  The portions of the code that I have not written
34or altered are naturally under the original license.
35
36### You changed something and broke my project!
37
38Your tears are delicious, and your code will burn.
39
40[1]: https://github.com/refraction-networking/utls
41[2]: https://datatracker.ietf.org/doc/draft-ietf-tls-certificate-compression/
42[3]: https://www.gnu.org/licenses/gpl.txt
43

README.upstream.md

1# ![uTLS](logo_small.png) uTLS
2[![Build Status](https://travis-ci.org/refraction-networking/utls.svg?branch=master)](https://travis-ci.org/refraction-networking/utls)
3[![godoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/refraction-networking/utls#UConn)
4---
5uTLS is a fork of "crypto/tls", which provides ClientHello fingerprinting resistance, low-level access to handshake, fake session tickets and some other features. Handshake is still performed by "crypto/tls", this library merely changes ClientHello part of it and provides low-level access.
6Golang 1.11+ is required.
7If you have any questions, bug reports or contributions, you are welcome to publish those on GitHub. If you want to do so in private, you can contact one of developers personally via sergey.frolov@colorado.edu
8
9Documentation below may not keep up with all the changes and new features at all times,
10so you are encouraged to use [godoc](https://godoc.org/github.com/refraction-networking/utls#UConn).
11
12# Features
13## Low-level access to handshake
14* Read/write access to all bits of client hello message.
15* Read access to fields of ClientHandshakeState, which, among other things, includes ServerHello and MasterSecret.
16* Read keystream. Can be used, for example, to "write" something in ciphertext.
17
18## ClientHello fingerprinting resistance
19Golang's ClientHello has a very unique fingerprint, which especially sticks out on mobile clients,
20where Golang is not too popular yet.
21Some members of anti-censorship community are concerned that their tools could be trivially blocked based on
22ClientHello with relatively small collateral damage. There are multiple solutions to this issue.
23
24**It is highly recommended to use multiple fingeprints, including randomized ones to avoid relying on a single fingerprint.**
25[utls.Roller](#roller) does this automatically.
26
27### Randomized Fingerprint
28Randomized Fingerprints are supposedly good at defeating blacklists, since
29those fingerprints have random ciphersuites and extensions in random order.
30Note that all used ciphersuites and extensions are fully supported by uTLS,
31which provides a solid moving target without any compatibility or parrot-is-dead attack risks.
32
33But note that there's a small chance that generated fingerprint won't work,
34so you may want to keep generating until a working one is found,
35and then keep reusing the working fingerprint to avoid suspicious behavior of constantly changing fingerprints.
36[utls.Roller](#roller) reuses working fingerprint automatically.
37
38#### Generating randomized fingerprints
39
40To generate a randomized fingerprint, simply do:
41```Golang
42uTlsConn := tls.UClient(tcpConn, &config, tls.HelloRandomized)
43```
44you can use `helloRandomizedALPN` or `helloRandomizedNoALPN` to ensure presence or absence of
45ALPN(Application-Layer Protocol Negotiation) extension.
46It is recommended, but certainly not required to include ALPN (or use helloRandomized which may or may not include ALPN).
47If you do use ALPN, you will want to correctly handle potential application layer protocols (likely h2 or http/1.1).
48
49#### Reusing randomized fingerprint
50```Golang
51// oldConn is an old connection that worked before, so we want to reuse it
52// newConn is a new connection we'd like to establish
53newConn := tls.UClient(tcpConn, &config, oldConn.ClientHelloID)
54```
55
56### Parroting
57This package can be used to parrot ClientHello of popular browsers.
58There are some caveats to this parroting:
59* We are forced to offer ciphersuites and tls extensions that are not supported by crypto/tls.
60This is not a problem, if you fully control the server and turn unsupported things off on server side.
61* Parroting could be imperfect, and there is no parroting beyond ClientHello.
62#### Compatibility risks of available parrots
63
64| Parrot        | Ciphers* | Signature* | Unsupported extensions | TLS Fingerprint ID              |
65| ------------- | -------- | ---------- | ---------------------- | --------------------------------------------- |
66| Chrome 62     | no       | no         | ChannelID              | [0a4a74aeebd1bb66](https://tlsfingerprint.io/id/0a4a74aeebd1bb66) |
67| Chrome 70     | no       | no         | ChannelID, Encrypted Certs | [bc4c7e42f4961cd7](https://tlsfingerprint.io/id/bc4c7e42f4961cd7) |
68| Chrome 72     | no       | no         | ChannelID, Encrypted Certs | [bbf04e5f1881f506](https://tlsfingerprint.io/id/bbf04e5f1881f506) |
69| Chrome 83     | no       | no         | ChannelID, Encrypted Certs | [9c673fd64a32c8dc](https://tlsfingerprint.io/id/9c673fd64a32c8dc) |
70| Firefox 56    | very low | no         | None                   | [c884bad7f40bee56](https://tlsfingerprint.io/id/c884bad7f40bee56) |
71| Firefox 65    | very low | no         | MaxRecordSize                   | [6bfedc5d5c740d58](https://tlsfingerprint.io/id/6bfedc5d5c740d58) |
72| iOS 11.1      | low** | no         | None                   | [71a81bafd58e1301](https://tlsfingerprint.io/id/71a81bafd58e1301) |
73| iOS 12.1      | low** | no         | None                   | [ec55e5b4136c7949](https://tlsfingerprint.io/id/ec55e5b4136c7949) |
74
75\* Denotes very rough guesstimate of likelihood that unsupported things will get echoed back by the server in the wild,
76*visibly breaking the connection*.
77\*\* No risk, if `utls.EnableWeakCiphers()` is called prior to using it.
78
79#### Parrots FAQ
80> Does it really look like, say, Google Chrome with all the [GREASE](https://tools.ietf.org/html/draft-davidben-tls-grease-01) and stuff?
81
82It LGTM, but please open up Wireshark and check. If you see something — [say something](issues).
83
84> Aren't there side channels? Everybody knows that the ~~bird is a word~~[parrot is dead](https://people.cs.umass.edu/~amir/papers/parrot.pdf)
85
86There sure are. If you found one that approaches practicality at line speed — [please tell us](issues).
87
88However, there is a difference between this sort of parroting and techniques like SkypeMorth.
89Namely, TLS is highly standardized protocol, therefore simply not that many subtle things in TLS protocol
90could be different and/or suddenly change in one of mimicked implementation(potentially undermining the mimicry).
91It is possible that we have a distinguisher right now, but amount of those potential distinguishers is limited.
92
93### Custom Handshake
94It is possible to create custom handshake by
951) Use `HelloCustom` as an argument for `UClient()` to get empty config
962) Fill tls header fields: UConn.Hello.{Random, CipherSuites, CompressionMethods}, if needed, or stick to defaults.
973) Configure and add various [TLS Extensions](u_tls_extensions.go) to UConn.Extensions: they will be marshaled in order.
984) Set Session and SessionCache, as needed.
99
100If you need to manually control all the bytes on the wire(certainly not recommended!),
101you can set UConn.HandshakeStateBuilt = true, and marshal clientHello into UConn.HandshakeState.Hello.raw yourself.
102In this case you will be responsible for modifying other parts of Config and ClientHelloMsg to reflect your setup
103and not confuse "crypto/tls", which will be processing response from server.
104
105### Fingerprinting Captured Client Hello
106You can use a captured client hello to generate new ones that mimic/have the same properties as the original.
107The generated client hellos _should_ look like they were generated from the same client software as the original fingerprinted bytes.
108In order to do this:
1091) Create a `ClientHelloSpec` from the raw bytes of the original client hello
1102) Use `HelloCustom` as an argument for `UClient()` to get empty config
1113) Use `ApplyPreset` with the generated `ClientHelloSpec` to set the appropriate connection properties
112```
113uConn := UClient(&net.TCPConn{}, nil, HelloCustom)
114fingerprinter := &Fingerprinter{}
115generatedSpec, err := fingerprinter.FingerprintClientHello(rawCapturedClientHelloBytes)
116if err != nil {
117  panic("fingerprinting failed: %v", err)
118}
119if err := uConn.ApplyPreset(generatedSpec); err != nil {
120  panic("applying generated spec failed: %v", err)
121}
122```
123The `rawCapturedClientHelloBytes` should be the full tls record, including the record type/version/length header.
124
125## Roller
126
127A simple wrapper, that allows to easily use multiple latest(auto-updated) fingerprints.
128
129```Golang
130// NewRoller creates Roller object with default range of HelloIDs to cycle
131// through until a working/unblocked one is found.
132func NewRoller() (*Roller, error)
133```
134
135```Golang
136// Dial attempts to connect to given address using different HelloIDs.
137// If a working HelloID is found, it is used again for subsequent Dials.
138// If tcp connection fails or all HelloIDs are tried, returns with last error.
139//
140// Usage examples:
141//
142// Dial("tcp4", "google.com:443", "google.com")
143// Dial("tcp", "10.23.144.22:443", "mywebserver.org")
144func (c *Roller) Dial(network, addr, serverName string) (*UConn, error)
145```
146
147## Fake Session Tickets
148Fake session tickets is a very nifty trick that allows power users to hide parts of handshake, which may have some very fingerprintable features of handshake, and saves 1 RTT.
149Currently, there is a simple function to set session ticket to any desired state:
150
151```Golang
152// If you want you session tickets to be reused - use same cache on following connections
153func (uconn *UConn) SetSessionState(session *ClientSessionState)
154```
155
156Note that session tickets (fake ones or otherwise) are not reused.
157To reuse tickets, create a shared cache and set it on current and further configs:
158
159```Golang
160// If you want you session tickets to be reused - use same cache on following connections
161func (uconn *UConn) SetSessionCache(cache ClientSessionCache)
162```
163
164# Client Hello IDs
165See full list of `clientHelloID` values [here](https://godoc.org/github.com/refraction-networking/utls#ClientHelloID).
166There are different behaviors you can get, depending  on your `clientHelloID`:
167
1681. ```utls.HelloRandomized``` adds/reorders extensions, ciphersuites, etc. randomly.
169`HelloRandomized` adds ALPN in a percentage of cases, you may want to use `HelloRandomizedALPN` or
170`HelloRandomizedNoALPN` to choose specific behavior explicitly, as ALPN might affect application layer.
1712. ```utls.HelloGolang```
172    HelloGolang will use default "crypto/tls" handshake marshaling codepath, which WILL
173    overwrite your changes to Hello(Config, Session are fine).
174    You might want to call BuildHandshakeState() before applying any changes.
175    UConn.Extensions will be completely ignored.
1763. ```utls.HelloCustom```
177will prepare ClientHello with empty uconn.Extensions so you can fill it with TLSExtension's manually.
1784. The rest will will parrot given browser. Such parrots include, for example:
179	* `utls.HelloChrome_Auto`- parrots recommended(usually latest) Google Chrome version
180	* `utls.HelloChrome_58` - parrots Google Chrome 58
181	* `utls.HelloFirefox_Auto` - parrots recommended(usually latest) Firefox version
182	* `utls.HelloFirefox_55` - parrots Firefox 55
183
184# Usage
185## Examples
186Find basic examples [here](examples/examples.go).
187Here's a more [advanced example](https://github.com/sergeyfrolov/gotapdance/blob//9a777f35a04b0c4c5dacd30bca0e9224eb737b5e/tapdance/conn_raw.go#L275-L292) showing how to generate randomized ClientHello, modify generated ciphersuites a bit, and proceed with the handshake.
188### Migrating from "crypto/tls"
189Here's how default "crypto/tls" is typically used:
190```Golang
191    dialConn, err := net.Dial("tcp", "172.217.11.46:443")
192    if err != nil {
193        fmt.Printf("net.Dial() failed: %+v\n", err)
194        return
195    }
196
197    config := tls.Config{ServerName: "www.google.com"}
198    tlsConn := tls.Client(dialConn, &config)
199    n, err = tlsConn.Write("Hello, World!")
200    //...
201```
202To start using using uTLS:
2031. Import this library (e.g. `import tls "github.com/refraction-networking/utls"`)
2042. Pick the [Client Hello ID](#client-hello-ids)
2053. Simply substitute `tlsConn := tls.Client(dialConn, &config)`
206with `tlsConn := tls.UClient(dialConn, &config, tls.clientHelloID)`
207
208### Customizing handshake
209Some customizations(such as setting session ticket/clientHello) have easy-to-use functions for them. The idea is to make common manipulations easy:
210```Golang
211    cRandom := []byte{100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
212        110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
213        120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
214        130, 131}
215    tlsConn.SetClientRandom(cRandom)
216    masterSecret := make([]byte, 48)
217    copy(masterSecret, []byte("masterSecret is NOT sent over the wire")) // you may use it for real security
218
219    // Create a session ticket that wasn't actually issued by the server.
220    sessionState := utls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12),
221        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
222        masterSecret,
223        nil, nil)
224    tlsConn.SetSessionState(sessionState)
225```
226
227For other customizations there are following functions
228```
229// you can use this to build the state manually and change it
230// for example use Randomized ClientHello, and add more extensions
231func (uconn *UConn) BuildHandshakeState() error
232```
233```
234// Then apply the changes and marshal final bytes, which will be sent
235func (uconn *UConn) MarshalClientHello() error
236```
237
238## Contributors' guide
239Please refer to [this document](./CONTRIBUTORS_GUIDE.md) if you're interested in internals
240
241## Credits
242The initial development of uTLS was completed during an internship at [Google Jigsaw](https://jigsaw.google.com/). This is not an official Google product.
243