Roberto Sánchez
2014-02-21 8cc95fdfbe8146af8d5d4bcac7f7b9e3e2eb95c6
#0 feaure - Created main methods for License validation
1 files deleted
15 files added
1 files modified
3 files renamed
changed files
doc/README.md patch | view | blame | history
pom.xml patch | view | blame | history
src/main/java/net/curisit/securis/CryptoHelper.java patch | view | blame | history
src/main/java/net/curisit/securis/HWInfo.java patch | view | blame | history
src/main/java/net/curisit/securis/License.java patch | view | blame | history
src/main/java/net/curisit/securis/LicenseManager.java patch | view | blame | history
src/main/java/net/curisit/securis/LicenseValidator.java patch | view | blame | history
src/main/java/net/curisit/securis/ReqGenerator.java patch | view | blame | history
src/main/java/net/curisit/securis/SeCurisException.java patch | view | blame | history
src/main/java/net/curisit/securis/SignatureHelper.java patch | view | blame | history
src/main/java/net/curisit/securis/beans/LicenseBean.java patch | view | blame | history
src/main/java/net/curisit/securis/beans/RequestBean.java patch | view | blame | history
src/main/java/net/curisit/securis/utils/JsonUtils.java patch | view | blame | history
src/main/java/net/curisit/securis/utils/LicUtils.java patch | view | blame | history
src/main/java/net/curisit/securis/utils/Params.java patch | view | blame | history
src/main/resources/images/logo_customer.png patch | view | blame | history
src/main/resources/log4j.xml patch | view | blame | history
src/main/resources/securis-client.properties patch | view | blame | history
src/net/curisit/securis/ReqGenerator.java patch | view | blame | history
src/patch/java/net/curisit/securis/LicenseGenerator.java patch | view | blame | history
doc/README.md
....@@ -0,0 +1,16 @@
1
+### Private and Public keys generation
2
+
3
+DSA
4
+
5
+ openssl dsaparam -out dsaparam.pem 2048
6
+ openssl gendsa -pkcs8 -out privkey.pem dsaparam.pem
7
+
8
+ openssl dsa -in privkey.pem -pubout > mykey.pub
9
+ openssl pkcs8 -topk8 -inform PEM -in privkey.pem -out privkey.pkcs8 -nocrypt
10
+
11
+RSA
12
+
13
+ openssl genrsa -des3 -out privkey.pem 2048
14
+ openssl rsa -in privkey.pem -pubout > mykey.pub
15
+ openssl pkcs8 -topk8 -inform PEM -in privkey.pem -out privkey.pkcs8 -nocrypt
16
+
pom.xml
....@@ -4,7 +4,6 @@
44 <artifactId>securis-client</artifactId>
55 <version>0.0.1-SNAPSHOT</version>
66 <build>
7
- <sourceDirectory>src</sourceDirectory>
87 <plugins>
98 <plugin>
109 <artifactId>maven-compiler-plugin</artifactId>
....@@ -37,5 +36,20 @@
3736 <artifactId>commons-cli</artifactId>
3837 <version>1.2</version>
3938 </dependency>
39
+ <dependency>
40
+ <groupId>commons-net</groupId>
41
+ <artifactId>commons-net</artifactId>
42
+ <version>3.3</version>
43
+ </dependency>
44
+ <dependency>
45
+ <groupId>org.codehaus.jackson</groupId>
46
+ <artifactId>jackson-mapper-asl</artifactId>
47
+ <version>1.9.13</version>
48
+ </dependency>
49
+ <dependency>
50
+ <groupId>org.apache.logging.log4j</groupId>
51
+ <artifactId>log4j-api</artifactId>
52
+ <version>2.0-rc1</version>
53
+ </dependency>
4054 </dependencies>
4155 </project>
src/main/java/net/curisit/securis/CryptoHelper.java
....@@ -0,0 +1,155 @@
1
+package net.curisit.securis;
2
+
3
+import java.io.UnsupportedEncodingException;
4
+import java.security.InvalidKeyException;
5
+import java.security.NoSuchAlgorithmException;
6
+import java.security.NoSuchProviderException;
7
+import java.security.SecureRandom;
8
+import java.security.spec.InvalidKeySpecException;
9
+import java.util.Arrays;
10
+
11
+import javax.crypto.BadPaddingException;
12
+import javax.crypto.Cipher;
13
+import javax.crypto.IllegalBlockSizeException;
14
+import javax.crypto.NoSuchPaddingException;
15
+import javax.crypto.SecretKey;
16
+import javax.crypto.SecretKeyFactory;
17
+import javax.crypto.spec.PBEKeySpec;
18
+import javax.crypto.spec.SecretKeySpec;
19
+
20
+import org.apache.commons.net.util.Base64;
21
+import org.slf4j.Logger;
22
+import org.slf4j.LoggerFactory;
23
+
24
+//import net.curisit.common.ui.Dialogs;
25
+
26
+public class CryptoHelper {
27
+
28
+ private static final Logger log = LoggerFactory.getLogger(SignatureHelper.class);
29
+
30
+ private static final String KEY_FACTORY = "PBEWITHHMACSHA1";
31
+ private static final String PPROVIDER = "BC";
32
+ private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
33
+
34
+ private static CryptoHelper singleton = new CryptoHelper();
35
+
36
+ private String passPhrase = null;
37
+
38
+ private CryptoHelper() {
39
+ }
40
+
41
+ public static CryptoHelper getInstance() {
42
+ return singleton;
43
+ }
44
+
45
+ /**
46
+ * Encrypts a given text with AES algorithm
47
+ *
48
+ * @param plainText
49
+ * @return The encrypted text in Base64
50
+ */
51
+ public String encrypt(String plainText) throws SeCurisException {
52
+ return encrypt(plainText, this.passPhrase);
53
+ }
54
+
55
+ public String encrypt(String plainText, String pass) throws SeCurisException {
56
+ Cipher aes;
57
+ try {
58
+ aes = Cipher.getInstance(CIPHER_ALGORITHM);
59
+ byte[] salt = getSalt();
60
+ aes.init(Cipher.ENCRYPT_MODE, getSecretKey(salt, pass));
61
+ byte[] ciphertext = aes.doFinal(plainText.getBytes("utf-8"));
62
+
63
+ return Base64.encodeBase64String(salt) + "\n" + Base64.encodeBase64String(ciphertext);
64
+ } catch (NoSuchAlgorithmException e) {
65
+ log.error("Error decrypting text", e);
66
+ throw new SeCurisException("Error decrypting text", e);
67
+ } catch (NoSuchPaddingException e) {
68
+ log.error("Error decrypting text", e);
69
+ throw new SeCurisException("Error decrypting text", e);
70
+ } catch (InvalidKeyException e) {
71
+ log.error("Error decrypting text", e);
72
+ throw new SeCurisException("Error decrypting text", e);
73
+ } catch (IllegalBlockSizeException e) {
74
+ log.error("Error decrypting text", e);
75
+ throw new SeCurisException("Error decrypting text", e);
76
+ } catch (BadPaddingException e) {
77
+ log.error("Error decrypting text", e);
78
+ throw new SeCurisException("Error decrypting text", e);
79
+ } catch (UnsupportedEncodingException e) {
80
+ log.error("Error decrypting text", e);
81
+ throw new SeCurisException("Error decrypting text", e);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Encrypts a given text with AES algorithm
87
+ *
88
+ * @param plainText
89
+ * in Base64
90
+ * @return
91
+ */
92
+ public String decript(String ciphertext) throws SeCurisException {
93
+ return decript(ciphertext, this.passPhrase);
94
+ }
95
+
96
+ public String decript(String ciphertext, String pass) throws SeCurisException {
97
+ Cipher aes;
98
+ try {
99
+ aes = Cipher.getInstance(CIPHER_ALGORITHM);
100
+ int sep = ciphertext.indexOf('\n');
101
+ if (sep == -1)
102
+ throw new SeCurisException("Unknown format ciphered text");
103
+ byte[] salt = Base64.decodeBase64(ciphertext.substring(0, sep));
104
+ aes.init(Cipher.DECRYPT_MODE, getSecretKey(salt, pass));
105
+ byte[] encryptedBytes = Base64.decodeBase64(ciphertext.substring(sep + 1));
106
+ String cleartext = new String(aes.doFinal(encryptedBytes));
107
+ return cleartext;
108
+ } catch (NoSuchAlgorithmException e) {
109
+ log.error("Error decrypting text", e);
110
+ throw new SeCurisException("Error decrypting text", e);
111
+ } catch (NoSuchPaddingException e) {
112
+ log.error("Error decrypting text", e);
113
+ throw new SeCurisException("Error decrypting text", e);
114
+ } catch (InvalidKeyException e) {
115
+ log.error("Error decrypting text", e);
116
+ throw new SeCurisException("Error decrypting text", e);
117
+ } catch (IllegalBlockSizeException e) {
118
+ log.error("Error decrypting text", e);
119
+ throw new SeCurisException("Error decrypting text", e);
120
+ } catch (BadPaddingException e) {
121
+ log.error("Error decrypting text", e);
122
+ throw new SeCurisException("Error decrypting text", e);
123
+ }
124
+ }
125
+
126
+ private byte[] getSalt() throws SeCurisException {
127
+ byte[] salt = new byte[20];
128
+ new SecureRandom().nextBytes(salt);
129
+ return salt;
130
+ }
131
+
132
+ private SecretKeySpec getSecretKey(byte[] salt, String pass) throws SeCurisException {
133
+ String passPhrase = pass.replace('a', 'ä');
134
+
135
+ try {
136
+ int iterations = 10000;
137
+
138
+ SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_FACTORY, PPROVIDER);
139
+ SecretKey tmp = factory.generateSecret(new PBEKeySpec(passPhrase.toCharArray(), salt, iterations, 128));
140
+ byte[] key = Arrays.copyOf(tmp.getEncoded(), 16);
141
+ SecretKeySpec spec = new SecretKeySpec(key, "AES");
142
+ return spec;
143
+
144
+ } catch (NoSuchAlgorithmException e) {
145
+ log.error("Error generation secret key", e);
146
+ throw new SeCurisException("Error generation secret key", e);
147
+ } catch (InvalidKeySpecException e) {
148
+ log.error("Error generation secret key", e);
149
+ throw new SeCurisException("Error generation secret key", e);
150
+ } catch (NoSuchProviderException e) {
151
+ log.error("Error generation secret key", e);
152
+ throw new SeCurisException("Error generation secret key", e);
153
+ }
154
+ }
155
+}
src/main/java/net/curisit/securis/HWInfo.java
....@@ -0,0 +1,122 @@
1
+package net.curisit.securis;
2
+
3
+import java.net.InetAddress;
4
+import java.net.NetworkInterface;
5
+import java.net.SocketException;
6
+import java.net.UnknownHostException;
7
+import java.util.ArrayList;
8
+import java.util.Collections;
9
+import java.util.List;
10
+
11
+import org.slf4j.Logger;
12
+import org.slf4j.LoggerFactory;
13
+
14
+/**
15
+ * Retrieve HW info
16
+ *
17
+ * @author cesarcalvo
18
+ *
19
+ */
20
+public class HWInfo {
21
+
22
+ private static final Logger log = LoggerFactory.getLogger(HWInfo.class);
23
+
24
+ public static String getOsName() {
25
+ return System.getProperty("os.name");
26
+ }
27
+
28
+ public static String getArch() {
29
+ return System.getProperty("os.arch");
30
+ }
31
+
32
+ public static int getNumCpus() {
33
+ return Runtime.getRuntime().availableProcessors();
34
+ }
35
+
36
+ /**
37
+ * Get MAC address
38
+ *
39
+ * @return
40
+ */
41
+ public static List<String> getMACAddress() throws SeCurisException {
42
+ List<byte[]> macs = new ArrayList<byte[]>();
43
+ try {
44
+ // Get MAC for ethX interface, where X is the lower number with MAC address != null
45
+ for (NetworkInterface network : Collections.list(NetworkInterface.getNetworkInterfaces())) {
46
+ if (!network.isLoopback() && !network.isVirtual() && !network.isPointToPoint() && network.getHardwareAddress() != null) {
47
+ macs.add(network.getHardwareAddress());
48
+ log.debug("Interface added {}, MAC: {}", network.getName(), network.getHardwareAddress());
49
+ logInterface(network);
50
+ }
51
+ }
52
+
53
+ // If not found interface ethX
54
+ if (macs.isEmpty()) {
55
+ NetworkInterface network = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
56
+ if (network.getHardwareAddress() != null)
57
+ macs.add(network.getHardwareAddress());
58
+ log.debug("Selected interface (Inet Address rule)");
59
+ logInterface(network);
60
+ }
61
+
62
+ // If not found interface, last attempt, we get any mac
63
+ if (macs.isEmpty()) {
64
+ for (NetworkInterface network : Collections.list(NetworkInterface.getNetworkInterfaces())) {
65
+ if (!network.isLoopback() && !network.isVirtual() && !network.isPointToPoint() && network.getHardwareAddress() != null) {
66
+ if (network.getHardwareAddress() != null)
67
+ macs.add(network.getHardwareAddress());
68
+ log.debug("Selected interface (Any with MAC rule)");
69
+ logInterface(network);
70
+ break;
71
+ }
72
+ }
73
+ }
74
+
75
+ if (macs.isEmpty())
76
+ throw new SeCurisException("Unable to get MAC address");
77
+
78
+ List<String> macAddresses = new ArrayList<String>();
79
+ for (byte[] mac : macs) {
80
+ macAddresses.add(printMacAddress(mac));
81
+ }
82
+ log.info("MAC Addresses: {}", macAddresses);
83
+ return macAddresses;
84
+
85
+ } catch (UnknownHostException e) {
86
+ throw new SeCurisException("Unable to get MAC address", e);
87
+ } catch (SocketException e) {
88
+ throw new SeCurisException("Unable to get MAC address", e);
89
+ } catch (Exception e) {
90
+ throw new SeCurisException("Unable to get MAC address", e);
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Get microprocessor name
96
+ *
97
+ * @return
98
+ */
99
+ public static String getCPUName() throws SeCurisException {
100
+ return System.getenv("PROCESSOR_IDENTIFIER");
101
+ }
102
+
103
+ private static void logInterface(NetworkInterface network) {
104
+ log.debug("Interface name: {}", network.getName());
105
+ log.debug("Interface display name: {}", network.getDisplayName());
106
+ try {
107
+ log.debug("Interface mac: {}", printMacAddress(network.getHardwareAddress()));
108
+ } catch (SocketException e) {
109
+ // Silent
110
+ }
111
+ }
112
+
113
+ private static String printMacAddress(byte[] mac) {
114
+ StringBuilder sb = new StringBuilder();
115
+ for (int i = 0; i < mac.length; i++) {
116
+ sb.append(String.format("%s%02X", (i > 0) ? "-" : "", mac[i]));
117
+ }
118
+ return sb.toString();
119
+
120
+ }
121
+
122
+}
src/net/curisit/securis/License.java
similarity index 82%rename from src/net/curisit/securis/License.javarename to src/main/java/net/curisit/securis/License.java
....@@ -7,8 +7,12 @@
77 import org.apache.commons.cli.Options;
88 import org.apache.commons.cli.ParseException;
99 import org.apache.commons.cli.PosixParser;
10
+import org.slf4j.Logger;
11
+import org.slf4j.LoggerFactory;
1012
1113 public class License {
14
+
15
+ private static final Logger log = LoggerFactory.getLogger(License.class);
1216
1317 public static void main(String[] args) {
1418 CommandLine cmd = getCommandLine(args);
....@@ -47,11 +51,12 @@
4751 options.addOption("h", "help", false, "Show help.");
4852 options.addOption(OptionBuilder.withArgName("req_file").withLongOpt("rfile").withDescription("Set request file for its generation or for license requesting.").hasArg(true).create('r'));
4953 options.addOption(OptionBuilder.withArgName("url_license_server").withLongOpt("server").withDescription("License server url.").hasArg(true).create('s'));
50
- options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("license").withDescription("Validate lic file.").hasArg(true).create('l'));
54
+ options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("validate").withDescription("Validate lic file.").hasArg(true).create('l'));
5155
5256 options.addOption("g", "gen_request", false, "Generate request file. If --rfile parameter is missing then It is generated in current directory.");
5357 options.addOption("c", "create", false, "Request a license file from server. --rfile and --server parameters are mandatory.");
5458 options.addOption("t", "test_lc", false, "Test if License Server (LC) is available. --server parameter is mandatory.");
59
+ options.addOption(OptionBuilder.withArgName("lic_file").withLongOpt("sync").withDescription("Synchronize/renew the current license file. --server parameter is mandatory.").hasArg(true).create('y'));
5560
5661 return options;
5762 }
src/main/java/net/curisit/securis/LicenseManager.java
....@@ -0,0 +1,47 @@
1
+package net.curisit.securis;
2
+
3
+import java.io.File;
4
+import java.io.IOException;
5
+
6
+import net.curisit.securis.beans.LicenseBean;
7
+import net.curisit.securis.beans.RequestBean;
8
+import net.curisit.securis.utils.JsonUtils;
9
+
10
+import org.apache.commons.io.FileUtils;
11
+
12
+/**
13
+ * Manage all licenses tasks, just like, validation, sync, requesting, ...
14
+ *
15
+ * @author roberto <roberto.sanchez@curisit.net>
16
+ */
17
+public class LicenseManager {
18
+
19
+ private static LicenseManager singleton = new LicenseManager();
20
+
21
+ private LicenseManager() {
22
+ }
23
+
24
+ public static LicenseManager getInstance() {
25
+ return singleton;
26
+ }
27
+
28
+ public LicenseBean validateLicense(File licFile, String appCode, String customerCode) throws SeCurisException {
29
+ LicenseBean licBean;
30
+ try {
31
+ licBean = JsonUtils.json2object(FileUtils.readFileToString(licFile), LicenseBean.class);
32
+ } catch (IOException e) {
33
+ throw new SeCurisException("Error validating license", e);
34
+ }
35
+ SignatureHelper.getInstance().validateSignature(licBean);
36
+ validateHW(licBean, appCode, customerCode);
37
+
38
+ return licBean;
39
+ }
40
+
41
+ private void validateHW(RequestBean reqBean, String appCode, String customerCode) throws SeCurisException {
42
+ RequestBean currentHW = ReqGenerator.getInstance().createRequest(appCode, customerCode);
43
+ if (!currentHW.match(reqBean))
44
+ throw new SeCurisException("Current System info mismatch the License System info: " + JsonUtils.toJSON(reqBean));
45
+ }
46
+
47
+}
src/net/curisit/securis/LicenseValidator.java
similarity index 100%rename from src/net/curisit/securis/LicenseValidator.javarename to src/main/java/net/curisit/securis/LicenseValidator.java
src/main/java/net/curisit/securis/ReqGenerator.java
....@@ -0,0 +1,59 @@
1
+package net.curisit.securis;
2
+
3
+import java.io.IOException;
4
+import java.io.InputStream;
5
+import java.io.UnsupportedEncodingException;
6
+
7
+import net.curisit.securis.beans.RequestBean;
8
+import net.curisit.securis.utils.LicUtils;
9
+
10
+import org.apache.commons.io.IOUtils;
11
+import org.slf4j.Logger;
12
+import org.slf4j.LoggerFactory;
13
+
14
+public class ReqGenerator {
15
+
16
+ @SuppressWarnings("unused")
17
+ private static final Logger log = LoggerFactory.getLogger(ReqGenerator.class);
18
+
19
+ private static ReqGenerator singleton = new ReqGenerator();
20
+
21
+ private byte[] LOGO_SECRET;
22
+
23
+ private ReqGenerator() {
24
+ try {
25
+ LOGO_SECRET = "Logo ipsum s3cr3t test áíóú".getBytes("utf-8");
26
+ } catch (UnsupportedEncodingException e) {
27
+ e.printStackTrace();
28
+ }
29
+ }
30
+
31
+ public static ReqGenerator getInstance() {
32
+ return singleton;
33
+ }
34
+
35
+ public RequestBean createRequest(String appCode, String customerCode) throws SeCurisException {
36
+ RequestBean req = new RequestBean();
37
+
38
+ req.setAppCode(appCode);
39
+ req.setCustomerCode(customerCode);
40
+ req.setArch(HWInfo.getArch());
41
+ req.setCrcLogo(getCrcLogo());
42
+ req.setMacAddresses(HWInfo.getMACAddress());
43
+ req.setOsName(HWInfo.getOsName());
44
+
45
+ return req;
46
+ }
47
+
48
+ private String getCrcLogo() {
49
+ String logResource = "images/logo_customer.png";
50
+ InputStream is = getClass().getClassLoader().getResourceAsStream(logResource);
51
+ try {
52
+ String shaLogo = LicUtils.sha256(IOUtils.toByteArray(is), LOGO_SECRET);
53
+ return shaLogo;
54
+ } catch (IOException e) {
55
+ log.error("Customer logo was not found in classpath in " + logResource, e);
56
+ return null;
57
+ }
58
+ }
59
+}
src/main/java/net/curisit/securis/SeCurisException.java
....@@ -0,0 +1,17 @@
1
+package net.curisit.securis;
2
+
3
+public class SeCurisException extends Exception {
4
+
5
+ private static final long serialVersionUID = 5702956178417661458L;
6
+
7
+ public SeCurisException() {
8
+ }
9
+
10
+ public SeCurisException(String msg, Exception e) {
11
+ super(msg, e);
12
+ }
13
+
14
+ public SeCurisException(String msg) {
15
+ super(msg);
16
+ }
17
+}
src/main/java/net/curisit/securis/SignatureHelper.java
....@@ -0,0 +1,144 @@
1
+package net.curisit.securis;
2
+
3
+import java.io.File;
4
+import java.io.IOException;
5
+import java.io.UnsupportedEncodingException;
6
+import java.security.InvalidKeyException;
7
+import java.security.KeyFactory;
8
+import java.security.KeyPair;
9
+import java.security.NoSuchAlgorithmException;
10
+import java.security.PrivateKey;
11
+import java.security.PublicKey;
12
+import java.security.Signature;
13
+import java.security.SignatureException;
14
+import java.security.spec.InvalidKeySpecException;
15
+import java.security.spec.PKCS8EncodedKeySpec;
16
+import java.security.spec.X509EncodedKeySpec;
17
+import java.util.Date;
18
+
19
+import net.curisit.securis.beans.LicenseBean;
20
+import net.curisit.securis.beans.RequestBean;
21
+import net.curisit.securis.utils.JsonUtils;
22
+import net.curisit.securis.utils.Params;
23
+
24
+import org.apache.commons.io.FileUtils;
25
+import org.apache.commons.net.util.Base64;
26
+import org.apache.log4j.xml.DOMConfigurator;
27
+import org.slf4j.Logger;
28
+import org.slf4j.LoggerFactory;
29
+
30
+//import net.curisit.common.ui.Dialogs;
31
+
32
+/**
33
+ * digital Signature utilities
34
+ *
35
+ * @author roberto <roberto.sanchez@curisit.net>
36
+ */
37
+public class SignatureHelper {
38
+
39
+ private static final Logger log = LoggerFactory.getLogger(SignatureHelper.class);
40
+ private static String AUX = "hEDhryRjs2QRE";
41
+
42
+ private static SignatureHelper singleton = new SignatureHelper();
43
+
44
+ private static final String DEFAULT_ALGORITHM = "RSA";
45
+ protected static final String SIGNATURE_GENERATION_ALGORITHM = "SHA256withRSA";
46
+
47
+ private SignatureHelper() {
48
+ }
49
+
50
+ public static SignatureHelper getInstance() {
51
+ return singleton;
52
+ }
53
+
54
+ protected void prepareSignature(Signature signature, LicenseBean licBean) throws SeCurisException {
55
+ try {
56
+ log.info("JSON: {}", JsonUtils.toJSON(licBean));
57
+ signature.update(JsonUtils.toJSON(licBean).getBytes("utf-8"));
58
+ signature.update(AUX.getBytes("utf-8"));
59
+ } catch (SignatureException | UnsupportedEncodingException e) {
60
+ throw new SeCurisException("Error generating or validating signature", e);
61
+ }
62
+ }
63
+
64
+ public void validateSignature(LicenseBean licBean) throws SeCurisException {
65
+ Signature signature;
66
+ try {
67
+ signature = Signature.getInstance(SIGNATURE_GENERATION_ALGORITHM);
68
+ signature.initVerify(generatePublicKey());
69
+
70
+ prepareSignature(signature, licBean);
71
+
72
+ if (signature.verify(Base64.decodeBase64(licBean.getSignature())))
73
+ return;
74
+ } catch (NoSuchAlgorithmException e) {
75
+ log.error("Error validating license for " + licBean, e);
76
+ } catch (InvalidKeyException e) {
77
+ log.error("Error validating license for " + licBean, e);
78
+ } catch (InvalidKeySpecException e) {
79
+ log.error("Error validating license for " + licBean, e);
80
+ } catch (IOException e) {
81
+ log.error("Error validating license for " + licBean, e);
82
+ } catch (SignatureException e) {
83
+ log.error("Error validating license for " + licBean, e);
84
+ }
85
+ throw new SeCurisException("License could not be validated");
86
+
87
+ }
88
+
89
+ private PublicKey generatePublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
90
+ return generatePublicKey(new File(Params.get(Params.KEYS.PUBLIC_KEY_FILE, System.getenv("SECURIS_PUBLIC_KEY_FILE"))));
91
+ }
92
+
93
+ private PublicKey generatePublicKey(File publicKeyFile) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
94
+ String pubKeyBase64 = FileUtils.readFileToString(publicKeyFile);
95
+ int from = pubKeyBase64.indexOf('\n');
96
+ int to = pubKeyBase64.indexOf("-----END", from);
97
+ pubKeyBase64 = pubKeyBase64.substring(from, to);
98
+
99
+ KeyFactory keyFactory = KeyFactory.getInstance(DEFAULT_ALGORITHM);
100
+ X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(pubKeyBase64));
101
+ PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
102
+ log.info("Public key read sucessfully from file: {}", publicKeyFile.getAbsolutePath());
103
+ return publicKey;
104
+ }
105
+
106
+ protected PrivateKey generatePrivateKey(File privateKeyFile) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
107
+ String privKeyBase64 = FileUtils.readFileToString(privateKeyFile);
108
+ int from = privKeyBase64.indexOf('\n');
109
+ int to = privKeyBase64.indexOf("-----END", from);
110
+ privKeyBase64 = privKeyBase64.substring(from, to);
111
+
112
+ KeyFactory keyFactory = KeyFactory.getInstance(DEFAULT_ALGORITHM);
113
+ PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privKeyBase64));
114
+ PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
115
+
116
+ return privateKey;
117
+ }
118
+
119
+ private KeyPair generateKeyPair(File privateKeyFile, File publicKeyFile) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
120
+
121
+ PublicKey publicKey = generatePublicKey(publicKeyFile);
122
+ PrivateKey privateKey = generatePrivateKey(privateKeyFile);
123
+
124
+ KeyPair kp = new KeyPair(publicKey, privateKey);
125
+ return kp;
126
+ }
127
+
128
+ public static void main(String[] args) throws SeCurisException {
129
+ // org.apache.log4j.Logger.getRootLogger().addAppender(new Appender);
130
+ DOMConfigurator.configure("/Users/cproberto/Documents/wsCurisIT/SeCurisClient/src/main/resources/log4j.xml");
131
+ RequestBean req = ReqGenerator.getInstance().createRequest("CI", "Roberto");
132
+
133
+ LicenseGenerator lg = LicenseGenerator.getInstance();
134
+ LicenseBean lic = lg.generateLicense(req, 12, new Date(new Date().getTime() + 24 * 3600 * 1000 * 10));
135
+ System.out.println(JsonUtils.toJSON(lic, true));
136
+ System.out.println(JsonUtils.toJSON(lic));
137
+ }
138
+
139
+ static {
140
+ byte[] s = new byte[]
141
+ { 64, -31, -81, 36, 99, -77, 100, 17, 16, -119, 31, 72, 123, -88, -32, 51, 39, -96, -35, 116, -65, 8, 41, -119, -108, -34, 41, 19, 26, -102, -16, -120, -96, 1, -5, -26, -13, 61, -121, 94, 59, 54, 110, 110, -55, 127, -106 };
142
+ AUX = Base64.encodeBase64String(s);
143
+ }
144
+}
src/main/java/net/curisit/securis/beans/LicenseBean.java
....@@ -0,0 +1,64 @@
1
+package net.curisit.securis.beans;
2
+
3
+import java.util.Date;
4
+
5
+import org.codehaus.jackson.annotate.JsonPropertyOrder;
6
+
7
+@JsonPropertyOrder(
8
+ { "maxUsers", "expirationDate", "appCode", "arch", "osName", "customerCode", "macAddresses", "crclogo" })
9
+public class LicenseBean extends RequestBean {
10
+ private int maxUsers;
11
+ private Date expirationDate;
12
+ /**
13
+ * Signature is stored in Base64 code
14
+ */
15
+ private String signature;
16
+
17
+ public LicenseBean() {
18
+ }
19
+
20
+ public LicenseBean(RequestBean req) {
21
+ super.setAppCode(req.getAppCode());
22
+ super.setArch(req.getArch());
23
+ super.setCrcLogo(req.getCrcLogo());
24
+ super.setCustomerCode(req.getCustomerCode());
25
+ super.setMacAddresses(req.getMacAddresses());
26
+ super.setOsName(req.getOsName());
27
+ }
28
+
29
+ public String getSignature() {
30
+ return signature;
31
+ }
32
+
33
+ public void setSignature(String signature) {
34
+ this.signature = signature;
35
+ }
36
+
37
+ public Date getExpirationDate() {
38
+ return expirationDate;
39
+ }
40
+
41
+ public void setExpirationDate(Date expirationDate) {
42
+ this.expirationDate = expirationDate;
43
+ }
44
+
45
+ public int getMaxUsers() {
46
+ return maxUsers;
47
+ }
48
+
49
+ public void setMaxUsers(int maxUsers) {
50
+ this.maxUsers = maxUsers;
51
+ }
52
+
53
+ @Override
54
+ public boolean equals(Object obj) {
55
+ if (!(obj instanceof LicenseBean))
56
+ return false;
57
+ LicenseBean rb = (LicenseBean) obj;
58
+ boolean result = (maxUsers == rb.maxUsers);
59
+ result = result && ((expirationDate == null && rb.expirationDate == null) || (expirationDate != null && expirationDate.equals(rb.expirationDate)));
60
+ result = result && ((signature == null && rb.signature == null) || (signature != null && signature.equals(rb.signature)));
61
+
62
+ return result && super.equals(obj);
63
+ }
64
+}
src/main/java/net/curisit/securis/beans/RequestBean.java
....@@ -0,0 +1,97 @@
1
+package net.curisit.securis.beans;
2
+
3
+import java.util.List;
4
+
5
+import org.codehaus.jackson.annotate.JsonAutoDetect;
6
+
7
+@JsonAutoDetect
8
+public class RequestBean {
9
+ private String customerCode;
10
+ private String crcLogo;
11
+ private String appCode;
12
+ private List<String> macAddresses;
13
+ private String osName;
14
+ private String arch;
15
+
16
+ public String getCustomerCode() {
17
+ return customerCode;
18
+ }
19
+
20
+ public void setCustomerCode(String customerCode) {
21
+ this.customerCode = customerCode;
22
+ }
23
+
24
+ public String getCrcLogo() {
25
+ return crcLogo;
26
+ }
27
+
28
+ public void setCrcLogo(String crcLogo) {
29
+ this.crcLogo = crcLogo;
30
+ }
31
+
32
+ public String getAppCode() {
33
+ return appCode;
34
+ }
35
+
36
+ public void setAppCode(String appCode) {
37
+ this.appCode = appCode;
38
+ }
39
+
40
+ public List<String> getMacAddresses() {
41
+ return macAddresses;
42
+ }
43
+
44
+ public void setMacAddresses(List<String> macAddresses) {
45
+ this.macAddresses = macAddresses;
46
+ }
47
+
48
+ public String getOsName() {
49
+ return osName;
50
+ }
51
+
52
+ public void setOsName(String osName) {
53
+ this.osName = osName;
54
+ }
55
+
56
+ public String getArch() {
57
+ return arch;
58
+ }
59
+
60
+ public void setArch(String arch) {
61
+ this.arch = arch;
62
+ }
63
+
64
+ public boolean match(RequestBean rb) {
65
+
66
+ boolean result = appCode != null && appCode.equals(rb.appCode);
67
+ result = result && (arch != null && arch.equals(rb.arch));
68
+ result = result && (crcLogo != null && crcLogo.equals(rb.crcLogo));
69
+ result = result && (customerCode != null && customerCode.equals(rb.customerCode));
70
+ result = result && (osName != null && osName.equals(rb.osName));
71
+ result = result && (macAddresses != null && rb.macAddresses != null) && anyMacIsIncluded(rb.getMacAddresses());
72
+
73
+ return result;
74
+ }
75
+
76
+ private boolean anyMacIsIncluded(List<String> macList) {
77
+ for (String mac : macList) {
78
+ if (macAddresses.contains(mac))
79
+ return true;
80
+ }
81
+ return false;
82
+ }
83
+
84
+ @Override
85
+ public boolean equals(Object obj) {
86
+ if (!(obj instanceof RequestBean))
87
+ return false;
88
+ RequestBean rb = (RequestBean) obj;
89
+ boolean result = (rb.appCode == null && appCode == null) || (appCode != null && appCode.equals(rb.appCode));
90
+ result = result && ((rb.arch == null && arch == null) || (arch != null && arch.equals(rb.arch)));
91
+ result = result && ((rb.crcLogo == null && crcLogo == null) || (crcLogo != null && crcLogo.equals(rb.crcLogo)));
92
+ result = result && ((rb.customerCode == null && customerCode == null) || (customerCode != null && customerCode.equals(rb.customerCode)));
93
+ result = result && ((rb.osName == null && osName == null) || (osName != null && osName.equals(rb.osName)));
94
+ result = result && ((rb.macAddresses == null && macAddresses == null) || (macAddresses != null && macAddresses.equals(rb.macAddresses)));
95
+ return result;
96
+ }
97
+}
src/main/java/net/curisit/securis/utils/JsonUtils.java
....@@ -0,0 +1,205 @@
1
+package net.curisit.securis.utils;
2
+
3
+import java.io.IOException;
4
+import java.util.List;
5
+import java.util.Map;
6
+
7
+import net.curisit.securis.SeCurisException;
8
+
9
+import org.codehaus.jackson.JsonParseException;
10
+import org.codehaus.jackson.JsonParser;
11
+import org.codehaus.jackson.JsonProcessingException;
12
+import org.codehaus.jackson.map.ObjectMapper;
13
+import org.codehaus.jackson.map.SerializationConfig;
14
+import org.codehaus.jackson.type.TypeReference;
15
+import org.slf4j.Logger;
16
+import org.slf4j.LoggerFactory;
17
+
18
+/**
19
+ * Helper method to perform JSON tasks
20
+ *
21
+ * @author cproberto
22
+ */
23
+public class JsonUtils {
24
+
25
+ private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
26
+
27
+ final private static ObjectMapper MAPPER = new ObjectMapper();
28
+
29
+ static {
30
+ MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
31
+ MAPPER.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
32
+ MAPPER.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
33
+ MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
34
+ MAPPER.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
35
+ MAPPER.configure(SerializationConfig.Feature.INDENT_OUTPUT, false);
36
+ MAPPER.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true);
37
+ MAPPER.configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true);
38
+
39
+ }
40
+
41
+ /**
42
+ * Convert an object in the type pass as parameter, avoiding to use casting in code.
43
+ *
44
+ * @param value
45
+ * @param type
46
+ * @return
47
+ */
48
+ public static <T> T value(Object value, Class<T> type) {
49
+
50
+ return (T) value;
51
+ }
52
+
53
+ public static <T> T parseJSON(String json, Class<T> type) throws SeCurisException {
54
+ try {
55
+ if (json == null)
56
+ return null;
57
+ return MAPPER.readValue(json, type);
58
+ } catch (JsonParseException e) {
59
+ log.error("Error parsing JSON string to obejct: {}", json, e);
60
+ if (json.length() > 60)
61
+ json = json.substring(0, 50) + "...";
62
+ throw new SeCurisException("Error parsing JSON string to object: " + json, e);
63
+ } catch (IOException e) {
64
+ log.error("Error parsing JSON string to object: {}", json, e);
65
+ if (json.length() > 60)
66
+ json = json.substring(0, 50) + "...";
67
+ throw new SeCurisException("Error parsing JSON string to object: " + json, e);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Create a JSON string from a object compatible or annotated with Jackson, i.e: <code>
73
+ * {"f1":2345,"f2":"Test de valor"}
74
+ *
75
+ * @param obj
76
+ * @return JSON string representation from object
77
+ */
78
+ public static String toJSON(Object obj) throws SeCurisException {
79
+ // and could also do other configuration...
80
+ try {
81
+ if (obj == null)
82
+ return null;
83
+ return MAPPER.writeValueAsString(obj);
84
+ } catch (JsonProcessingException e) {
85
+ log.error("Error formating JSON from object: {}", obj, e);
86
+ throw new SeCurisException("Error formating JSON from object: " + obj, e);
87
+ } catch (IOException e) {
88
+ log.error("Error formating JSON from object: {}", obj, e);
89
+ throw new SeCurisException("Error formating JSON from object: " + obj, e);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Create a JSON string from a object compatible or annotated with Jackson, i.e: <code>
95
+ * {"f1":2345,"f2":"Test de valor"}
96
+ *
97
+ * @param obj
98
+ * @return JSON string representation from object
99
+ */
100
+ public static String toJSON(Object obj, boolean pretty) throws SeCurisException {
101
+ // and could also do other configuration...
102
+ try {
103
+ if (obj == null)
104
+ return null;
105
+ MAPPER.enable(SerializationConfig.Feature.INDENT_OUTPUT);
106
+ String json = MAPPER.writeValueAsString(obj);
107
+ MAPPER.disable(SerializationConfig.Feature.INDENT_OUTPUT);
108
+ return json;
109
+ } catch (JsonProcessingException e) {
110
+ log.error("Error formating JSON from object: {}", obj, e);
111
+ throw new SeCurisException("Error formating JSON from object: " + obj, e);
112
+ } catch (IOException e) {
113
+ log.error("Error formating JSON from object: {}", obj, e);
114
+ throw new SeCurisException("Error formating JSON from object: " + obj, e);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Create a Map from a json string, i.e: <code>
120
+ * {"f1":2345,"f2":"Test de valor"}
121
+ * </code>
122
+ *
123
+ * @param json
124
+ * String with json format
125
+ * @return
126
+ */
127
+ public static Map<String, Object> json2map(String json) throws JsonParseException {
128
+
129
+ try {
130
+ if (json == null)
131
+ return null;
132
+ return MAPPER.readValue(json, Map.class);
133
+ } catch (JsonParseException e) {
134
+ log.error("Error parsing JSON string to map: {}", json, e);
135
+ throw e;
136
+ } catch (IOException e) {
137
+ log.error("Error parsing JSON string to map: {}", json, e);
138
+ }
139
+ return null;
140
+ }
141
+
142
+ /**
143
+ * Create a JSON strin from a Map object, i.e: <code>
144
+ * {"f1":2345,"f2":"Test de valor"}
145
+ *
146
+ * @param map
147
+ * @return
148
+ */
149
+ public static String map2json(Map<String, Object> map) {
150
+ // and could also do other configuration...
151
+ try {
152
+ if (map == null)
153
+ return null;
154
+ return MAPPER.writeValueAsString(map);
155
+ } catch (JsonProcessingException e) {
156
+ log.error("Error formating JSON from map: {}", map, e);
157
+ } catch (IOException e) {
158
+ log.error("Error formating JSON from map: {}", map, e);
159
+ }
160
+
161
+ return null;
162
+ }
163
+
164
+ /**
165
+ * Create a Map from a json string, i.e: <code>
166
+ * [{"f1":2345}, {"f2":"Test de valor"}]
167
+ * </code>
168
+ *
169
+ * @param json
170
+ * String with json format
171
+ * @return
172
+ */
173
+ public static List<Object> json2list(String json) {
174
+ try {
175
+ return MAPPER.readValue(json, List.class);
176
+ } catch (JsonParseException e) {
177
+ log.error("Error converting JSON string to object {}", json, e);
178
+ } catch (IOException e) {
179
+ log.error("Error converting JSON string to object {}", json, e);
180
+ }
181
+ return null;
182
+ }
183
+
184
+ public static <T> T json2object(String json, Class<T> classObject) throws SeCurisException {
185
+ try {
186
+ return MAPPER.readValue(json, classObject);
187
+ } catch (JsonParseException e) {
188
+ throw new SeCurisException("Error converting JSON to object", e);
189
+ } catch (IOException e) {
190
+ throw new SeCurisException("Error converting JSON to object", e);
191
+ }
192
+ }
193
+
194
+ public static <T> T json2object(String json, TypeReference<T> typeReference) throws SeCurisException {
195
+ try {
196
+ return MAPPER.readValue(json, typeReference);
197
+ } catch (JsonParseException e) {
198
+ throw new SeCurisException("Error converting JSON to object", e);
199
+ } catch (IOException e) {
200
+ e.printStackTrace();
201
+ throw new SeCurisException("Error converting JSON to object", e);
202
+ }
203
+ }
204
+
205
+}
src/net/curisit/securis/utils/LicUtils.java
similarity index 100%rename from src/net/curisit/securis/utils/LicUtils.javarename to src/main/java/net/curisit/securis/utils/LicUtils.java
src/main/java/net/curisit/securis/utils/Params.java
....@@ -0,0 +1,191 @@
1
+package net.curisit.securis.utils;
2
+
3
+import java.io.IOException;
4
+import java.io.InputStream;
5
+import java.text.MessageFormat;
6
+import java.util.ArrayList;
7
+import java.util.List;
8
+import java.util.Properties;
9
+
10
+import org.slf4j.Logger;
11
+import org.slf4j.LoggerFactory;
12
+
13
+/**
14
+ * Class that loads and serves global config parameters.
15
+ *
16
+ * @author rsanchez
17
+ */
18
+public class Params {
19
+
20
+ private static Logger log = LoggerFactory.getLogger(Params.class);
21
+
22
+ /**
23
+ * Key used to store config file resource location. In a web application, can be set as initial parameter in a servlet loaded on startup
24
+ */
25
+ public static final String KEY_CONFIG_FILE = "/securis-client.properties";
26
+
27
+ private static Properties params = null;
28
+
29
+ static {
30
+ try {
31
+ loadParameters(KEY_CONFIG_FILE);
32
+ } catch (IOException e) {
33
+ log.error("Config file {} was not found in classpath", KEY_CONFIG_FILE);
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Loads application global parameters from a classpath resource
39
+ *
40
+ * @param resource
41
+ * : Resource location in classpath, i.e: "/resource/cp-securis.conf"
42
+ * @throws IOException
43
+ */
44
+ public static void loadParameters(String resource) throws IOException {
45
+
46
+ log.info("Loading params from " + resource);
47
+ InputStream fileis = Params.class.getResourceAsStream(resource);
48
+
49
+ params = new Properties();
50
+ try {
51
+
52
+ params.load(fileis);
53
+ log.info("Params loaded OK");
54
+ } catch (IOException e) {
55
+ log.error("Error loading config file: " + e);
56
+ params = null;
57
+ throw e;
58
+ }
59
+
60
+ }
61
+
62
+ public static String getByDomain(String domain, String paramname) {
63
+ return getByDomain(domain, paramname, null);
64
+ }
65
+
66
+ public static String getByPrefix(String prefix, String paramname) {
67
+ return get(prefix + "." + paramname, get(paramname));
68
+ }
69
+
70
+ public static String getByPrefix(String prefix, String paramname, String defaultVal) {
71
+ return get(prefix + "." + paramname, get(paramname, defaultVal));
72
+ }
73
+
74
+ public static String getByDomain(String domain, String paramname, String defaultval) {
75
+ return get(paramname + "." + domain, defaultval);
76
+ }
77
+
78
+ public static int getIntByDomain(String domain, String paramname) {
79
+ return getInt(paramname + "." + domain, getInt(paramname));
80
+ }
81
+
82
+ public static int getIntByDomain(String domain, String paramname, int defaultval) {
83
+ return getInt(paramname + "." + domain, defaultval);
84
+ }
85
+
86
+ /**
87
+ * Gets a List with all values of properties that begins with <code>prefix</code> It reads sequentially. For example:
88
+ *
89
+ * <pre>
90
+ * securis.sort.comparator.0: net.cp.securis.comparators.ComparePttidVsPtn
91
+ * securis.sort.comparator.1: net.cp.securis.comparators.CompareFrequency
92
+ * securis.sort.comparator.2: net.cp.securis.comparators.CompareOutgoingVsIncomming
93
+ * securis.sort.comparator.3: net.cp.securis.comparators.CompareDuration
94
+ * securis.sort.comparator.4: net.cp.securis.comparators.CompareCallVsSms
95
+ * </pre>
96
+ *
97
+ * That config (for prefix: "securis.sort.comparator" ) will return a List<String> with values:
98
+ *
99
+ * <pre>
100
+ * "net.cp.securis.comparators.ComparePttidVsPtn",
101
+ * "net.cp.securis.comparators.CompareFrequency",
102
+ * "net.cp.securis.comparators.CompareOutgoingVsIncomming",
103
+ * "net.cp.securis.comparators.CompareDuration",
104
+ * "net.cp.securis.comparators.CompareCallVsSms"
105
+ * </pre>
106
+ *
107
+ * Note: If there is a gap between suffixes process will stop, that is, only will be returned properties found before gap.
108
+ *
109
+ * @param prefix
110
+ * @return
111
+ */
112
+ public static List<String> getListByPrefix(String prefix) {
113
+ List<String> list = new ArrayList<String>();
114
+
115
+ String tpl = prefix + ".{0}";
116
+
117
+ int i = 0;
118
+ String value = get(MessageFormat.format(tpl, i++));
119
+ while (value != null) {
120
+ list.add(value);
121
+ value = get(MessageFormat.format(tpl, i++));
122
+ }
123
+
124
+ return list;
125
+ }
126
+
127
+ /**
128
+ * Gets param value in config file or environment variables
129
+ *
130
+ * @param paramname
131
+ * Global parameter's name
132
+ * @return Value of paramname or null if paramname is not found neither in config file nor in environment variables
133
+ */
134
+ public static String get(String paramname) {
135
+
136
+ assert (params != null) : "Parameters have not been loaded. Call method loadParameters(resource) before use Params.";
137
+
138
+ String value = params.getProperty(paramname);
139
+ if (value == null)
140
+ value = System.getenv(paramname);
141
+ return value;
142
+ }
143
+
144
+ /**
145
+ * Gets param value from config file or environment variables
146
+ *
147
+ * @param paramname
148
+ * Global parameter's name
149
+ * @param defaultval
150
+ * @return Value of paramname or defaultval if paramname is not found
151
+ */
152
+ public static String get(String paramname, String defaultval) {
153
+ String value = get(paramname);
154
+ return (value == null ? defaultval : value);
155
+ }
156
+
157
+ /**
158
+ * Gets param value in config file or environment variables
159
+ *
160
+ * @param paramname
161
+ * Global parameter's name
162
+ * @return Integer value of paramname or -1 if paramname is not found neither in config file nor in environment variables
163
+ */
164
+ public static int getInt(String paramname) {
165
+ String value = get(paramname);
166
+ return (value == null ? -1 : Integer.parseInt(value));
167
+ }
168
+
169
+ /**
170
+ * Gets param value from config file or environment variables
171
+ *
172
+ * @param paramname
173
+ * Global parameter's name
174
+ * @param defaultval
175
+ * @return Integer value of paramname or defaultval if paramname is not found
176
+ */
177
+ public static int getInt(String paramname, int defaultval) {
178
+ String value = get(paramname);
179
+ return (value == null ? defaultval : Integer.parseInt(value));
180
+ }
181
+
182
+ public static class KEYS {
183
+
184
+ /**
185
+ * Public key file, Usually in "PEM" format
186
+ */
187
+ public static final String PUBLIC_KEY_FILE = "public.key.file";
188
+
189
+ }
190
+
191
+}
src/main/resources/images/logo_customer.png
Binary files differ
src/main/resources/log4j.xml
....@@ -0,0 +1,26 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
3
+
4
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
5
+
6
+ <appender name="console" class="org.apache.log4j.ConsoleAppender">
7
+ <param name="Target" value="System.out"/>
8
+ <layout class="org.apache.log4j.PatternLayout">
9
+ <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
10
+ </layout>
11
+ </appender>
12
+
13
+ <logger name="net.curisit">
14
+ <level value="INFO"/>
15
+ </logger>
16
+
17
+ <logger name="sandbox">
18
+ <level value="DEBUG"/>
19
+ </logger>
20
+
21
+ <root>
22
+ <priority value ="INFO" />
23
+ <appender-ref ref="console" />
24
+ </root>
25
+
26
+</log4j:configuration>
src/main/resources/securis-client.properties
....@@ -0,0 +1 @@
1
+public.key.file = /Users/cproberto/Documents/wsPython/doky/tests/mykey.pub
src/net/curisit/securis/ReqGenerator.java
deleted file mode 100644
....@@ -1,11 +0,0 @@
1
-package net.curisit.securis;
2
-
3
-import org.slf4j.Logger;
4
-import org.slf4j.LoggerFactory;
5
-
6
-public class ReqGenerator {
7
-
8
- @SuppressWarnings("unused")
9
- private static final Logger log = LoggerFactory.getLogger(ReqGenerator.class);
10
-
11
-}
src/patch/java/net/curisit/securis/LicenseGenerator.java
....@@ -0,0 +1,106 @@
1
+package net.curisit.securis;
2
+
3
+import java.io.File;
4
+import java.io.IOException;
5
+import java.security.InvalidKeyException;
6
+import java.security.NoSuchAlgorithmException;
7
+import java.security.NoSuchProviderException;
8
+import java.security.Signature;
9
+import java.security.SignatureException;
10
+import java.security.spec.InvalidKeySpecException;
11
+import java.text.MessageFormat;
12
+import java.util.Date;
13
+
14
+import net.curisit.securis.beans.LicenseBean;
15
+import net.curisit.securis.beans.RequestBean;
16
+
17
+import org.apache.commons.net.util.Base64;
18
+import org.slf4j.Logger;
19
+import org.slf4j.LoggerFactory;
20
+
21
+/**
22
+ * License generator and signer
23
+ *
24
+ * @author roberto <roberto.sanchez@curisit.net>
25
+ */
26
+public class LicenseGenerator {
27
+
28
+ @SuppressWarnings("unused")
29
+ private static final Logger log = LoggerFactory.getLogger(LicenseGenerator.class);
30
+
31
+ private static LicenseGenerator singleton = new LicenseGenerator();
32
+
33
+ private LicenseGenerator() {
34
+ }
35
+
36
+ public static LicenseGenerator getInstance() {
37
+ return singleton;
38
+ }
39
+
40
+ /**
41
+ * Generate a license bean with the specified data
42
+ *
43
+ * @param hw
44
+ * @param customerCode
45
+ * - e.g: "BP"
46
+ * @param maxInstances
47
+ * @param maxUsers
48
+ * @param maxTimeThreshold
49
+ * Max time between synchronizations expressed in days
50
+ * @return
51
+ * @throws SeCurisException
52
+ */
53
+ public LicenseBean generateLicense(RequestBean req, int maxUsers, Date expirationDate) throws SeCurisException {
54
+ log.info(MessageFormat.format("Generating license: MAC: {0}, Customer code: {1}, AppCode: {2}", req.getMacAddresses(), req.getCustomerCode(), req.getAppCode()));
55
+ LicenseBean license = new LicenseBean(req);
56
+ license.setExpirationDate(expirationDate);
57
+ license.setMaxUsers(maxUsers);
58
+ sign(license);
59
+
60
+ return license;
61
+ }
62
+
63
+ /**
64
+ * TODO: This method should be removed from client code.
65
+ *
66
+ * @param licBean
67
+ * @return
68
+ * @throws NoSuchAlgorithmException
69
+ * @throws IOException
70
+ * @throws InvalidKeySpecException
71
+ * @throws InvalidKeyException
72
+ * @throws SignatureException
73
+ */
74
+ public String sign(LicenseBean licBean) throws SeCurisException {
75
+ SignatureHelper sh = SignatureHelper.getInstance();
76
+
77
+ Signature signature;
78
+ try {
79
+ signature = Signature.getInstance(SignatureHelper.SIGNATURE_GENERATION_ALGORITHM);
80
+ signature.initSign(sh.generatePrivateKey(new File("/Users/cproberto/Documents/wsPython/doky/tests/privkey.pkcs8")));
81
+
82
+ sh.prepareSignature(signature, licBean);
83
+
84
+ byte[] signatureData = signature.sign();
85
+ licBean.setSignature(Base64.encodeBase64String(signatureData));
86
+ return licBean.getSignature();
87
+ } catch (NoSuchAlgorithmException e) {
88
+ log.error("Error signing license for " + licBean, e);
89
+ } catch (InvalidKeyException e) {
90
+ log.error("Error signing license for " + licBean, e);
91
+ } catch (InvalidKeySpecException e) {
92
+ log.error("Error signing license for " + licBean, e);
93
+ } catch (IOException e) {
94
+ log.error("Error signing license for " + licBean, e);
95
+ } catch (SignatureException e) {
96
+ log.error("Error signing license for " + licBean, e);
97
+ }
98
+ throw new SeCurisException("License could not be generated");
99
+ }
100
+
101
+ public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException, InvalidKeyException, SignatureException {
102
+
103
+ System.out.print("os.arch: " + System.getProperty("os.arch") + " " + System.getProperty("os.name"));
104
+
105
+ }
106
+}