SSL handshake duration / time benchmark without body - webserver

is there any way to benchmark SSL handshake time?
I want to know how much ssl handshakes my server can handle but i dont want the body of the website.
I tried ApacheBench and Vegeta but i think these tools are not the right thing.

Related

Secure socket vs data encryption

I have a project where data sent between two peers needs to be encrypted. I dont need to authenticate the server or the client , I just need my data to be unreadable on the network.
I have two options:
1- Secure socket
- Open a secure socket
- Write clear data
2- Socket
- Open a socket
- Encrypt data
- Write encrypted data
Is there a performance benefit in using a secure socket instead of "normal" socket in which I write encrypted data? (let's say i'm using the same cipher in both case)
No, there is no difference with regards to speed when it comes to the algorithms used. In general you'd need authenticity, integrity and authenticity of messages in a transport protocol. Generally after the initial handshake this is performed by symmetric algorithms in a rather efficient manner.
Creating your own transport protocol is so fraught with danger that the chance of creating and implementing a secure protocol by a novice is about zero. For instance, if you don't know about plaintext or padding oracle attacks then you may loose confidentiality of the message, basically leaving you with messages without any protection.
So check the fastest TLS 1.2 or 1.3 ciphersuites and use that. You may want to check what Google has introduced to TLS; they've really focussed on speed and security.
(Note that a secure socket without authentication allows a man in the middle (MITM) to intercept and thus see in the clear your data.)
A secure socket will take longer to establish, then taken about the same to encrypt. So performance wise, if you have a pre-shared symmetric encryption key, you would benefit a from skipping the ssl/tls handshake and go directly to tcp socket. That would show as a big speedup for numerous short connections, in particular if they were not using sslcontext and session resumption (lots of JSSE jargon, I know, but I keep it obscure because this you know or you don't, here is not the place).
However, if you don't have a pre-shared key, the whole handshake is really something you shouldn't avoid.

How to cancel a persistent connection using NSURLConnection?

Is it possible to destroy a persistent connection that has been created with NSURLConnection? I need to be able to destroy the persistent connection and do another SSL handshake.
As it is now, calling [conn cancel] leaves a persistent connection behind that gets used with the next connection request to that host, which I don't want to happen.
As it turns out, I believe the Secure Transport TLS session cache is to blame.
I also asked the question on the apple developer forums, and got a response from an Apple person. He pointed me to this Apple sample code readme where it says:
At the bottom of the TLS stack on both iOS and Mac OS X is a component known as Secure Transport. Secure Transport maintains a per-process TLS session cache. When you connect via TLS, the cache stores information about the TLS negotiation so that subsequent connections can connect more quickly. The on-the-wire mechanism is described at the link below.
http://en.wikipedia.org/wiki/Transport_Layer_Security#Resumed_TLS_handshake
This presents some interesting gotchas, especially while you're debugging. For example, consider the following sequence:
You use the Debug tab to set the TLS Server Validation to Disabled.
You connect to a site with a self-signed identity. The connection succeeds because you've disabled TLS server trust validation. This adds an entry to the Secure Transport TLS session cache.
You use the Debug tab to set the TLS Server Validation to Default.
You immediately connect to the same site as you did in step 2. This should fail, because of the change in server trust validation policy, but it succeeds because you never receive an NSURLAuthenticationMethodServerTrust challenge. Under the covers, Secure Transport has resumed the TLS session, which means that the challenge never bubbles up to your level.
On the other hand, if you delay for 11 minutes between steps 3 and 4, things work as expected (well, fail as expected :-). This is because Secure Transport's TLS session cache has a timeout of 10 minutes.
In the real world this isn't a huge problem, but it can be very confusing during debugging. There's no programmatic way to clear the Secure Transport TLS session cache but, as the cache is per-process, you can avoid this problem during debugging by simply quitting and relaunching your application. Remember that, starting with iOS 4, pressing the Home button does not necessarily quit your application. Instead, you should use quit the application from the recent applications list.
So, based on that, a user would have to either kill their app and restart it or wait more than 10 minutes before sending another request.
I did another google search with this new information and found this Apple technical Q&A article that matches this problem exactly. Near the bottom, it mentions adding a trailing '.' to domain names (and hopefully IP addresses) for requests in order to force a TLS session cache miss (if you can't modify the server in some way, which I can't), so I am going to try this and hopefully it will work. I will post my findings after I test it.
### EDIT ###
I tested adding a '.' to the end of the ip address, and the request was still completed successfully.
But I was thinking about the problem in general, and there's really no reason to force another SSL handshake. In my case, the solution to this problem is to keep a copy of the last known SecCertificateRef that was returned from the server. When making another request to the server, if a cached TLS session is used (connection:didReceiveAuthenticationChallenge: was not called), we know that the saved SecCertificateRef is still valid. If connection:didReceiveAuthenticationChallenge: is called, we can get the new SecCertificateRef at that time.
Starting with OS X 10.9, NSURLSession is the solution.
First, you should use
[self.conn cancel]
and second, that does just what it says. It cancels itself. If you don't want to use an NSURLConnection after that anymore, it won't do anything and if you'll use it again, you can just set a different request, which will connect to the given server.
Hope that helps.

SSL socket connection on iPhone

Is there a way to reuse SSL socket connections on the iPhone. I'm seeing an extra 3-4 second overhead in doing SSL handshaking. I'm using NSURLconnection currently to do the API calls and each one of them is taking 4-5 seconds on Wifi. Any suggestions would be greatly appreciated.
Are you asking how to "reuse" sockets for the same specific address and port? Or for different URLs?
If the former, just don't close the socket until you're absolutely sure you don't need it anymore.
If the latter, there's nothing you can do about that. The SSL certificate verification process is likely where you're getting the overhead from.
You'll need to add more context to your question if you want a more specific answer.
you might want to establish an SSL connection an keep reusing it. Rather than make a new connection each time. There is definitely an overhead to SSL connections as well as handshaking. You cant get rid of the overhead from the encryption but the handshaking can be reduced by using NSStreams and keeping the connection open as you use it.
I have posted code and instructions on how to do it here:
NSStream SSL on used socket

Secure communication between django server and iphone app

I'm writing an iPhone application that needs to send small bits of information (two strings of under 128 characters each, at a time, and this doesn't happen too frequently) to a server when users interact with it. I would like this information to remain confidential, so I'm thinking of some sort of encryption or secure connection would be necessary.
My question is about the server side of things. The server the iPhone app has to communicate with is written in django and is running on lighttpd. What is the most appropriate way (or what is a standard way) of doing this. I was thinking https, which I know on the iPhone I can use ASIHTTPRequest to do a POST request, but I don't know what it requires on the server side. Do I need a certificate? How does the data get encrypted/secured? Are there any django modules to help with this? Do I have to do something to configure lighttpd?
Would something like xml-rpc or json-rpc be simpler? Is it possible to secure such communication? At what level would that occur?
Any help would be much appreciated.
Using xml-rpc or json-rpc are only means to encapsulate your data into a form that is easy to transport. Your iPhone app can transform the Objective C data using one of those formats and your Django server app can transform the data back into Python objects.
Neither of these have anything to do with security.
Creating an HTTPS (SSL) connection encrypts all communication between the client (iPhone) and the server (Django). You will need to get a certificate for the server side. This indicates to the client that the server is who it claims to be. Your next line of research down this path should be about how to configure lighttpd to handle SSL traffic. Once lighttpd negotiates the SSL communication, your Django app will operate as it does for non-secured traffic.
This is your best choice.
If, for whatever reason, you don't want to use SSL, then you could find strong encryption libraries for both ends of the communication. The iPhone app could encrypt the data, send it over an HTTP connection and the Django app could decrypt it. For example, the pycrypto Python library implements strong encryption ciphers such as AES and Blowfish. You might be able to find an implementation of one of these ciphers written in Objective C.
Did you notice that this is getting increasingly complex?
Go with SSL. It's the way security is done for HTTP-based communication.
Hmm it looks like this might be what you're after, have you seen it?
Setting up SSL for Lighttpd/Django
If I read that right, that setup allows your server to answer https and http requests (?)
Then if your whole app isn't going to be https there's this SSL Middleware to help configure some paths as ssl and some not.
If you use https (SSL) on the server side it shouldn't matter if you use XML-RPC or JSON-RPC. All the data you transfer will be encrypted and secure.
I can only speak from our Rails application and nginx. I bought a SSL certificate from GoDaddy (very cheap) and nginx is setup to encrypt the content (Rails is not doing this itself) on the fly when it sends it out. On the iPhone ASIHTTPRequest will be responsible to decrypt the data. All other layers shouldn't be concerned about the encryption, you can send anything you want.
You might also be able to use a self-signed certificate. We decided to use GoDaddy as we also use the SSL certificate for regular browsers, and those show a warning message to the user if they encounter a self-signed certificate, which obviously scares people away.

Is HTTP 1.1 pipelining discouraged in native mobile apps?

For several years, I've been facing problems with HTTP 1.1 pipelining & continued to ask the server to send the HTTP Header:
Connection: close
I want to revisit this decision. Does your native mobile apps use HTTP pipelining ?
Some problems with HTTP pipelining I've faced:
Server not releasing TCP connections
My client is receiving multiple replies from one HTTP connection
That's exactly what persistent connections and pipelining are for: keeping the TCP connection open until the timeout expires (or the browser closes), and sending multiple requests down the same pipe.
You might want to consider removing persistent connections if your server serves a high number of clients (you might run out of workers, RAM, or even free ports, raising response time for new requests)
If you want to read further, a pointer about persistent connection behaviour
One of the requirements for clients/servers to be compatible with HTTP/1.1 is the support of pipelining. So I don't see how using it would be a problem... I would rather think it would be encouraged. Using pipelining you cut down on creating new resources, network bandwidth, etc.
All modern web servers support pipelining and any reasonably complete client library should, so I'm not sure what the problem could be... perhaps if you ask about specific errors we could help you with them.
HTTP "pipelining" does not only mean to keep the TCP connection open between consecutive requests/responses. It describes a user agent behaviour where it sends the next HTTP request even without waiting for the pending response to the last request.
In my experience almost any HTTP server supports persistent connections. Using pipelining additionally is less stable. Firefox implements this feature but diables it by default.
You're confusing HTTP pipelining and HTTP persistent connections.
Persistent connection is where you keep the TCP connection around for future requests, but still send them serially: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Pipelining is a rarely used feature of HTTP 1.1 where you just fire multiple requests on the same connection without waiting for the responses. It's actually required by the HTTP specification, but rarely used by clients (Android's HTTP library doesn't, for example). Most servers seem to support it, though. It's described in section 8.1.2.2 of the same RFC.