As Octavian mentioned in his recent blog entry, Java Store and License Management, the Java Store will soon offer a simple license rights management system to developers. Octavain's post was based upon early work and, because there have been questions about it, I'm posting updated sample source code for the license management feature. Enjoy!
package com.sun.javastore.licenserightsapp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
/**
* A sample application demonstrating how to decode and verify the Java Store licensing rights object. This
* sample shows the rights code executing within the {@code main()} method that normally starts your
* application. In a real application you should move this code to wherever your application decides which
* functions are available. Note: An application can be run in demo/preview mode, in which case, none of
* the rights objects are to be set, which is an indicator to the application that it is being run in such
* mode.
*
* You may wish to use several copies of the code in different places in your
* application to check for different rights. You should try to avoid using a pattern like :
*
*
|
And a unit test which invokes the sample code.
package com.sun.javastore.licenserightsapp;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase {
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest(String testName) {
super(testName);
}
/**
* @return the suite of tests being tested
*/
public static Test suite() {
return new TestSuite(AppTest.class);
}
/**
* Rigourous Test :-)
*/
public void testApp() {
String SAMPLE_RIGHTS_BLOB =
"I1dlZCBTZXAgMTYgMTc6MzM6NDQgUERUIDIwMDkKc3lzdGVtSWQ9MzU5Nzg3MQpyaWdodC4yPUkx" +
"ZGxaQ0JUWlhBZ01UWWdNVGM2TXpNNk5EUWdVRVJVSURJd01Ea0taWGh3YVhKaGRHbHZiajB4TWpV" +
"ek1UVXhNakV5TkRFNENtNWhiV1U5YzNSdmNtVmNPbk4xWW5OamNtbHdkR2x2YmdwcGMwZHlZVzUw" +
"WldROWRISjFaUXB5WldObGFYQjBTV1E5TWdwd1lYbHRaVzUwVkhKaGJuTmhZM1JwYjI1SlpEMHhN" +
"alFLWVdOMGFYWmhkR2x2YmoweE1qVXpNVFEzTmpFeU5ERTRDbkJoZVcxbGJuUlFjbTlqWlhOemIz" +
"STlVR0Y1VUdGc1FWQUsKcmlnaHQuMT1JMWRsWkNCVFpYQWdNVFlnTVRjNk16TTZORFFnVUVSVUlE" +
"SXdNRGtLYm1GdFpUMXpkRzl5WlZ3NmNuVnVDbWx6UjNKaGJuUmxaRDEwY25WbENuSmxZMlZwY0hS" +
"SlpEMHhDbkJoZVcxbGJuUlVjbUZ1YzJGamRHbHZia2xrUFRFeU13cHdZWGx0Wlc1MFVISnZZMlZ6" +
"YzI5eVBWQmhlVkJoYkVGUUNnXD1cPQp1c2VySWQ9MQpwcm9kdWN0SWQ9Mwp0aW1lc3RhbXA9MTI1" +
"MzE0NzYyNDYwMwpkZXZpY2VJZD05MzIxRTAyMy1DRUEyLTQxQTItODM1Mi1ERUVFODYxMDA4OEMK";
String SAMPLE_RIGHTS_SIG =
"GHNXWheMgBv8NC/jR9rVuwufyLgtirKsFq7C8dWL4Uzb4+3pZmfoqNLrxbXiTErCP4F42UnkP8mF" +
"i8sFsdO99xGCuaa1zQqZO9zXNScKBxzRlKcSuzIRDynnq0CN9Wz82ibeA+b5S7HpsQ7nUbHb6SEu" +
"9BqjArTEc8wu7RCcTZo=";
String SAMPLE_RIGHTS_CERT =
"MIIE5jCCA86gAwIBAgIQXqXlgX7rylXBGhLidL9EhzANBgkqhkiG9w0BAQUFADCBgzEdMBsGA1UE" +
"ChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx" +
"JTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNjcmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBT" +
"aWduaW5nIENBMB4XDTA5MDgyNzAwMDAwMFoXDTEyMDgyNjIzNTk1OVowbTEdMBsGA1UEChQUU3Vu" +
"IE1pY3Jvc3lzdGVtcyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEQMA4G" +
"A1UECxQHQ2xhc3MgQzEXMBUGA1UEAxQOU3VuIEphdmEgU3RvcmUwgZ8wDQYJKoZIhvcNAQEBBQAD" +
"gY0AMIGJAoGBAJghrmyAl2/ercRZRFfMPX5Ie+LusqP3UwMSB2A9Xl3via+kboXjuNHxTYyMEOUa" +
"b3DorVSWsWHF5UKDK7KxkW+w/g2vYKnVZIKPH+VHRXYAwUMpEDNSSVMOyNKYF39uj0Ec9uRvhBw5" +
"pxeKMRqQ0KhEhHMBH1EZQzUtPcYraHxPAgMBAAGjggHtMIIB6TAJBgNVHRMEAjAAMA4GA1UdDwEB" +
"/wQEAwIHgDBrBgNVHR8EZDBiMGCgXqBchlpodHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9T" +
"dW5NaWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nQ2xhc3NDL0xhdGVzdENSTC5j" +
"cmwwHwYDVR0jBBgwFoAUs0crgn5TtHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFJHwpfEC3ziinvN3" +
"8dKlgVR5OrW1MDsGCCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3Nw" +
"LnZlcmlzaWduLmNvbTCBuQYDVR0gBIGxMIGuMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYBBQUHAgEW" +
"HGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwcQYLYIZIAYb3AIN9nD8wYjAnBggrBgEFBQcC" +
"ARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDcGCCsGAQUFBwICMCsWKU5vdCBWYWxpZGF0" +
"ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVyYXRpb25zMBEGCWCGSAGG+EIBAQQEAwIEEDATBgNVHSUE" +
"DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAPoQ8RWJ6xfnY8YxHL3kEVEPxKyDAa+sG" +
"Ng5Rw2SaXFek9KMfMvU6DUXdj/BYIuLu9S2cVIHlIyFINzT6gtxsDNTkByMmRys8lsCZhXv767Pe" +
"b/KW2sZWA8fxSE6JDRpWsE7j4PSr3rBB6YNqCTX0qH5yzumx2Lfk28BILKW7ri4cmakaql+Vi+6q" +
"QIqhxDu1FzAdbwp/DzAJYtafcAZa381jDH3kwpSXpP15V1jqZgGYs387hQEYDWie4J5sol7g0cN9" +
"zlRZQMxwU6Rcz/nWiM24mGB/W0NH7ggMS7/AWz6efN534OAxgWuBA96Qwf7TWKdZWzWEdhZar483" +
"hfmZiw==";
System.setProperty("jnlp.javastore.appwrapper.UserID", "1");
System.setProperty("jnlp.javastore.appwrapper.ProductID", "3");
System.setProperty("jnlp.javastore.appwrapper.VersionID", "3");
// This value will be calculated by the java store runtime.
int systemId = "user".hashCode() ^ "os".hashCode();
System.setProperty("jnlp.javastore.appwrapper.SystemID", Integer.toString(systemId));
System.setProperty("jnlp.javastore.appwrapper.rightsBlob", SAMPLE_RIGHTS_BLOB);
System.setProperty("jnlp.javastore.appwrapper.rightsSig", SAMPLE_RIGHTS_SIG);
System.setProperty("jnlp.javastore.appwrapper.rightsCert", SAMPLE_RIGHTS_CERT);
App.main(new String[0]);
}
}
|