|By Shane Isbell||
|March 5, 2004 12:00 AM EST||
The mobile industry is standardizing both application provisioning and digital rights management (DRM). Provisioning includes the discovery and downloading of an application to a client device, while DRM deals with how to protect the application from unauthorized use.
The Java Community Process recently finalized JSR 124, J2EE Client Provisioning Specification, which a number of content server providers are rapidly incorporating into their products. On the DRM side, the Open Mobile Alliance has defined the industry standard in its document Digital Rights Management version 1.0. Nokia, a strong supporter of the OMA, implemented a key OMA DRM feature - forward locking - in its 3595 model. Forward locking occurs when the device embeds a hardware identifier in the application so that the application can be used only on that device.
One goal of this article is to demonstrate how to use class-level instrumentation to provide DRM solutions for J2ME applications. I'll show how to create a J2ME DRM wrapper that's similar to forward locking, but less restrictive. Another goal of this article is to provide insight into how provisioning and stocking (the submittal and registration of content) takes place.
Running the sample application requires a Web or application server with a servlet container. JBoss is a popular open source product that serves this purpose. For the client side, download Sun's Wireless Toolkit for MIDP 2.0 from http://java.sun.com. The toolkit also contains the sample JAR and JAD files used in this article. If you don't have a J2ME wireless mobile device, use the toolkit's emulator.
You'll need the source code that's included with this article to build the provisioning WAR file and the client content submittal program (download from www.sys-con.com/java/sourcec.cfm). Ant scripts are included; to use them, download the Ant build utility at http://apache.org.
Submitting Content from the Provider
To submit content, the content provider places the JAR file that contains the J2ME application on a publicly accessible URL. Next, the provider creates a JAD file containing seven required properties, including the MIDlet-Jar-URL property. Finally, the content submitter posts the JAD file to the content server.
It's common in the industry for the content provider to submit both the JAR and the JAD files to the content server. However, since the JAD contains the JAR's URL, submitting the JAR file is unnecessary. Note that the JAD file contains the MIDlet-Jar-URL property so that the application manager on the mobile device knows where to find the J2ME application. We'll use the MIDlet-Jar-URL property in a different way: to get the JAR file from the provider's server onto the content server.
Let's see how to make this work in practice. Go to the WTK20/apps/games/bin directory. There are two files: games.jad and games.jar. Make the games.jar accessible on a Web server and test that the JAR exists by typing in the URL on a Web browser at http://localhost:8080/ROOT/ games.jar. If a dialog box appears asking to download the file, then the JAR file is accessible. Note that you should replace localhost and 8080 with the domain name and port of your Web server.
Open the games.jad file and change the MIDlet-Jar-URL property to http://localhost: 8080/ROOT/games.jar. Also add an Install-Notify property with a value of http://localhost:8080/ provisioning/InstallNotify. I'll explain why you need the Install-Notify property in the section on OTA provisioning. Now instantiate the org.jvending.vending. client.ContentSubmitter class, feeding in two arguments on the command line: the URL of the content server stocking servlet and the local file system path of the games.jad file. The instance of the ContentSubmitter class will post the contents of the games.jad file to the content server over HTTP.
Stocking Content on the Server
Look at the Stocker class provided in the source code to understand the stocking process from the content server's perspective. An instance of this class divides the stocking of content into the following steps:
- Reading the request input stream and creating a JAD object
- Getting the MIDlet-Jar-URL property from an instance of the JAD object and pulling the JAR file located at that URL to the server
- Adding the DRM wrapper to the JAR file and setting the new JAR size (MIDlet-Jar-Size) on the JAD instance
- Adding the modified JAR file to the local in-memory cache
In the second step, the Stocker object gets the JAR file containing the J2ME application from the content provider's server. The Stocker object creates an instance of JarFetcher and invokes the fetch method, using the JAD object as a parameter. The JarFetcher opens a JarUrlConnection to the JAR URL specified within the JAD and downloads the games.jar file from the content provider's server. The fetch method returns a java.util.jar.JarFile instance. Since the content server instruments the main MIDlets class files, we need to pull out specific class files. Thus we prefer using a JarFile object over the lower-level InputStream because the JarFile class has handy methods for accessing each class file within a JAR file.
In the third step, the content server instruments the class files. The Stocker object instantiates the DrmInstrumenter class and invokes the modifyJar(Jad jad, JarFile jar) method. This method invokes the getMIDletNames method on the JAD object to determine the MIDlet class names. Next, the modifyJar method pulls the byte code of the MIDlet classes from the JARFile object. The DrmInstrumenter instance then instruments the MIDlet classes, adds the DRM class (ClientAuthenticator) to the JarFile object, and returns the new JAR as a byte array.
The Stocker object expands the JAR file size when it instruments the class files. The Application Management Software (AMS) on the device is responsible for downloading and installing the J2ME application. If we don't reset the JAR size, when the AMS downloads the application it will return an error because the JAR size given in the JAD won't match the actual downloaded JAR size. Thus, the Stocker object resets the JAR size attribute by invoking jad.setJarSize(String.valueOf (drmJar.length)), where drmJar is the JAR byte array.
The final step in the stocking process involves putting the JAD object and the instrumented JAR byte array into separate HashMaps indexed with the same universally unique identifier (UUID). The UUID is important for a couple of reasons. First, when the user downloads the JAD and JAR, the content server uses the UUID to return each object from the cache. Within a production environment the content server would, of course, persist the JAD and JAR to a file system or database.
The second reason the UUID is important is that the content server will use the unique ID for authorization. The content server embeds the application UUID within the application. When the user initializes the J2ME application, the application will post the UUID to the content server. The server then matches the user's Mobile Subscriber ISDN (MSISDN) in the HTTP header to the UUID of the application to determine authorization.
DRM Instrumentation Wrapper
There are a couple of ways we can create a J2ME wrapper. We can either add all of the code directly to the MIDlet subclass, or we can create a separate class that contains the DRM code and reference that class from the MIDlet subclass. For this implementation we'll choose the second approach because processing time is faster, instrumentation is easier to code, and, most important, we avoid having to deal with the pesky stack map attribute that is unique to J2ME classes. The stack map improves the efficiency of the runtime verification of J2ME applications during runtime by recording local variables and stack items for byte-code offsets.
Note that to avoid the stack map attribute within our instrumentation, we must not include conditional if statements and try/catch blocks within the instrumented byte code. Therefore, the MIDlet subclass has only one public method (run) with a void return type. See the CLDC Spec 1.0 for more information about the stack map attribute.
Take a look at the DRM class, org.jvending.wrapper. ClientAuthenticator. This class contains only two public methods: ClientAuthenticator(MIDlet MIDlet, String id) and run(). An instance of the MIDlet subclass, e.g., TilePuzzle, invokes the constructor of the ClientAuthenticator, passing in a reference to itself (TilePuzzle) and the unique ID of the game as parameters. Next, TilePuzzle invokes the run method. View the code below:
String id = "abcd-efa3-sddaf-467sdk";
ClientAuthenticator ma = new ClientAuthenticator(this, id);
The DRM wrapper should make an authorization call to the server upon startup of the application. Thus we embed the authorization code prior to the initial application logic within the startApp method. This requires instantiating the ClientAuthenticator class at the beginning of the startApp method. If the startApp method already contains stack map attributes, we need to change the byte offsets and references to the constant pool because we're adding byte code to the beginning of the method.
To avoid dealing with the stack map attribute, rename the startApp method to newStartApp method. This keeps the offsets and constant pool references the same. The startApp method in the MIDlet now invokes the newStartApp method, which contains a copy of the original execution code for the MIDlet subclass.
OTA Provisioning of the Application
A critical step to providing a DRM solution is to authenticate the user. Otherwise the user could forge the HTTP header and claim to be someone he or she is not, thus getting unauthorized access to the application. When users use their mobile device within a GPRS carrier environment, the request goes through a base station subsystem, through the serving GPRS support node (SGSN), onto the gateway GPRS support node (GGSN), and finally to the WAP gateway.
By this point, the system has already authenticated the user and appended a MSISDN, which is the user's phone number, to the HTTP header. Thus, by the time the HTTP request hits the content server, the server only needs to extract the MSISDN HTTP header to know the identity of the user. Before going further with the authentication and authorization of the user, let's briefly discuss how the user discovers the instrumented application.
The user can do application discovery through a WML microbrowser or an HTML browser, depending on the capabilities of the handset. After users discover the link to the JAD file, they click it. The URL will look something like http:// localhost:8080/provisioning/596162646162614A787.jad.
On the content server, any URL with a *.jad extension maps to the org.jvending.provisioning.JadDownloader servlet. The JadDownloader instance extracts the UUID and gets the JAD from the cache. Next, the JadDownloader sets the content type on the response to text/vnd.sun.j2me.app-descriptor and returns the JAD stream to the browser.
The device starts downloading the JAD file over WAP. The browser detects that there is a content type of text/vnd. sun.j2me.app-descriptor and passes control over to the AMS. The AMS on the device reads the properties of the JAD file and extracts the MIDlet-Jar-URL property, which looks like http://localhost:8080/provisioning/596162646162614 A787.jar.
The AMS hits this link over WAP or directly over TCP/IP, depending on the device. Since the URL contains a *.jar extension, it maps to the org.jvending.provisioning. JarDownloader servlet. The JarDownloader servlet extracts the UUID and looks up the instrumented JAR file from the cache. Next, the servlet sets the response content type to application/java-archive and downloads the JAR to the device.
The device knows where to post the status report by reading the MIDlet-Install-Notify attribute in the JAD. Remember, you should have added this to the games.jad file earlier. If the device successfully downloads and installs the application, it posts a 900 response code to the content server at http://localhost:8080/provisioning/InstallNotify?uuid=596162646162614A787.
When the HTTP post hits the InstallNotify servlet with a successful 900 response, the content server extracts the MSISDN from the HTTP header and the UUID from the URL. The server caches the MSISDN and UUID into an instance of AuthorizationMap using the MSISDN as the key.
After successfully downloading the application, the user clicks the application start button on the device. At this point, control passes to the startApp method of the main MIDlet. The startApp method instantiates the ClientAuthenticator class, which posts the UUID to the content server's AuthorizationServlet. The AuthorizationServlet extracts the MSISDN and UUID from the header. Using the MSISDN from the HTTP header as a key, the servlet looks up the UUID from an instance of AuthorizationMap.
If the UUID in the header doesn't match the UUID in the AuthorizationMap instance, the servlet sends an unlock response value of false. The ClientAuthenticator invokes the notifyDestroyed method on the MIDlet subclass instance, ending the application. This need to destroy the application from within the wrapper is why the ClientAuthenticator constructor signature contains a reference to the invoking MIDlet subclass.
If the UUIDs match, the servlet sends back an unlock response value of true to the J2ME application. The run method returns immediately, authorizing the user. In the MIDlet, control now goes to the newStartApp method, which contains the original MIDlet code. The application begins.
Digital rights management and content provisioning are two critical components of the rapid growth of applications in the mobile space. Currently, it's very easy for a user to forward content or to upload it to the Internet for others to download. Not only do we need intelligent ways for the user to discover and download applications, but we also need to protect the content from piracy. This article discusses one way - using a DRM wrapper - to protect content from unauthorized use. The source code in this article is open source. You can find updates at www.jvending.org.
|Wes Biggs 04/05/04 05:13:33 PM EDT|
A couple of notes:
MSISDN is not typically available in the HTTP headers unless you have a business relationship with the carrier.
The DRM solution suggested in the article is a good step, but de-instrumentation is relatively straightforward, given enough incentive (and access to the instrumenting source code, as we have here). A user with a laptop and GSM modem could spoof the MSISDN header, download the JAR, deinstrument and redistribute.
|Shane Isbell 03/05/04 04:56:08 PM EST|
The contact info and bio for me is out of date. You can e-mail me at [email protected]
As organizations shift towards IT-as-a-service models, the need for managing & protecting data residing across physical, virtual, and now cloud environments grows with it. CommVault can ensure protection & E-Discovery of your data - whether in a private cloud, a Service Provider delivered public cloud, or a hybrid cloud environment – across the heterogeneous enterprise.
Nov. 29, 2015 06:00 PM EST Reads: 230
Today air travel is a minefield of delays, hassles and customer disappointment. Airlines struggle to revitalize the experience. GE and M2Mi will demonstrate practical examples of how IoT solutions are helping airlines bring back personalization, reduce trip time and improve reliability. In their session at @ThingsExpo, Shyam Varan Nath, Principal Architect with GE, and Dr. Sarah Cooper, M2Mi’s VP Business Development and Engineering, explored the IoT cloud-based platform technologies driving t...
Nov. 29, 2015 06:00 PM EST Reads: 439
In his General Session at DevOps Summit, Asaf Yigal, Co-Founder & VP of Product at Logz.io, explored the value of Kibana 4 for log analysis and provided a hands-on tutorial on how to set up Kibana 4 and get the most out of Apache log files. He examined three use cases: IT operations, business intelligence, and security and compliance. Asaf Yigal is co-founder and VP of Product at log analytics software company Logz.io. In the past, he was co-founder of social-trading platform Currensee, which...
Nov. 29, 2015 04:00 PM EST Reads: 251
The Internet of Things (IoT) is growing rapidly by extending current technologies, products and networks. By 2020, Cisco estimates there will be 50 billion connected devices. Gartner has forecast revenues of over $300 billion, just to IoT suppliers. Now is the time to figure out how you’ll make money – not just create innovative products. With hundreds of new products and companies jumping into the IoT fray every month, there’s no shortage of innovation. Despite this, McKinsey/VisionMobile data...
Nov. 29, 2015 02:00 PM EST Reads: 485
Culture is the most important ingredient of DevOps. The challenge for most organizations is defining and communicating a vision of beneficial DevOps culture for their organizations, and then facilitating the changes needed to achieve that. Often this comes down to an ability to provide true leadership. As a CIO, are your direct reports IT managers or are they IT leaders? The hard truth is that many IT managers have risen through the ranks based on their technical skills, not their leadership ab...
Nov. 29, 2015 01:00 PM EST Reads: 414
Just over a week ago I received a long and loud sustained applause for a presentation I delivered at this year’s Cloud Expo in Santa Clara. I was extremely pleased with the turnout and had some very good conversations with many of the attendees. Over the next few days I had many more meaningful conversations and was not only happy with the results but also learned a few new things. Here is everything I learned in those three days distilled into three short points.
Nov. 29, 2015 01:00 PM EST Reads: 352
DevOps is about increasing efficiency, but nothing is more inefficient than building the same application twice. However, this is a routine occurrence with enterprise applications that need both a rich desktop web interface and strong mobile support. With recent technological advances from Isomorphic Software and others, rich desktop and tuned mobile experiences can now be created with a single codebase – without compromising functionality, performance or usability. In his session at DevOps Su...
Nov. 29, 2015 12:45 PM EST Reads: 419
As organizations realize the scope of the Internet of Things, gaining key insights from Big Data, through the use of advanced analytics, becomes crucial. However, IoT also creates the need for petabyte scale storage of data from millions of devices. A new type of Storage is required which seamlessly integrates robust data analytics with massive scale. These storage systems will act as “smart systems” provide in-place analytics that speed discovery and enable businesses to quickly derive meaningf...
Nov. 29, 2015 12:30 PM EST Reads: 425
In his keynote at @ThingsExpo, Chris Matthieu, Director of IoT Engineering at Citrix and co-founder and CTO of Octoblu, focused on building an IoT platform and company. He provided a behind-the-scenes look at Octoblu’s platform, business, and pivots along the way (including the Citrix acquisition of Octoblu).
Nov. 29, 2015 12:00 PM EST Reads: 527
In his General Session at 17th Cloud Expo, Bruce Swann, Senior Product Marketing Manager for Adobe Campaign, explored the key ingredients of cross-channel marketing in a digital world. Learn how the Adobe Marketing Cloud can help marketers embrace opportunities for personalized, relevant and real-time customer engagement across offline (direct mail, point of sale, call center) and digital (email, website, SMS, mobile apps, social networks, connected objects).
Nov. 29, 2015 11:45 AM EST Reads: 327
The buzz continues for cloud, data analytics and the Internet of Things (IoT) and their collective impact across all industries. But a new conversation is emerging - how do companies use industry disruption and technology enablers to lead in markets undergoing change, uncertainty and ambiguity? Organizations of all sizes need to evolve and transform, often under massive pressure, as industry lines blur and merge and traditional business models are assaulted and turned upside down. In this new da...
Nov. 29, 2015 11:30 AM EST Reads: 275
In recent years, at least 40% of companies using cloud applications have experienced data loss. One of the best prevention against cloud data loss is backing up your cloud data. In his General Session at 17th Cloud Expo, Sam McIntyre, Partner Enablement Specialist at eFolder, presented how organizations can use eFolder Cloudfinder to automate backups of cloud application data. He also demonstrated how easy it is to search and restore cloud application data using Cloudfinder.
Nov. 29, 2015 10:00 AM EST Reads: 203
The Internet of Everything is re-shaping technology trends–moving away from “request/response” architecture to an “always-on” Streaming Web where data is in constant motion and secure, reliable communication is an absolute necessity. As more and more THINGS go online, the challenges that developers will need to address will only increase exponentially. In his session at @ThingsExpo, Todd Greene, Founder & CEO of PubNub, exploreed the current state of IoT connectivity and review key trends and t...
Nov. 29, 2015 09:45 AM EST Reads: 453
Two weeks ago (November 3-5), I attended the Cloud Expo Silicon Valley as a speaker, where I presented on the security and privacy due diligence requirements for cloud solutions. Cloud security is a topical issue for every CIO, CISO, and technology buyer. Decision-makers are always looking for insights on how to mitigate the security risks of implementing and using cloud solutions. Based on the presentation topics covered at the conference, as well as the general discussions heard between sessi...
Nov. 29, 2015 09:15 AM EST Reads: 345
We all know that data growth is exploding and storage budgets are shrinking. Instead of showing you charts on about how much data there is, in his General Session at 17th Cloud Expo, Scott Cleland, Senior Director of Product Marketing at HGST, showed how to capture all of your data in one place. After you have your data under control, you can then analyze it in one place, saving time and resources.
Nov. 29, 2015 08:45 AM EST Reads: 223