Jini-Based Dynamic Discovery, Query, and Selection


Jini Architecture and Security


The Jini architecture and application program interfaces provide a convenient and relatively general framework for dynamic discovery and configuration of distributed services. Although Jini is designed to support dynamic system configuration and network communication, the security aspects of Jini are extremely limited.


Jini extends the Java environment from a single virtual machine to a network of machines. In general, a Jini system contains a set of services each of which offers some functionality to any member of a coalition. Services are located and installed using a lookup mechanism that involves network transfer of Java bytecode.


Jini communication is based on Java remote method invocation (RMI). Specifically, if a process on machine A wishes to communicate with a process on machine B, then machine A installs a surrogate stub object that communicates with a corresponding object on machine B through remote method invocation. This surrogate stub object is called a proxy. If the object on machine B provides a lookup service, then the stub object installed on machine A is called a lookup proxy. . If the object on machine B provides a distributed service, then the stub object installed on machine A is called a service proxy.


A Jini client obtains a lookup proxy and a service proxy through the following steps:

        Discovery: The client broadcasts a request for a lookup service. The lookup service responds with a lookup proxy. This stub object (proxy) allows the client to make further queries of the lookup service.

        Query: The client queries the lookup service for a service with specific property. The lookup service responds with a list of services and supplies a list of attributes associated with each service.

        Selection: The client requests and receives a service proxy for a specific service. The result of selection may be a signed or unsigned jar file.

The diagram below shows the communication phases that occur in discovery, query, selection, and installation of a service.


Figure 1: Jini architecture for discovery and installation of service


The first phase, used in discovery, involves communication with a subnet or multicast group, in order to locate a lookup service. In the second phase, which includes query and selection, the agent communicates with the lookup service through a lookup proxy that was obtained by communication from phase 1. While standard Jini uses remote method invocation, other forms of communication could conceivably be substituted. Since the agent must install and execute a lookup proxy (interface or driver), the agent is susceptible to errors or attacks resulting from corrupted or malicious proxy code. In the third phase, the agent interfaces with the installed service through a service proxy. Again, standard Jini relies on remote method invocation, but if the service is distributed, then other communication mechanisms could be appropriate. As with installation of the lookup proxy, the agent is again subject to risks associated with execution of service proxy code received over the network.


The standard Jini security model is simply the Java security model, designed by Li Gong who is a consultant to Stanford on this Dynamic Coalitions project The final jar file received as the result of selection may be signed. The client Java security manager may be configured to provide each lookup proxy or service proxy with specific access rights, according to the signing key used in creation of the jar file. This provides some protection, since it may prevent malicious bytecode attacks. However, a number of important problems must be addressed by extensions to the Jini framework:

        How does an entity prevent malicious attacks through malicious lookup proxies or service proxies?

        If an entity requires a service, and the only available service is unsigned or signed by a key not previously known to the client, how can the client proceed?

        How does the service authenticate the client?




Architecture for trust management and code filtering

The Stanford architecture for trust management and mobile code security is based on enhancements to the Jini primitives and conventions for calling library services under construction at Stanford. The main concepts are as follows:


        Trust between client and server is based on credentials provided by a trust management system. In the Jini architecture, a trust management credential authority and trust management inference engine run as a Jini service.


        The Jini lookup server stores credentials for registered services. Services include credentials in their serviceItem when registering with the lookup service.


        A Jini client establishes trust with a service by sending the credential received from the lookup service to the Trust Management service.


        A Jini client manages mobile code risks by invoking a Java bytecode filter that screens Java bytecode for security risks. The filter may be customized to enforce coding restrictions or software conventions established by a coalition and designed to prevent mobile code attacks.


        A Jini service establishes trust with a client by requesting credentials through the service proxy installed on the client (as part of the normal Jini service configuration) and sending the credential received from the lookup service to the Trust Management service.

















The figure above shows a client requesting a service through the lookup service. The service has previously registered with the lookup service and therefore does not participate in this transaction. The lookup service provides the service credential to the client and the client consults a trust management service to determine if the service is allowed for this client. For example, a service may provide maps or navigation information about some area. The client locates an untrusted lookup service and asks for a service that provides navigation information. The lookup service responds and sends a service credential. The client can then consult a trust management service to see if there is a credential chain proving that this is a trusted coalition service. In this process, the trust management service provides the credential chain to the client, eliminating the need for the client to trust the trust management service performing chain discovery.


The following figure shows how the client may filter bytecode implementing the service proxy and received from the lookup service.













After the client has checked the service credentials and requested a bytecode service proxy, this code is sent from the lookup service to the client. The client passes this code through the Stanford bytecode filter, running locally on the client. The bytecode filter is invoked using an extension of the Java class loader, intercepting code before it is installed on the client computing environment. In this process, the client may use the service credential to verify the the service proxy is in fact signed by a key associated with a trusted service.


After the client has installed a service proxy, the client may communicate with the service. At this point, the service must determine whether to trust the client. This steps for accomplishing this are shown in the following figure.















The client uses the service proxy, shown as a shaded square in the client computing environment, to initiate communication with the service. The interface for this communication is set by the service, as part of the service proxy. Therefore, the service may require that the client send a credential as part of the initial RMI call via the proxy. The service then sends the credential to a trust management service to find a credential chain that would prove that this is a trusted or authorized coalition client.


Additional details and data formats are shown in the following figure.


The service registers with the lookup service through the three messages shown on the right. In the first message, the service discovers the lookup service. Then the lookup service responds with a serviceRegister message. Finally, the service registers, sending a serviceItem containing service proxy code (indicated SP), and identification number (ID#), and an attribute list (attr[]). The attribute list will contain a credential.























The steps used by the client for installing the service proxy and establishing trust are shown as steps 1 5 on the left. After discovering a lookup service, the client queries the lookup service to obtain a service matching requested attributes. In response, the lookup service sends the serviceItem containing the service credentials. The credentials are then sent to the trust management engine (step 4), with a trust management response in step 5. The client may then install the service proxy and begin communicating with the service, if the trust management engine provides a satisfactory credential chain, or reject the service and request another service from the lookup service.