| 1 | |
| 2 | = Debian OpenSSL Bugs and Foolscap = |
| 3 | |
| 4 | As you've probably heard, last week (13 May 2008) the debian project |
| 5 | published a security advisory that described how the openssl package has been |
| 6 | using a 17-bit random number generator for the last two years. As a result, |
| 7 | keys and certificates generated by the affected versions (or used for DSA |
| 8 | signatures by affected versions) should be considered compromised and |
| 9 | immediately replaced. This affects the last 3 or 4 Ubuntu releases too |
| 10 | (Dapper was correct, Edgy was broken). All affected releases now have fixed |
| 11 | versions available for download, and obviously everyone using an affected |
| 12 | release needs to upgrade immediately. |
| 13 | |
| 14 | http://lists.debian.org/debian-security-announce/2008/msg00152.html |
| 15 | |
| 16 | Since the bug affected key generation, keys which were created by the broken |
| 17 | versions will remain broken even after openssl itself is upgraded. The Debian |
| 18 | and Ubuntu projects have released tools to detect weak ssh keys that were |
| 19 | generated by these versions and disable them. Other projects (including |
| 20 | Foolscap) use generated keys for various purposes, so the effects of this bug |
| 21 | will linger even after openssl has been fixed. |
| 22 | |
| 23 | How does this affect Foolscap? The short answer: Weak keys generated by the |
| 24 | broken versions of openssl will enable a man-in-the-middle attack, which (if |
| 25 | successful) would reveal the private swissnums that protect access to |
| 26 | Referenceables. Foolscap users who have created Tubs while they had the |
| 27 | broken versions installed should stop using the associated FURLs and generate |
| 28 | new certificates/FURLs. |
| 29 | |
| 30 | The longer answer: There are three things in Foolscap that use random |
| 31 | numbers: |
| 32 | |
| 33 | 1. TubIDs [COMPROMISED]. These are a hash of the public key that corresponds |
| 34 | to a Tub's private key, and are included in FURLs (as the base32 part |
| 35 | immediately following the pb:// prefix). This provides protection against a |
| 36 | man-in-the-middle attack: when connecting to a FURL, the certificate of the |
| 37 | remote end is compared against the TubID in the FURL, and the connection is |
| 38 | dropped with extreme prejudice if they do not match. This validation is |
| 39 | performed before any secrets are passed over the wire. |
| 40 | |
| 41 | |
| 42 | 2. SwissNums [SAFE]. These are a randomly-generated name for a reference, |
| 43 | created when tub.registerReference(obj) is called without a name= argument, |
| 44 | and when a Referenceable is sent over the wire without being explicitly |
| 45 | registered. They appear at the right-hand end of the FURL, after the last |
| 46 | slash. Most Referenceables are given these unguessable names, because that |
| 47 | limits access to parties that have been explicitly granted access. (when |
| 48 | registerReference() is called with a guessable name, anyone who can guess |
| 49 | that name will get reference to the given object). The capability-based |
| 50 | security of foolscap Referenceables depends upon these swissnums remaining |
| 51 | secret. |
| 52 | |
| 53 | 3. SSL transport sessions [VULNERABLE]. Foolscap runs over SSL, which uses |
| 54 | random numbers to generate the Diffie-Hellman key agreement parameters. An |
| 55 | eavesdropper who can guess one of these parameters will be able to determine |
| 56 | the session key, and can decrypt the remainder of the conversation. |
| 57 | |
| 58 | TubIDs are derived from an SSL certificate that OpenSSL generates on demand, |
| 59 | and if the broken version of OpenSSL was used for this purpose, than that |
| 60 | certificate will be guessable. (at some point it would be great to write a |
| 61 | tool that would generate the 128000-ish TubIDs that can be generated by the |
| 62 | broken SSL, to create a blacklist like the ones created by debian/ubuntu for |
| 63 | ssh keys). |
| 64 | |
| 65 | So if you've generated a TubID with the broken version of openssl, it is |
| 66 | pretty easy to guess the corresponding private key. This allows an attacker |
| 67 | to mount an undetectable man-in-the-middle attack: if they can convince you |
| 68 | to make your TCP connection to their server instead of the right one, then |
| 69 | they can impersonate the real server, and they'll get to see the unencrypted |
| 70 | conversation (revealing the private swissnums). |
| 71 | |
| 72 | Swissnums are generated by calling os.urandom(), which was not affected by |
| 73 | the openssl bug. As long as one of the other problems (man-in-the-middle |
| 74 | attack) doesn't reveal your swissnums to an attacker, access to |
| 75 | Referenceables will remain limited to the parties to whom you've explicitly |
| 76 | granted it (by telling them the swissnum, in a FURL). |
| 77 | |
| 78 | Foolscap uses SSL for its encrypted transport, and SSL frequently uses |
| 79 | Diffie-Hellman key negotiation to establish a session key. This key |
| 80 | negotiation process depends upon random numbers, generated by the same buggy |
| 81 | RNG that is used to create keys. So if one of the two ends of an encrypted |
| 82 | session was using the buggy version of openssl, then an attacker may be able |
| 83 | to guess the session key, and thus decrypt the conversation. (note, I'm not a |
| 84 | cryptographer, and I'm not as confident about this attack as I am about the |
| 85 | others). So like the MitM attack, it seems likely that swissnums used by |
| 86 | sessions established during the buggy openssl era may be compromised: an |
| 87 | eavesdropper who recorded that encrypted conversation may be able to decrypt |
| 88 | it after the fact. |
| 89 | |
| 90 | |
| 91 | Of course, the whole idea of capabilities is to implement the Principle Of |
| 92 | Least Authority: each FURL gives access to a specific Referenceable that will |
| 93 | only do some specific limited task. If an MitM/eavesdropper manages to guess |
| 94 | your supposedly-unguessable swissnums, they'll still only be able to do |
| 95 | whatever the Referenceable will let them do. |
| 96 | |
| 97 | |
| 98 | So to summarize: if you've been using the buggy openssl libraries, here's |
| 99 | what you need to do: |
| 100 | |
| 101 | 1. upgrade openssl |
| 102 | 1. throw out your old FURLs (tell everyone that you've given them to to stop |
| 103 | using them): this protects clients from the MitM attack. |
| 104 | 1. throw out your old Tub certificates: the certFile= argument to Tub() |
| 105 | provides a persistent location for this.. just delete that file. This |
| 106 | prevents clients from ever successfully using the old FURLs to connect |
| 107 | to your server. |
| 108 | 1. restart the Tub, allowing it to create a new certificate |
| 109 | 1. regenerate and distribute new FURLs |
| 110 | |
| 111 | You can also just upgrade openssl (and keep using your old certs and FURLs) |
| 112 | if you're willing to remain vulnerable to man-in-the-middle attacks or |
| 113 | eavesdroppers who have recorded your earlier conversations. |