huitema / dnssdprivacy

1 stars 2 forks source link

Scaling issues with different kinds of trust tokens #8

Open huitema opened 6 years ago

huitema commented 6 years ago

I have been reviewing the DNS-SD privacy issues in light of Stuart's draft (draft-cheshire-dnssd-privacy-considerations-01) and his presentation at IETF 100 (https://datatracker.ietf.org/meeting/100/materials/slides-100-dnssd-04-stuart-privacy/). Draft and presentation reflect uneasiness with several of the design choices that we made in draft-ietf-dnssd-privacy-03, draft-ietf-dnssd-pairing-03, and draft-ietf-dnssd-pairing-info-00. One of the issues is the type of secret used to prove the trust relationship.

There is little doubt that maintaining privacy requires some type of trust establishment. In our drafts, we chose to base that trust on pairwise shared secrets, established through a pairing operation. Pairwise secrets have the advantage of being easy to understand and manage, since the secret is shared between just two entities. But pairwise operation scales at best as O(N), possibly O(N**2). The alternative may be to use public key technology. This would scale better when entities have to manage a large number of pairings, such as for example a printer that can be used by a whole group of people, but it is pretty hard to establish trust using public keys without disclosing at least one of the public keys to third parties. This may be OK when one of the parties does not have privacy concerns. For example, in the group printer example, it may be OK to disclose the identity of the printer as long as the identity of the users is kept private.

huitema commented 6 years ago

We want privacy. That means that the devices will "offer service to some subset of clients", rather than "offer to everybody". But we do not delegate privacy to the infrastructure, so we cannot have solutions in which the infrastructure performs access control. That leaves solution in which the service is "offered to everybody", but only qualified clients understand the "real name" behind the obfuscated name. Hence the general structure: service announces an obfuscated name, typically function of time and secret. Clients will find the available services on the network, and filter out those that they are not interested in.

There are two options for the trust token: symmetric key, or asymmetric.

In the symmetric version, client and server manage a shared secret. Both client and server can construct the obfuscated name. Server publishes a name, encrypt or hash of time-based nonce with shared key. Clients can also construct a priori the obfuscated names of the servers that they are interested in. Client retrieves all names and check whether some of them match the expected peer list. Or, in server based discovery, client asks server whether obfuscated name is published. The problem there is a tradeoff between scalability and impersonation. If we use the same shared secret for all clients, the protocol scales well, but any authorized client can impersonate the server for all other clients. If we use pairwise secrets, as specified in the current draft, clients cannot impersonate the server for other clients but the protocol complexity increases significantly.

In the asymmetric version, client knows the public key of the server. Server constructs the obfuscated instance name by encrypting the a time-based nonce with the private key. Client looks at all available obfuscated names, and attempts to decrypt every available name. This does not scale very well - public key operation times number of keys known to client times number of services present. But...

In the asymmetric version, server could also construct an obfuscated service name by encrypting a time-based nonce with the public key. Client can also construct the obfuscated service name, because it knows the public key. It can look for that name, and normally only finds one instance of the server. It can verify that this is the right server by decrypting the obfuscated name. So we get a privacy respecting discovery system in which the server publishes exactly one record, and the client typically accesses exactly one record per service/server that it discovers.

huitema commented 6 years ago

In the asymmetric key version, privacy depends on the public key being secret. If it is not, anybody can attempt to decrypt the obfuscated name published by the servers, and check whether the result matches the expected time-based nonce -- we get a "nonce-oracle". Adversaries can collect lists of public keys, and use the oracle to track which servers are advertising on a given network.

Treating the public key as a shared secret between the server and authorized clients does significantly simplify the protocol: "authorization to discover" simply means access to the public key. As we saw above, we can use a nonce encrypted with the public key (or hashed with the public key) as a service identifier. Maybe add the actual service name in the mix if several services are managed using the same public key.

Note that using the same key for all clients does not diminish privacy compared to a solution that uses just bilateral secrets. The real secret is the identity, presence and location of the server, and that secret can be discovered by any authorized client. If just one client is compromised, the server privacy is compromised, and having separate secrets for each client won't change that.

huitema commented 6 years ago

There is also an interesting relation between "authorization to discover" and "authorization to use". We can assume that many services will be developed on top of TLS. With standard TLS, the client that attempts a connection will obtain the public key of the server if using naked public key, or the public key and the name, if using certificates. If we want to provide server privacy, we have to consider that too.

If the server wants to maintain privacy, it should not accept connections from unauthorized clients. But in TLS, client authentication only happens after server authentication, so we get some kind of catch 22. The way out is to require some kind of token in the "Client Hello", proving that the client is authorized. In TLS, this could be done by demonstrating knowledge of a shared secret. There is something elegant about making that shared secret the public key -- if the client demonstrably knows the public key, the server can disclose that public key without compromising privacy.

The details need work, but one design would be passing a PSK ID that contains an encryption of a random number with the public key.