On Wed, Jul 29, 2020 at 1:15 AM Matthew Finkel sysrqb@torproject.org wrote:
Hello everyone,
Hi, Matt!
There's a part of this that I'm still trying to figure out:
The safest usage of the long-term keys for alternative purposes I see appears to be by deriving a (fixed/deterministic) blinded key pair using the same scheme that Tor uses, and signing/verification simply follow the same process as Tor, except the derived keys need not rotate periodically (is this true?). The derived key should be used for certifying a freshly generated ed25519 key, which is used in the application protocol. For example, if I want to use a key for code signing such that it is bound to my onion service key, then I could derive a certifying key by following Tor's derivation scheme, by substituting:
BLIND_STRING = "Derive temporary signing key" | INT_1(0) N = "key-blind" | INT_8(period-number) | INT_8(period_length)
with
BLIND_STRING = "Derive code signing key" | INT_1(0) N = "code-sigining-key-blind" | "v0" | "YYYY-MM-DD" | INT_8(validity_period)
In the case of v3 onion services, 'period-number' comes from the current time, and 'period-length' comes from the consensus, so it's easy for the client to know what parameters to use when deriving the key.
But how is the party that relies on the derived key supposed to know what values were used for "YYYY-MM-DD" and "validity period" in this case? It seems like those two values would need to be shipped along with the key, which could make for logistical issues.
I guess in the case of an X.509 certificate, we could use the validAfter and validUntil fields to set the parameters -- though it's a little weird to have to look at _just_ those fields to see what the signing key is supposed to be.
Maybe, for an X.509 cert, we could have
N = "x509 onion key derivation" | H(unsigned-certificate)
where `unsigned-certificate` is a DER-encoded TBSCertificate (the part of the certificate that's signed). That way, we get a separate blinded key for each certificate.
[...]
The above process seems like a lot to ask from application developers. Can we make it easier for them?
Open questions:
- Going back to the long-term secret key, can LH and RH be used directly in EdDSA without reducing the security and unlinkability of the blinded keys?
From a practical point of view: Forcing the signer to keep LH and RH
online reduces the security of the protocol IMO; the current protocol is designed so that the onion service doesn't need to keep its long-term identity key online.
Also note that if we care about keeping the primary identity key offline, LH' and RH' shouldn't be used directly! Although it is not possible to derive a long-term public key from a blinded public key, it IS possible to derive a long-term _private_ key from a blined private key. That's why in the v3 onion service system, blinded private keys aren't kept for any longer than needed in order to certify a short-term randomly generated signing key.
- Should other use cases of the long-term keys only derive distinct (blinded) keys, instead of using the long-term keys directly?
IMO yes.
If other use cases should only use derived keys, then is there an alternative derivation scheme for when unlinkability between derived keys is not needed (without reducing the security properties of the onion service blinded keys), and is allowing linkability useful/worthwhile?
Is the above example derivation scheme safe if different applications tweak the above prefix strings in similar ways?
Should Tor simply derive one blinded key that can be used by all alternative applications? Is that safe?
Yes, but only if that key will never ever need to rotate.
Here's a suggestion -- what if we come up with a single profile for this kind of key derivation, to be used in X.509. Along with it, we could have a nice small library that can generate and verify the "root" certificates (the ones signed by a blinded key).
What important parts of the application space would be left unaddressed by that?