Authentication Protocol
When a network connection is established between two Vanadium processes, they authenticate each other, i.e., exchange blessings so that both ends can identify the specific principal at the other end. The remote blessing names are then used to authorize RPCs. This document describes:
- the properties desired from the authentication protocol
- the current implementation that provides these properties
- the reasons behind various design choices in a question-and-answer format.
Principals & blessings
A principal is defined by a unique (public, private) key pair (P, S)
and a
set of blessings in the form of certificate chains that bind a name to P
. For
more details, read security concepts.
Within the Go codebase, the set of blessings is encapsulated within the
v.io/v23/security.Blessings
type. The principal and all private key
operations are encapsulated in the v.io/v23/security.Principal
type.
Authentication
Communication between two processes takes place after they establish a confidential, authenticated connection. Encryption with keys derived from an Elliptic curve Diffie-Hellman (ECDH) exchange is used to provide message confidentiality and integrity . The goal of the authentication protocol is to exchange the blessings in a way that provides the following properties:
- Session binding: The private counterpart
S
of the public keyP
to which the blessings are bound must be possessed by the same process with which the session encryption keys have been established. - Client Privacy: An active or passive network attacker listening in on all communication between the two processes cannot determine the set of blessings presented by the initiator of the connection (the "Client").
Additionally the protocol also offers an optional mode where Server Privacy is upheld, i.e., an active or passive network attacker cannot determine the set of blessings presented by the responder of the connection (the "Server"). This mode makes use of Identity-Based Encryption and has an additional performance overhead.
Current implementation
As of March 2016, the reference implementation of the Vanadium networking stack
in [v.io/x/ref/runtime/internal/flow/conn
] provides confidential,
authenticated communication streams (referred to as virtual circuits or VCs).
Blessings bound to the public key used to establish the communication stream are
provided with each RPC request.
In this implementation, NaCl/box is used to establish an authenticated-encryption channel based on an ECDH key exchange.
Where:
{foo}k
represents the messagefoo
encrypted using the keyk
- Channel bindings C1 and C2 at the Client and Server ends respectively are constructed by appending a specific tag to the (sorted) pair of NaCl/box public keys generated for the session. The tags are different for the Client and Server ends, and are meant to prevent type flaws.
ClientPublicKey
andServerPublicKey
are the public keys to which the blessings are bound. The NaCl/box public keys are ephemeral and distinct from these public keys.
Server Privacy
In the protocol described above, the server presents its blessings first and thus reveals it to active network attackers that initiate a connection to it. (Note that while such active network attackers may learn the server's blessings they would not be able to complete the protocol unless they can present valid blessings that satisfy the server's authorization policy.) In light of this privacy threat, the protocol offers a server privacy mode wherein the server's blessings only get revealed to clients that satisfy its authorization policy.
The key primitive in the design of our protocols is a mechanism to encrypt a message under an authorization policy so that it can only be decrypted by principals possessing blessings satisfying the policy. Once we have such a primitive we can modify the above protocol by having the server send its blessings encrypted under its authorization policy. This would ensure that the server's blessings get revealed only to authorized clients and thus protect the server's privacy.
Authorization policies in Vanadium are based on blessing patterns, which are a special form of name prefixes. Encrypting a message under a blessing pattern is possible using a prefix-encryption scheme which can be built using Identity-Based Encryption (IBE).
An IBE scheme requires a trusted root authority for extracting and handing out
identity secret keys corresponding to the blessing names possessed by principals.
Such trusted root authorities may coincide with blessing roots in the Vanadium setting.
For example, the principal Alice could be an IBE root as well as a blesing roots that
issues a blessing and an identity secret key for the name Alice:Device:TV
to its
television set.
Correctness Proof
The protocol along with the guarantees that it makes has been formalized in ProVerif to provide a proof of correctness. This formalization is available here
Code pointers
Pointers to code in the reference implementation of the Vanadium APIs:
- Session encryption is encapsulated in the
ControlCipher
interface - NaCl/box implementation of the interface)
- The authentication protocol is implemented by the
dialHandshake
andacceptHandshake
functions inv.io/x/ref/runtime/internal/flow/auth/conn.go
- Blessing-Based Encryption library for encrypting messages with respect to blessing pattern policies, implemented as a wrapper around the Identity-Based Encryption (IBE) library
- Identity-Based Encryption library
Questions
Why don't the the Client and Server send their blessings in parallel, instead of Server first?
Doing so provides Client privacy.
If the Client sent its blessings before validating and authorizing the server's blessings then an active network intermediary can learn the Client's blessings and compromise Client privacy as it will learn of the Client's intention to communicate.
Can an intermediary fake a blessing by modifying messages between the Client and Server?
No.
Since all messages are exchanged using a negotiated encryption key, the only malicious intermediary to consider is one that breaks the connection and establishes separate encrypted sessions with the Client and Server. Doing so will result in different channel bindings and the processes will realize that they are not directly connected.
This session binding technique is inspired by Dirk Balfanz and Ryan Hamilton's channel ids proposal.
Did you consider using TLS instead of NaCl/box?
Initially, TLS 1.2 was used instead of NaCl/box to establish the encrypted sesssion. However, only a stripped down version was needed (since TLS was used only for establishing an encrypted session, not for authentication via exchange of blessings) and the libraries being used made this more heavy-weight than NaCl/box. For example, using TLS 1.2 required 3 round-trips to establish the session keys while with NaCl/box, a single round-trip suffices.
TLS 1.3 is simpler and more robust compared to TLS 1.2; we may consider switching to it once the standard is stable and implemented by standard libraries.
Why are blessings encrypted with the session key?
The reason is threefold:
- To bind the session key to the blessings presented by each end. By encrypting its blessings under the session key (using an authenticated-encryption scheme) each end proves knowledge of the session key to the other end.
- To prevent passive network sniffers from determining the blessings being exchanged over a network connection.
- To prevent active network attackers from learning the Client's blessings.