






Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Material Type: Lab; Class: Object-Oriented Programming and Data Structures; Subject: Computer Science; University: Cornell University; Term: Spring 1998;
Typology: Lab Reports
1 / 12
This page cannot be seen from the preview
Don't miss anything!







[email protected] [email protected]
Current implementations of Java make security decisions by searching the runtime call stack. These systems have attractive security properties, but they have been criticized as being dependent on specific artifacts of the Java imple- mentation. This paper models the stack inspection algorithm in terms of a well-understood logic for access control and demonstrates how stack inspection is a useful tool for ex- pressing and managing complex trust relationships. We show that an access control decision based on stack in- spection corresponds to the construction of a proof in the logic, and we present an efficient decision procedure for generating these proofs. By examining the decision procedure, we demonstrate that many statements in the logic are equivalent and can thus be expressed in a simpler form. We show that there are a finite number of such statements, allowing us to rep- resent the security state of the system as a pushdown au- tomaton. We also show that this automaton may be em- bedded in Java by rewriting all Java classes to pass an ad- ditional argument when a procedure is invoked. We call this security-passing style and describe its benefits over previous stack inspection systems. Finally, we show how the logic allows us to describe a straightforward design for extending stack inspection across remote procedure calls.
The Java language [7] and virtual machine [11] are now being used in a wide variety of applications: Web
Copyright 1998 IEEE. Published in the Proceedings of S&P’98, 3-6 May 1998 in Oakland, California. Personal use of this material is permitted. However, permission to reprint/republish this material for ad- vertising or promotional purposes or for creating new collective works for resale or redistribution to servers or lists, or to reuse any copyrighted component of this work in other works, must be obtained from the IEEE. Contact: Manager, Copyrights and Permissions / IEEE Service Center / 445 Hoes Lane / P.O. Box 1331 / Piscataway, NJ 08855-1331, USA. Telephone: + Intl. 908-562-3966.
browsers and servers, multi-user chat systems (MUDs), agent systems, commerce applications, smart cards, and more. Some systems use Java simply as a better pro- gramming language, using Java’s type-safety to prevent a host of bugs endemic to C programming. In other sys- tems, Java is also being relied upon for access control. Java’s promise, from its initial debut in the HotJava Web browser, has been to allow mutually untrusting code mod- ules to co-exist in the same virtual machine in a secure and controllable manner. While there have been several secu- rity problems along the way [4, 13], the security of Java implementations is improving and Java has continued to grow in popularity. To implement a Java application that runs untrusted code within itself (such as the HotJava Web browser), the Java system libraries need a way to distinguish between calls originating from untrusted code, which should be re- stricted, and calls originating from the application itself, which should be allowed to proceed (subject to any access controls applied by the underlying operating system). To solve this problem, the Java runtime system exports an interface to allow security-checking code to examine the runtime stack for frames executing untrusted code, and al- lows security decisions to be made at runtime based on the state of the stack. While a number of other techniques may be used to achieve the same goals as stack inspection [21], stack in- spection has proven to be quite attractive and has been adopted by all the major Java vendors [15, 6, 14] to meet their need to provide more flexible security policies than the rigid “sandbox” policy, which restricted all non-local code to the same set of privileges. Stack inspection is also a useful technique to allow highly-trusted code to operate with less than its full privileges, which can help prevent common program bugs from becoming security holes. Stack inspection has been criticized for its implementation-specific and seemingly ad-hoc defi- nition, which restricts the flexibility of an optimizing compiler and hinders its applicability to other languages. To address these concerns, we will present a model of
stack inspection using a belief logic designed by Abadi, Burrows, Lampson, and Plotkin [1] (hereafter, ABLP logic) to reason about access control. Using this logic, we will derive an alternate technique for implementing stack inspection which is applicable to Java and other languages. Our procedure applies to remote procedure calls as well as local ones. This paper is organized as follows. Section 2 begins by reviewing Java’s stack inspection model. Next, Sec- tion 3 explains the subset of ABLP logic we use. Sec- tion 4 shows the mapping from stack inspection to ABLP logic and discusses their equivalence. Section 5 presents a high-performance and portable procedure to implement stack inspection. Finally, Section 6 considers remote pro- cedure calls and shows how stack inspection helps to ad- dress remote procedure call security. The appendices list the axioms of ABLP logic used in this paper, and present proofs of our theorems.
This section describes Java’s current stack inspection mechanism 1. Variations on this approach are taken by Netscape’s Communicator 4.0 [15], Microsoft’s In- ternet Explorer 4.0 [14], and Sun’s Java Development Kit 1.2 [6]. Stack inspection has a number of useful security prop- erties [21] but very little prior art. In some ways, it resem- bles dynamic variables (where free variables are resolved from the caller’s environment rather than from the envi- ronment in which the function is defined), as used in early versions of LISP [12]. In other ways, it resembles the no- tion of effective user ID in Unix, where the current ID is either inherited from the calling process or set to the exe- cutable’s owner through an explicit setuid bit.
Java’s security depends fundamentally on the type safety of the Java language. Type safety guarantees that a pro- gram may not treat pointers as integers and vice versa and likewise may not exceed the allocated size of an ar- ray. This prevents arbitrary access to memory and makes it possible for a software module to encapsulate its state: to declare that some of its variables and procedures may not be accessed by code outside itself. By allowing ac- cess only through a few carefully written entry points, a module can apply access control checks to all attempts to access its state. For example, the Java virtual machine protects access to operating system calls in this way. Only the virtual
(^1) This approach is sometimes incorrectly referred to as “capability- based security” in vendor literature.
machine may directly make a system call, and other code must call into the virtual machine through explicit entry points which implement security checks.
To explain how stack inspection works, we will first con- sider a simplified model of stack inspection. In this model, the only principals are “system” and “untrusted”. Like- wise, the only privilege available is “full.” This model resembles the stack inspection system used internally in Netscape Navigator 3.0 [17]. In this model, every stack frame is labeled with a princi- pal (“system” if the frame is executing code that is part of the virtual machine or its built-in libraries, and “untrusted” otherwise), and contains a privilege flag which may be set by a system class which chooses to “enable its privileges,” explicitly stating that it wants to do something dangerous. An untrusted class cannot set its privilege flag. When a stack frame exits, its privilege flag (if any) automatically disappears. All procedures about to perform a dangerous operation such as accessing the file system or network first apply a stack inspection algorithm to decide whether access is al- lowed. The stack inspection algorithm searches the frames on the caller’s stack in sequence, from newest to oldest. The search terminates, allowing access, upon finding a stack frame with a privilege flag. The search also termi- nates, forbidding access and throwing an exception, upon finding an untrusted stack frame (which could never have gotten a privilege flag).
The stack inspection algorithm used in current Java sys- tems can be thought of as a generalization of the simple stack inspection model described above. Rather than hav- ing only “system” and “untrusted” principals, many prin- cipals may exist. Likewise, rather than having only “full” privileges, a number of more specific privileges are de- fined, so different principals may have different degrees of access to the system. Four fundamental primitives are necessary to use stack inspection:^2
enablePrivilege()
disablePrivilege()
checkPrivilege()
revertPrivilege() (^2) Each Java vendor has different syntax for these primitives. This paper follows the Netscape syntax.
saying both A says s and B says s.
Quotation allows a principal to make a statement about what another principal says. The notation A j B says s , which we pronounce “A quoting B says s,” is equivalent to A says ( B says s ). As with any statement, we must consider whether A ’s utterance might be incorrect, and our degree of faith in s will depend on our beliefs about A and B. When A quotes B , we have no guarantee that B ever actually said any- thing.
We grant authority to a principal by allowing that principal to speak for another principal who has power to do something. The statement A ) B , pro- nounced “A speaks for B,” means that if A makes a statement, we can assume that B supports the same statement. If A ) B , then A has at least as much au- thority as B. Note that the )-operator can be used to represent group membership: if P is a member of the group G , we can say P ) G , meaning that P can exercise the rights granted to G.
Appendix A gives a full list of the axioms of the logic. This is a subset of the ABLP logic: we omit some of the operators defined by ABLP since we do not need them.
We will now describe a mapping from the stack, the priv- ilege calls, and the stack inspection algorithm into ABLP logic.
In Java, code is digitally signed with a private key, then shipped to the virtual machine where it will run. If KSigner is the public key of Signer , the public-key infrastructure can generate a proof^3 of the statement
KSigner ) Signer. (1)
Signer ’s digital signature on the code Code is interpreted as
KSigner says Code ) K (^) Signer. (2)
Using equations 1 and 18, this implies that
Code ) Signer : (3) (^3) Throughout this paper we assume that sound cryptographic proto- cols are used, and we ignore the extremely unlikely possibility that an adversary will successfully guess a private key.
When Code is invoked, it generates a stack frame Frame. The virtual machine assumes that the frame speaks for the code it is executing:
Frame ) Code : (4)
The transitivity of ) (which can be derived from equa- tion 17) then implies
Frame ) Signer : (5)
We define Φ to be the set of all such valid Frame ) Signer statements. We call Φ the frame credentials. Note also that code can be signed by more than one principal. In this case, the code and its stack frames speak for all of the signers. To simplify the discussion, all of our examples will use single signers, but the theory supports multiple signers without any extra difficulty.
Recall that the resources we wish to protect are called tar- gets. For each target, we create a dummy principal whose name is identical to that of the target. These dummy prin- cipals do not make any statements themselves, but various principals may speak for them. For each target T , the statement Ok ( T ) means that access to T should be allowed in the present context. The axiom
8 T 2 Targets ; ( T says Ok ( T )) Ok ( T ) (6)
says that T can allow access to itself. Many targets are defined in relation to services offered by the operating system underlying the Java Virtual Ma- chine (JVM). From the operating system’s point of view, the JVM is a single process and all system calls coming from the JVM are performed under the authority of the JVM’s principal (often the user running the JVM). The JVM’s responsibility, then, is to allow a system call only when there is justification for issuing that system call un- der the JVM’s authority. Our model will support this in- tuition by requiring the JVM to prove in ABLP logic that each system call has been authorized by a suitable princi- pal.
We use a standard access matrix [10] to keep track of which principals have permission to access which targets.
of statements of the form P ) T where P is a principal and
the access credentials for the virtual machine VM.
Figure 2: Example of interaction between stack frames. Each rectangle represents a stack frame. Each stack frame is labeled with its name. In this example, each stack frame makes one enablePrivilege() or disablePrivilege() call, which is also written inside the rectangle. Below each frame is written its belief set after its call to enablePrivilege() or disablePrivilege().
When a Java program is executing, we treat each stack frame as a principal. At any point in time, a stack frame F has a set of statements that it believes. We refer to this as
the beliefs come from.
4.4.1 Starting a Program
When a program starts, we need to set the belief set of the
Targets g. These correspond to Netscape’s initial unprivi- leged state and Sun and Microsoft’s initial privileged state.
4.4.2 Enabling Privileges
If a stack frame F calls enablePrivilege( T ) for some target T , it is really saying it authorizes access to the target. We can represent this simply by adding Ok ( T )
4.4.3 Calling a Procedure
When a stack frame F makes a procedure call, this creates a new stack frame G. As a side-effect of the creation of G , F tells G all of F ’s beliefs. When F tells G a statement S ,
4.4.4 Disabling and Reverting Privileges
A stack frame can also choose to disable some of its priv- ileges. The call disablePrivilege( T ) asks to dis- able any privilege to access the target T. This is imple- mented by giving the frame a new belief set which con- sists of the old belief set with all statements in which anyone says Ok ( T ) removed. revertPrivilege() is handled in a similar manner, by giving the frame a new belief set that is equal to the belief set it originally had. While our treatment of disablePrivilege() and revertPrivilege() is a bit inelegant, it seems to be the best we can do.
4.4.5 Example
Figure 2 shows an example of these rules in ac-
enablePrivilege( T 1 ), which adds the statement
When F 2 is created, F 1 tells it Ok ( T 1 ), so
and F 2 says Ok ( T 2 ). When F 3 calls disablePrivilege( T 2 ), the latter belief is deleted
When F 4 calls enablePrivilege( T 2 ), this adds
Before making a system call or otherwise invoking a dangerous operation, the Java virtual machine calls checkPrivilege() to make sure that the requested operation is authorized. checkPrivilege( T ) re- turns true if the statement Ok ( T ) can be derived from Φ,
checkPrivilege()). We define VM(F) to be the virtual machine in which a given frame F is running. Next, we can define
The goal of checkPrivilege( T ) is to determine,
While such questions are generally undecidable in ABLP logic, there is an efficient decision procedure that gives the correct answer for our subset of the logic. checkPrivilege() implements that decision proce- dure. The decision procedure used by checkPrivilege() takes, as arguments, an en-
three classes.
4.6.4 Optimization: Frame Credentials
Java implementations do not treat stack frames or their code as separate principals. Instead, they only track the public key which signed the code and call this the frame’s principal. As we saw in section 4.1, for any stack frame, we can prove the stack frame speaks for the public key which signed the code. In practice, neither the stack frame nor the code speaks for any principal except the public key. Likewise, access control policies are represented di- rectly in terms of the public keys, so there is no need to separately track the principal for which the public key speaks. As a result, the Java implementations say the prin- cipal of any given stack frame is exactly the public key which signed that frame’s code. This means that Java im- plementations do not have an internal notion of the frame credentials used here.
In addition to improving our understanding of stack in- spection, our model and decision procedure can help us find more efficient implementations of stack inspection. We improve the performance in two ways. First, we show that the evolution of belief sets can be represented by a finite pushdown automaton; this opens up a variety of ef- ficient implementation techniques. Second, we describe security-passing style , an efficient and convenient integra- tion of the pushdown automaton with the state of the pro- gram.
We can simplify the representation of belief sets by mak- ing two observations about our decision procedure.
Both observations are easily proven, since they follow di- rectly from the structure of the decision procedure. It follows that without affecting the result of the deci- sion procedure we can rewrite each belief into a canoni- cal form in which each atomic principal appears at most once, and the atomic principals appear in some canonical order. After rewriting the beliefs into canonical form, we can discard any duplicate beliefs from the belief set. Since the set of principals is finite, and the set of targets is finite, and no principal or target may be mentioned more than once in a canonical-form belief, there is a finite set of
possible canonical-form beliefs. It follows by a simple ar- gument that only a finite number of canonical-form belief sets may exist. We can therefore represent the evolution of a stack frame’s belief set by a finite automaton. Since stack frames are created and destroyed in LIFO or- der, the execution of a thread can be represented by a finite pushdown automaton, where calling a procedure corresponds to a push operation (and a state transition), returning from a procedure corre- sponds to a pop operation, and enablePrivilege(), disablePrivilege() and revertPrivilege() correspond to state transitions^4. Representing the system as an automaton has several advantages. It allows us to use analysis tools such as model checkers to derive properties of particular policies. It also admits a variety of efficient implementation tech- niques such as lazy construction of the state set and the use of advanced data structures.
The implementation discussed thus far has the disadvan- tage that security state is tracked separately from the rest of the program’s state. This means that there are two subsystems (the security subsystem and the code execu- tion subsystem) with separate semantics and separate im- plementations of pushdown stacks coexisting in the same Java Virtual Machine (JVM). We can improve this situa- tion by implementing the security mechanisms in terms of the existing JVM mechanisms. We do this by adding an extra, implicit argument to every procedure. The extra argument encodes the secu- rity state (the finite-state representation of the belief set) of the procedure’s stack frame. This eliminates the need to have a separate pushdown stack for security states. We dub this approach security-passing style , by analogy to continuation-passing style [18], a transformation tech- nique used by some compilers that also replaces an ex- plicit pushdown stack with implicitly-passed procedure arguments. We note that security-passing style can be implemented by rewriting code as it is being loaded into the system, to add the extra parameter to all procedures and proce- dure calls, and to rewrite the privilege-manipulation op- erations into equivalent operations on the security state. This is straightforward to implement for Java bytecode, since the bytecode format contains enough information to make rewriting possible. (^4) One more nicety is required. To implement revertPrivilege(), we need to remember what the security state was when each stack frame was created. We can encode this information in the finite state, or we can store it on the stack by doing another push operation on procedure call.
The main advantage of security-passing style is that once a program has been rewritten, it no longer needs any special security functionality from the JVM. The rewritten program consists of ordinary Java bytecode, which can be executed by any JVM, even one that knows nothing about stack inspection. This has many advantages, including portability and efficiency. The main performance benefit is that the JVM can use standard compiler optimizations such as dead-code elimination and constant propagation to remove unused security tracking code, or inlining and tail-recursion elimination to reduce procedure call over- head. Another advantage of security-passing style is that it lets us express the stack inspection model within the exist- ing semantics of the Java language, rather than requiring an additional and possibly incompatible definition for the semantics of the security mechanisms. Security-passing style also lets us more easily transplant the stack inspec- tion idea into other language and systems. We are currently implementing security-passing style by rewriting bytecode at load time using the JOIE [3] tool. The rewriter is a trusted module which we add to the JVM. A full description of security-passing style and its implications for programming language implementations will appear in a future paper.
Another advantage of security-passing style is that it sug- gests an implementation strategy for remote procedure call (RPC) security. Though a simple translation of security-passing style into the RPC case does not work, security-passing style with a few modifications works well for RPCs. RPC security has received a good deal of attention in the literature. The two prevailing styles of security are ca- pabilities and access control lists [19, 5, 8, 16, 20]. Most of these systems support only simple principals. Even in systems that support more complex principals [22], the mechanisms to express those principals are relatively un- wieldy. This section discusses how to extend the Java stack in- spection model across RPCs. One of the principal uses for ABLP logic is in reasoning about access control in dis- tributed systems, and we use the customary ABLP model of network communication to derive a straightforward ex- tension of our model to the case of RPC.
When two machines establish an encrypted channel be- tween them, each machine proves that it knows a specific private key which corresponds to a well-known public key.
When one side sends a message through the encrypted channel, we model this (following [1] and [22]) as a state- ment made by the sender’s session key: we write K says s , where K is the sender’s session key and s is the statement. As discussed in section 4.1, the public-key infrastructure and the session key establishment protocol together let us establish that K speaks for the principal that sent the mes- sage. In order to extend Java stack inspection to RPCs, each RPC call must transmit the belief set of the RPC caller to the RPC callee. Since each of the caller’s beliefs is sent through a channel established by the caller’s virtual ma- chine, a belief B of the caller’s frame arrives on the callee side as K (^) CVM says B , where KCVM is a cryptographic key that speaks for the caller’s virtual machine. The stack frame that executes the RPC on the callee is given an ini- tial belief set consisting of all of these arriving statements. Note that this framework supports the intuition that a remote caller should not be allowed to access resources unless that caller’s virtual machine is trustworthy. All of the beliefs transmitted across the network arrive as state- ments of the caller’s virtual machine (or more properly, of its key); the callee will disbelieve these statements unless it trusts the caller’s virtual machine. This strategy fits together well with security-passing style. We can think of the transmitted belief set as a rep- resentation of the caller’s security state: to pass a secu- rity state across the net we translate it into a belief set in canonical form; on arrival at the destination we translate it back into a security state. There is one more issue to deal with. The RPC caller’s belief set is expressed in terms of the caller’s stack frames; though these are the “correct” beliefs of the caller, they are not useful to the callee, since the callee does not know about caller-side stack frames. To address this issue, be- fore the caller sends a belief across the network, the caller replaces each stack-frame principal F (^) i with an encryption- key principal Ki such that F (^) i ) Ki. Ki can be the key that signed Fi ’s code. If F (^) i was running unsigned code, then F (^) i is powerless anyway so beliefs regarding its statements can safely be discarded. Figure 3 presents an example of how this would work. The Java stack inspection algorithm executes on the callee’s machine when an access control decision must be made, exactly as in the local case.
An interesting question is what an attacker can accomplish by sending false or misleading statements across a chan- nel. If the caller’s virtual machine is malicious, it may send whatever “beliefs” it wants, provided that they have the correct format. Regardless of the beliefs sent, each be- lief arrives at the callee as a statement made by the caller’s
ming Languages and Systems 15 , 4 (Sept. 1993), 706–734.
[2] B IRRELL , A. D., N ELSON , G., O WICKI , S., AND W OBBER , E. P. Network objects. Software: Prac- tice and Experience S4 , 25 (Dec. 1995), 87–130.
[3] C OHEN , G., C HASE , J., AND K AMINSKY, D. Au- tomatic program transformation with JOIE. In Proc. 1998 Usenix Technical Symposium (June 1998). To appear.
[4] D EAN , D., F ELTEN , E. W., AND WALLACH , D. S. Java security: From HotJava to Netscape and be- yond. In Proceedings of the 1996 IEEE Symposium on Security and Privacy (Oakland, California, May 1996), pp. 190–200.
[5] G ONG , L. A secure identity-based capability sys- tem. In Proceedings of the 1989 IEEE Symposium on Security and Privacy (Oakland, California, May 1989), pp. 56–63.
[6] G ONG , L., AND S CHEMERS , R. Implementing pro- tection domains in the Java Development Kit 1.2. In The Internet Society Symposium on Network and Distributed System Security (San Diego, California, Mar. 1998), Internet Society.
[7] G OSLING , J., J OY, B., AND S TEELE , G. The Java Language Specification. Addison-Wesley, Reading, Massachusetts, 1996.
[8] H U , W. DCE Security Programming. O’Reilly & Associates, Inc., Sebastopol, California, July 1995.
[9] L AMPSON , B., A BADI , M., B URROWS , M., AND W OBBER , E. Authentication in distributed systems: Theory and practice. ACM Transactions on Com- puter Systems 10 , 4 (Nov. 1992), 265–310.
[10] L AMPSON , B. W. Protection. In Proceedings of the Fifth Princeton Symposium on Information Sciences and Systems (Princeton University, Mar. 1971), pp. 437–443. Reprinted in Operating Systems Review , 8 1 (Jan. 1974), pp. 18–24.
[11] L INDHOLM , T., AND Y ELLIN , F. The Java Virtual Machine Specification. Addison-Wesley, Reading, Massachusetts, 1996.
[12] M C C ARTHY, J., A BRAHAMS , P. W., E DWARDS , D. J., H ART, T. P., AND L EVIN , M. I. LISP 1.5 Programmer’s Manual , 2nd ed. The Computa- tion Center and Research Laboratory of Electronics, Massachusetts Institute of Technology, Cambridge, Massachusetts, 1962.
[13] M C G RAW, G., AND F ELTEN , E. W. Java Security: Hostile Applets, Holes, and Antidotes. John Wiley and Sons, New York, New York, 1997.
[14] M ICROSOFT C ORPORATION. Trust-Based Se- curity for Java. Redmond, Washington, Apr.
[15] N ETSCAPE C OMMUNICATIONS C ORPO - RATION. Introduction to the Capabilities Classes. Mountain View, California, Aug. 1997. http://developer.netscape.com/ library/documentation/signedobj/ capabilities/index.html.
[16] O BJECT M ANAGEMENT G ROUP. Common Secure Interoperability , July 1996. OMG Document Num- ber: orbos/96-06-20.
[17] R OSKIND , J. Evolving the Security Model For Java From Navigator 2.x to Navigator 3.x. Netscape Communications Corporation, Mountain View, California, Aug. 1996. http: //developer.netscape.com/library/ technote/security/sectn1.html.
[18] S TEELE , G. L. Rabbit: a compiler for Scheme. Tech. Rep. AI-TR-474, MIT, Cambridge, MA, 1978.
[19] TANENBAUM , A. S., M ULLENDER , S. J., AND VAN R ENESSE , R. Using sparse capabilities in a dis- tributed operating system. In 6th International Con- ference on Distributed Computing Systems (Cam- bridge, Massachusetts, May 1986), pp. 558–563.
[20] VAN D OORN , L., A BADI , M., B URROWS , M., AND W OBBER , E. Secure network objects. In Proceed- ings of the 1996 IEEE Symposium on Security and Privacy (Oakland, California, May 1996).
[21] WALLACH , D. S., B ALFANZ , D., D EAN , D., AND F ELTEN , E. W. Extensible security architectures for Java. In Proceedings of the Sixteenth ACM Sympo- sium on Operating System Principles (Saint-Malo, France, Oct. 1997), pp. 116–128.
[22] W OBBER , E., A BADI , M., B URROWS , M., AND L AMPSON , B. Authentication in the Taos operating system. ACM Transactions on Computer Systems 12 , 1 (Feb. 1994), 3–32.
Here is a list of the subset of axioms in ABLP logic used in this paper. We omit axioms for delegation, roles, and
exceptions because they are not necessary to discuss Java stack inspection.
Axioms About Statements
If s is an instance of a theorem of proposi- tional logic then s is true in ABLP.
If s and s s^0 then s^0 : (9) ( A says s ^ A says ( s s^0 )) A says s^0 : (10) If s then A says s for every principal A : (11)
Axioms About Principals
( A ^ B ) says s ( A says s ) ^ ( B says s ) (12) ( A j B ) says s A says B says s (13) A = B ( A says s B says s ) (14) j is associative. (15) j distributes over ^ in both arguments. (16) ( A ) B ) ( A = A ^ B ) (17) ( A says ( B ) A )) ( B ) A ) (18)
This section proves the theorems from section 4.5.
Theorem 1 (Termination) The decision procedure al- ways terminates.
has bounded cardinality. This implies that each loop in the algorithm has a bounded number of iterations; and clearly the amount of work done in each iteration is bounded.
Theorem 2 (Soundness) If the decision procedure re- turns true when invoked in stack frame F , then there exists
Lemma 1 If there is a path from A to B in the speaks-for
Proof: By assumption, there is a path
( A ; v 1 ; v 2 ; : : : ; vk ; B )
exist, we know that the statements
A ) v 1 ;
v (^) i ) vi + 1 for all i 2 [ 1 ; k 1 ];
and
vk ) B
that
Proof of Theorem 2: There are two cases in which the decision procedure can return true.
P 1 j P 2 j j Pk says Ok ( T );
where for all i 2 [ 1 ; k ] there is path from Pi to T in the
that for all i 2 [ 1 ; k ], Pi ) T. It follows that
Applying equation 6 repeatedly, we can directly de-
Theorem 3 (Equivalence to Stack Inspection) The de- cision procedure described in section 4.5 is equivalent to the Java stack inspection algorithm of section 2.
Proof: The Java stack inspection algorithm (Figure 1) itself does not have a formal definition. However, we can treat the evolution of the system inductively and focus on the enablePrivilege() and checkPrivilege() primitives. Our induction is over the number of steps taken, where a step is either a procedure call or an enablePrivilege() operation. For clarity, we ignore the existence of disablePrivilege(), revertPrivilege(), and procedure return opera- tions; our proof can easily be extended to accommodate them. We also assume Netscape semantics. A simple adjust- ment to the base case can be used to prove equivalence between the decision procedure and the Sun/Microsoft se- mantics.
Base case: In the base case, no steps have been taken. In this case, the stack inspection system has a single stack frame with no privilege annotation; in the ABLP model, the stack frame’s belief set is empty. In this base case, checkPrivilege() will fail in both systems.