getting to TLS (STARTTLS HOWTO)
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.
SMTPThe polite SMTP handshake (on port 25 or port 587) that negotiates a TLS upgrade looks like:
C: EHLO myhostname.example S: [...] S: 250-STARTTLS S: [...] S: 250 [somefeature] C: STARTTLS S: 220 2.0.0 Ready to start TLS <Client can begin TLS handshake>
IMAPThe polite IMAP handshake (on port 143) that negotiates a TLS upgrade looks like:
S: OK [CAPABILITY IMAP4rev1 [...] STARTTLS [...]] [...] C: A STARTTLS S: A OK Begin TLS negotiation now <Client can begin TLS handshake>
POPThe polite POP handshake (on port 110) that negotiates a TLS upgrade looks like:
S: +OK POP3 ready C: STLS S: +OK Begin TLS <Client can begin TLS handshake>
XMPPThe 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:stream S: 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>I don't know (but would like to) how to do:
- postgresql TLS negotiation
- mysql TLS negotiation
- other reasonable network protocols capable of upgrade
- other free TLS wrapping tools like openssl s_client or gnutls-cli that can start off in the clear and negotiate to TLS. I am trying to get libNSS's tstclnt into the libnss3-tools package, but that hasn't happened yet.
Other interesting notes: RFC 2817, a not-widely-supported mechanism for upgrading to TLS in the middle of a normal HTTP session.