Scott D Stoller
email: stoller@cs.stonybrook.edu

Yanhong A Liu
email: liu@cs.stonybrook.edu

Algorithm Diversity for Resilient Systems

Diversity can significantly increase the resilience of systems, by reducing the prevalence of shared vulnerabilities and making vulnerabilities harder to exploit. Work on software diversity for security typically creates variants of a program using low-level code transformations. This paper is the first to study algorithm diversity for resilience. We first describe how a method based on high-level invariants and systematic incrementalization can be used to create algorithm variants. Executing multiple variants in parallel and comparing their outputs provides greater resilience than executing one variant. To prevent different parallel schedules from causing variants' behaviors to diverge, we present a synchronized execution algorithm for DistAlgo, an extension of Python for high-level, precise, executable specifications of distributed algorithms. We propose static and dynamic metrics for measuring diversity. An experimental evaluation of algorithm diversity combined with implementation-level diversity for several sequential algorithms and distributed algorithms shows the benefits of algorithm diversity.

Introduction

Diversity can significantly increase the resilience of systems, by reducing the prevalence of shared vulnerabilities and making vulnerabilities harder to exploit. The idea of intentionally introducing software diversity as a defense mechanism has been around for decades, e.g., [START_REF] Cohen | Operating system protection through program evolution[END_REF][START_REF] Forrest | Building diverse computer systems[END_REF]. It is closely related to the well-known moving target defense (MTD) strategy: running different variants of a program at different times is MTD. Software diversity is an effective defense against attacks whose success depends on details of the victim software. Without knowing those details for the specific instance (variant) of the software being attacked, attackers can still attempt such attacks (e.g., by making random guesses at those details), but the probability of success is greatly reduced [START_REF] Larsen | Sok: Automated software diversity[END_REF].

There is a large corpus of research on techniques for automatically introducing software diversity that increase resilience to various classes of attacks [START_REF] Larsen | Sok: Automated software diversity[END_REF]. For example, Address Space Layout Randomization (ASLR), which randomizes the starting addresses of segments in a process's address space, is a classic form of software diversity that increases resilience to some types of memory corruption attacks.

The most common way to use software diversity to increase resilience is to run a randomly selected variant each time the program is executed. With this approach, the use of diversity alters, with high probability, the effect of an attack, so the attack does not have the intended effect (e.g., gaining root privilege and installing a rootkit) [START_REF] Larsen | Sok: Automated software diversity[END_REF]. The attack might still have a less malicious and less predictable but nevertheless undesirable effect (e.g., crash or incorrect output).

Another way is to run multiple variants of the application in parallel and compare their outputs. We call this diversified replication. Any difference in the outputs of the variants indicates misbehavior of one or more variants due to an attack; this triggers defensive action. This approach provides greater resilience, at the cost of more computational resources. It also provides greater resilience than traditional replication, in which replicas are identical and exhibit the same (incorrect) behavior when their vulnerabilities are exploited. Note that diversity may lead to different behavior (and therefore attack detection) in two ways: [START_REF] Avizienis | The N-version approach to fault-tolerant software[END_REF] it might cause a difference in the direct effect of the attack (e.g., which data structure is overwritten) or, [START_REF] Bhatkar | Efficient techniques for comprehensive protection from memory error exploits[END_REF] even if the direct effect of the attack is the same (e.g., the same data structure is overwritten), it might cause differences in subsequent behavior, due to differences in the algorithms or implementations used by the variants (e.g., one variant reads the affected data structure earlier in its computation and hence before the attack, and another reads the affected data structure later in its computation and hence after the attack).

This paper focuses on algorithm diversity for software resilience, in which different variants run different algorithms, i.e., perform different computations at a high level. In contrast, all of the work surveyed in [START_REF] Larsen | Sok: Automated software diversity[END_REF] creates implementation-level diversity, changing details of the implementation without changing the algorithm. Algorithm diversity can introduce new and larger differences between variants than implementation-level diversity and hence can provide greater resilience, especially when used together with implementation-level diversity.

Algorithm variants may be obtained in a variety of ways, besides writing them manually. For standard problems (e.g., dictionary ADT), they can be obtained from algorithm libraries. A more general automated approach is to generate them by starting with a high-level algorithm (or specification) and applying different optimizations (algorithm improvements, automated using program analysis and transformation). In particular, we have used a method based on systematic incrementalization [START_REF] Paige | Finite differencing of computable expressions[END_REF][START_REF] Liu | Incrementalization across object abstraction[END_REF][START_REF] Liu | A language and framework for invariant-driven transformations[END_REF][START_REF] Liu | Demand-driven incremental object queries[END_REF], which transforms programs to maintain high-level invariants incrementally, and related optimizations to generate multiple variants of many sequential algorithms and distributed algorithms [START_REF] Liu | Systematic Program Design: From Clarity To Efficiency[END_REF][START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF][START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF].

Algorithm diversity and implementation-level diversity introduce different kinds of variation and together offer more diversity than either alone. We introduce diversity metrics that quantify the difference between-or equivalently, the similarity of-variants. We consider a static metric, code diversity, based on the instruction sequences in the compiled program, and two dynamic (behavioral) metrics: trace diversity, based on the sequence of instructions executed, and input access diversity, based on the sequence of accesses to input data. The latter dynamic metric is motivated by the fact that invalid inputs are the primary attack vector for external attackers. A direction for future work is to augment these broad diversity metrics with more specialized metrics that quantify resilience to specific classes of attacks.

Algorithm diversity can be applied to programs in any language. In this paper, we focus on Python and DistAlgo [START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF][START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF], an extension of Python for high-level, precise, executable specifications of distributed algorithms. In contrast, existing work on automated software diversity primarily targets C programs or (disassembled) machine code.

Python is interpreted-more precisely, CPython, the predominant implementation of Python, compiles Python to bytecode and then runs the bytecode in an interpreter. Algorithm diversity applied to Python programs can be used together with implementation-level diversity applied to Python programs and the runtime system. This achieves greater total diversity and increases resilience to vulnerabilities in the runtime system, because vulnerabilities manifest only with specific inputs, and the runtime system's inputs include Python programs as well as network messages, UI events, etc. Diversity at the high-level language level provides additional protection from dataonly attacks [START_REF] Chen | Non-control-data attacks are realistic threats[END_REF][START_REF] Rogowski | Revisiting browser security in the modern era: New data-only attacks and defenses[END_REF], against which many runtime-system-level defenses are less effective. Algorithm diversity applied to Python programs can also provide resilience to functional faults in the runtime system, if the runtime system does not correctly implement the semantics of some built-in constructs or library functions in some (corner) cases.

Diversified replication requires synchronized execution (often called N-version execution [START_REF] Avizienis | The N-version approach to fault-tolerant software[END_REF]) of the variants; otherwise, their executions might diverge due to scheduling differences. Synchronized execution of distributed programs generally requires synchronization of message delivery order. DistAlgo's asynchronous message handling requires additional synchronization, to ensure that all variants handle corresponding messages at corresponding points in their executions. We developed a synchronized execution framework for DistAlgo that ensures this. Our framework can also suppport variants whose behaviors differ in prescribed ways.

Measuring dynamic diversity for Python and DistAlgo programs required development of new runtime monitoring tools, which are also more broadly useful. We designed and implemented a tool that intercepts accesses to fields of selected objects; we use it to log accesses to objects read as input, including objects received in messages. Handling built-in types such as integers and strings is tricky, because they are sometimes accessed directly by C code in the Python interpreter, but essential, because they are commonly used in program inputs.

We also designed and implemented a tracing tool that reconstructs the exact sequence of bytecode instructions executed by a Python program. It uses the standard Python tracing module to record the sequence of source lines executed, and then analyzes the compiled program to determine the sequence of bytecode instructions corresponding to each source line. Supporting DistAlgo requires some extra work, due to details of DistAlgo's implementation by translation to Python.

In summary, the contributions of this paper include:

-The first study of semi-automated algorithm diversity for software resilience, using a method based on systematic incrementalization to generate algorithm variants. -A synchronized execution framework for DistAlgo and for high-level executable specifications of distributed algorithms. -Static and dynamic metrics for measuring diversity.

-A runtime monitoring tool for Python and DistAlgo that logs accesses to fields of selected objects, including instances of built-in types. -A tracing tool for Python and DistAlgo that reconstructs the exact sequence of executed bytecode instructions. -Experimental evaluation of algorithm diversity combined with implementationlevel diversity for several sequential algorithms and distributed algorithms, demon-strating that algorithm diversity can achieve more diversity than implementationlevel diversity, and the two together can achieve even more.

Background on DistAlgo

Liu et al. [START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF][START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF] propose DistAlgo, a language for high-level, precise, executable specifications of distributed algorithms, and study its use for specification, implementation, optimization, and simplification of such algorithms. For expressing distributed algorithms at a high level, DistAlgo supports four main concepts by building on an object-oriented programming language, Python: (1) distributed processes that send messages, (2) control flow for handling received messages, (3) high-level queries for synchronization conditions, and (4) configuration for setting up and running. DistAlgo is specified precisely by a formal operational semantics [START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF].

Processes That Send Messages. A process type P is defined by a class definition for P that inherits from DistAlgo's built-in process class. The definition of P may contain, in addition to the usual definitions that may appear in Python classes, definition of a setup method for taking in and setting up the values used by the process, definition of a run method containing the main control flow of the process, and definitions of receive handlers for handling messages, as described below.

To create instances of P , DistAlgo provides a new P construct; it can optionally be preceded by the number of processes to create (the default is 1) and followed by "at h" where h identifies the host where the process(es) should be created (the default is the local host). After a new process has been created, and its setup method called to initialize it, invoking its start method causes execution of its run method.

Processes send messages using the statement send m to ps, where ps is a process or set of processes.

Control Flow for Handling Received Messages. Received messages can be handled asynchronously, using receive definitions, and synchronously, using await statements. A receive definition has the form receive m from p: stmt. It handles un-handled messages that match m from p, where m and p are patterns. If matching succeeds, unbound variables in m (and p) are bound to the corresponding component of the message (and the message's sender, respectively), and then stmt is executed.

To synchronize message handling with local computation, receive handlers are executed only at yield points. The program point before or after any statement can be declared as a yield point. In addition, there is an implicit yield point before each await statement, for handling messages while waiting. By default, any number of pending messages can be handled at a yield point.

An await statement has the form DistAlgo automatically maintains histories of messages sent and received by each process in variables sent and received; they are automatically eliminated if unused.

Configuration. Configuration for requirements such as use of logical clocks and use of reliable and FIFO channels can be specified using DistAlgo's configure statement. For example, configure clock = Lamport specifies that Lamport's logical clocks are used; it configures sending and receiving of a message to update the clock value, and defines a function logical_time() that returns the clock value.

Creating Variants using Incrementalization

Algorithm variants differ from each other due to different high-level invariants they maintain and different ways of maintaining them. We describe the ideas of transforming expensive queries into high-level invariants and using systematic incrementalization to generate efficient algorithms that maintain the query results incrementally. Each resulting combination of ways of maintaining the invariants forms an algorithm variant.

Example. We use as an example Lamport's algorithm for distributed mutual exclusion, described in his seminal paper that proposed logical clocks [START_REF] Lamport | Time, clocks, and the ordering of events in a distributed system[END_REF]. The problem is for multiple processes to access a shared resource mutually exclusively, in what is called a critical section, i.e., there can be at most one process in a critical section at a time.

Each process can be expressed in DistAlgo as in Figure 1 [START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF]. The process is set up with sets s and q (lines 3-4). To run a task mutually exclusively, the process sends a request and adds it to q (lines 6-8), waits for (i) own request (t,self) to be before each other request (t2,p2) in q and (ii) having received an ack with a time t2 later than t from each process p2 in s (lines 9-10) before doing the task in critical section (line 11), and then removes the request from q and sends a release (lines 12-13). When receiving a request or release, it sends back an ack and adds to or removes from q (lines 14-19).

The two conditions in await are key to the algorithm to ensure mutual exclusion, while the rest does basic sending and receiving of messages and bookkeeping of q.

Incrementalization. Incrementalization transforms queries and updates to maintain high-level invariants, including invariants for intermediate and auxiliary values, incrementally [START_REF] Paige | Finite differencing of computable expressions[END_REF][START_REF] Liu | Incrementalization across object abstraction[END_REF][START_REF] Liu | Systematic Program Design: From Clarity To Efficiency[END_REF][START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF]. It can yield diverse algorithms. For the example in Figure 1, the two conditions in await are queries, consisting of three quantifications including two that are nested; and assignments and bookkeeping for s and q and implicitly adding to received at receive handlers are updates.

The most direct algorithm can compute queries using iterations, in for-loops, whereas an incremental algorithm can maintain the results of queries at updates and look up the results as needed. An incrementalized algorithm maintains high-level invariants not only for the query results but also for intermediate and auxiliary values needed. Alternative invariants can often be used, yielding even greater diversity.

For example, the condition on line 10 in Figure 1 The resulting algorithm differs significantly from direct iteration for the nested quantifications. The condition on line 10 could also be transformed into two nested count queries, and the condition on line 9 can be transformed into a count query also, or an aggregate query using min, yielding different algorithms for incremental maintenance. Details of these transformations are in [START_REF] Liu | From clarity to efficiency for distributed algorithms[END_REF].

In general, incrementalization can also transform nested loops that compute aggregate values such as sum and min [START_REF] Liu | Optimizing aggregate array computations in loops[END_REF][START_REF] Gautam | Simplifying reductions[END_REF][START_REF] Liu | Systematic Program Design: From Clarity To Efficiency[END_REF]. For recursive functions as queries, the resulting incremental algorithm can still use recursion, forming an optimized recursive algorithm, or use iteration, forming an optimized iterative algorithm [START_REF] Liu | From recursion to iteration: what are the optimizations?[END_REF][START_REF] Liu | Systematic Program Design: From Clarity To Efficiency[END_REF]. Additionally, more refined data structures can be used to implement sets more efficiently [START_REF] Cai | Type analysis and data structure selection[END_REF][START_REF] Goyal | A Language Theoretic Approach to Algorithms[END_REF][START_REF] Liu | Systematic Program Design: From Clarity To Efficiency[END_REF], such as using one bit for each process in the set responded above. Incrementalization also enables new additional optimizations that are made possible as the results of systematic transformations [START_REF] Liu | Systematic Program Design: From Clarity To Efficiency[END_REF].

Synchronized Execution for DistAlgo

A diversified process is a process with variants. A system may contain a mixture of diversified and un-diversified processes. A gateway process is created for each diversified process. It represents the variants of a diversified process to the rest of the system, making them appear as a single process. The gateway intercepts and forwards all inbound and outbound messages of all variants of the diversified process. We focus on synchronization of DistAlgo constructs; other I/O events, such as file accesses, can be synchronized using standard techniques.

Our synchronized execution framework consists of two parts: (1) an automated program transformation that (1a) ensures all messages are routed via the gateway, and (1b) inserts synchronization with the gateway at yield points, to ensure that all variants have yielded the same number of times before handling their copies of a given inbound message, despite differences in message latency and process execution speed; and (2) an algorithm run by the gateway that determines when to forward messages and when to report divergence (i.e., differences in behavior). When divergence is reported, the system may initiate application-specific defensive action.

We first present the core version of this approach, which assumes all variants of a process have the same communication pattern, i.e., send the same messages to the same destinations in the same order; we discuss later how to relax this assumption.

Handling Outbound Messages. To route outbound messages via the gateway, the transformation replaces all calls to DistAlgo's send method with calls to send_sync, and it inserts a definition of that method in every process class. send_sync sends the original message and its original destination to the gateway. Processes often send their own process id in messages. Since each variant of a diversified process has a unique process id, such messages will differ. To accommodate this as normal behavior, not divergence, send_sync replaces all occurrences of the variant's process id in the message with the gateway's process id. This also reflects the principle that the gateway represents the variants to the rest of the system. Pragmatically, it ensures that, if the recipient sends a reply to the process id contained in the message, the reply goes to the gateway, as desired.

The gateway stores un-forwarded outbound messages received from each variant in a separate FIFO queue. When all of the queues are non-empty, it compares the messages (including their destinations) at the heads of the queues. If they are identical, the gateway dequeues the message from all queues and forwards one copy to the destination, otherwise it reports divergence. To ensure liveness if some divergent variant fails to send a message, once one queue becomes non-empty, the gateway waits a limited amount of time for all queues to become non-empty; if this time limit is exceeded, the gateway reports divergence.

Synchronization at Yield Points and await Statements. The transformation inserts a call to yield_sync(block, timeout) at every yield point, and it inserts a definition of that method in every process class. The first argument block is a boolean that indicates whether the yield point is associated with an await statement. The second argument timeout, meaningful when the first argument is True, is a timeout duration if the timeout clause is present in that await statement and is None otherwise. The transformation also extends the setup method to initialize a variable num_yields to zero. yield_sync increments num_yields, sends a yield message containing block, timeout, and num_yields to the gateway and waits for a yield-reply message from the gateway before returning.

The transformation for an await statement with timeout ensures the total wait time is preserved, even though the waiting period may be split by interactions with the gateway. It transforms Handling Inbound Messages. When the gateway receives an inbound message m, it stores m in a queue of un-forwarded inbound messages, waits until it has received yield messages with the same num_yields from all variants, forwards to all variants and dequeues all un-forwarded inbound messages, and then sends a yield-reply message to all variants. The gateway communicates with the variants over FIFO channels, so all variants handle the forwarded messages before proceeding from the current yield point. In the copy of m to be forwarded to variant p, the gateway replaces all occurrences of its own process id with p's process id.

If the gateway has received a yield message from all variants, and has no inbound message to forward to them, its behavior depends on the values of block and timeout in the yield messages (if the values of block differ, or the values of timeout differ by more than a small amount, divergence is reported). If block=False, the gateway sends a yield-reply message to all variants, allowing them to proceed. If block=True and timeout=None, the gateway waits until it has received and forwarded an inbound message before sending a yield-reply message, since the conditions in the await statements will remain false until the variants' states are updated by handling of an inbound message. If block=True and timeout is a number, the gateway behaves as in the previous sentence, except it will also send a yield-reply message after time timeout has elapsed.

Process Creation. The program transformation reads a configuration file that specifies which process types are diversified and the types of their variants. For each diversified process type P , a gateway type GatewayP is generated (basically, this is done by instantiating template code with the type P and the types of its variants), and process creation statements with type P are transformed to create instances of GatewayP instead. The setup method of GatewayP creates an instance of each of the specified variant types, and passes the gateway's process id to the variants as an additional argument to their setup methods, which are transformed to accept this additional argument.

Relaxed Synchronization. The above approach effectively introduces a barrier synchronization for a diversified process's variants at each synchronization point. This ensures the most timely detection of divergence. An alternative approach, used in some other synchronized execution frameworks [START_REF] Hosek | Varan the unbelievable: An efficient n-version execution framework[END_REF][START_REF] Xu | Bunshin: Compositing security mechanisms through diversification[END_REF], is to allow one variant (the "leader") to get ahead, try to make the actions of the other processes (the "followers") consistent with the leader's actions (e.g., by delivering the same number of messages at the corresponding yield event), and reporting divergence when this is not possible. This may provide speedup but allows a divergent leader to perform divergent actions before the leader's divergence is detected; when this is unacceptable, such actions should not be allowed to have externally visible effects until the followers catch up and agree on the actions.

Allowing Differences in Message Pattern. It may be desirable to relax the requirement that corresponding messages sent by all variants of a process are identical, in order to allow greater diversity. For example, Lamport's distributed mutual exclusion algorithm [START_REF] Lamport | Time, clocks, and the ordering of events in a distributed system[END_REF] sends in ack messages the current value of the sender's logical clock, whereas the variant in [17, Fig. 3] sends in ack messages the logical time of the request being acknowledged. To support algorithm variants that have the same communication pattern but different message content, we modify the gateway to omit the equality check on outbound messages when the destination is a diversified process, in which case the gateway sends to the other gateway an array containing the message from each variant, which forwards each message in the array to its corresponding variant. The correspondence is determined by indexing variants in the order that their types are listed in the configuration file.

To support algorithm variants with different communication patterns, the configuration file can specify that certain types of messages are un-synchronized. When the gateway receives a message of an un-synchronized type from its i'th variant, it immediately forwards the message to the destination's gateway, which forwards the message to its i'th variant. For example, for synchronized execution of Lamport's distributed mutual exclusion algorithm and Ricart-Agrawala's distributed mutual exclusion algorithm [START_REF] Ricart | An optimal algorithm for mutual exclusion in computer networks[END_REF], we specify that ack and release messages (used only in Lamport's algorithm) and response messages (used only in Ricart-Agrawala's algorithm) are un-synchronized; the gateway still synchronizes messages of other types.

Diversity Metrics and Runtime Monitoring Tools

Code Diversity

Since diversity is the complement of similarity, we measure code diversity with a wellestablished document similarity metric, namely, n-gram similarity with winnowing [START_REF] Schleimer | Winnowing: Local algorithms for document fingerprinting[END_REF], which is used in the popular software plagiarism detection tool Moss to measure similarity of program source code. We apply it to Python bytecode, specifically, the sequence of bytecode instructions in a compiled program. Bytecode similarity is more relevant than source-level similarity, because diversity at the Python level aims to increase resilience to flaws in the runtime system, and bytecode is the program representation used by the runtime system.

An n-gram is a sequence of n consecutive instructions, starting at any position. The algorithm computes the hash of every n-gram in the compiled program, and then (for scalability) selects a subset of those hashes and stores them in a set called the program's fingerprint. The number of selected hashes is controlled indirectly by an algorithm parameter w called the window size. A window of size w consists of the hashes of w consecutive n-grams in the program. The winnowing algorithm is guaranteed to select at least one hash from each window of size w, although it may select more.

A robust metric should have the property that a slightly modified program has high similarity to the original program. In Python bytecode, local variables and global variables are identified by index. Inserting one new global variable at the beginning of the program causes renumbering of all global variables; this could make the metric non-robust. To ensure robustness, we normalize variable indices within each n-gram: we re-index the first global variable accessed in the n-gram as 0, the second one as 1, etc., and similarly for local variables. For similar reasons, we replace absolute line numbers used as targets in jump instructions with a place holder.

We quantify code diversity (and similarity) of two programs as 1 minus the Jaccard similarity of their fingerprints. Recall that the Jaccard similarity of sets S and T is |S ∩ T |/|S ∪T |. We use 1 minus Jaccard similarity so larger values indicate greater diversity.

An alternative to n-gram similarity is Levenshtein distance (a.k.a. edit distance, namely, the minimum number of single-element insertions, deletions, and substitutions needed to change one string to another) between the bytecode sequences in the compiled programs. Levenshtein distance is less suitable here, because it is sensitive to bytecode orderings in the compiled program that may be unimportant at runtime. For example, permuting the order in which function definitions appear in the compiled program has no effect on the program's runtime behavior but has a large effect on the Levenshtein distance. Similarly, swapping the branches in a conditional statement and negating the condition yields an equivalent program with high n-gram similarity to the original but (if the branches are large) a large Levenshtein distance from the original.

Trace Diversity

Trace diversity measures the similarity of the sequences of bytecode instructions executed by two programs. Our bytecode-level tracing tool uses the standard Python trace module to obtain a source-level trace, and then translates it to a bytecode trace. A "blacklist" of modules to be ignored during the conversion can be specified; in experiments, we blacklist some system modules, such as bootstrap and trace. For each source line mentioned in the trace, identified by filename and line number, the translator compiles that .py file to a .pyc file, loads the .pyc file using the marshal module to obtain a code object, repeatedly uses the dis (disassembler) module to obtain the bytecode for the entire program as a list of Instruction objects, and uses the source line number information in the Instruction objects to determine the sequence of instructions corresponding to each line of source code in that file. In the traces to be compared, we include only the opcode and argument attributes of each Instruction; other attributes (e.g., is_jump_target) are less important. We quantify similarity of two traces as the Levenshtein distance (edit distance) between them divided by their average length, for normalization.

Input Access Diversity

Input access diversity measures the similarity of sequences of accesses to input data by two programs, quantified as Levenshtein distance between the sequences divided by their average length, for normalization. The core of the implementation is a general tool to intercept accesses to attributes of selected objects, by overriding the __getattribute__ method of appropriate classes. In our use case, the overriding method logs the access and then calls the original __getattribute__ method. For userdefined classes, this is easily accomplished by inserting a definition of __getattribute__ in the class. This approach does not work for built-in types such as int, string, and tuple, which are common types of input data.

For each of these built-in classes, we define a new class, e.g. tracked_int for int, that inherits from the built-in class and overrides the __getattribute__ method. In the remainder of the description, we focus on int; other built-in types are handled similarly. The problem is that some accesses to attributes of tracked_int are not logged, because attributes of built-in types are sometimes accessed directly by C code in the CPython runtime system. For example, even if x is a tracked_int, the addition operator in x+y compiles to the bytecode instruction BINARY_ADD, which does not call __getattribute__ on either argument.

We overcome this problem by augmenting tracked_int to override all methods of int that access the integer value: __add__, __eq__, __le__, etc. If x is a tracked_int, an expression like x+y now compiles to bytecode that uses the CALL_FUNCTION instruction to explicitly invoke x's __add__ method with argument y. The tracked_int.__add__ method logs the access to the first argument (self), calls __getattribute__ on the second argument (so the access to it will be logged, if it is a tracked_int), and then calls the built-in __add__ method. Since we need to override these operations anyway, we augment log entries to indicate which operation was performed on the accessed attribute.

If x is an int, not a tracked_int, then CALL_FUNCTION invokes the built-in __add__ method, which is implemented by C code that accesses the second argument without calling __getattribute__. Consequently, accesses to y are not logged, even if y is a tracked_int. To overcome this remaining problem, we modify the program to replace the remaining uses of int with a new class my_int, which inherits from int and overrides each two-argument method of int with a method that calls __getattribute__ on the second argument and then calls the original method. To accomplish this replacement, we bind the name int to our class my_int, using the assignment int = my_int. As a result, a constructor call such as int(1) returns an instance of my_int. The literal 1 still produces an int. Therefore, we transform the source program to replace literals with constructor calls, e.g., 1 with int(1).

The remaining aspects of input access tracking differ for Python and DistAlgo. These aspects are (1) determining which objects are tracked, and (2) creating meaningful identifiers for tracked objects. We could easily use the result of Python's built-in id function to identify objects, but it would be difficult to compare input access traces from different variants (or even different runs of the same variant), because the object identifiers in them would be unrelated. Instead, we create object identifiers that can be compared meaningfully with object identifiers in other logs, as described below. The identifier is stored in an attribute of each tracked object.

Python. For Python programs, the user specifies which objects should be tracked by modifying the program to make them instances of tracked classes. For convenience, our tracker class provides a method that recursively traverses an object or collection (dictionary, list, tuple, or set) and replaces all instances of trackable built-in types (i.e., types for which a corresponding tracked type exists) with instances of tracked types. In our benchmark programs, inserting one or two calls to this method suffices. Tracked objects are identified by a sequence number assigned in the order that the objects are created. When tracked objects are used for data read as input, these identifiers are meaningful across logs from different variants, because the variants are given the same inputs and hence read the inputs in the same order.

DistAlgo. For DistAlgo programs, all messages are automatically considered as inputs; additional inputs, if any, are handled as described above for Python programs. Instances of trackable built-in types in messages are automatically replaced with instances of tracked types. Our tracker class, which inherits from DistAlgo's process class, is automatically inserted as a parent class of every process class in the given program. It overrides process.send with a method that replaces all instances of trackable built-in types in the message with instances of tracked types.

To create meaningful identifiers for tracked objects received in messages, we observe that such an identifier should identify the message in which the object was received. Our identifier for such an object is a tuple (host, procNum, msgNum, ob-jNum), where host is the host on which the sender is running, procNum identifies the sending process relative to the host, msgNum identifies the message relative to the sending process, and objNum identifies the object within the message.

To avoid dependence on standard process identifiers that cannot be meaningfully compared across executions, we identify processes by a sequence number assigned in the order in which the processes are created. The tracker class overrides process.setup with a method that assigns the process sequence number; tracker.setup stores the next available process sequence number in a local file. msgNum is a per-sender sequence number assigned in the order in which messages are sent. The object sequence number objNum is assigned to each object in the message in the order that the object is encountered in a depth-first traversal of the message.

Input access logs for DistAlgo programs also contain entries corresponding to receive events, so we can determine that a particular data item (possibly received in a previous message and stored in a data structure) was accessed while processing a particular message.

Evaluation

We evaluated our approach on several sequential and distributed algorithms, using Python 3.7.2 and DistAlgo 1.1.0b13. Our software is available at https://www.cs. stonybrook.edu/~stoller/software.

For each problem and each diversity metric, we measure the diversity achieved (1) by algorithm diversity alone by averaging the diversity metric for each pair of algorithms; (2) by implementation-level diversity (ILD) alone by averaging the diversity metric for each pair of an algorithm and its ILD variant (i.e., the variant obtained by applying ILD transformations to it); (3) by both forms of diversity together by averaging the diversity metric for each pair of an algorithm and the ILD variant of another algorithm. For code diversity, we used n = 5 (the value used in [START_REF] Schleimer | Winnowing: Local algorithms for document fingerprinting[END_REF]), and we disabled winnowing (i.e., included all hashes in the fingerprint), because the bytecode for our examples is not too large. Library code is not included in our code diversity measurements.

Implementation-Level Diversity (ILD). We created ILD by applying these typical ILD transformations: (1) NOP insertion: after each line of code, insert a pass statement with probability 0.05; (2) instruction reordering: for each two adjacent independent lines of code, swap them with probability 0.5; (3) branch reordering: for each if-statement, swap the branches and negate the condition (if there is no else branch, pretend else: pass is present) with probability 0.5; (4) function (including receive handler) reordering: for each two adjacent independent def statements, swap them with probability 0.5; (5) argument reordering: for each function (excluding run, setup, and receive handlers), swap the first two arguments, swap the third and fourth arguments, etc.; (6) field reordering: reorder the assignment statements that initialize the fields in each class, by swapping the first two, the third and fourth, etc. Applying more complicated implementation-level diversity techniques is future work; it will require significant effort, because existing implementations of those techniques do not handle Python.

Sequential Algorithms

Our experiments use these algorithms for these problems: [START_REF] Avizienis | The N-version approach to fault-tolerant software[END_REF] 1. We see from the last column that, for all three metrics, algorithm diversity creates more diversity than ILD, and that the two together create even more.

Distributed Algorithms

Our experiments use the following algorithms: (1) 2-phase commit (2PC); (2) Hirschberg-Sinclair's leader election (HSleader) [START_REF] Hirschberg | Decentralized extrema-finding in circular configurations of processors[END_REF]; (3) Lamport's distributed mutual exclusion (Lamutex) [START_REF] Lamport | Time, clocks, and the ordering of events in a distributed system[END_REF]; (4) Lamport's basic Paxos [START_REF] Lamport | Paxos made simple[END_REF]; (5) Ricart-Agrawala's distributed mutual exclusion (RAmutex) [START_REF] Ricart | An optimal algorithm for mutual exclusion in computer networks[END_REF]. We used configurations with 3 or 4 processes for each algorithm. There are two variants of each algorithm: one variant that uses high-level queries over message histories, and one that explicitly maintains the result of those queries (and related intermediate results and auxiliary values), updating them in assignment statements, especially in receive handlers.

When measuring the dynamic metrics, we avoid spurious differences between the variants due to the platform's scheduling variability by running all variants in parallel using synchronized execution (for programs other than 2PC, due to a bug that we are still resolving in the interaction between our program transformations for synchronized execution and input access tracing, when measuring input access diversity, we instead avoided such spurious differences by running the variants separately but each with the In the "Level" column, "algo" and "impl" denote algorithm diversity and implementation-level diversity, respectively.

same pattern of injected message delays that are larger than the platform's scheduling variability and designed to avoid races in message delivery order).

The results are in Table 2. We see from the last column that, for all three metrics, algorithm diversity creates significantly more diversity than ILD. The trace diversity produced by ILD is considerably smaller than the input access diversity it creates. These results are not inconsistent, because both are measured as ratios, and input accesses constitute a small fraction of the program's full activity recorded in the bytecode trace. The results for trace diversity for algorithm diversity for distributed algorithms are notably smaller than for sequential algorithms, because the trace includes execution of DistAlgo runtime library for networking, which is not diversified.

Related Work

Existing techniques for automated software diversity, including all those surveyed in [START_REF] Larsen | Sok: Automated software diversity[END_REF], create implementation-level diversity, changing details of the implementation without changing the algorithm. Typically this is done by applying relatively simple local transformations, like those used in our evaluation. There are also some complex global transformations, such as instruction set randomization. These transformations are fully automated and more easily applied to large programs, but they are limited in that they do not create algorithm diversity. For example, they do not change the pattern in which inputs are used by the program.

Most work on automated software diversity for resilience transforms C programs or (disassembled) machine code, for broader applicability to systems code. There is some work on automated diversity for programs in JIT-compiled high-level languages, which diversifies the machine code generated by the JIT compiler. For example, librando does this for Java and JavaScript [START_REF] Homescu | Librando: transparent code randomization for just-in-time compilers[END_REF], and INSeRT does this for JavaScript [START_REF] Wei | INSeRT: Protect dynamic code generation against spraying[END_REF]. This low-level approach is suitable for creating implementation-level diversity. Our methodology diversifies the high-level program directly to create algorithm diversity.

In N-version programming [START_REF] Avizienis | The N-version approach to fault-tolerant software[END_REF], N versions of a system (or component) are created by separate and independent manual design and implementation efforts starting from the same requirements specification, and the versions are run in parallel with synchronized execution. The goal is resilience in the presence of design faults, since independent teams are less likely to make the same design mistakes. Our work, like other work on software diversity, aims to mitigate software vulnerabilities, not design errors. The two techniques could be used together to address both. N-version programming may introduce algorithm diversity, but not in a controlled way, and at the cost of significant manual effort. In contrast, our approach is to create variants using a program transformation and optimization method based on systematic incrementalization, which guides the process, helps control how much diversity is introduced, and helps ensure correctness compared to ad-hoc development of variants. Our program transformation system InvTS [START_REF] Liu | A language and framework for invariant-driven transformations[END_REF][START_REF] Gorbovitski | Composing transformations for instrumentation and optimization[END_REF] provides semi-automated support for the method, significantly reducing manual effort.

Synchronized execution has been widely studied in the fault-tolerance community, where it is often called N-version execution. N-version execution frameworks typically work at the system-call level, so they can be applied to software running on a given operating system, regardless of the application programming language. Our synchronized execution framework is applicable only to applications written in DistAlgo, but it is more portable and lighter weight. It can be used on any OS supported by DistAlgo (Windows, macOS, Linux, and Android), while system-call based approaches are highly OS-specific, e.g., Varan [START_REF] Hosek | Varan the unbelievable: An efficient n-version execution framework[END_REF] and Bunshin [START_REF] Xu | Bunshin: Compositing security mechanisms through diversification[END_REF] are N-version execution frameworks for Ubuntu. It is lighter-weight because a single high-level synchronization event is typically implemented by multiple system calls.

Evaluation of Diversity Techniques

A few approaches are commonly used to evaluate implementation-level diversity techniques. One is to estimate the probability of a successful memory-related exploit (e.g., buffer overflow or format string attack) based on the information about the diversified program that the attacker would need to guess, more specifically, the type of information (e.g., the address of a specific object, or the difference between the addresses of two specific objects) and the number of possible values of that type of information due to the randomization in the diversity transformation. This approach is used in, e.g., [START_REF] Bhatkar | Efficient techniques for comprehensive protection from memory error exploits[END_REF][START_REF] Giuffrida | Enhanced operating system security through efficient and fine-grained address space randomization[END_REF].

Diversity techniques designed specifically to defend against ROP attacks are typically evaluated using a coverage metric that measures the fraction of ROP gadgets relocated by the transformation, and sometimes also an entropy metric that measures the number of possible new positions of the ROP gadgets, reflecting the probability of the attacker correctly guessing the new locations. This approach is used in, e.g., [START_REF] Pappas | Smashing the gadgets: Hindering return-oriented programming using in-place code randomization[END_REF][START_REF] Homescu | Librando: transparent code randomization for just-in-time compilers[END_REF]).

These approaches based on specific vulnerabilities in low-level languages are unsuitable for evaluating diversity for interpreted languages, such as Java and Python.

4 remaining8

 4 await c1: s1 or . . . or c k : s k timeout t: s into 1 start_time = time.time() 2 while not (c1 or ... or c k ): 3 elapsed = time.time() -start_time if c1: s1 9 elif c2: s2 10 . . . 11 elif c k : s k 12 else s If the await statement has no timeout, then lines 1, 3-6, and 12 are omitted, and the second argument of yield_sync is None.

  await cond1 : stmt1 or ... or cond k : stmt k timeout t: stmt It waits until one of cond1 , ..., cond k is true or time t has elapsed, and then nondeterministically selects one of stmt1 , ..., stmt k , stmt whose condition is true and executes the selected statement. Each branch is optional. some v1 in s1 , ..., v k in s k | cond. It returns true iff cond holds for some combination of values of variables that satisfies all vi in si clauses. Universal quantification is similar, with keyword each instead of some.A comprehension has the form {e: v1 in s1 , ..., v k in s k , cond}. It returns the set of values of e for all combinations of values of variables that satisfy all vi in si clauses and condition cond.

	High-Level Queries for Synchronization Conditions. DistAlgo provides constructs
	to express synchronization conditions in await statements as high-level queries over
	message histories (or other sets or sequences). A query can be an existential or univer-
	sal quantification, a comprehension, or an aggregation. An existential quantification
	has the form

  Variable total is computed at set up of s, and responded and number at request, and the following receive handler is added:

	number = total
	receive ('ack', t2, p2):	# new message handler
	if t2 > t:	# comparison in the condition
	if p2 in s:	# membership in the condition
	if p2 not in responded:	# test before adding
	responded.add(p2)	# add to responded
	number +:= 1	# increment number

can be transformed into count {p2: p2 in s, ('ack', t2, p2) in received, t2 > t} = count s and then-with variables responded, number, and total holding the set value and two count values, respectively, forming three invariants-transformed into:

Table 1 .

 1 Experimental results for sequential algorithms. In the "Level" column, "algo" and "impl" denote algorithm and implementation-level diversity, respectively. The last column contains averages.

	graph reachability:

(generated from rules using the method in

[START_REF] Liu | From Datalog rules to efficient programs with time and space guarantees[END_REF]

); (2) Hanoi Tower: original recursive algorithm, optimized recursive algorithm, optimized iterative algorithm, and optimized iterative algorithm with swap; (3) longest common subsequence (LCS): original recursive algorithm, optimized recursive algorithm, and optimized iterative algorithm; (4) pattern searching: naive algorithm, Knuth Morris Pratt (KMP) algorithm, Rabin Karp algorithm; (5) sorting: heap sort, quicksort, insertion sort, and merge sort; (6) tree search: recursive and iterative algorithms for AVL trees, recursive algorithm for B-trees, iterative algorithm for red-black trees, and recursive and iterative algorithms for (unbalanced) binary search trees.

The results are in Table

Table 2 .

 2 Experimental results for distributed algorithms, with 2 variants for each algorithm.

	Metric	Level	2PC	HSleader Lamutex	Paxos RAmutex Average
	Code	algo	0.56	0.66	0.50	0.68	0.53	0.59
	Diversity	impl	0.19	0.18	0.08	0.30	0.27	0.21
		both	0.59	0.68	0.53	0.68	0.54	0.60
	Input Access algo	1.10	0.47	0.21	0.28	0.61	0.53
	Diversity	impl	0.08	0.04	0	0.03	0.17	0.06
		both	1.09	0.52	0.21	0.30	0.61	0.55
	Trace	algo	0.20	0.35	0.13	0.54	0.21	0.29
	Diversity	impl	0.06	0.03	0.02	0.13	0.04	0.06
		both		0.36	0.14	0.52	0.21	0.29

Acknowledgements. This material is based on work supported in part by ONR Grant N00014-15-1-2208, NSF Grants CCF-1414078 and CNS-1421893, and DARPA Contract FA8650-15-C-7561. We thank Thang Bui, Rahul Gadi, Shikhar Sharma, Shalaka Sidmul, Shubham Singhal, and Swetha Tatavarthy for their contributions to the implementation and experiments.


Salvatore Manfredi
email: smanfredi@fbk.eu

Silvio Ranise
email: ranise@fbk.eu

Lost in TLS? No more! Assisted Deployment of Secure TLS Configurations

Keywords: TLS misconfiguration, vulnerability detection, assisted mitigations

Over the last few years, there has been an almost exponential growth of TLS popularity and usage, especially among applications that deal with sensitive data. However, even with this widespread use, TLS remains for many system administrators a complex subject. The main reason is that they do not have the time to understand all the cryptographic algorithms and features used in a TLS suite and their relative weaknesses. For these reasons, many different tools have been developed to verify TLS implementations. However, they usually analyze the TLS configuration and provide a list of possible attacks, without specifying their mitigations. In this paper, we present TLSAssistant, a fully-featured tool that combines state-of-the-art TLS analyzers with a report system that suggests appropriate mitigations and shows the full set of viable attacks.

Introduction

Transport Layer Security (TLS) consists of a set of cryptographic protocols designed to provide secure communications over a network. Developed as a successor of the Secure Socket Layer (SSL) protocol, TLS has gained popularity and widespread usage since the release of its first version in 1999 [START_REF] Group | The TLS Protocol: Version 1[END_REF]. According to [START_REF]SSL Pulse[END_REF], more than 130,000 of the top Alexa websites [START_REF] Services | Alexa Top Sites[END_REF] support one or multiple versions of the TLS protocol.

The popularity of TLS has encouraged attackers to find vulnerabilities and develop exploits as documented by a long line of reported attacks and corresponding fixes [START_REF]Microsoft-Inria: Triple Handshakes Considered Harmful: Breaking and Fixing Authentication over TLS[END_REF][START_REF]IMPERVA: Attacking SSL when using RC4[END_REF][START_REF] Green | A diversion: BEAST Attack on TLS/SSL Encryption[END_REF]33,3,[START_REF] Adrian | Imperfect forward secrecy: How diffie-hellman fails in practice[END_REF][START_REF] Alfardan | Lucky thirteen: Breaking the TLS and DTLS record protocols[END_REF][START_REF] Möller | This POODLE Bites: Exploiting The SSL 3.0 Fallback[END_REF][START_REF] Vanhoef | RC4 NOMORE (Numerous Occurrence MOnitoring & Recovery Exploit[END_REF][START_REF] Bhargavan | Transcript collision attacks: Breaking authentication in tls, IKE and SSH[END_REF][START_REF]SecurityLearn[END_REF][START_REF] Bhargavan | On the practical (in-)security of 64-bit block ciphers: Collision attacks on HTTP over TLS and openvpn[END_REF][START_REF] Smyth | Truncating TLS connections to violate beliefs in web applications[END_REF][START_REF] Gluck | BREACH: reviving the CRIME attack[END_REF] together with the evolution of the standard TLS specification from 1.0 to 1.3 as a result of the strategies put in place by Internet service providers such as Apple, Google, Amazon, and Mozilla to deprecate the use of TLS versions 1.0 and 1.1 [START_REF] Bright | Apple, Google[END_REF] and of the SHA-1 hash function [START_REF] Blog | SHA-1 Certificates in Chrome[END_REF]. The types of attacks vary widely and include the renegotiation of cipher suites to exploit weak encryption algorithms [START_REF]Microsoft-Inria: Triple Handshakes Considered Harmful: Breaking and Fixing Authentication over TLS[END_REF], the knowledge of initialization vectors to retrieve symmetric keys [START_REF] Green | A diversion: BEAST Attack on TLS/SSL Encryption[END_REF], and the use of libraries to exploit poor certificate validation in deployments where clients are non-browsers [START_REF] Georgiev | The most dangerous code in the world: validating ssl certificates in non-browser software[END_REF]. The variety attacks is the result of (i) maintaining backward compatibility and (ii) evolving use case scenarios in which TLS is deployed. The main problem with (i) is illustrated by the following observation from [START_REF]SSL Pulse[END_REF]: more than 108,000 web sites still support TLS 1.0 that is vulnerable to a set of well-known attacks including Man In The Middle (MITM). The problem with (ii) has already been pointed out in [START_REF] Georgiev | The most dangerous code in the world: validating ssl certificates in non-browser software[END_REF] for SSL where it is shown that certificate validation-as supported by available libraries for developing clients not based on browsers (e.g., native mobile applications)-is flawed and permits to mount MITM attacks.

To help administrators in deploying secure TLS instances, a variety of tools [39, [START_REF] Kolybabi | ssl-enum-ciphers[END_REF][START_REF] Siles | TLSSLed v1.3[END_REF][START_REF] Somorovsky | Systematic fuzzing and testing of tls libraries[END_REF][START_REF] Young | TLS Extended Master Secret Extension: Fixing a Hole in TLS[END_REF][START_REF] Wetter | /bin/bash based SSL/TLS tester: testssl[END_REF][START_REF] Fahl | Why eve and mallory love android: An analysis of android ssl (in)security[END_REF][START_REF] Dormann | Announcing CERT Tapioca 2.0 for Network Traffic Analysis[END_REF] have been developed for identifying weaknesses that may lead to one or more known attacks. While such tools are quite effective in automatically finding vulnerabilities and issuing warning about possible attacks, the burden of finding adequate mitigation measures is completely left on the administrator who must first collect information about the identified problem and related fixes. Typically, such information is distributed in several sources ranging from scientific papers to blog posts. Even disregarding the effort to collect enough material to mitigate a security problem-notice that available tools have varying coverage of the known TLS attacks-administrators should have enough skills to understand the (often subtle) details and turn the information in a concrete strategy to fix the problem. In other words, there is a problem in making actionable the reports returned by available tools. To overcome this problem, we make the following four main contributions:

we build an exhaustive catalogue of known attacks to TLS deployments; we perform a comparison of the state-of-the-art tools capable of identifying attacks of TLS deployments and characterize the coverage with respect to the catalogue compiled in the previous point; we design and build an open-source tool, called TLSAssistant3 , that reuses some of the tools for identifying attacks considered in the previous point to maximize coverage and enriches reports with possible mitigations and fixes, including code snippets when the TLS entities are among the most widely used (e.g., the TLS server is Apache); we experimentally evaluate the effectiveness of TLSAssistant by reporting our experience in using it in the context of the deployment of a large scale infrastructure for identity management and, most importantly, in a user study involving users with little or no security skills. The findings of the user study provide encouraging first evidence of the effectiveness of the tool as even un-experienced users were able to successfully mitigate complex attacks.

While many of the problems reported by TLSAssistant are server-side, particular attention has been devoted to the security issues that result from inadequate certificate validation in mobile applications. The main motivation for this choice is the increasing role of mobile applications in accessing Internet resources combined with the serious security consequences of managing certificates without the help of browsers (as already observed in [START_REF] Georgiev | The most dangerous code in the world: validating ssl certificates in non-browser software[END_REF]).

Plan of the paper. Section 2 provides the necessary background notions on TLS and a brief overview of its vulnerabilities. Section 3 contains a comparison of the state-of-the-art automated tools for identifying TLS attacks both server and (mobile) client-side. Section 4 contains a comprehensive catalogue of attacks and related mitigations in the various version of TLS. Section 5 introduces the tool TLSAssistant with its architecture, usage, and some details about the implementation. Section 6 reports the use of TLSAssistant in the deployment of an eIDAS solution based on the new Italian identity cards and a user study involving bachelor and master degree students that were asked to fix two non-trivial vulnerabilities. Section 7 concludes the paper and highlights future work.

Background

We provide some background notions about TLS needed to better understand the security implications of its use. We briefly describe the general structure of the TLS suite and some details in Section 2.1 and then give a concise guide to the main vulnerabilities in Section 2.2.

TLS

The Transport Layer Security (TLS) suite is composed of two main protocols:

Handshake: allows the parties to exchange all information required to establish a reliable session. Depending on the configuration, the handshake can provide either mutual or one-way authentication (usually is one-way, thus only server provides a certificate). The protocol supports two special messages: (i) Change Cipher Spec that signals the transition of the session to a different ciphering strategy and (ii) Alert which propagates potential alert messages. Record: encapsulates the messages to be transmitted to ensure their security.

The record protocol is composed of the following steps: (i) splitting of the data stream into chunks; (ii) compression of the chunks; (iii) generation of the Message Authentication Code (MAC) with the algorithm agreed during the handshake; (iv) encryption of the payload using the cipher chosen during the handshake; and (v) addition of the header to enable the packet to be transmitted.

Over the years, TLS has seen the release of four versions: v1.0 released in 1999 [START_REF] Group | The TLS Protocol: Version 1[END_REF], v1.1 released in 2006 [START_REF] Group | The Transport Layer Security (TLS) Protocol: Version 1[END_REF], v1.2 released in 2008 [START_REF] Group | The Transport Layer Security (TLS) Protocol: Version 1[END_REF], v1.3 released in 2018 (August) [START_REF]IETF: The Transport Layer Security (TLS) Protocol: Version 1[END_REF]. In the following we will detail v1.2, as is the most widely supported, and v1.3, as it has introduced a set of changes to mitigate known vulnerabilities that affected the previous TLS versions. TLS 1.2 According to Qualys' March monthly scan [START_REF]SSL Pulse[END_REF], TLS 1.2 is currently the most widely supported protocol with a coverage of 94.8%. Each message of the full handshake is shown in Fig. 1 (the striped sections show the encrypted transmission, asterisks indicate optional messages). For lack of space, we refer to the TLS specification [START_REF] Group | The Transport Layer Security (TLS) Protocol: Version 1[END_REF] for the description of all the messages. Here, we specify the first two messages: Client Hello and Server Hello. As we will describe in Section 5, our tool analyzer will send different Client Hello messages and analyze the Server Hello answers to check the presence of vulnerabilities. The remaining messages are used to authenticate the parties, calculate the symmetric key and to apply the ciphering strategies.

Client Hello. The client can start the handshake at any time by sending a Client Hello message to the server, it contains: (i) the version of the protocol that the client wants to use (it should be the highest available); (ii) a random value obtained by chaining the timestamp (32 bit in UNIX time) and a randomly generated nonce (28 bytes); (iii) a session identifier: empty field indicating the will to create a new session (in case of session resumption the client behaves differently); (iv) list of supported cipher suites, each element has the following structure: TLS KeyExchange WITH Cipher Mac ; (v) a list of supported compression methods; and (vi) a list of requested extensions (set of additional functionalities the server has to provide).

Server Hello. In response to the Client Hello, the server sends its hello message that contains: (i) a chosen protocol (the highest version supported by both parties); (ii) a random value obtained by chaining the timestamp (32 bit in UNIX time) and a randomly generated nonce (28 bytes); (iii) a freshly-generated value that will identify the new session (in case of session resumption, the server behaves differently); (iv) a chosen cipher suite; (v) a chosen compression method; and (vi) a list of required extensions (additional features). TLS 1.3 After years in the making, the final version of the standard has been published this August, 2018. Table 1 summarizes the key differences with TLS 1.2 according to the RFC [START_REF]IETF: The Transport Layer Security (TLS) Protocol: Version 1[END_REF]. Thanks to these changes, TLS 1.3 is not prone to any of the known attacks such as the ones related to legacy ciphers (e.g., Lucky 13) or broken hash algorithms (e.g., SLOTH).

Vulnerabilities

There exist many TLS-related vulnerabilities: some of them exploit the support of weak cryptographic aspects (e.g., weak ciphers and hash functions), others use an (un)voluntary weakening of security properties to bypass the authentication process (e.g., accepting self-signed certificates [START_REF] Nowsecure | Fully Validate SSL/TLS[END_REF] and setting a permissive hostname verifier [START_REF] Nowsecure | Fully Validate SSL/TLS[END_REF]) or the loss of trust in the PKI system due to a improper certificate generation (e.g., CA impairment [START_REF] Green | The Internet is broken: could we please fix it?[END_REF] and Certificate Spoofing [START_REF] Group | OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens[END_REF]). In Table 2 we detail a set of well-known TLS attacks, each line contains: (i) the name given by the authors; (ii) the feature or weakness exploited; (iii) a brief description on how the attack can be mounted, and (iv) which version of TLS can be affected by such attack. To better understand the described vulnerability exploitation, we review some cryptographic aspects: Export ciphers. Weakened ciphers introduced by the U.S. government to limit the security of foreign countries' transmissions [START_REF] Grimmett | Encryption export controls[END_REF]; Stream ciphers. Symmetric key ciphers in which each digit is encrypted combining it with a pseudorandom cipher [START_REF] Robshaw | Stream ciphers[END_REF]; Block ciphers. Symmetric key ciphers in which a set of bits with a fixed length (called block) is encrypted all at once [START_REF] Shannon | Communication theory of secrecy systems*[END_REF]; Among all the attacks, here we detail the two used in our experimentation (see Section 6.2): CRIME [33] and BREACH [START_REF] Gluck | BREACH: reviving the CRIME attack[END_REF]. Both attacks are related to the availability of DEFLATE [START_REF] Group | Transport Layer Security Protocol Compression Methods[END_REF], a compression algorithm that reduces the size of an input by replacing duplicate strings with a reference to their last occurrence. Given that neither TLS nor HTTP hide the size of each message, an attacker can exploit this information leakage to steal sensitive data. Supposing the will to steal session cookies, the attack is performed by injecting (e.g., using a controlled JavaScript loaded by the victim) different characters into the client's messages trying to guess the cookie. Thanks to DEFLATE, if the guess is wrong and the characters are not part of the cookie, the size of the response will be bigger. On the other hand, if the attacker guessed correctly, the size will remain the same. This attack is referred as CRIME if it exploits the compression within TLS, BREACH otherwise.

Tools Comparison

There are many TLS analyzers on the market and we wanted to understand which one suited better our purposes. For this reason, we decided to compare them to find the one who had the highest amount of features.

Table 3 shows the comparison between six tools that perform server-related TLS vulnerabilities 4 . Each detection is identified depending on the type of information resulting. In particular, G, Q and H mean an explicit, implicit (which can be inferred using other explicit detections) or missing detection, respectively. The evaluated tools are: sslscan [39]: the analyzer is able to detect the full set of available ciphers on a webserver. The default output shows the full list of accepted/rejected connections, detailing each line with the cipher's name, its key length and the used protocol; ssl-enum-ciphers [START_REF] Kolybabi | ssl-enum-ciphers[END_REF]: script developed for the nmap security scanner [START_REF] Lyon | Nmap: the Network Mapper[END_REF] that lists all the available cipher suites, compression methods and a small set of possible misconfigurations. The generated report shows the set of ciphers (available per protocol) with the relative Qualys' rating [START_REF] Qualys | SSL Server Rating Guide[END_REF], a grade which goes from A+ to F depending on the level of provided security;

TLSSLed.sh [START_REF] Siles | TLSSLed v1.3[END_REF]: built on top of an older version of sslscan [39], this script check if the server supports old protocols, weak ciphers and for the certificate signature. The verbose output highlights the results using different colours;

TLS-Attacker [START_REF] Somorovsky | Systematic fuzzing and testing of tls libraries[END_REF]: open source framework for analyzing TLS libraries. It can be fully-customized to perform any kind of connection and contains a set of pre-configured attacks for testing purposes. By running each attack, the user can understand whether or not the server is vulnerable;

3SHAKE checker [START_REF] Young | TLS Extended Master Secret Extension: Fixing a Hole in TLS[END_REF]: is a simple script that checks if the target server supports extended master secret, an extension specifically designed to mitigate the 3SHAKE [START_REF]Microsoft-Inria: Triple Handshakes Considered Harmful: Breaking and Fixing Authentication over TLS[END_REF] attack. The output shows, for each available version of TLS, if the extension request has been accepted; testssl.sh [START_REF] Wetter | /bin/bash based SSL/TLS tester: testssl[END_REF]: is a fully-featured open source command-line tool able to analyze a server's configuration. The tool is mainly focused on detecting weaknesses and various configuration issues while being able to perform a wider set of tests. Among these, testssl.sh is able to list the set of ciphers available per protocol, analyze the chain of trust of a provided certificate, simulate handshakes and much more. These features make testssl.sh the most powerful tool among the evaluated. The generated report contains the results for

G G G G H G AES ciphers Q Q G G H G Weak ciphers Q Q G Q H G SSLv2, Secure renegotia- tion G H G G H G POODLE, CBC-mode ci- pher, 3DES G G H G H G MD5/SHA1-signature alert G G G H H G Sweet32 G Q H Q H G Certificate expiration G H G H H G Weak DH parameters G G H H H G Heartbleed,-TLS- compression G H H G H G BEAST Q H G H H G TLS 1.3, DROWN H H H G H G Qualys scoring H G H H H G More analysis a H H H H H G 3SHAKE H H H H G H
a server's default picks, certificate info, HSTS, HPKP, security headers, cookie, reverse proxy, client simulations, SPDY and HTTP2 availability all the performed analysis, associated with a colour that signals the severity of the detected result.

All the listed tools work by repeatedly connecting to the target server using specifically crafted ClientHello messages. By checking the server's responses (i.e. ServerHello), the tools are able to understand the server's configuration. Besides the amount of provided features, the compared tools have a major limitation: all of them offer little or no explanation on how to actually mitigate the detected weaknesses. This somehow defies their purpose given that a system administrator will still have to spend a lot of time and effort researching the most appropriate set of mitigations to apply.

Mobile clients

As mentioned in the introduction, while in a browser the handle of TLS and its certificates is built-in, this is not the case for mobile native applications: a developer can either choose to use one of the many available TLS libraries or to implement his own methods. In both cases, an incorrect certificate handling may lead to several authentication-related issues. For this reason, there is the need for specific tools.

Table 4 shows the differences between two Android-related analyzers:

Mallodroid [START_REF] Fahl | Why eve and mallory love android: An analysis of android ssl (in)security[END_REF]: Python script (built on top of Androguard [START_REF] Desnos | Github: Androguard[END_REF]) that performs static analysis on the code of an Android application. Taking as input the app installer (.apk), Mallodroid uses the capabilities inherited from Androguard to decompile the application. Once the script acquires the source code, it (i) extracts the set of URLs the app is instructed to connect and checks the validity of their certificates, and (ii) identifies if the app is using an non-standard trust manager and checks the related methods; Tapioca [START_REF] Dormann | Announcing CERT Tapioca 2.0 for Network Traffic Analysis[END_REF]: testing framework that performs a series of unique checks by simulating a MITM. Using different types of packet capture, the tools is able to: (i) validate the negotiation between server and client; (ii) enumerate all the URLs the app tries to connect; (iii) verify if the client correctly validates the received certificates; and (iv) (prior packet decryption) search among the messages to locate known strings.

Mitigations Identification

Given the known vulnerabilities described in Section 2.2, system administrators should identify and follow a set of mitigations. To assist them we have collected in Table 5 the current best practice to mitigate the known vulnerabilities of TLS 1.2. The vast majority of the mitigations is applied by changing some lines in the server's configuration file while the remaining are related to vulnerable/outdated support libraries. The identification of such mitigations is not trivial because the currently available reports (see Appendix B) lack of clear indications on which is the source of misconfiguration.

TLSAssistant

During our study of TLS-related vulnerabilities, we noticed that all the currently available TLS analyzers have two major limitations. Putting aside the amount of provided features, all the examined tools gave little or no explanation on how to actually mitigate the detected weaknesses. On the other hand, every tool focuses on a specific party of the communication (either server or client) thus making its usage only part of a complete analysis. To assist average system administrators and app developers to deploy resilient instances of the TLS protocol we propose TLSAssistant. By bringing together different powerful analyzers, our tool is able to cover a full-range of analysis on all the parties involved in a secure communication and to provide a set of mitigation measures that aim to thwart the impact of the identified vulnerabilities. BREACH [START_REF] Gluck | BREACH: reviving the CRIME attack[END_REF] Ignore self-signed certificates and perform a complete validation (up to the trusted root) Accept-self-signed certs [START_REF] Nowsecure | Fully Validate SSL/TLS[END_REF] Check if the hostname (from the certificate) matches the one related to the transmission Setting a permissive hostname verifier [START_REF] Nowsecure | Fully Validate SSL/TLS[END_REF] Server related TLSAssistantis written in Bash and can thus be invoked via command-line. Among the available parameters, the tool takes as input the target to be evaluated (e.g., the IP address of a server) and outputs a single report file. The content of the report depends on the detected weaknesses and on the level of verbosity the user chose. Being built on top of other works, our TLSAssistant has been designed to be modular and easily upgradable. Fig. 2 shows the architecture with its two main components: Analyzer and Evaluator.

Analyzer. Takes as input a series of parameters depending on which analysis the user wants to run. By design, our tool has a flexible architecture that allows a continuous integration of newer and more sophisticated tools. Currently, the set of integrated tools consists of command-line scripts written either in Bash or Python. At the time of writing, the Analyzer integrates the following tools:

Testssl.sh [START_REF] Wetter | /bin/bash based SSL/TLS tester: testssl[END_REF] chosen among many others (as shown in Section 3) due to the enormous amount of features and for its ongoing development; 3SHAKE checker [START_REF] Young | TLS Extended Master Secret Extension: Fixing a Hole in TLS[END_REF] added to make the Analyzer able to test whether a server is vulnerable to the Triple Handshake Attack or not. This is an example of the continuous integration that has driven the design of TLSAssistant: being able to integrate different analyzers to become a useful toolbox for a complete TLS-vulnerability detection; Mallodroid [START_REF] Fahl | Why eve and mallory love android: An analysis of android ssl (in)security[END_REF] even if less powerful than Tapioca (see Section 3), it was more suitable for our modularity requirement. Indeed, the current version of the installer of Tapioca turns the client machine into a dedicated appliance; a design choice incompatible with our tool.

The integrated tools allow the Analyzer to take as input: (i) a hostname/IP address (optionally specifying the port to scan); (ii) an apk installer or (iii) both of the previous. Once loaded, the module will run each of the tools related to the required scan, collect their reports and transmit them to the Evaluator.

Evaluator. Core of TLSAssistant and our main contribution, it is responsible for the enumeration of the detected vulnerabilities and the generation of the report that will guide the system administrator towards all the mitigations to be applied. It can be seen as two dependent modules:

Vulnerability enumerator collects and analyzes the reports generated by the analyzer. By parsing the inputs, this module is able to compile a list containing the discovered vulnerabilities. Report handler takes the vulnerability list and, in accordance with the system administrators' choice, renders the final output. While TLSAssistant has been developed to be modular, the only available source of information currently available is the Mitigations module. It consists of a shared database containing a list of all the known TLS vulnerabilities with their descriptions and related fixes. The Report handler currently offers three kinds of report, each version provides the content of the previous one and adds more technical details. For every detected weakness, the main information contained in each version of the report is the following: v0 mitigations' description. Is the most basic form of report, it only contains a description of how the related mitigation works; v1 code snippet. Provides a fragment of code that can be copy-pasted into the webserver's configuration to seamlessly fix the weakness. TLSAssistant can detect any webserver but is currently only able to provide snippets for Apache HTTP server. We plan to extend the code coverage to all the most common webservers available on the market; v2 tools' individual reports. In addition to our detailed contribution, this kind of report also provides the full set of individual reports generated by each tool.

Experimental Evaluation

To evaluate TLSAssistant's efficacy, we have analyzed a real use-case scenario involving the Italian eID card (CIE 3.0) [START_REF] Dell'interno | Carta di identitá elettronica[END_REF] (Section 6.1) and conducted a userstudy experimentation involving university students (Section 6.2). These two instances helped us prove that the result of our work is effective both for security experts, who may benefit from an additional support, and for unexperienced users who seamlessly became able to perform complex mitigations without the need for an in-depth knowledge.

6.1 Use-case: CIE 3.0

In a joint collaboration between FBK and IPZS (acronym for "Istituto Poligrafico e Zecca dello Stato") [START_REF] Poligrafico E Zecca | [END_REF], which is the Italian state printing office and mint, we implemented a mobile authentication mechanisms that uses the Italian electronic identity card (CIE 3.0 -Carta d'Identitá Elettronica) [START_REF] Dell'interno | Carta di identitá elettronica[END_REF] to access public administration online services. Being the use of TLS the basic building block of the solution, any unpatched vulnerability (see Section 2.2) may compromise the entire authentication process.

For this reason, we run TLSAssistant targeting a prototype of the infrastructure and found that the deployment (which was entering in the final development stages) was prone to Lucky 13, 3SHAKE and an incorrect certificate handling. These three issues, that can be easily go unnoticed for a variety of reasons, have now been fixed. This example clearly shows how running a tool like TL-SAssistant can help even expert system administrators to determine if a new deployment contains some severe misconfigurations.

User study

The following paragraphs will detail the settings of the experimentation (designed following the template and guidelines by Wohlin et al. [START_REF] Cartwright | Book review: Experimentation in software engineering: An introduction[END_REF]) and a summary of the main results.

Experiment Scoping and Planning As described in Section 5, TLSAssistant is based on the most powerful TLS analyzers available on the market. The main additional feature is the generation of a report that assist the user during the mitigation process: together with the list of vulnerabilities, a textual description of the mitigations and (when is possible) a corresponding code snippet is provided.

The goal of this study is to analyze the effect of providing a set of mitigations with the purpose of evaluating the support offered by TLSAssistant in patching a TLS configuration.

The context of this study consists of: It is important to note that the proposed objects are representative of realistic TLS misconfigurations. To fit the time constraint of our experiment, only one vulnerability is present in each object. The selected objects are comparable in terms of complexity of the operation required to patch the problem.

Subjects
Research Questions and Hypothesis Formulation. In this study, we want to evaluate whether the report provided by TLSAssistant (with textual descriptions of the mitigations and code snippets) facilitates the patching task in terms of time and correctness. Thus, our research questions are:

RQ 1 (on time): does the time spent by a system administrator in patching an error decrease when the tool provides a text description of the mitigation and the corresponding code snippet? RQ 2 (on correctness): does the capabilities of a system administrator in patching an error increase when the tool provides a text description of the mitigation and the corresponding code snippet?

Thus, the null hypothesis can be formulated as follows:

H 01 (on time): providing a text description of the mitigation and the corresponding code snippet does not significantly decrease the time spent by a system administrator to patch the error; H 02 (on correctness): providing a text description together with a code snippet of the mitigation does not significantly increase the capability of a system administrator to patch the error.

Variables Selection. To measure the subject's capability to perform a patching task (vulnerability detected and solved) and the time spent, we asked subjects to run the provided tool, look at the resulting report, and perform the patching task (perform the required operations to patch the misconfiguration).

The main factor of the experiment -that acts as an independent variable -is the presence of the treatment during the execution of the task. In our experiment, we have considered the following alternative treatments:

Treatment 1 (Tr 1 ): TLSAssistant provides as report a list of vulnerabilities plus a textual description of the mitigations and a suggested code snippet to perform the mitigation. Treatment 2 (Tr 2 ): TLSAssistant provides as report the original reports of the tools that are composing the server-related module of the Analyzer (Testssl.sh and 3SHAKE checker).

Experiment Design and Procedure. We adopt a counter-balanced experiment design intended to fit two lab sessions. Subjects are classified into four groups (despite they work alone), each one working in two labs on different objects with different treatments. The design allows for considering different combinations of objects and treatments in different order across labs (see Table 6). Before our experiment, subjects were properly trained with lectures and exercises on TLS. The purpose of training is to make subjects confident about the kind of tasks they are going to perform and the environment they will have available.

The experiment was carried out according to the following procedure. Subjects had to:

1. complete a pre-experiment survey questionnaire; 2. for each of the two labs to be performed: (i) mark the start time; (ii) perform the patching task; and (iii) mark the stop time; 3. complete a post-experiment survey questionnaire.

Post-experiment survey questionnaire (reported in Appendix A) deals with object clarity of the tasks, cognitive effects of the treatments on the behaviour of the subjects and perceived usefulness of TLSAssistant.

Results. The amount of time required to correctly patch a vulnerability is significantly longer when working with the report provided in Tr 2 than when working with the report with the mitigations (Tr 1 ): 25 minutes on average to fix a vulnerability with Tr 2 , 7 minutes on average to fix a vulnerability with Tr 1 . Thus, hypothesis H 01 on time can be rejected. Therefore, we can formulate the following alternative hypothesis: H A1 : providing a text description of the mitigation and the corresponding code snippet decreases the time spent by a system administrator to patch the error.

Regarding the task correctness all students were able to correctly patch the vulnerability with Tr 1 ; however, just the 68.75% of students was able to perform a proper vulnerability patch with Tr 2 , which corresponds to a 31.25% difference on the overall sampled population. For this reason, we can accept the following alternative hypothesis: H A2 : providing a text description together with a code snippet of the mitigation increases the capability of a system administrator to patch the error.

Moreover, from the post-experiment survey we can learned that the 81.25% of the students considers Tr 1 more useful and the 93.25% assessed that Tr 2 is more complex to understand. In addition, all the students positively recommend our tool. Here we report some comments: "Fast, correct and easy to use. It found the vulnerability and helped me solving it" "It would be very easy to fix such vulnerabilities following the given instructions. Also, you can search for more info about the vulnerability itself, which can help you to learn more about TLS." "I won't waste a lot of time looking for all vulnerabilities" 7 Conclusions and Future Work

To assist system administrators with limited security skills to deploy resilient instances of the TLS protocol suite we propose TLSAssistant, a fully-featured tool that combines state-of-the-art tools with a report system that provides appropriate mitigations.

To design this tool, we have: (i) compared the state-of-the-art tools for TLS analysis, (ii) classified known TLS vulnerabilities and (iii) identified their mitigations. Finally, to validate the efficacy of our tool, we performed a user-study experimentation involving university students and analyzed a real use-case scenario involving the Italian eID card (CIE 3.0) [START_REF] Dell'interno | Carta di identitá elettronica[END_REF].

As future work, we plan to extend TLSAssistant 's capabilities by (i) improving the webserver coverage; (ii) supporting more inputs (e.g., configuration files); (iii) automatize the mitigation process and further analyze experimentation's results by using statistical test, including co-factor analysis such as subject's experience, learning across tasks and more. As a second objective, we plan to use TLSAssistant to increase awareness and education in cybersecurity. A step in this direction is being made by integrating CVE identifiers, CVSS scores and modelling a series of attack trees [START_REF] Schneier | Attack Trees[END_REF], a hierarchical representation on how each attack can be mounted and which security properties it violates. Finally, we also plan to make TLSAssistant's source code freely available for anyone who wants to contribute to this project.

A Post-questionnaire

The following table shows the content of the post-experiment survey questionnaire mentioned in Section 6.2. It deals with object clarity of the tasks, cognitive effects of the treatments on the behaviour of the subjects and perceived usefulness of TLSAssistant. The first set of questions (Q1-Q6) needs to be answered twice (one answer for each performed lab) while the remaining set only needs to be answered once as it refers to the overall session.

ID Applies to Question

Q1 Each lab I had enough time to perform the tasks. (1-5). Q2 Each lab I experienced no difficulty in patching the vulnerability given the report. (1-5). Q3 Each lab How much time (in terms of percentage) did you spend looking at the TLS configuration code? (0, < 20%, ≥ 20% and < 40%, ≥ 40% and < 60%, ≥ 60% and < 80%, ≥ 80%) Q4 Each lab How much time (in terms of percentage) did you spend looking at online documentation on TLS vulnerabilities? (0, < 20%, ≥ 20% and < 40%, ≥ 40% and < 60%, ≥ 60% and < 80%, ≥ 80%) Q5 Each lab Provide some examples of online queries you used to search the vulnerabilities online (e.g., keywords used). Q6 Each lab Which steps did you take to perform the tasks? (e.g., run command Y, opened file X, ..).

Q7

Overall Which report did you find more useful. (Report of Lab 1-2) Q8

Overall Which report did you find more easy to read. (Report of Lab 1-2) Q9

Overall Which report did you find more complex to understand. (Report of Lab 1-2) Q10 Overall The textual description of the mitigation is useful to complete the tasks. (1-5). Q11 Overall The code snippet is useful to complete the tasks.

B Report snippet

To show the effort required by a system administrator in identifying the required mitigation, we show a snippet of the testssl's report (see Fig. 3). It contains the list of checked vulnerabilities matched with their presence in the analyzed TLS deployment. The status of each vulnerability is shown with a combination of a string (e.g.; "potentially vulnerable") and a color that represents the severity of the finding. Not the shown snippet nor any other part of the report give any useful insight on how to actually mitigate the detected vulnerabilities.

Fig. 1 .

 1 Fig. 1. TLS 1.2 Full Handshake.

  Fig. 2. TLSAssistant architecture

  (1-5). Q12 Overall How did you use the code snippet? (Copy-pasted where needed, Typed manually where needed, Used to perform a web search) Q13 Overall Would you use TLSAssistant for your work? (Yes, No, Maybe) Q14 Overall Motivate your answer (to the previous question). (open question) Q15 Overall Do you know any tool that performs similar tasks? (open question) Q16 Overall Do you have any suggestion related to the tool usage? (open question) Q17 Overall Do you have any suggestion related to the amount of information provided by TLSAssistant's report? (open question)

Fig. 3 .

 3 Fig. 3. testssl report snippet

Table 1 .

 1 Main differences introduced with TLS 1.3

	Status What	Why
	Removed not-AEAD ciphers	avoid attacks on legacy ciphers
		RSA key exchange	always provide forward secrecy
		broken hash algorithms (MD5, SHA-1) avoid SLOTH and similar attacks
		Change Cipher Spec message	streamline the handshake
		data compression	avoid CRIME attack
		session renegotiation	avoid renegotiation attacks
	Added	0-RTT mode for a quick resumption	increase resumption speed
		EncryptedExtensions msg	avoid transmitting preferences in
			plaintext
	Changed msg encryption starts after the	allow Client certificate encryption
		Server Hello
		Hello content (structure unchanged)	extend Handshake capabilities

Table 2 .

 2 Known TLS Attacks. TLS feature used to reduce the amount of data sent through the network[START_REF] Group | Transport Layer Security Protocol Compression Methods[END_REF]; Hash functions. Function that takes as input data of arbitrary size and produces as output a string with fixed length[START_REF] Weisstein | Hash Function[END_REF]; Renegotiation. TLS feature used to enhance the security of an already established session without dropping the current connection[START_REF]IETF: Transport Layer Security (TLS) Renegotiation Indication Extension[END_REF]; Termination protocol. Exchange of alert messages which signals the end of the message sending [21, §7.2.1].

	Name	Vulnerability	Attack			Affects
	3SHAKE [31] Renegotiation feature	Completing three handshakes	ANY
			with incorrectly placed certifi-
			cates
	Bar-Mitzvah	RC4 steam cipher	Extracting weak keys by targeting	ANY
	[28]		the first 100 bytes of the cipher-
			text
	BEAST [17]	Initialization vector in ci-	Guessing the plaintext to retrieve	TLS 1.0
		pher block chain	the symmetric key
	CRIME [33]	TLS header compression	Continuously requesting data	ANY
		mechanism (DEFLATE)	from the server in order to
			decrypt the session cookies
			(inferring the encryption)
	DROWN [3, 36] SSLv2 weakness due to	Decrypting intercepted TLS con-	SSLv2
		the use of export ciphers	nections by connecting to an
			SSLv2 server that uses the same
			private key
	Logjam [1, 18] Weakness of export cipher	Negotiating the use of weak cipher	TLS 1.1
		suites	suites (DHE EXPORT)
	Lucky 13 [2, 12] CBC-mode weakness due	Replacing the last bytes with	ANY
		to HMAC-SHA1 decryp-	chosen bytes and monitoring the
		tion failure information	transmission time
		leakage
	POODLE [32] SSLv3 weakness due to	Downgrading to SSLv3 and guess-	SSLv3
		the missing validation of	ing the padding in order to slowly
		padding bytes	recover plaintext
	RC4	Bias in the generation of	Statistically	analyzing	the	ANY
	NOMORE [48]	the "random" keys of the	Fluhrer-McGrew biases
		RC4 stream cipher
	SLOTH [4, 13] Availability of weak hash	Requesting a RSA-MD5 certifi-	TLS 1.2
		functions	cate signature and looking for col-
			lisions
	Reneg. [42]	Renegotiation feature	Blocking the handshake process of	ANY
			the victim and use it to complete
			the attacker's transaction
	Sweet32 [5]	64-bit block ciphers	Mounting a birthday attack which	TLS 1.2
			creates collisions
	Truncation [46] Server incorrect handling	Keeping the victim's session alive	ANY
		of the TLS termination	(by blocking the logout request
		mode through multiple	sent to the server)
		connections
	BREACH [16] HTTP compression mech-	Requesting data from the server in
		anism	order to guess the response body
			(note: without downgrading the
			SSL/TLS connection)

ANY

Compression mechanism.

Table 3 .

 3 Tool Comparison -Server.

	Checks	sslscan sslenum TLSSLed TLS-atk 3Shake chk testssl
	SSLv3, TLS 1.0, 1.1 and
	1.2, RC4

Table 4 .

 4 Tool Comparison -Mobile clients.

	Checks

Table 5 .

 5 List of Mitigations for TLS 1.2.

	Mitigation	Attack
	Disable renegotiation	3SHAKE [31]
		Renegotiation attack [42]
	Enable the use of extended master secret TLS extension 3SHAKE [31]
	Disable RC4	Bar Mitzvah [28]
		RC4 NOMORE [48]
	Disable the compression mechanism	CRIME [33]
	Disable SSLv2	DROWN [3]
	Use AEAD ciphers	Lucky 13 [2]
	Disable SSLv3	POODLE [32]
	Disable RSA-MD5 certificate signature	SLOTH [4]
	Enforce AES usage (and disable 3DES when possible)	Sweet32 [5]
	Enforce the termination mode	TLS Truncation [46]
	Disable HTTP compression (may slow down the transmis-
	sion)

Table 6 .

 6 Labs.

		Group A	Group B	Group C	Group D
	Lab 1	O1 with Tr1	O2 with Tr2	O2 with Tr1	O1 with Tr2
	Lab 2	O2 with Tr2	O1 with Tr1	O1 with Tr2	O2 with Tr1

Table 7 .

 7 Post-experiment survey questionnaire.

Available at sites.google.com/fbk.eu/tlsassistant

Given the need for modularity, we focused on local analyzers rather than their online counterparts.

Acknowledgments

The authors would like to thank IPZS for the collaboration on the development of the authentication solution based on the CIE 3.0 carried out in the context of the joint laboratory DigimatLab between FBK and IPZS.