``` Filename: 228-cross-certification-onionkeys.txt Title: Cross-certifying identity keys with onion keys Author: Nick Mathewson Created: 25 February 2014 Status: Closed 0. Abstract In current Tor router descriptor designs, routers prove ownership of an identity key (by signing the router descriptors), but not of their onion keys. This document describes a method for them to do so. 1. Introduction. Signing router descriptors with identity keys prevents attackers from impersonating a server and advertising their own onion keys and IP addresses. That's good. But there's nothing in Tor right now that effectively stops you (an attacker) from listing somebody else's public onion key in your descriptor. If you do, you can't actually recover any keys negotiated using that key, and you can't MITM circuits made with that key (since you don't have the private key). (You _could_ do something weird in the TAP protocol where you receive an onionskin that you can't process, relay it to the party who can process it, and receive a valid reply that you could send back to the user. But this makes you a less effective man-in-the-middle than you would be if you had just generated your own onion key. The ntor protocol shuts down this possibility by including the router identity in the material to be hashed, so that you can't complete an ntor handshake unless the client agrees with you about what identity goes with your ntor onion key.) Nonetheless, it's probably undesirable that this is possible at all. Just because it isn't obvious today how to exploit this doesn't mean it will never be possible. 2. Cross-certifying identities with onion keys 2.1. What to certify Once proposal 220 is implemented, we'll sign our Ed25519 identity key as described in proposal 220. Since the Ed25519 identity key certifies the RSA key, there's no strict need to certify both separately. On the other hand, this proposal may be implemented before proposal 220. If it is, we'll need a way for it to certify the RSA1024 key too. 2.2. TAP onion keys We add to each router descriptor a new element, "onion-key-crosscert", containing a RSA signature of: A SHA1 hash of the identity key [20 bytes] The Ed25519 identity key, if any [32 bytes] If there is no ed25519 identity key, or if in some future version there is no RSA identity key, the corresponding field must be zero-filled. Parties verifying this signature MUST allow additional data beyond the 52 bytes listed above. 2.3. ntor onion keys Here, we need to convert the ntor key to an ed25519 key for signing. See the appendix A for how to do that. We'll also need to transmit a sign bit. We can add an element "ntor-onion-key-crosscert", containing an Ed25519 certificate in the format from proposal 220 section 2.1, with a sign indicator to indicate which ed25519 public key to use to check the key: "ntor-onion-key-crosscert" SP SIGNBIT SP CERT NL SIGNBIT = "0" / "1" Note that this cert format has 32 bytes of of redundant data, since it includes the identity key an extra time. That seems okay to me. The signed key here is the master identity key. The TYPE field in this certificate should be set to [0A] - ntor onion key cross-certifying ntor identity key 3. Authority behavior Authorities should reject any router descriptor with an invalid onion-key-crosscert element or ntor-onion-key-crosscert element. Both elements should be required on any cert containing an ed25519 identity key. See section 3.1 of proposal 220 for rules requiring routers to eventually have ed25519 keys. 4. Performance impact Routers do not generate new descriptors frequently enough for the extra signing operations required here to have an appreciable affect on their performance. Checking an extra ed25519 signature when parsing a descriptor is very cheap, since we can use batch signature checking. The point decompression algorithm will require us to calculate 1/(u+1), which costs as much as an exponentiation in GF(2^255-19). Checking an RSA1024 signature is also cheap, since we use small public exponents. Adding an extra RSA signature and an extra ed25519 signature to each descriptor will make each descriptor, after compression, about 128+100 bytes longer. (Compressed base64-encoded random bytes are about as long as the original random bytes.) Most clients don't download raw descriptors, though, so it shouldn't matter too much. A. Converting a curve25519 public key to an ed25519 public key Given a curve25519 x-coordinate (u), we can get the y coordinate of the ed25519 key using y = (u-1)/(u+1) and then we can apply the usual ed25519 point decompression algorithm to find the x coordinate of the ed25519 point to check signatures with. Note that we need the sign of the X coordinate to do this operation; otherwise, we'll have two possible X coordinates that might have correspond to the key. Therefore, we need the 'sign' of the X coordinate, as used by the ed25519 key expansion algorithm. To get the sign, the easiest way is to take the same private key, feed it to the ed25519 public key generation algorithm, and see what the sign is. B. Security notes It would be very bad for security if we provided a diffie-hellman oracle for our curve25519 ntor keys. Fortunately, we don't, since nobody else can influence the certificate contents. C. Implementation notes As implemented in Tor, I've decided to make this proposal cross-dependent on proposal 220. A router descriptor must have ALL or NONE of the following: * An Ed25529 identity key * A TAP cross-certification * An ntor cross-certification Further, if it has the above, it must also have: * An ntor onion key. ```