2 Hemant Gouni and Jonathan Aldrich
A classical information ow control system [Myers 1999; Simonet 2003] might support the
specication of the ow architecture in Fig. 1 by providing two lattices: one for reasoning about
condentiality, or the property that condential data does not leak to inappropriately visible places,
and one for integrity, or the property that untrusted data does not propagate to inappropriately
integral places. All data in the program must have a label relevant to each lattice, denoting its
levels of condentiality and integrity. Two separate lattices are required for each property owing
to the duality between them: two distinct and opposing invariants must be enforced when data
is labeled as both highly condential and highly integral, such as with
db_handle
in Fig. 1. First,
it must never ow to data labeled as being of low condentiality, such as
network_io
. Second,
data labeled as being of low integrity, again like
network_io
, must never ow to
db_handle
. This
separate treatment complicates reasoning— for example, Jif [Pullicino 2014], a state of the art IFC
system for Java, provides entirely new (dual) semantics for lattice operations when reasoning about
integrity versus condentiality.
Our system resolves this issue by presenting a single, straightforward abstraction for declaring
information ow policies, simplifying specications while retaining expressivity. Instead of organiz-
ing data inside a lattice and reasoning about ows in the context of it, we opt to allow programmers
to directly specify which ows between places in a program are not permitted, as presented in the
architecture in Fig. 1. A declaration
flow b ->! c
states that data aected by variable
b
cannot
ow to variable
c
, and a declaration
flow mod network_io ->! mod db_handle
states that data
aected by the
network_io
module cannot ow to the
db_handle
module. We will refer to the part
before the arrow as the source, and the part after as the destination. This streamlined annotation
language contributes to a system which is:
(1) Uniform:
a ow annotation
flow b ->! c
may be an integrity specication, a condentiality
specication, or potentially both— the programmer need not shift their reasoning
(2) Incremental:
our approach to ow annotations encourages partial and local specications
on the way to proving higher level program properties, and
(3) Simple:
we provide a small number of straightforward constructs which are highly general
and composable, minimizing changes needed to the semantics of the language and easing
adoption of the system by new users.
We will explore these properties further by analyzing cryptographic key management in two
popular Rust programs, Rocket and Conduit. A brief formal description of our IFC system, as an
extension to the Rust type system, is provided in the appendix for the curious reader.
2 MOTIVATION: MANAGING KEYS
2.1 Case Study: Rocket
Rocket is a fully edged and widely used HTTP framework for Rust. Like many web frameworks, it
provides optional support for serving trac over Transport Layer Security, or TLS, connections. TLS
is an essential feature for securing data between clients, such as browsers, and servers, encrypting
data in transit. A critical component of TLS is a public-private keypair held by the server, in this
case Rocket. Each domain which aims to communicate securely with web browsers and clients at
large must obtain a certied keypair, which is valid for any trac served by it. While a typical web
service consists of a large number of physical servers, each of them may use the same TLS keypair,
assuming they are serving a single domain. This is convenient, but risky— leakage of the private
key for a domain from any of its servers risks compromising the security of the entire service. It is
essential, then, that this does not occur, and an IFC system may be able to provide that assurance.
Most of our discussion will be directed at the particular Rocket code path that deals with con-
ditionally conguring TLS functionality, shown in Fig. 2. Specically, we analyze the function