Ability to specify desired set of cipher suites

Is there any way to explicitly specify the set of cipher suites that you'd like your `URLSession` client to try and use when establishing a secure connection?


I know that there's the `NSExceptionRequiresForwardSecrecy` key in the `NSAppTransportSecurity` dictionary but that doesn't seem to be what I need.


I basically just want to be able to tell the client to notify the server that it is only willing to use the following cipher suites:


TLS_RSA_WITH_RC4_128_SHA,

TLS_RSA_WITH_3DES_EDE_CBC_SHA,

TLS_RSA_WITH_AES_128_CBC_SHA,

TLS_RSA_WITH_AES_256_CBC_SHA,

TLS_RSA_WITH_AES_128_GCM_SHA256,

TLS_RSA_WITH_AES_256_GCM_SHA384,


That way I can decrypt the HTTP/2 traffic that I'm having the client and server communicate with in Wireshark.


Thanks!

Replies

Is there any way to explicitly specify the set of cipher suites that you'd like your

URLSession
client to try and use when establishing a secure connection?

No. You can control the cypher suites offered when using lower-level APIs (Secure Transport and CFSocketStream) but that doesn’t really help you much if you want to use NSURLSession.

That way I can decrypt the HTTP/2 traffic that I'm having the client and server communicate with in Wireshark.

I’m confused why you need this. If you have the server’s private key, you should be able to decode any TLS traffic that’s not using forward secrecy. Alternatively, unless you care about the low-level details, you can make a lot of headway with an HTTP debugging proxy; Technote 2232 HTTPS Server Trust Evaluation has links to the most commonly used tools in this space.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the link to that Technote. I'll take a proper look at that later today.


I'm not familiar with CFSocketStream so this might be a stupid question, but does it have HTTP/2 support as with NSURLSession?


And the reason that I'd like to be able to specify the cipher suites is that even when I try and restrict the available cipher suites on the server's side, it seems that because the macOS client is still signalling that it's happy with cipher suites that use forward secrecy, then it's a cipher suite that uses forward secrecy that ends up being used.


I've got a barebones http/2 server here (written with Go) that I've been testing with: https://github.com/hamchapman/http2-barebones-server


I tried adding this code to restrict the cipher suites on the server but it still ended up using one with forward secrecy:


package http2test


import (
  "crypto/tls"
  "net/http"


  "github.com/zimbatm/httputil2"
)


type Server struct {
  Muxer
  *httputil2.MiddlewareList
  *http.Server
}


func NewServer() *Server {
  mux := newServeMux()
  ml := &httputil2.MiddlewareList{}
  ml.Handler = mux
  ml.Use(
       httputil2.CleanPathMiddleware(),
       httputil2.GzipMiddleware(-1),
       httputil2.RecoveryMiddleware(httputil2.DefaultCallback),
  )
  server := &http.Server{}


  server.TLSConfig = new(tls.Config)
  server.TLSConfig.InsecureSkipVerify = true
  server.TLSConfig.CipherSuites = []uint16{
       tls.TLS_RSA_WITH_RC4_128_SHA,
       tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
       tls.TLS_RSA_WITH_AES_128_CBC_SHA,
       tls.TLS_RSA_WITH_AES_256_CBC_SHA,
       tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
       tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
  }

  return &Server{mux, ml, server}
}


func (s *Server) ListenAndServeTLS(certFile string, keyFile string) error {
  s.Server.Handler = s.Chain()
  return s.Server.ListenAndServeTLS(certFile, keyFile)
}

I'm not familiar with CFSocketStream so this might be a stupid question, but does it have HTTP/2 support as with NSURLSession?

No. CFSocketStream is a stream abstraction used (via the NSStream and CFStream API) to run a TCP connection. The only way to get at iOS’s HTTP/2 implementation is via NSURLSession (or higher-level stuff layered on top of that).

And the reason that I'd like to be able to specify the cipher suites is that even when I try and restrict the available cipher suites on the server's side, it seems that because the macOS client is still signalling that it's happy with cipher suites that use forward secrecy, then it's a cipher suite that uses forward secrecy that ends up being used.

This seems like a problem with your server-side code. TLS cypher suite negotiation works as follows:

  1. the client offers a set of cypher suites (in its

    Client Hello
    message)
  2. the server picks its favourite from that list and tells the client (via the

    Server Hello
    message)
  3. if the client doesn’t like the result, it can disconnect (it shouldn’t do this in the case of cypher suites — after all, it offered to support all of the cypher suites listed in its

    Client Hello
    — but it can happen in other cases, like the TLS version number)

You can use a packet trace to verify that the client is offering cypher suites that don’t support forward secrecy. If the server then chooses one of the forward secrecy cypher suites, that’s something you’ll have to fix on the server. I can’t help you with that, partly because it’s outside of my remit but mostly because I don’t know anything about Go server development )-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"