Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why does this work? #3

Closed
spalger opened this issue Jan 21, 2016 · 2 comments
Closed

Why does this work? #3

spalger opened this issue Jan 21, 2016 · 2 comments

Comments

@spalger
Copy link
Contributor

spalger commented Jan 21, 2016

Hey @mscdex

I'm interested in using this library to provide automatic redirection from http -> https (see elastic/kibana#5959) but we're concerned about the magic here.

Would you be able to support this implementation with some information about how/why this works?

var firstByte = d[start];
      if (firstByte < 32 || firstByte >= 127) {
        // tls/ssl

We are concerned about unintended side effects of serving both http and https traffic via the same port. Do you know of any caveats? Know of any supporting reference info?

Thank you so much for your help and this really neat (and surprisingly simple) library!

@spalger
Copy link
Contributor Author

spalger commented Jan 21, 2016

Alright, I just read through RFC 5245 - The Transport Layer Security (TLS) Protocol - Version 1.2 and RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing which outline the structure of TLS and HTTP, and therefore explain why this works.

It boils down to two facts, the first byte of a TLS message is always 22 and the first byte of an HTTP message will always be greater than 32 and less than (not equal to) 127. This means that the condition in the code is asserting that any message whose first byte is outside of the range of a valid HTTP message must be a TLS message. And that totally works! 💃


Here is the breakdown of why, with references:

TLS

  1. The first message sent on a new connection between client and a server is a Handshake of type ClientHello [ref]
  2. The Handshake Protocol defines the format of the ClientHello message, and says that handshake messages are encapulated in TLSPlaintext structures [ref]
  3. TLSPlaintext structures start with a ContentType [ref]
  4. ContentType is an enum, and handshake === 22 [ref]

HTTP

  1. HTTP messages are sent in a "sequence of octets in an encoding that is a superset of US-ASCII" [ref - paragraph 3]

  2. The body of HTTP requests always start with a request-line, the first part of which is the HTTP method [ref]

  3. HTTP methods must be make up of 1 or more tchar values. tchar is a subset of ASCII described as any VCHAR, except delimiters. The full list of options is below: [tchar ref and vchar ref]

    ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'*+-.^_`|~
    
  4. This means all possible decimal values for the first letter of the HTTP method are within the following ranges [ref]

    chars decimal range
    A-Z 65-90
    a-z 97-122
    0-9 48-57
    ! 33
    # 35
    $ 36
    % 37
    & 38
    ' 39
    * 42
    + 43
    - 45
    . 46
    ^ 94
    _ 95
    ` 96
    ~ 126

@silverwind
Copy link

Nice writeup! This might be good material for a 'How it works' section of the Readme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants