Skip to content
This repository has been archived by the owner on Oct 2, 2019. It is now read-only.

Raw Socket API: Support for secure sockets #10

Open
ClaesNilsson opened this issue Apr 25, 2013 · 17 comments
Open

Raw Socket API: Support for secure sockets #10

ClaesNilsson opened this issue Apr 25, 2013 · 17 comments
Assignees

Comments

@ClaesNilsson
Copy link
Contributor

Support for secure sockets need more investigation. Some issues:

  • Do we need support for secure transport over UDP?
  • Do we neerd client authentication?
  • Provision to specify keys and certificates ?
@ghost ghost assigned ClaesNilsson Apr 25, 2013
@anotherlin
Copy link

As for secure UDP, it's your suggestion Claes :) A spec exists and it is implemented (OpenSSL does have support for instance). I personally don't know of use for secure UDP, but why not.

Yes, client authentification must be available. There are use cases when you want to be certain that you are talking with the real (authentified server) and the server wants to be certain that the client is who it pretends it is.

Yes, constructor must be given keys, etc. It is quite complicated.

@sicking
Copy link

sicking commented Jul 8, 2013

On Jul 4, 2013 7:19 PM, "Lin Ke-Fong" [email protected] wrote:

As for secure UDP, it's your suggestion Claes :) A spec exists and it is
implemented (OpenSSL does have support for instance). I personally don't
know of use for secure UDP, but why not.

The "why not" is always easy to answer:

Adding features to the web platform comes at a very high cost. It requires
implementation, code maintenance, documentation, documentation maintenance,
developer mind share, risk of compatibility bugs, and risk of conflicting
with other features that we want to add in the future.

Adding something only once we have strong use cases means not wasting time
and money on features that aren't as heavily used. And waiting to add
features almost always means that we have more experience and ability to
use better technical solutions.

So we should only add secure UDP support if there are strong demand for it.
Given how little it is used today, I think we should not do so.

/ Jonas

@anotherlin
Copy link

Regarding secure UDP, I agree with you. I don't know of actual use case. And adding support for anything related to security, is gonna be high cost.

Besides, if secured datagram is really needed, then you can just use a secure TCP socket (SSL) to exchange a symmetric encryption key (like AES). Then open a UDP socket and exchange encrypted packet with peer.

Still, Claes may have actual use cases that require it. Let's wait till he's back.

@marcoscaceres
Copy link
Contributor

If UDP grows in usage, and people come to rely on it for communication, won't it be subject to surveillance like other Web content? If so, then that is pretty strong motivator to secure it from the start.

@sicking
Copy link

sicking commented Jul 9, 2013

Please keep in mind that the main use cases for the UDP and TCP socket APIs is compatibility with existing hardware and software. When deploying something new using WebSocket and PeerConnection is preferable since their security model enables us to expose them to all apps and pages. UDP and TCP sockets can only be exposed to just signed ones.

To put it another way: I hope that UDPSocket usage doesn't grow in usage. I hope PeerConnection does. PeerConnection already has nice features like, goes through firewalls, protects the remote party, and is encrypted.

@marcoscaceres
Copy link
Contributor

@sicking good point :)

@ClaesNilsson
Copy link
Contributor Author

Some notes/ questions on secure sockets follow below. I hope that 4D, and/or other security experts, could provide input to be discussed at the Toronto meeting.

I guess that in most cases something very easy is enough. Then there are use cases, e.g. corporate e-mail, which will require a more detailed control.

Questions to be discussed follow:

  • TCP (Client) Socket, server authentication: The simplest approach is to state in the constructor options that TSL or SSL should be used. By default the default root certificate and keys are used. The Client checks the server’s certificate and then uses the certificate’s public key to get the session key.
    In addition more advanced options could be provided based on the uses cases we need to support:
  • The possibility to configure protocols and cipher suites to use with the secure socket.
  • Cert pinning, i.e. define that you only trust certain certificates and not trust the default keystore.
  • TCP (Client) Socket, server authentication: I guess that there must be an option to select the certificate that should be used by the server to authenticate the client. But I am not sure if this should be an option for the web application or by another UI?
  • TCP Server Socket: I guess that it must be possible to elect server certificate but not sure on the options that should be provided to the web application or by another UI.

@anotherlin
Copy link

Simplest (and probably most common) case for client socket is to take the server's certificate, authenticate it, and do the key exchange (SSL handshake), then the secure session is open and running. This is what happens when using SSL for HTTPS or emails (SMTP, IMAP). To add support for that scenario, from an API point of view, would just require adding a secureFlag in constructor and an UpgradeToSecure() method (STARTTLS). This is the simplest case, the client doesn't authenticate itself, no need to manage keys and stuff.

Because the API is also intended to be rather complete, client authentication must be supported too. This will require to add options/arguments to specify security credentials (public key, certificate, etc).

Server side is the more complicated because of wide range of options.

@ClaesNilsson
Copy link
Contributor Author

Ok, thanks Ke-Fong. Looking into the specification this would mean:

  • Creating a secure TCPSocket supporting server authentication: We already have the "useSecureTransport" field in the TCPOptions dictionary that is the type of the "options" argument in the TCPSocket constructor.
  • An asynchronous method startTLS() to upgrade an existing TCPSocket to a secure socket. Assume that we should design a promised-based method.
  • I guess that we should add ReadyState "opensecure" or similar.

The addition of startTLS() should be quite straightforward and I can make a proposal.

For Client autjentication and and TCPServer socket I would be happy for more expert input.

@sicking
Copy link

sicking commented Aug 19, 2013

On Mon, Aug 19, 2013 at 2:02 AM, Claes Nilsson [email protected] wrote:

An asynchronous method startTLS() to upgrade an existing TCPSocket to a secure socket. Assume that we should design a promised-based method.

What would happen to data that is sent between startTLS() is called,
and the returned promise is fulfiled? I would expect it to be queued?

I guess that we should add ReadyState "opensecure" or similar.

Sounds good.

/ Jonas

@ClaesNilsson
Copy link
Contributor Author

Another option is to have two more ReadyStates:

  • startingtls
  • opensecure

This means that the first step for send() would be:

  1. If readyState is not "open" or "opensecure" throw DOMException InvalidStateError and abort these steps.

@anotherlin
Copy link

A STARTTLS initiates the TLS/SSL handshake, authentifying peers and negociating encryption keys, this can take a little time and may fail for various reasons (unable to validate certificate, unsupported encryption method, etc). It of course requires a readyState and an event (for example "onsecured" or "onupgraded") when the handshake complete. I don't think it makes sense to send (queue) data while waiting for the handshake to complete : Why send data when you're not even sure that your peer is authentified and secure communication is possible.

Regarding the "open" and "opensecure" readyStates, I don't think it is a good idea to have to two states for "open". For instance, code for SMTP in SSL (port 465) and non-SSL (25) differs only in connection. Otherwise this is transparent for user. Having to states would require two if cases to check for state. Would rather recommend to make "secure" an attribute instead.

@ClaesNilsson
Copy link
Contributor Author

Thanks Ke-Fong. A potential definition of an upgradeToSecure() method based on promises could be:

Method definition:

Promise upgradeToSecure ();

Upgrades an existing insecure TCP connection to an encrypted (TLS or SSL) connection, instead of using a separate port for encrypted communication. This method is known as “STARTTLS”.

No parameters.

Return type: Promise

Stepwise description:

The upgradeToSecure method when invoked must run the following steps:

  1. If readyState is not "open" throw DOMException InvalidStateError and abort these steps.
  2. Initiate “STARTTLS” and set the readyState attribute to "upgradingtosecure"
  3. Let promise be a new Promise object and resolver its associated resolver.
  4. Return promise and run the remaining steps asynchronously.
  5. If an error occurs, run these substeps and then terminate these steps:
 1. Set the readyState attribute to "open"
 2. Let error be a new DOMError object whose name is "…".
 3. Create a new instance of SocketErrorEvent.
 4. Set the error.name attribute of the SocketErrorEvent object to "NetworkError".
 5. Set the error.type attribute of the SocketErrorEvent object to the appropriate error type. See enum SocketErrorType.
 6. Set the error.message attribute of the SocketErrorEvent object to an informative message stating the reason for the error.
 7. Run resolver's internal reject algorithm with with the newly created SocketErrorEvent instance as value.
  1. When the operation completes successfully, run these substeps:
  2. Set the readyState attribute to "open".
  3. Set the secure attribute to true.
  4. Run resolver's internal fulfill algorithm with no value.

@marcoscaceres
Copy link
Contributor

Please avoid throwing exceptions - always return the promise and then asynchronously call the error instead.
Also, I'm not sure if step 2 should happen synchronously there. Shouldn't that be done in a task? The same applies to other microtasks such as the operation completing successfully.

@ClaesNilsson
Copy link
Contributor Author

Ok, thanks for comments Marcos. I am not yet sure on how to design methods based on promises. Looking forward to your page https://github.com/w3ctag/promises-spec-text :-).

I am also not sure when a task needs to be queued. Compare with the TCPSocket constructor step 7. Here I state "Attempt to connect to the requested address and port in the background (without blocking scripts).". Could we have some wording analogous to this for STARTTLS, e.g.
"Execute “STARTTLS” in the background (without blocking scripts).and set the readyState attribute to "upgradingtosecure" "?

For the operation completing successfully I just follow the same pattern as the Task Scheduler API.

@ClaesNilsson
Copy link
Contributor Author

Comment from Patrcik Manus/Mozilla:

  • on security - we need to think about this a little harder. What does
    it mean to be priv'd enough to use this API? Simply being an installed
    app or being an audited/signed one? The security implications are
    pretty staggering here and I'm pretty sure the answer needs to be more
    than "unprivd js off a webpage can't do this". Our user's privacy is
    pretty much undermined by allowing this.. I know this is desired as a
    backwards looking bridge, but the truth is it brings new functionality
    to the mobile platform and that platform ought to at least be dealing
    only in TLS and DTLS as table stakes.. While I think TLS and DTLS
    ought to be mandatory - at the very least they ought to possible and
    it doesn't really look like that use case has been fully baked into
    the API yet.

[Ke-Fong]: I'm supposed to help write the proposal in that regard.
The problem is the TLS and DTLS specs are rather complicated.
And there are quite a few questions about what to include or not.

Having basic client capabilities (to allow secure connection to SMTPS
or HTTPS, etc) will be pretty easy.
Problem is mostly server.

[Claes] Patrick, please see the discussion at #10 .

@noloader
Copy link

noloader commented Jun 1, 2014

Do we need support for secure transport over UDP?

RFC 6520 lists a couple of reasons in the context of TLS/DTLS. https://tools.ietf.org/html/rfc6520. I'm not sure if and how they intersect with modern web apps, though.

The mobile shell also uses it. http://mosh.mit.edu/. I'm not sure if the project would have any interest in a Web 2.0 port.

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

No branches or pull requests

5 participants