Skip to content

Why does this work? #3

Closed
Closed

Description

@spalger

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!

Activity

  1. spalger commented on Jan 21, 2016

    @spalger
    ContributorAuthor

    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
  2. silverwind commented on Jan 21, 2016

    @silverwind

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions