From e32a89a958cc42e24a43abf375044cb57c1c73d8 Mon Sep 17 00:00:00 2001 From: Patrik Dufresne Date: Wed, 16 Jan 2019 16:05:42 -0500 Subject: [PATCH] TASK-1080 Promote the license module --- README | 27 --- README.md | 74 ++++++++ docs/examples/Main.java | 41 +++++ docs/examples/application.lic | 7 + docs/examples/privkey.der | Bin 0 -> 1218 bytes docs/examples/privkey.pem | 27 +++ docs/examples/pubkey.der | Bin 0 -> 294 bytes pom.xml | 12 ++ .../java/com/patrikdufresne/license/Main.java | 159 ++++++++++++++++++ 9 files changed, 320 insertions(+), 27 deletions(-) delete mode 100644 README create mode 100644 README.md create mode 100644 docs/examples/Main.java create mode 100644 docs/examples/application.lic create mode 100644 docs/examples/privkey.der create mode 100644 docs/examples/privkey.pem create mode 100644 docs/examples/pubkey.der create mode 100644 src/main/java/com/patrikdufresne/license/Main.java diff --git a/README b/README deleted file mode 100644 index bc20128..0000000 --- a/README +++ /dev/null @@ -1,27 +0,0 @@ -# How it work ? - - -# Usage - -## Generate your public and private key - -Create the private key (containing information to create the public key). - - $ openssl genrsa -out privkey.pem 2048 - $ openssl pkcs8 -topk8 -in privkey.pem -inform PEM -nocrypt -outform DER -out privkey.der - -Extract the public key, for publishing. - $ openssl rsa -in privkey.pem -out pubkey.der -pubout -outform DER - - - -# License - -This program is free software; you can redistribute it and/or modify -it under the terms of Apache License 2.0 - -You should have received a copy of the Apache License 2.0 -along with this program in the file named "LICENSE". - -This package is based on the following article: -http://blog.afewguyscoding.com/2012/02/licensing-module-java/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..89503ea --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +# How it work ? +This project provide a java library to be used by your java project to easily validate a license file. + +1. You generate a private and public key. +2. You publish your application with this library and your public key. +3. You keep the private key for youself. + +1. You generate a license file for your user with a deadline. +2. You are sending this file to your user (via email or similar). +3. Your user install this license file where your application can pick it up. +4. When your application start, this library is used to validate the license file and validate the deadline. + +# Usage + +## Generate your public and private key + +Create the private key: + + openssl genrsa -out privkey.pem 2048 + openssl pkcs8 -topk8 -in privkey.pem -inform PEM -nocrypt -outform DER -out privkey.der + +Extract the public key, for publishing: + + openssl rsa -in privkey.pem -out pubkey.der -pubout -outform DER + +## Publish your application with this library +To make use of this license library, you must change a bit the implementation of your application. First, you must import the library. For maven project, you may edit the `pom.xml` as follow: + + + + patrikdufresne + http://nexus.patrikdufresne.com/content/groups/public/ + + + + ... + + + + com.patrikdufresne + license + 0.11 + + + + +In your java code, you must implement something similar. + + License l; + try { + l = LicenseManager.validate(Main.class.getResourceAsStream("/pubkey.der"), new File("application.lic")); + } catch (LicenseException e) { + System.out.println("invalid license file:" + e.getMessage()); + System.exit(1); + return; + } + System.out.println("License to: " + l.getProperty(License.NAME)); + System.out.println("Expired: " + l.getProperty(License.EXPIRATION)); + +Take a loot at http://git.patrikdufresne.com/pdsl/license/blob/master/docs/examples/Main.java + +## Generate a license file + +To generate a license file you may use the jar it self in command line: + + wget https://nexus.patrikdufresne.com/repository/public/com/patrikdufresne/license/0.11/license-0.11.jar + java -jar license-0.11.jar create -p pubkey.der -P privkey.der -n username -m test@example.com -e 2020-01-09 + +It's generate a license file named `application.lic`. + + +# Notes +This library is compatible with Java 7 and earlier. This library doesn't need any dependecies. + diff --git a/docs/examples/Main.java b/docs/examples/Main.java new file mode 100644 index 0000000..d5ef3e0 --- /dev/null +++ b/docs/examples/Main.java @@ -0,0 +1,41 @@ +/** + * Copyright(C) 2013 Patrik Dufresne Service Logiciel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.ekwos; + +import java.io.File; + +import com.patrikdufresne.license.License; +import com.patrikdufresne.license.LicenseException; +import com.patrikdufresne.license.LicenseManager; + +public class Main { + + public static void main(String[] args) { + + License l; + try { + l = LicenseManager.validate(Main.class.getResourceAsStream("/pubkey.der"), new File("application.lic")); + } catch (LicenseException e) { + System.out.println("invalid license file:" + e.getMessage()); + System.exit(1); + return; + } + System.out.println("License to: " + l.getProperty(License.NAME)); + System.out.println("Expired: " + l.getProperty(License.EXPIRATION)); + + } + +} diff --git a/docs/examples/application.lic b/docs/examples/application.lic new file mode 100644 index 0000000..a92afc7 --- /dev/null +++ b/docs/examples/application.lic @@ -0,0 +1,7 @@ +#License file +#Wed Jan 16 16:00:25 EST 2019 +signature=JLGa91NTwe4KBppK+dmy7JIor9QdW+frG8Zmun5i57b3b1jgeeNDtGibxM1poMdPPg4lyoP6R8qCQwSbfzE/DV7uj+awNzHesAxMohOfGI7rc7RH91o9OUzx8r1iuObJnOhhDOnxVmFrBdKxxYXopl1gqdF9B+wGzv7pyHp9hG3ayTId0NG6zISlX1RWDVqeVnXQoarVSa6Xmc7fBSW1XswFtyLCuJO932IS73V6Det0Y+3xAwvZRShouMSL5NOUyCZcwVCsvghY24x5BJYd7PmYOTEwuwW1uCEzRAu64G0a/Ysh/5/ciVc2FyNPOmODvf4P02FW6z6hL4sEfLcwyQ\=\= +licenseType=trial +expiration=2020-01-01 +email=info@patrikdufresne.com +name=patrik diff --git a/docs/examples/privkey.der b/docs/examples/privkey.der new file mode 100644 index 0000000000000000000000000000000000000000..e2783a2d8d375804835860b3c91be1fad5479558 GIT binary patch literal 1218 zcmV;z1U>sOf&{(-0RS)!1_>&LNQUrs4#*Aqyhl|0)hbn0NJG>@8?Ti zYS60G*E!a1^vNx(2}buFPNQr@RdD^3ON1J8`cz=96Vjq@?|9|EB}f%b;?E&UQYp1Z~Xd(KUMCN{!?_TmBgoWCgjNdI0x<(Bk7{19f3n?Xu+_zUj z;D2d|Aq?6vHl#XBIYNYj@U!0|)*xRRqEgqh z_x32lWjZ$*ra~`j!u(i5p{}lCeQ?&**n7j+A+tw#YeDWjCc4(rQ*Rx`3s}66YEbQr z+Z7JL)Tqr4I~ZrMkc=1Sh~ij}`Qg_h@^XXYG+4-|sRo~$b;&t6@+`)vu!~}6g7XYz1YOk3v?VpJyCfk)iP?JV?@QEX=Oyt z0%K3tie~@>*K~!s`SOU3RA#HNi|vp?r$lbBeR68N)MV!|L`sjI;9*jE8NmX9fdKBe z$NZ*wh{0YxhKK$R(Ct3hdSEj|I}k(oR_(WSBeoWp+Lt-vNq;9GOqQ1>p!Z+Cx$=?Y zr&uXb_ok2)$S{MrZNZ>RbM?}_3-jF%86KIb(im2O=ThU`=cw+S!?pYg?9XxOQ0ZA$ zNPu*B3E_kYyz_x6K^T&LD7B$fn>%59?is^|GuDF=M{KChhR2 z#`z#5OyTY`-g$K;BDWlbg(qu~5KY`mQ^94y^16cv@nzWWtExt%IrF2x{;fh*NL2!X zfdJ!*@TkS|P{pXz(wS^DsW*#J1C0?d_iwPORtfKROWgE3Eg3rolyVGIfJ}z9K6kC2 z`c>L<`hHQIod^1jn5~V_&1K{&C)H@vfSK6=cd6)3M$rO+fdGP^yioxdRBKCPm^=b*H6$D1hU@s7 z(lVrOjXXX@4DD;cCYM|^Q(l&80tIkE+VjRBPlJW3{*iqRw8CH}73RIPR{f>;#5r`D z39p3C0XL7^fdjbGVxmg}dx%SShb88>iw=oki}BK>PLXcc|&w0l{Jv%Ni8$Y`Sl zviSmmfNskfTb=+|0Al9rWc9HMniDfi8CFWiw7ZbfE9s=^i_pZ0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>l*`*=x=SyB{(5lqe zIo59U$t|o2M)w^~qijS~aQ&1^gc@`DRA8(&r?BN{A^Mp_=6;m#Uh*G=h1!~o-z^ckMhzeszR5ESDJ6;Aw^u>ne`$yz z4B9a^q&iDELWF|wv)?1uAYU4yQrENN{?G@d-U@0N@)5S-+fCmOO~l_2cvf?sL+47J zrrY+*t+Ufalse + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.patrikdufresne.license.Main + + + + diff --git a/src/main/java/com/patrikdufresne/license/Main.java b/src/main/java/com/patrikdufresne/license/Main.java new file mode 100644 index 0000000..d70ccd1 --- /dev/null +++ b/src/main/java/com/patrikdufresne/license/Main.java @@ -0,0 +1,159 @@ +/** + * Copyright(C) 2018 Patrik Dufresne Service Logiciel + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.patrikdufresne.license; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Main entry point when this library is executed from command line. + * + * @author Patrik Dufresne + * + */ +public class Main { + + public static void create(String publicKey, String privateKey, String name, String email, String expiration, String output) + throws GeneralSecurityException, + IOException { + if (publicKey == null) { + throw new IllegalArgumentException("public key is missing"); + } + if (privateKey == null) { + throw new IllegalArgumentException("private key is missing"); + } + if (expiration == null) { + throw new IllegalArgumentException("expiration date is missing"); + } + + // Create license obj + License license = new License(); + license.setProperty(License.NAME, name); + license.setProperty(License.EMAIL, email); + license.setProperty(License.LICENSE_TYPE, License.TYPE_TRIAL); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date d; + try { + d = dateFormat.parse(expiration); + } catch (ParseException e1) { + throw new IllegalArgumentException("Wrong date value: " + expiration); + } + license.setExpiration(d); + + // Create the license file + LicenseManager manager = new LicenseManager(publicKey, privateKey); + manager.writeLicense(license, new File(output)); + + } + + public static void main(String[] args) throws GeneralSecurityException { + if (args.length == 0) { + usage(); + return; + } + // Parse arguments + String publicKey = null; + String privateKey = null; + String name = ""; + String email = ""; + String expiration = null; + String file = "application.lic"; + + String action = args[0]; + if (!action.equals("create") && !action.equals("validate")) { + usage(); + return; + } + int idx = 1; + while (idx < args.length) { + switch (args[idx]) { + case "-p": + case "--public": + idx++; + publicKey = args[idx]; + break; + case "-P": + case "--private": + idx++; + privateKey = args[idx]; + break; + case "-n": + case "--name": + idx++; + name = args[idx]; + break; + case "-m": + case "--email": + idx++; + email = args[idx]; + break; + case "-e": + case "--expiration": + idx++; + expiration = args[idx]; + break; + case "-f": + case "--file": + idx++; + file = args[idx]; + break; + default: + System.err.println("unknown arguments: " + args[idx]); + usage(); + return; + } + idx++; + } + // Take action. + try { + if (action.equals("create")) { + create(publicKey, privateKey, name, email, expiration, file); + System.out.println("license " + file + " created"); + } else if (action.equals("validate")) { + try { + LicenseManager.validate(new FileInputStream(publicKey), new File(file)); + } catch (LicenseException e) { + System.out.println("license " + file + " invalid: " + e.getMessage()); + System.exit(1); + } + System.out.println("license " + file + " valid"); + } else { + usage(); + } + } catch (IOException | IllegalArgumentException e) { + System.err.println(e.getMessage()); + System.exit(1); + } + + } + + public static void usage() { + System.out.println("usage:"); + System.out.println(" create -p pubkey.der -P privkey.der [-n name] [-m email] -e YYYY-mm-dd [-f application.lic]"); + System.out.println(" validate -p pubkey.der [-f application.lic]"); + System.out.println(""); + System.out.println(" -p, --public define the public key file in DER format"); + System.out.println(" -P, --private define the private key file file in DER format"); + System.out.println(" -n, --name name to be stored in the license file (optional)"); + System.out.println(" -m, --mail email to be stored in the license file (optional)"); + System.out.println(" -e, --expiration expiration date in YYYY-mm-dd format"); + System.out.println(" -f, --file the license file to be created or validated (default: application.lic)"); + System.exit(1); + } + +} -- GitLab