I'm making TLS client connections in Node.js. Some servers I communicate with request a client certificate. I'd like to be able to detect when this has been requested, so I can log it. At the protocol level I believe this is sent along with the TLS server hello, so the data is there, but I'm not sure how I can get at it.
I'm never actually providing a client certificate for now, I'm just aiming to report which servers requested one.
I think there's probably two cases here:
A cert has been requested, not provided, and the server has accepted the connection anyway (and then probably given my some kind of 'not authenticated' response).
A cert has been requested, not provided, and the server has rejected the TLS connection entirely.
At the moment I can't detect either case, solutions for either or both very welcome.
Related
I have a question about SSL. As I know, when we use browser to request from https server, it will make an SSL handshake first then all data will be encryption in the connection. But if I make a request without browser (like request module in nodejs, postman...), will it be an SSL handshake and data encryption on the connection?
Anyone know please explain to me, thank you.
First, stop saying SSL. Its successor is TLS, and it will have 20 years next January.
TLS is a protocol sitting on top of TCP typically (other variants can also use UDP), and provides on top of TCP features some new features about endpoints authentication and transport confidentiality and integrity.
In a way, you can understand it as being sandwiched between TCP and the higher level application protocol, like HTTP.
Saying otherwise you can use many others protocols on top of TLS: you have all email related ones (SMTP, IMAP, POP, etc.), you can have FTP on top of it (while probably not a good idea nowadays), XMPP for realtime communications, etc.
In short, any protocol using TCP could use TLS with some adaptation.
So HTTP is one case among others. HTTP is between an HTTP client and an HTTP server, or webserver for short.
A browser is an HTTP client. One among many ones. When you use curl or wget you are also an HTTP client. So if any HTTP client access an http:// link it will first do the TLS handshake, after the TCP connection and before starting to do anything really related to the HTTP protocol.
You have specialized libraries dealing with TLS so that not all program need to recode everything about this again, since it is also complicated.
I need a security protocol where the client authenticates before the server. This is necessary because its a matter of privacy. I dont want any unknown party to know who they are connecting to unless they are allowed to know. In the TLS protocol, the server send his cert first thereby eliminating this possibility. I know enough to know that implementing my own protocol is a bad idea. However, is there a choice? I.e. is there a way to alter the protocol to send the certs in the other order? Wikipidea reference to TLS: http://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake
You could reverse the roles of the client and server.
Normally, with TCP, the client is the endpoint that did connect() (and send a SYN) and the server is the endpoint that did accept() (it received the SYN and sent back a SYN|ACK). But once the connection is established, there is no longer any difference between the client's socket and the server's socket.
If you're using, say, OpenSSL, you normally call SSL_connect() after a successful connect() and you normally call SSL_accept() after a successful accept(). But if you flip that around and call SSL_accept() after connect() on the client side and call SSL_connect() after accept() on the server side, OpenSSL will never know the difference. And the client will behave as a TLS server and identify itself first.
In a TLS handshake configured with a client authentication, there is a step where the server receives the client's certificate and choose to trust it or not (for instance, in Java it is done via a TrustManager).
I would like to know if the eventual "trust failure" message from the server is sent before or after the server made sure that the client really own that public key (for example, by receiving first some messages from the handshake encoded with the client's private key).
The purpose of my question is to see if it is possible for a third party to check if the server trust a client, by pretending to be this client and by using his public key.
Note: The risk is real when TLS is used in a context with specific security requirements. For instance, let's suppose a P2P application which uses TLS between peers, and which use the TrustManager as a way to authenticate peers from his contact list. This contact list is supposed to be private. An ISP can list the IPs with who a node communicates, then get his public certificate by starting a TLS handshake with it, then he can try to connect each another nodes on the IP list. In the end, the ISP can get a big part of the contact list which was supposed to be private.
OpenSSL verifies the client certificate, too, immediately upon receiving it in the Client Certificate message.
But it is as Eugene says, if the server sends meaningful alerts, then it does not matter if you send bad_certificate right away or only after having verified the signature in the Certificate Verify message. This would only prevent someone from finding out whether a certificate is trusted or not if they additionally send a malformed signature (e.g. by using the wrong key). But if a server were implemented that way, all you had to do is sign your Certificate Verify message with a private key you just generated. Then the signature will be valid and the server will then dutifully validate the certificate you sent, revealing the same information as before.
To mitigate this situation you would really have to use a customized server that does not send the corresponding alert at all, but rather something less revealing.
This depends on implementation. Our implementation sends the error immediately, as for other implementations - I guess most do the same.
However it doesn't matter: the server sends specific error code (BadCertificate) if the certificate is not valid, so no matter when this code is sent, the attacker would know that the certificate has not been accepted. Protecting the server from this attack would require the server send a different error code and this would confuse legitimate clients.
The risk (or unpleasant consequences) of detecting that the certificate is accepted by the server or not is questionable. If this matters to you, you can change the error code and build your custom version of OpenSSL or other SSL server module you use.
This question already has answers here:
Is a HTTPS query string secure?
(9 answers)
Closed 9 years ago.
Suppose I setup a simple php web server with a page that can be accessed by HTTPS. The URL has simple parameters, like https://www.example.com/test?abc=123.
Is it true that the parameter here in this case will be safe from people sniffing the packets? And would this be true if the server does not employ any SSL certificate?
Yes your URL would be safe from sniffing; however, one hole that is easily overlooken is if your page references any third party resources such as Google Analytics, Add Content anything, your entire URL will be sent to the third party in the referer. If its really sensitive it doesn't belong in the query string.
As for your second part of the question, you can't use SSL if you don't have a certificate on the server.
http://answers.google.com/answers/threadview/id/758002.html
HTTPS Establishes an underlying SSL
connection before any HTTP data is
transferred. This ensures that all URL
data (with the exception of hostname,
which is used to establish the
connection) is carried solely within
this encrypted connection, and is
protected from man-in-the-middle
attacks in the same way that any HTTPS
data is.
All HTTP-level transactions within an
HTTPS connection are conducted within
the established SSL session, and no
query data is transferred before the
secure connection is established.
From the outside the only data that is
visible to the world is the hostname
and port you are connecting to.
Everything else is simply a stream of
binary data which is encrypted using a
private key shared only between you
and the server.
In the example you provide your
browser would do this:
Derive
hostname (and port if present)
from URL.
Connect to host.
Check certificate (it must be 'signed'
by a known authority, applied specifically
to correct IP address and port, and be
current).
The browser and server
exchange cryptographic data and the
browser receives a private key.
The
HTTP request is made, and encrypted with
established cryptography.
HTTP response is received. Also encrypted.
HTTP is an 'Application Layer'
protocol. It is carried on top of the
secure layer. According to the SSL
specification, drawn up by Netscape,
it dictates that no application layer
data may be transmitted until a secure
connection is established - as
outlined in the following paragraph:
"At this point, a change cipher spec
message is sent by the client, and the
client copies the pending Cipher Spec
into the current Cipher Spec. The
client then immediately sends the
finished message under the new
algorithms, keys, and secrets. In
response, the server will send its own
change cipher spec message, transfer
the pending to the current Cipher
Spec, and send its finished message
under the new Cipher Spec. At this
point, the handshake is complete and
the client and server may begin to
exchange application layer data."
http://wp.netscape.com/eng/ssl3/draft302.txt
So yes. The data contained in the URL
query on an HTTPS connection is
encrypted. However it is very poor
practice to include such sensitive
data as a password in a 'GET'
request. While it cannot be
intercepted, the data would be logged
in plaintext server logs on the
receiving HTTPS server, and quite
possibly also in browser history. It
is probably also available to browser
plugins and possibly even other
applications on the client computer.
At most a HTTPS URL could be
reasonably allowed to include a
session ID or similar non-reusable
variable. It should NEVER contain
static authentication tokens.
The HTTP connection concept is most
clearly explained here:
http://www.ourshop.com/resources/ssl_step1.html
The requested URI (/test?abc=123) is sent to the web server as part of the HTTP request header and thus encrypted.
However URLs can leak in other ways, usually web browser toolbars, bookmarks, and sending links to friends. POSTing data may be more appropriate depending on the context/sensitivity of the data you're sending.
I believe an HTTPS connection requires an SSL certificate, even a self-generated one if you don't want to buy one.
Hope that helps a bit!
depends on what you mean by safe
SSL encrypts the entire HTTP request/response, so the URL in the GET portion will be encrypted. This does not stop MITM attacks and corruption of the integrity of the SSL session itself. If a non-authoritative certificate is used, this makes potential attack vectors simpler.
Are REST request headers encrypted by SSL?
Is a similar question.
The url:s will be stored both in the server logs and in the browser history so even if they aren't sniffable they are far from safe.
On the wire, yes. At the end points (browser and server) not necessarily. SSL/TLS is transport layer security. It will encrypt your traffic between the browser and the server. It is possible on the browser-side to peek at the data (a BHO for example). Once it reaches the server-side, it is available to the recipient of course and is only as secure as he treats it. If the data needs to move securely beyond the initial exchange and protected from prying eyes on the client, you should also look at message layer security.
The SSL/TSL is a Transport Layer Security, yes the data can be picked with BHO (as #JP wrote) or any add on but also with "out of browser" HTTP sniffers. They read messaging between winsock32 and the application. The encryption takes place in the winsock32 not in the browser.
Take a look (this part was taked from the page of IEinspector):
IEInspector HTTP Analyzer is such a handy tool that allows you to monitor, trace, debug and analyze HTTP/HTTPS traffic in real-time.
I've just started learning SSL and boy is it confusing
Q1 - How long does SSL connection between a client and server persist? Until client surfs to some other URL or…?
Q2
A) Assume a client (browser) establishes a SSL connection with a IIS server.
Now how does IIS figure out on each postback that it is dealing with same authenticated client/browser and thus that it already has a SSL connection established with that client?
B) Assuming SSL connection isn’t lost if browser surfs to some other URL:
Suppose that moments after SSL connection is established, client surfs to some other URL, and shortly there after it again requests ( via https ) the original page ( one with which it has SSL connection established).
How will IIS server be able to figure out that current request for a page comes from a client that already has SSL connection established with that page and thus will use already established SSL connection?
thanx
EDIT:
Assuming browser surfs to some other URL and if on returning back to original page the SSL connection is still established, how will browser "remember" the value of symetric encryption key, which the two sides used for communicating?
I realize it depends on what browser you use, but with IE and Firefox, I assume when you close a browser, it sends Connection.Close() ( or something to that effect ) to the server and thus SSL connection is immediately closed?
But if you browse away to some other URL, then if browsers doesn't send any notification to the server, wouldn't then SSL connection remain established for quite some time ( even 10 or more minutes ) and thus browser could easily surf back to that page as if nothing happened?!
I appreciate it
Q1. The SSL connection is only good for a single TCP connection between the client and the server. Current browsers (anything with HTTP/1.1 support) can reuse a single connection for downloading multiple resources. Current browsers also make multiple TCP connections to a server in order to download multiple resources in parallel. Because of this, you'll see multiple SSL connections for one page view.
Q2A. If the browser still has a TCP connection open with that server, it can reuse that connection. Otherwise, a new TCP connection with SSL and IIS authentication is negotiated.
Q2B. Same as Q2A. You can't depend on this, but the TCP connections won't be disposed of immediately. There's a chance you could reuse an existing one depending on your browser.
A1. An SSL connection persists until either the client or server closes it. When that happens depends on the protocol being used. For HTTP, most modern clients will make a few parallel connections to the server to fetch the page and its resources, and reuse those connections until the page is loaded.
A2A. The client must authenticate itself on each request if the authentication uses HTTP auth. If the client is using SSL certificate authorization, then this is obviously maintained on a per-connection basis so that subsequent requests on the same connection retain the same credentials.
A2B. The server would know this because presumably the request would come in on that already established SSL connection.
post-edit answers:
What I think you may be missing is that SSL is linked intrinsically to TCP. You cannot have an SSL "connection" to the server that doesn't ride on top of a TCP connection. You break one, you break the other.
Most SSL implementations include "shortcut" negotiation where subsequent new connections can leverage the public key encryption that has already taken place and instead directly use the most recently negotiated symmetric key. The details of this, however, are hidden within the SSL implementation. From the point of view of the user and/or client software, the fiction is maintained that the entire negotiation took place just like it did on the first connection.
If the SSL connection is still established, then it follows that the symmetric key information is still maintained on both ends.
Yes.
Yes, although it would be improbable for the client to keep a connection to a server once it has navigated away to some other site.