Many protocols today allow you to upgrade to TLS from within a cleartext version of the protocol. This often falls under the rubric of "STARTTLS", though different protocols have different ways of doing it.
I often forget the exact steps, and when i'm debugging a TLS connection
(e.g. with tools like gnutls-cli
) i need to poke a remote peer into
being ready for a TLS handshake. So i'm noting the different mechanisms
here. lines starting with C:
are from the client, lines starting with
S:
are from the server.
many of these are (roughly) built into openssl s_client
, using the
-starttls
option. Sometimes this doesn't work because the handshake
needs tuning for a given server; other times you want to do this with a
different TLS library. To use the techniques below with gnutls-cli
from the gnutls-bin
package, just provide the --starttls
argument
(and the appropriate --port XXX
argument), and then hit Ctrl+D when
you think it's ok to start the TLS negotiation.
SMTP
The polite SMTP handshake (on port 25 or port 587) that negotiates a TLS upgrade looks like:
C: EHLO myhostname.exampleS: [...]S: 250-STARTTLSS: [...]S: 250 [somefeature]C: STARTTLSS: 220 2.0.0 Ready to start TLS<Client can begin TLS handshake>
IMAP
The polite IMAP handshake (on port 143) that negotiates a TLS upgrade looks like:
S: OK [CAPABILITY IMAP4rev1 [...] STARTTLS [...]] [...]C: A STARTTLSS: A OK Begin TLS negotiation now<Client can begin TLS handshake>
POP
The polite POP handshake (on port 110) that negotiates a TLS upgrade looks like:
S: +OK POP3 readyC: STLSS: +OK Begin TLS <Client can begin TLS handshake>
XMPP
The polite XMPP handshake (on port 5222 for client-to-server, or port 5269 for server-to-server) that negiotiates a TLS upgrade looks something like (note that the domain requested needs to be the right one):
C: <?xml version="1.0"?><stream:stream to="example.net"C: xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">S: <?xml version='1.0'?>S: <stream:streamS: xmlns:db='jabber:server:dialback'S: xmlns:stream='http://etherx.jabber.org/streams'S: version='1.0'S: from='example.net'S: id='d34edc7c-22bd-44b3-9dba-8162da5b5e72'S: xml:lang='en'S: xmlns='jabber:server'>S: <stream:features>S: <dialback xmlns='urn:xmpp:features:dialback'/>S: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>S: </stream:features>C: <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls" id="1"/>S: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><Client can begin TLS handshake>
NNTP
RogerBW (in the comments below) points out that NNTP has TLS support:
C: CAPABILITIESS: [...]S: STARTTLSS: [...]S: .C: STARTTLSS: 382 Continue with TLS negotiation<Client can begin TLS handshake>
PostgreSQL
I got mail from James Cloos suggesting how to negotiate an upgrade to TLS over the PostgreSQL RDBMS. He points to the protocol docs, and in particular, to multiple protocol flow documents, and SSLRequest and StartupMessage chunks of the protocol spec (and clarification that data is sent in network byte order). It won't work in a text-mode communication, but it's worth noting here anyway:
The client starts by sending these eight octets:
0x00 0x00 0x00 0x08 0x04 0xD2 0x16 0x2F
and the server replies with 'S
' for secure or 'N
' for not. If the
reply is S
, TLS negotiation follows.
The message represents int32(8)
specifying that there are 8 octets and
int16(1234)
,int16(5678)
. All sent in network order.
(The non-TLS case starts with a similar message with
int16(3)
,int16(0)
for protocol version 3.0. Starttls is essentially
pg protocol version 1234.5678.)
what else?
I don't know (but would like to) how to do:
mysql
TLS negotiation- STARTTLS for LDAP
- other reasonable network protocols capable of upgrade
- other free TLS wrapping tools like
openssl s_client
orgnutls-cli
that can start off in the clear and negotiate to TLS. I am trying to get libNSS'ststclnt
into thelibnss3-tools
package, but that hasn't happened yet.
If you know other mechanisms, or see bugs with the simple handshakes i've posted above, please let me know either by e-mail or on the comments here.
Other interesting notes: RFC 2817, a not-widely-supported mechanism for upgrading to TLS in the middle of a normal HTTP session.
Tags: gnutls, imap, pop, postgresql, smtp, starttls, tls, xmpp