Filename: 195-TLS-normalization-for-024.txt Title: TLS certificate normalization for Tor 0.2.4.x Author: Jacob Appelbaum, Gladys Shufflebottom, Nick Mathewson, Tim Wilde Created: 6-Mar-2012 Status: Draft Target: 0.2.4.x
0. Introduction
The TLS (Transport Layer Security) protocol was designed for security and extensibility, not for uniformity. Because of this, it's not hard for an attacker to tell one application's use of TLS from another's.
We proposes improvements to Tor's current TLS certificates to reduce the distinguishability of Tor traffic.
0.1. History
This draft is based on parts of Proposal 179, by Jacob Appelbaum and Gladys Shufflebottom, but removes some already implemented parts and replaces others.
0.2. Non-Goals
We do not address making TLS harder to distinguish after the handshake is done. We also do not discuss TLS improvements not related to distinguishability (such as increased key size, algorithm choice, and so on).
1. Certificate Issues
Currently, Tor generates certificates according to a fixed pattern, where lifetime is fairly small, the certificate Subject DN is a single randomly generated CN, and the certificate Issuer DN is a different single randomly generated CN.
We propose several ways to improve this below.
1.1. Separate initial certificate from link certificate
When Tor is using the v2 or v3 link handshake (see tor-spec.txt), it currently presents an initial handshake authenticating the link key with the identity key.
We propose instead that Tor should be able to present an arbitrary initial certificate (so long as its key matches the link key used in the actual TLS handshake), and then present the real certificate authenticating the link key during the Tor handshake. (That is, during the v2 handshake's renegotiation step, or in the v3 handshake's CERTS cell.)
The TLS protocol and the Tor handshake protocol both allow this, and doing so will give us more freedom for the alternative certificate presentation ideas below.
1.2. Allow externally generated certificates
It should be possible for a Tor relay operator to generate and provide their own certificate and secret key. This will allow a relay or bridge operator to use a certificate signed by any member of the "SSL mafia,"[*] to generate their own self-signed certificate, and so on.
For compatibility, we need to require that the key be an RSA secret key, of at least 1024 bits, generated with e=65537.
As a proposed interface, let's require that the certificate be stored in ${DataDir}/tls_cert/tls_certificate.crt , that the secret key be stored in ${DataDir}/tls_cert/private_tls_key.key , and that they be used instead of generating our own certificate whenever the new boolean option "ProvidedTLSCert" is set to true.
(Alternative interface: Allow the cert and key cert to be stored wherever, and have the user provide their respective locations with TLSCertificateFile and TLSCertificateKeyFile options.)
1.3. Longer certificate lifetimes
Tor's current certificates aren't long-lived, which makes them different from most other certificates in the wild.
Typically, certificates are valid for a year, so let's use that as our default lifetime. [TODO: investigate whether "a year" for most CAs and self-signed certs have their validity dates running for a calendar year ending at the second of issue, one calendar year ending at midnight, or 86400*(365.5 +/- .5) seconds, or what.]
There are two ways to approach this. We could continue our current certificate management approach where we frequently generate new certificates (albeit with longer lifetimes), or we could make a cert, store it to disk, and use it for all or most of its declared lifetime.
If we continue to use fairly short lifetimes for the _true_ link certificates (the ones presented during the Tor handshake), then presenting long-lived certificates doesn't hurt us much: in the event of a link-key-only compromise, the adversary still couldn't actually impersonate a server for long.[**]
Using shorter-lived certificates with long nominal lifetimes doesn't seem to buy us much. It would let us rotate link keys more frequently, but we're already getting forward secrecy from our use of diffie-hellman key agreement. Further, it would make our behavior look less like regular TLS behavior, where certificates are typically used for most of their nominal lifetime. Therefore, let's store and use certs and link keys for the full year.
1.4. Self-signed certificates with better DNs
When we generate our own certificates, we currently set no DN fields other than the commonName. This behavior isn't terribly common: users of self-signed certs usually/often set other fields too. [TODO: find out frequency.]
Unfortunately, it appears that no particular other set of fields or way of filling them out _is_ universal for self-signed certificates, or even particularly common. The most common schema seem to be for things most censors wouldn't mind blocking, like embedded devices. Even the default openssl schema, though common, doesn't appear to represent a terribly large fraction of self-signed websites. [TODO: get numbers here.]
So the best we can do here is probably to reproduce the process that results in self-signed certificates originally: let the bridge and relay operators to pick the DN fields themselves. This is an annoying interface issue, and wants a better solution.
1.5. Better commonName values
Our current certificates set the commonName to a randomly generated field like www.rmf4h4h.net. This is also a weird behavior: nearly all TLS certs used for web purposes will have a hostname that resolves to their IP.
The simplest way to get a plausible commonName here would be to do a reverse lookup on our IP and try to find a good hostname. It's not clear whether this would actually work out in practice, or whether we'd just get dynamic-IP-pool hostnames everywhere blocked when they appear in certificates.
Alternatively, if we are told a hostname in our Torrc (possibly in the Address field), we could try to use that.
2. TLS handshake issues
2.1. Session ID.
Currently we do not send an SSL session ID, as we do not support session resumption. However, Apache (and likely other major SSL servers) do have this support, and do send a 32 byte SSLv3/TLSv1 session ID in their Server Hello cleartext. We should do the same to avoid an easy fingerprinting opportunity. It may be necessary to lie to OpenSSL to claim that we are tracking session IDs to cause it to generate them for us.
(We should not actually support session resumption.)
[*] "Hey buddy, it's a nice website you've got there. Sure would be a shame if somebody started poppin' up warnings on all your user's browsers, tellin' everbody that you're _insecure_..."
[**] Furthermore, a link-key-only compromise isn't very realistic atm; nearly any attack that would let an adversary learn a link key would probably let the adversary learn the identity key too. The most plausible way would probably be an implementation bug in OpenSSL or something.
Nick Mathewson nickm@freehaven.net writes:
Filename: 195-TLS-normalization-for-024.txt Title: TLS certificate normalization for Tor 0.2.4.x Author: Jacob Appelbaum, Gladys Shufflebottom, Nick Mathewson, Tim Wilde Created: 6-Mar-2012 Status: Draft Target: 0.2.4.x
<snip>
- TLS handshake issues
2.1. Session ID.
Currently we do not send an SSL session ID, as we do not support session resumption. However, Apache (and likely other major SSL servers) do have this support, and do send a 32 byte SSLv3/TLSv1 session ID in their Server Hello cleartext. We should do the same to avoid an easy fingerprinting opportunity. It may be necessary to lie to OpenSSL to claim that we are tracking session IDs to cause it to generate them for us.
(We should not actually support session resumption.)
This is a nice idea, but it opens us to the obvious active attack of Them checking if a host *actually* supports session resumption or if it's faking it.
What is the reason we don't like session resumption? Does it still makes sense to keep it disabled even after #4436 is implemented?
On 2012-03-10, George Kadianakis desnacked@riseup.net wrote:
Nick Mathewson nickm@freehaven.net writes:
Filename: 195-TLS-normalization-for-024.txt Title: TLS certificate normalization for Tor 0.2.4.x Author: Jacob Appelbaum, Gladys Shufflebottom, Nick Mathewson, Tim Wilde Created: 6-Mar-2012 Status: Draft Target: 0.2.4.x
<snip>
- TLS handshake issues
2.1. Session ID.
Currently we do not send an SSL session ID, as we do not support session resumption. However, Apache (and likely other major SSL servers) do have this support, and do send a 32 byte SSLv3/TLSv1 session ID in their Server Hello cleartext. We should do the same to avoid an easy fingerprinting opportunity. It may be necessary to lie to OpenSSL to claim that we are tracking session IDs to cause it to generate them for us.
(We should not actually support session resumption.)
This is a nice idea, but it opens us to the obvious active attack of Them checking if a host *actually* supports session resumption or if it's faking it.
What is the reason we don't like session resumption? Does it still makes sense to keep it disabled even after #4436 is implemented?
Session resumption requires keeping some key material around after a TLS connection is closed, thereby possibly denting Tor's link-protocol forward secrecy if a bridge/relay is compromised soon after a connection ends.
OpenSSL provides an implementation of session resumption, with the code quality you should expect to find in a rarely-used piece of OpenSSL. There have been several OpenSSL security-fix releases due to code-exec bugs in the session-resumption code.
Robert Ransom
Robert Ransom rransom.8774@gmail.com writes:
On 2012-03-10, George Kadianakis desnacked@riseup.net wrote:
Nick Mathewson nickm@freehaven.net writes:
Filename: 195-TLS-normalization-for-024.txt Title: TLS certificate normalization for Tor 0.2.4.x Author: Jacob Appelbaum, Gladys Shufflebottom, Nick Mathewson, Tim Wilde Created: 6-Mar-2012 Status: Draft Target: 0.2.4.x
<snip>
- TLS handshake issues
2.1. Session ID.
Currently we do not send an SSL session ID, as we do not support session resumption. However, Apache (and likely other major SSL servers) do have this support, and do send a 32 byte SSLv3/TLSv1 session ID in their Server Hello cleartext. We should do the same to avoid an easy fingerprinting opportunity. It may be necessary to lie to OpenSSL to claim that we are tracking session IDs to cause it to generate them for us.
(We should not actually support session resumption.)
This is a nice idea, but it opens us to the obvious active attack of Them checking if a host *actually* supports session resumption or if it's faking it.
What is the reason we don't like session resumption? Does it still makes sense to keep it disabled even after #4436 is implemented?
Session resumption requires keeping some key material around after a TLS connection is closed, thereby possibly denting Tor's link-protocol forward secrecy if a bridge/relay is compromised soon after a connection ends.
IIRC stateless TLS session resumption does not quire keeping key material. The required key material are all stored on the client side.
On Mar 10, 2012, at 2:18 AM, George Kadianakis wrote:
IIRC stateless TLS session resumption does not quire keeping key material. The required key material are all stored on the client side.
You're thinking of this RFC5077 or its predecessor RFC4507, which only became implemented in OpenSSL 0.9.9 (http://rt.openssl.org/Ticket/Display.html?id=1574). The usual way to achieve session resumption before that was to keep around (cache) symmetric key data for a predefined period of time. Trouble is that many unixoid OS distributions still ship with a system OpenSSL version < 0.9.9.
Cheers, Ralf
On Fri, Mar 9, 2012 at 7:18 PM, George Kadianakis [...]
What is the reason we don't like session resumption? Does it still makes sense to keep it disabled even after #4436 is implemented?
The main reason not to support session resumption is that, as noted later in this thread, it can require the server to keep key material around after the original connection has closed.
Now, we could set an extra-short timeout interval here, I guess. With a short enough interval, that would be functionally equivalent to what I proposed, and probably easier to do with OpenSSL via SSL_CTX_set_timeout() and regular calls to SSL_CTX_flush_sessions().
On 2012-03-09, Nick Mathewson nickm@freehaven.net wrote:
Filename: 195-TLS-normalization-for-024.txt Title: TLS certificate normalization for Tor 0.2.4.x Author: Jacob Appelbaum, Gladys Shufflebottom, Nick Mathewson, Tim Wilde Created: 6-Mar-2012 Status: Draft Target: 0.2.4.x
Introduction
The TLS (Transport Layer Security) protocol was designed for security and extensibility, not for uniformity. Because of this, it's not hard for an attacker to tell one application's use of TLS from another's.
We proposes improvements to Tor's current TLS certificates to reduce the distinguishability of Tor traffic.
0.1. History
This draft is based on parts of Proposal 179, by Jacob Appelbaum and Gladys Shufflebottom, but removes some already implemented parts and replaces others.
0.2. Non-Goals
We do not address making TLS harder to distinguish after the handshake is done. We also do not discuss TLS improvements not related to distinguishability (such as increased key size, algorithm choice, and so on).
Certificate Issues
Currently, Tor generates certificates according to a fixed pattern, where lifetime is fairly small, the certificate Subject DN is a single randomly generated CN, and the certificate Issuer DN is a different single randomly generated CN.
We propose several ways to improve this below.
1.1. Separate initial certificate from link certificate
When Tor is using the v2 or v3 link handshake (see tor-spec.txt), it currently presents an initial handshake authenticating the link key with the identity key.
We propose instead that Tor should be able to present an arbitrary initial certificate (so long as its key matches the link key used in the actual TLS handshake), and then present the real certificate authenticating the link key during the Tor handshake. (That is, during the v2 handshake's renegotiation step, or in the v3 handshake's CERTS cell.)
The TLS protocol and the Tor handshake protocol both allow this, and doing so will give us more freedom for the alternative certificate presentation ideas below.
1.2. Allow externally generated certificates
It should be possible for a Tor relay operator to generate and provide their own certificate and secret key. This will allow a relay or bridge operator to use a certificate signed by any member of the "SSL mafia,"[*] to generate their own self-signed certificate, and so on.
For compatibility, we need to require that the key be an RSA secret key, of at least 1024 bits, generated with e=65537.
As a proposed interface, let's require that the certificate be stored in ${DataDir}/tls_cert/tls_certificate.crt , that the secret key be stored in ${DataDir}/tls_cert/private_tls_key.key , and that they be used instead of generating our own certificate whenever the new boolean option "ProvidedTLSCert" is set to true.
(Alternative interface: Allow the cert and key cert to be stored wherever, and have the user provide their respective locations with TLSCertificateFile and TLSCertificateKeyFile options.)
Users need to specify a full certificate chain, not just the end-entity certificate.
Have you considered whether to allow the user to store the TLS certificate's private key in a hardware device?
1.3. Longer certificate lifetimes
Tor's current certificates aren't long-lived, which makes them different from most other certificates in the wild.
Typically, certificates are valid for a year, so let's use that as our default lifetime. [TODO: investigate whether "a year" for most CAs and self-signed certs have their validity dates running for a calendar year ending at the second of issue, one calendar year ending at midnight, or 86400*(365.5 +/- .5) seconds, or what.]
There are two ways to approach this. We could continue our current certificate management approach where we frequently generate new certificates (albeit with longer lifetimes), or we could make a cert, store it to disk, and use it for all or most of its declared lifetime.
If we continue to use fairly short lifetimes for the _true_ link certificates (the ones presented during the Tor handshake), then presenting long-lived certificates doesn't hurt us much: in the event of a link-key-only compromise, the adversary still couldn't actually impersonate a server for long.[**]
Using shorter-lived certificates with long nominal lifetimes doesn't seem to buy us much. It would let us rotate link keys more frequently, but we're already getting forward secrecy from our use of diffie-hellman key agreement. Further, it would make our behavior look less like regular TLS behavior, where certificates are typically used for most of their nominal lifetime. Therefore, let's store and use certs and link keys for the full year.
1.4. Self-signed certificates with better DNs
When we generate our own certificates, we currently set no DN fields other than the commonName. This behavior isn't terribly common: users of self-signed certs usually/often set other fields too. [TODO: find out frequency.]
Unfortunately, it appears that no particular other set of fields or way of filling them out _is_ universal for self-signed certificates, or even particularly common. The most common schema seem to be for things most censors wouldn't mind blocking, like embedded devices. Even the default openssl schema, though common, doesn't appear to represent a terribly large fraction of self-signed websites. [TODO: get numbers here.]
So the best we can do here is probably to reproduce the process that results in self-signed certificates originally: let the bridge and relay operators to pick the DN fields themselves. This is an annoying interface issue, and wants a better solution.
1.5. Better commonName values
Our current certificates set the commonName to a randomly generated field like www.rmf4h4h.net. This is also a weird behavior: nearly all TLS certs used for web purposes will have a hostname that resolves to their IP.
The simplest way to get a plausible commonName here would be to do a reverse lookup on our IP and try to find a good hostname. It's not clear whether this would actually work out in practice, or whether we'd just get dynamic-IP-pool hostnames everywhere blocked when they appear in certificates.
What if a bridge's IP address and reverse-DNS hostname change?
How does this interact with the v3 link protocol signaling mechanism?
How will a bridge's client be told what hostname to specify in its server name indication field?
Robert Ransom
On Fri, Mar 9, 2012 at 8:03 PM, Robert Ransom rransom.8774@gmail.com wrote:
Users need to specify a full certificate chain, not just the end-entity certificate.
Agreed that this is desirable, but if we take that route, we need to amend the current rule for deciding whether to use the v3/v2 vs the v1 handshake. Currently, according to tor-spec, a client that sees a certificate chain should assume that it's getting a v1 handshake.
Fortunately, every version of Tor that only allows the v1 handshake is now deprecated.
Have you considered whether to allow the user to store the TLS certificate's private key in a hardware device?
Sounds desirable. I have no idea how to do this from OpenSSL, but there is surely a way.
[...]
The simplest way to get a plausible commonName here would be to do a reverse lookup on our IP and try to find a good hostname. It's not clear whether this would actually work out in practice, or whether we'd just get dynamic-IP-pool hostnames everywhere blocked when they appear in certificates.
What if a bridge's IP address and reverse-DNS hostname change?
I believe in that case we would have to generate a new cert. I have no idea if this reverse-DNS idea is any good. Any better ones?
How does this interact with the v3 link protocol signaling mechanism?
The v3 link protocol signalling mechanism checks for any of the following not being true """ * The certificate is self-signed * Some component other than "commonName" is set in the subject or issuer DN of the certificate. * The commonName of the subject or issuer of the certificate ends with a suffix other than ".net". * The certificate's public key modulus is longer than 1024 bits. """ So I guess we should amend the proposal to say that nobody is allowed to self-generate a self-signed cert for a 1024-bit RSA key whose DN has only only a commonName ending with .net.
How will a bridge's client be told what hostname to specify in its server name indication field?
I was thinking through a torrc configuration values. Any better ideas?
Hello,
I'd like to comment on this topic, as I see a potential for improvements to stay below the radar and avoid all kinds of (minor) detections.
Perhaps countrary to how others reply, forgive me that I comment inline here as my reply is lengthy and typically comment on the block of text before it.
On 9/3/12 6:02 PM, Nick Mathewson wrote:
Filename: 195-TLS-normalization-for-024.txt Title: TLS certificate normalization for Tor 0.2.4.x
[...]
We proposes improvements to Tor's current TLS certificates to reduce the distinguishability of Tor traffic.
[...]
1.2. Allow externally generated certificates
It should be possible for a Tor relay operator to generate and provide their own certificate and secret key. This will allow a relay or bridge operator to use a certificate signed by any member of the "SSL mafia,"[*] to generate their own self-signed certificate, and so on.
For compatibility, we need to require that the key be an RSA secret key, of at least 1024 bits, generated with e=65537.
I would like to suggest to add a statement to use SHA1 (or if you can work this in) use a SHA2 hash. My motivation here is not to avoid MD5, but more that the majority of CAs is using SHA1 now and will soon migrate to SHA2. Using MD5 is a yellow flag in some situation.
As a proposed interface, let's require that the certificate be stored in ${DataDir}/tls_cert/tls_certificate.crt , that the secret key be stored in ${DataDir}/tls_cert/private_tls_key.key , and that they be used instead of generating our own certificate whenever the new boolean option "ProvidedTLSCert" is set to true.
(Alternative interface: Allow the cert and key cert to be stored wherever, and have the user provide their respective locations with TLSCertificateFile and TLSCertificateKeyFile options.)
Would it be possible to use a similar approach to SSLSniff? As it doesn't really matter what kind of certificate is issued here, you could think of generating something fitting on the fly. There is a better motivation further in my reply on what fitting is as this is part of my comment too.
1.3. Longer certificate lifetimes
Typically, certificates are valid for a year, so let's use that as our default lifetime. [TODO: investigate whether "a year" for most CAs and self-signed certs have their validity dates running for a calendar year ending at the second of issue, one calendar year ending at midnight, or 86400*(365.5 +/- .5) seconds, or what.]
It depends on the CA and the resource provider. Each have their influences and various motivations to have result in a certain validity period. Sometimes it could hint a policy change at a CA or a change in the resource en service provider.
Let's take exhibit A. over here: Tuesday, 28 February 2012 2:00:10 PM Thursday, 28 February 2013 2:10:10 PM
And exhibit B.: Thursday, 17 November 2011 1:00:00 AM Saturday, 14 July 2012 1:59:59 AM
This is slightly longer then six months valid and used by a lot of people.
Most of the times I see certificates get issues regardless of leap year details. So that would be per calendar year. Just, date to date, plus or minus one day depending on how cool the CA could be. Or even plus or minus one month. In that case you have one year of usage and one month of a planned migration opportunity to a new certificate. This is very luxerious and might be rare in the commercial world, but happens too.
There are two ways to approach this. We could continue our current certificate management approach where we frequently generate new certificates (albeit with longer lifetimes), or we could make a cert, store it to disk, and use it for all or most of its declared lifetime.
Using shorter-lived certificates with long nominal lifetimes doesn't seem to buy us much. It would let us rotate link keys more frequently, but we're already getting forward secrecy from our use of diffie-hellman key agreement. Further, it would make our behavior look less like regular TLS behavior, where certificates are typically used for most of their nominal lifetime. Therefore, let's store and use certs and link keys for the full year.
I would try to mimic the normal certificate lifecycle. Which means that a connections will typically not have a certificate validation time of today. It will most likely be something in the past. It's typically going to be valid for more then 6 months (otherwise operational costs are going to be too high if the time is lowered). It should be used more or less persistently. What I mean by that is that a client connecting to a service will likely get a similar certificate in return when it reconnects within the day. This mimics the behavior of a real servers that would present the same certificate with a similar connection request. I'm ignoring the existence of TLS.1.1+ here as I'm focussing on patterns and lowering the opportunities for pattern matching.
Another opportunity here is to use the public key rekeying feature provided by the CAs. When something might be fishy and you don't really know if the private key was kept in check, then to avoid a big fuzz you can go for rekeying. If not used too much you could use this in Tor's advantages and cycle the keys and keeping the same certificate. Keeping the same certificate is the persistence I was focussing on previously.
1.4. Self-signed certificates with better DNs
When we generate our own certificates, we currently set no DN fields other than the commonName. This behavior isn't terribly common: users of self-signed certs usually/often set other fields too. [TODO: find out frequency.]
Do you use Subject Alt Names? If not, I would yellow flag your certificate. If you mimic an HTTPS connection I would use it as a (partial) signature if you wouldn't comply to RFC2818 (http://tools.ietf.org/html/rfc2818, section 2.2.1).
Unfortunately, it appears that no particular other set of fields or way of filling them out _is_ universal for self-signed certificates, or even particularly common. The most common schema seem to be for things most censors wouldn't mind blocking, like embedded devices. Even the default openssl schema, though common, doesn't appear to represent a terribly large fraction of self-signed websites. [TODO: get numbers here.]
So the best we can do here is probably to reproduce the process that results in self-signed certificates originally: let the bridge and relay operators to pick the DN fields themselves. This is an annoying interface issue, and wants a better solution.
If you want to do sneaky self-signed certificates, you could make the Subject DN and the Issuer DN different. It would be one less hint or identifier to track. Typically the amount of traffic to services hosting self-signed certificates is lower then the big sites, therefore I think you can take the load of doing this indepth inspection if you wanted to.
Why can't the tool construct a various amounts of elements (somewhere between 3 and 7) of RDNs in the Subject and Issuer DNs? The bridge or relay operators should be able to add a personal touch for human entropy's sake. It also avoid making similar uber-short Subject DNs which is an easy pattern to track. I'm amazed this wasn't observed/used before.
Perhaps it would even make sense to build-in a signing policy for each bridge or relay, I would pitch it as a tiny-CPS. This means that the bridges/relays will scope the namespace of the Subject DNs that it will construct, including the Subject DN of its own CA itself. Normal CAs (should) typically follow a fix pattern. If the pattern is chosen believable enough, then you could think of using this predictability to stay below the radar on that end.
Example: "/C=NL/O=acme inc/OU=trust me" "/C=NL/O=acme inc/OU=trusted auth/OU=vaccuum/CN=host-15.dyndns.org
Perhaps this is more engineering work then it will pay off, but ok, I'm pitching an idea for completeness sake in this sense.
1.5. Better commonName values
Our current certificates set the commonName to a randomly generated field like www.rmf4h4h.net. This is also a weird behavior: nearly all TLS certs used for web purposes will have a hostname that resolves to their IP.
The simplest way to get a plausible commonName here would be to do a reverse lookup on our IP and try to find a good hostname. It's not clear whether this would actually work out in practice, or whether we'd just get dynamic-IP-pool hostnames everywhere blocked when they appear in certificates.
Alternatively, if we are told a hostname in our Torrc (possibly in the Address field), we could try to use that.
Why are we bothering with the Subject DN's CN field in this part? It's been legacy since May 2000. I would suggest to leave it out and make it unusable. Perhaps I'm too modern here and I would creep up on some radar by doing this...
According to RFC2818: Though shall check the Subject Alt Names first. If you really don't have a Subject Alt Names block in the cert, then take the most significant CN field. There is an exception rule which states that you could use a certificate signed for a different hosts if the client is expecting this. These details don't matter here, but apparently Tor has been hanging on to the exception rule here. I would yellow flag this 'to safe guard my users'.
If I sound weird in this, have a look at libcurl's way of doing its checks in the code. I personally favor the OpenSSL connectors for readability (weirdly enough).
As stated before I would love to see that the connection could be a truly verifiable correct connection on this level, compliant to RFC2818 and others. If DNSnames don't make sense you could think of adding IP-addresses in the SubjectAltNames of even the CN fields. It's something you don't see in the commercial CA business that often, but it happens and could be used to Tor's advantage.
The proposal seems quite thought through. Some comments inline:
On 03/09/2012 06:02 PM, Nick Mathewson wrote:
1.2. Allow externally generated certificates
It should be possible for a Tor relay operator to generate and provide their own certificate and secret key. This will allow a relay or bridge operator to use a certificate signed by any member of the "SSL mafia,"[*] to generate their own self-signed certificate, and so on.
For compatibility, we need to require that the key be an RSA secret key, of at least 1024 bits, generated with e=65537.
I'd go for 2048 bits minimum (CAB forum is moving towards this value soon and other sources [1] suggest it for long-lived certs as well).
1.3. Longer certificate lifetimes
Tor's current certificates aren't long-lived, which makes them different from most other certificates in the wild.
Typically, certificates are valid for a year, so let's use that as our default lifetime. [TODO: investigate whether "a year" for most CAs and self-signed certs have their validity dates running for a calendar year ending at the second of issue, one calendar year ending at midnight, or 86400*(365.5 +/- .5) seconds, or what.]
Here are two quick statistics I did on my DB (1.5M+ unique certs), columns are "count, hour, minute, second":
not_before: http://pastie.org/3564679 not_after: http://pastie.org/3564694
Statitic on validity period:
There are two ways to approach this. We could continue our current certificate management approach where we frequently generate new certificates (albeit with longer lifetimes), or we could make a cert, store it to disk, and use it for all or most of its declared lifetime.
Note that there are many embedded devices that generate certs periodically (every day, every few days; I wonder if it's because somebody thought about the "shared prime due to low entropy fiasco" before and wanted to avoid it without HW RNG.)
I'd suggest we use some similar approach.
Using shorter-lived certificates with long nominal lifetimes doesn't seem to buy us much. It would let us rotate link keys more frequently, but we're already getting forward secrecy from our use of diffie-hellman key agreement. Further, it would make our behavior look less like regular TLS behavior, where certificates are typically used for most of their nominal lifetime. Therefore, let's store and use certs and link keys for the full year.
Agreed, good point.
1.4. Self-signed certificates with better DNs
When we generate our own certificates, we currently set no DN fields other than the commonName. This behavior isn't terribly common: users of self-signed certs usually/often set other fields too. [TODO: find out frequency.]
One statistic here (EFF's SSL Observatory is more thorough than my DB in self-signed certs, I'll post a statistic from it later):
But in general thousands of embedded devices share Issuer and Subject RDNs.
Unfortunately, it appears that no particular other set of fields or way of filling them out _is_ universal for self-signed certificates, or even particularly common. The most common schema seem to be for things most censors wouldn't mind blocking, like embedded devices. Even the default openssl schema, though common, doesn't appear to represent a terribly large fraction of self-signed websites. [TODO: get numbers here.]
So the best we can do here is probably to reproduce the process that results in self-signed certificates originally: let the bridge and relay operators to pick the DN fields themselves. This is an annoying interface issue, and wants a better solution.
There are many embedded devices we could fake (I could put together a list). Just for fun, we could use 'BlueCoat Series' :-)
My suggestion is that we put a list in Tor so that Tor node picks a issuer/subject randomly unless operator overrides it (but node needs to stick to one CN then, at least for a longer period of time - days/weeks).
1.5. Better commonName values
Our current certificates set the commonName to a randomly generated field like www.rmf4h4h.net. This is also a weird behavior: nearly all TLS certs used for web purposes will have a hostname that resolves to their IP.
The simplest way to get a plausible commonName here would be to do a reverse lookup on our IP and try to find a good hostname. It's not clear whether this would actually work out in practice, or whether we'd just get dynamic-IP-pool hostnames everywhere blocked when they appear in certificates.
Alternatively, if we are told a hostname in our Torrc (possibly in the Address field), we could try to use that.
Using reverse IP can be useful if both reverse and forward DNS records match. Though there are tons of misconfigurations in the wild (either due to not needing proper configuration or simple mistake).
[1] http://www.keylength.com/en/3/ (or http://www.ecrypt.eu.org/documents/D.SPA.17.pdf in case someone is interested in full report)
Ondrej