Skip to content

Commit 5743416

Browse files
authored
Make the API similar to Python and .NET versions (#7)
* Start on a new method for activate * Contd * Fix problem with types * Fix Activate * Move helpers to model package * Add IsOnRightMachine * Finish the example in TestKey * Update the example project * Update README.md * Make sure the raw response is included in BasicResult and LicenseKey
1 parent 70db098 commit 5743416

File tree

13 files changed

+624
-142
lines changed

13 files changed

+624
-142
lines changed

.idea/workspace.xml

Lines changed: 282 additions & 75 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,23 @@ The following example is similar to what is covered in the [key verification tut
1010
Assuming you have referenced the `cryptolens.jar` file, the code below should generate successful result. A working project with the code below can be found in the [example-app](https://github.com/Cryptolens/cryptolens-java/tree/master/example-app) folder.
1111

1212
```java
13-
import io.cryptolens.Cryptolens;
14-
import io.cryptolens.Helpers;
15-
import io.cryptolens.LicenseKey;
13+
import io.cryptolens.methods.*;
14+
import io.cryptolens.models.*;
1615

1716
public class Main {
1817

1918
public static void main(String[] args) {
2019
String RSAPubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
20+
String auth = "WyIyNjA5IiwiaWE5b0VFT3Q2eDlNR2FvbHBHK2VOYUZ4bzNjT3h5UkNrMCtiYnhPRSJd";
2121

22-
Cryptolens cryptolens = Cryptolens.getDefault();
23-
cryptolens.setRSAPublicKey(RSAPubKey);
22+
LicenseKey license = Key.Activate(auth, RSAPubKey, new ActivateModel(3349, "ICVLD-VVSZR-ZTICT-YKGXL", Helpers.GetMachineCode()));
2423

25-
Cryptolens.ActivateResponse response =
26-
cryptolens.activate( "WyIyNTk1IiwidVVrQm94OGlYS3pHZlhTc0x6Rm9mN1piektrT0FSd0REaFZ0ZXZJMSJd"
27-
, 3349
28-
, "ICVLD-VVSZR-ZTICT-YKGXL"
29-
, Helpers.GetMachineCode()
30-
);
31-
32-
if (!response.successful()) {
33-
System.out.println("Failed to activate!");
34-
Cryptolens.ActivateServerError er = response.getServerError();
35-
Exception ex = response.getException();
36-
37-
if (er != null) {
38-
System.out.println("Server error: " + er);
39-
}
40-
41-
if (ex != null) {
42-
ex.printStackTrace(System.out);
43-
}
44-
45-
return;
24+
if (license == null || !Helpers.IsOnRightMachine(license)) {
25+
System.out.println("The license does not work.");
26+
} else {
27+
System.out.println("The license is valid!");
28+
System.out.println("It will expire: " + license.Expires);
4629
}
47-
48-
LicenseKey licenseKey = response.getLicenseKey();
49-
50-
System.out.println("Activation was successful!");
51-
System.out.println(licenseKey.getKey());
52-
System.out.println(licenseKey.getF1());
5330
}
5431
}
5532

example-app/src/Main.java

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,19 @@
1-
import io.cryptolens.Cryptolens;
2-
import io.cryptolens.Helpers;
3-
import io.cryptolens.LicenseKey;
1+
import io.cryptolens.methods.*;
2+
import io.cryptolens.models.*;
43

54
public class Main {
65

76
public static void main(String[] args) {
8-
String RSAPubKey = "<RSAKeyValue><Modulus>sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
7+
String RSAPubKey = "<RSAKeyValue><Modulus> sGbvxwdlDbqFXOMlVUnAF5ew0t0WpPW7rFpI5jHQOFkht/326dvh7t74RYeMpjy357NljouhpTLA3a6idnn4j6c3jmPWBkjZndGsPL4Bqm+fwE48nKpGPjkj4q/yzT4tHXBTyvaBjA8bVoCTnu+LiC4XEaLZRThGzIn5KQXKCigg6tQRy0GXE13XYFVz/x1mjFbT9/7dS8p85n8BuwlY5JvuBIQkKhuCNFfrUxBWyu87CFnXWjIupCD2VO/GbxaCvzrRjLZjAngLCMtZbYBALksqGPgTUN7ZM24XbPWyLtKPaXF2i4XRR9u6eTj5BfnLbKAU5PIVfjIS+vNYYogteQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
8+
String auth = "WyIyNjA5IiwiaWE5b0VFT3Q2eDlNR2FvbHBHK2VOYUZ4bzNjT3h5UkNrMCtiYnhPRSJd";
99

10-
Cryptolens cryptolens = Cryptolens.getDefault();
11-
cryptolens.setRSAPublicKey(RSAPubKey);
10+
LicenseKey license = Key.Activate(auth, RSAPubKey, new ActivateModel(3349, "ICVLD-VVSZR-ZTICT-YKGXL", Helpers.GetMachineCode()));
1211

13-
Cryptolens.ActivateResponse response =
14-
cryptolens.activate( "WyIyNTk1IiwidVVrQm94OGlYS3pHZlhTc0x6Rm9mN1piektrT0FSd0REaFZ0ZXZJMSJd"
15-
, 3349
16-
, "ICVLD-VVSZR-ZTICT-YKGXL"
17-
, Helpers.GetMachineCode()
18-
);
19-
20-
if (!response.successful()) {
21-
System.out.println("Failed to activate!");
22-
Cryptolens.ActivateServerError er = response.getServerError();
23-
Exception ex = response.getException();
24-
25-
if (er != null) {
26-
System.out.println("Server error: " + er);
27-
}
28-
29-
if (ex != null) {
30-
ex.printStackTrace(System.out);
31-
}
32-
33-
return;
12+
if (license == null || !Helpers.IsOnRightMachine(license)) {
13+
System.out.println("The license does not work.");
14+
} else {
15+
System.out.println("The license is valid!");
16+
System.out.println("It will expire: " + license.Expires);
3417
}
35-
36-
LicenseKey licenseKey = response.getLicenseKey();
37-
38-
System.out.println("Activation was successful!");
39-
System.out.println(licenseKey.getKey());
40-
System.out.println(licenseKey.getF1());
4118
}
4219
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>io.cryptolens</groupId>
55
<artifactId>cryptolens</artifactId>
66
<packaging>jar</packaging>
7-
<version>1.2</version>
7+
<version>1.3</version>
88
<name>cryptolens</name>
99
<description>A client api to access Cryptolens Licensing API.</description>
1010
<url>https://github.com/cryptolens/cryptolens-java</url>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package io.cryptolens.internal;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.reflect.TypeToken;
5+
import io.cryptolens.*;
6+
import io.cryptolens.models.ActivateResult;
7+
import io.cryptolens.models.BasicResult;
8+
9+
import java.lang.reflect.Field;
10+
import java.lang.reflect.Type;
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
14+
public class HelperMethods {
15+
16+
public static <T extends BasicResult> T SendRequestToWebAPI(String method, Object model, Map<String,String> extraParams, Class<T> clazz) {
17+
18+
Map<String,String> params = new HashMap<>();
19+
20+
for(Field field : model.getClass().getDeclaredFields()) {
21+
field.setAccessible(true);
22+
try {
23+
Object value = field.get(model);
24+
if(value != null) {
25+
params.put(field.getName(), value.toString());
26+
}
27+
} catch (Exception ex) {
28+
System.err.println(ex.getStackTrace());
29+
}
30+
}
31+
32+
if(extraParams != null)
33+
params.putAll(extraParams);
34+
35+
RequestHandler requestHandler = new HttpsURLConnectionRequestHandler();
36+
37+
try {
38+
39+
String response = requestHandler.makePostRequest("https://app.cryptolens.io/api/" + method, params);
40+
41+
Gson gson = new Gson();
42+
43+
T res = gson.fromJson(response, clazz);
44+
res.RawResponse = response;
45+
return res;
46+
47+
} catch (Exception ex) {
48+
System.err.println(ex.getStackTrace());
49+
}
50+
51+
return null;
52+
}
53+
}

src/main/java/io/cryptolens/Helpers.java renamed to src/main/java/io/cryptolens/methods/Helpers.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
package io.cryptolens;
1+
package io.cryptolens.methods;
22

3+
import io.cryptolens.models.ActivatedMachine;
4+
import io.cryptolens.models.LicenseKey;
35
import oshi.SystemInfo;
46
import oshi.hardware.CentralProcessor;
57
import oshi.hardware.ComputerSystem;
@@ -20,6 +22,26 @@ public static String GetMachineCode() {
2022
return SHA256(getRawDeviceID());
2123
}
2224

25+
/**
26+
* Check if the device is registered with the license key.
27+
* @returns True if the license is registered with this machine and False otherwise.
28+
*/
29+
public static boolean IsOnRightMachine(LicenseKey license) {
30+
31+
String current_mid = Helpers.GetMachineCode();
32+
33+
if (license.ActivatedMachines == null){
34+
return false;
35+
}
36+
37+
for (ActivatedMachine machine : license.ActivatedMachines) {
38+
if(machine.Mid.equals(current_mid))
39+
return true;
40+
}
41+
42+
return false;
43+
}
44+
2345
/**
2446
* Return the sha256 checksum of a string.
2547
*/
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package io.cryptolens.methods;
2+
3+
import com.google.gson.Gson;
4+
import io.cryptolens.*;
5+
import io.cryptolens.internal.HelperMethods;
6+
import io.cryptolens.models.ActivateModel;
7+
import io.cryptolens.models.ActivateResult;
8+
import io.cryptolens.models.BasicResult;
9+
import io.cryptolens.models.LicenseKey;
10+
11+
import java.lang.reflect.Field;
12+
import java.nio.charset.StandardCharsets;
13+
import java.util.Base64;
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
17+
public class Key {
18+
19+
/**
20+
* Calls the Activate method (https://app.cryptolens.io/docs/api/v3/Activate).
21+
* @param token
22+
* @param RSAPubKey
23+
* @param model
24+
* @return
25+
*/
26+
public static LicenseKey Activate (String token, String RSAPubKey, ActivateModel model) {
27+
28+
Map<String,String> extraParams = new HashMap<>();
29+
30+
// force sign and the new protocol (only in activate)
31+
extraParams.put("Sign", "true");
32+
extraParams.put("SignMethod", "1");
33+
extraParams.put("token", token);
34+
35+
ActivateResult result = HelperMethods.SendRequestToWebAPI("key/activate", model, extraParams, ActivateResult.class);
36+
37+
if(result.result == 1) {
38+
System.err.println("The server returned an error: " + result.message);
39+
return null;
40+
}
41+
42+
try {
43+
Base64.Decoder decoder = Base64.getDecoder();
44+
45+
byte[] licenseKey = decoder.decode(result.licenseKey);
46+
byte[] signature = decoder.decode(result.signature);
47+
48+
// setting up the signatures
49+
JavaSecuritySignatureVerifier signatureVerifier = new JavaSecuritySignatureVerifier();
50+
int mstart = RSAPubKey.indexOf("<Modulus>");
51+
int mend = RSAPubKey.indexOf("</Modulus>");
52+
int estart = RSAPubKey.indexOf("<Exponent>");
53+
int eend = RSAPubKey.indexOf("</Exponent>");
54+
signatureVerifier.setModulusBase64(RSAPubKey.substring(mstart + 9, mend));
55+
signatureVerifier.setExponentBase64(RSAPubKey.substring(estart + 10, eend));
56+
57+
if (!signatureVerifier.verify(licenseKey, signature)) {
58+
System.err.println("Signature check failed");
59+
return null;
60+
}
61+
62+
String s = new String(licenseKey, StandardCharsets.UTF_8);
63+
LicenseKey license = new Gson().fromJson(s, LicenseKey.class);
64+
license.RawResponse = result.RawResponse;
65+
66+
return license;
67+
} catch (Exception ex) {
68+
System.err.println(ex.getStackTrace());
69+
}
70+
return null;
71+
}
72+
73+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package io.cryptolens.models;
2+
3+
public class ActivateModel {
4+
5+
/// <summary>
6+
/// The product id, which can be found on the product page.
7+
/// </summary>
8+
public int ProductId;
9+
10+
/// <summary>
11+
/// The Key string, eg. AAAA-BBBB-CCCC-DDDD.
12+
/// </summary>
13+
public String Key;
14+
15+
/// <summary>
16+
/// The machine code (a string that identifies a device) for activation.
17+
/// </summary>
18+
public String MachineCode;
19+
20+
/// <summary>
21+
/// An integer that allows you to restrict the information returned in the license key data object.
22+
/// Please read https://app.cryptolens.io/docs/api/v3/Activate#remarks for more details.
23+
/// </summary>
24+
public int FieldsToReturn;
25+
26+
/// <summary>
27+
/// Includes additional information about the license key, such as number of activated devices, etc.
28+
/// </summary>
29+
public boolean Metadata;
30+
31+
/// <summary>
32+
/// When set to something greater than zero, floating licensing will be enabled.
33+
/// The time interval is then used to check that no more than the allowed number
34+
/// of machine codes (specified in maximumNumberOfMachines) have been activated
35+
/// in that time period (in seconds).
36+
/// </summary>
37+
public int FloatingTimeInterval;
38+
39+
/// <summary>
40+
/// When set to something greater than zero (and assuming FloatingTimeInterval is set too)
41+
/// floating licensing will permit a license overdraft (eg. activation will succeed even if
42+
/// maximumNumberOfMachines is reached). MaxOverdraft value specifies how much we can exceed
43+
/// the maximumNumberOfMachines value.
44+
/// </summary>
45+
public int MaxOverdraft;
46+
47+
public ActivateModel() {
48+
49+
}
50+
public ActivateModel(int productId, String key, String machineCode) {
51+
ProductId = productId;
52+
Key = key;
53+
MachineCode = machineCode;
54+
}
55+
public ActivateModel(int productId, String key, String machineCode, int fieldsToReturn, boolean metadata, int floatingTimeInterval, int maxOverdraft) {
56+
ProductId = productId;
57+
Key = key;
58+
MachineCode = machineCode;
59+
FieldsToReturn = fieldsToReturn;
60+
Metadata = metadata;
61+
FloatingTimeInterval = floatingTimeInterval;
62+
MaxOverdraft = maxOverdraft;
63+
}
64+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.cryptolens.models;
2+
3+
public class ActivateResult extends BasicResult {
4+
5+
public String licenseKey;
6+
public String signature;
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.cryptolens.models;
2+
3+
public class ActivatedMachine {
4+
public String Mid;
5+
public String IP;
6+
public long Time;
7+
}

0 commit comments

Comments
 (0)