Exposing TLS & Certificate Information in Javascript

"Exposing the server certificate (possibly structured, if not we'll
need a bullet-proof, signed, X.509 library) and path of the TLS
connection as JavaScript objects"

This one was mine.  The following doesn't meet the bar of "concrete,
well-specified proposal" but it might be the beginning of one.

Use Cases

1. A large site that is commonly proxies by corporate and malicious
actors wishes to monitor how common this is done.  They place
javascript bindings in their code to view the user's certificate and
report the observed value.
Note this use case has already been performed by Facebook, who had to
resort to Flash to do so, because javascript did not provide the
functionality.
2. A large site wishes to detect advanced state actors who may perform
sophisticated SSL Man in the Middle.  Although it is possible for an
attacker to detect and negate the javascript checks, powerful
javascript obfuscation techniques can be used to make this extremely
difficult.
Note that this use case fits well with Gmail, who has gone to great
lengths to detect certificate attacks in Chrome, and has the necessary
javascript infrastructure in place to defend against sophisticated
replacement attacks.
3. A large organisation wishes to implement SSL pinning, but is unsure
of all the SSL certificates in use by the different teams of the
organisation.  They create a javascript include that reviews the
certificate chain, and reports it to a central server, and include it
in a central framework.
4. A user wants to write a certificate monitoring extension for Google
Chrome, which does not expose the certificate information via any
extension APIs.  If the bindings are in javascript, such an extension
can be written.  *Note: I'm not 100% sure about the Chrome extension
API, but...
5. A user wants to write a certificate reporting bookmarklet that does
not require any browser extension to be installed.  They write a
concise string of code that will upload the certificate chain for the
website to a central monitoring service.
6. A large website would like to determine how common it is for
network issues to downgrade TLS connections.  They detect the TLS
version negotiated with the client, and confirm the certificate used
so that the connection is with the site and not a proxy, and report
back to the server.

Specification

This is definitely not the correct syntax, but for now I think it gets
the point across:

window.location.tls = {
    version = 'SSL 3.0' || 'TLS 1.0' || 'TLS 1.1' || 'TLS 1.2' || '',

    //I'm really bad at naming things
    flavor = 'PKIX' || 'SRP' || 'PSK' || 'OpenPGP',

    ciphersuite = { //From
https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
        value = UInt8Array, //From the Value column
        description = string //From Description Column
        //Potentially fill out sub values like "Cipher", "Key Exchange"...
    },

    //.certificates is an array of Certificate Objects, or an
    //  empty array if no certificate is used (HTTP, TLS-PSK, DH-Anon, etc)
    //  [0] is the root, and it goes in ascending order to the leaf,
    //  based on the path constructed by the browser
    certificates = [
        CERTIFICATEOBJECT,
        ...
        ]
    },

    clientcertificate = [
        CERTIFICATEOBJECT,
        ...
        ] || null
} //End window.location.tls



CERTIFICATEOBJECT = {
    pem = '...', //A PEM Encoded version of the certificate

    fingerprint : {
        'sha1' : UInt8Array, //SHA1 is a MUST to implement
        'sha256' : UInt8Array //SHA256 is a SHOULD to implement
        },

    serial : UInt8Array,

    version : Uint8,

    signature : {
        algorithm : 'shaWithRSAEncryption', //human readable string
        algorithmid : '1.2.840.113549.1.1.5', //NUMERIC ID (See Below)
        value : UInt8Array //the actual signature
    }

    issuer: FIELDBAG, //See Below

    validity : {
        notBefore : date,
        notafter : date
        },

    subject : FIELDBAG, //See Below

    spki : {
        algorithm : 'rsaEncryption',
        algorithmid : '1.2.840.113549.1.1.1', //NUMERIC ID
        raw : UInt8Array //The raw SPKI from the certificate
        //Each defined type will have the individual components
        //   pulled out, e.g. for RSA
        e : UInt8Array,
        n : UInt8Array
        //Another idea to use JOSE here...
        },

    extensions = {
        //If an extension appears in the Known Extensions Registry,
        //  the extension MUST be exposed as a structured piece of data
        //  to be defined for each of the Known Extensions, and
        //  indexed by a NAME
        //  Example: For Extensions that behave as Subject or Issuer,
        //    use a FIELDBAG (see below)

        //Extensions not in the Known Extensions list MAY be exposed as
        //  a structured piece of data that is indexed by a NAME

        //All Extensions, including extensions not in the Known Extensions
        //  Registry are indexed by a NUMERIC ID and exposed as a UInt8Array
        //  of their value
        },
} //End CERTIFICATEOBJECT



NAME is defined as an ASCII string containing letters, numbers and punctuation
NUMERIC ID is defined as an ASCII string consisting of a series of
numbers with periods, but no other characters
//Two of Many Open Questions: Is there an efficient way to tell if a string is a
//  NAME or NUMERIC ID?  There is no Extension identified solely by a
NUMERIC ID correct?

Examples of Extensions in the 'Known Extensions Registry'
 - Enhanced Key Usage
 - Subject Alternate Name
 - Name Constraints
 - Basic Constraints



FIELDBAG
 - FieldBag.toString() returns the entire contents, e.g.
"E=webmaster@ritter.vg,CN=www.ritter.vg,C=US,Description=Rk4N5yzvvg52R4f4"
 - But is also accessible as a hash, e.g.
window.location.tls.certificates[0]['Subject']['E'] ==
'webmaster@ritter.vg'

Received on Friday, 1 February 2013 19:46:45 UTC