Merge branch 'dev' into es_integration

Original commit: elastic/x-pack-elasticsearch@7b3a74f175
This commit is contained in:
Areek Zillur 2014-10-07 12:38:24 -04:00
commit a034f96497
10 changed files with 129 additions and 178 deletions

View File

@ -13,38 +13,37 @@ Generates a 2048-bit RSA public/private key pair to be used for license generati
**Note:** Errors if provided file paths for public/private already exists **Note:** Errors if provided file paths for public/private already exists
**Output** - public/private key in the location provided with the provided key password **Output** - public/private key in the location provided
**Options:** **Options:**
`--publicKeyPath` - path to store the public key `--publicKeyPath` - path to store the public key
`--privateKeyPath` - path to store the private key `--privateKeyPath` - path to store the private key
`--keyPass` - password for the key pair
**Example Usage:** **Example Usage:**
```bash ```bash
$ bin/key-pair-generator --publicKeyPath ~/.es_temp_license/pub.key --privateKeyPath ~/.es_temp_license/pri.key --keyPass ab $ bin/key-pair-generator --publicKeyPath ~/.es_temp_license/pub.key --privateKeyPath ~/.es_temp_license/pri.key
``` ```
Outputs the public key to `~/.es_temp_license/pub.key`, private key to `~/.es_temp_license/pri.key` securing the key pair with the provided `--keyPass` of `ab` Outputs the public key to `~/.es_temp_license/pub.key`, private key to `~/.es_temp_license/pri.key`
### bin/license-generator ### bin/license-generator
Generates a signed license given a licensing spec and keyPair location Generates a signed license given a licensing spec and keyPair location
**Note:** a `license spec` (see format below) can be provided in two ways, using `--license` allows for passing the spec as a string using `--licenseFile` allows passing in a file that has the license spec **Note:** a `license spec` (see format below) can be provided in two ways, using `--license` allows for passing the spec as a string using `--licenseFile` allows passing in a file that has the license spec
**Output** - a signed license based on the provided `license spec`, private/public key location and password **Output** - a signed license based on the provided `license spec`, private/public key location
**Options:** **Options:**
`--license` - license spec as a string (optional when `--licenseFile` is provided) `--license` - license spec as a string (optional when `--licenseFile` is provided)
`--licenseFile` - path to a license spec file (optional when `--license` is provided) `--licenseFile` - path to a license spec file (optional when `--license` is provided)
`--publicKeyPath` - path to retrieve the public key `--publicKeyPath` - path to retrieve the public key
`--privateKeyPath` - path to retrieve the private key `--privateKeyPath` - path to retrieve the private key
`--keyPass` - password for the key pair provided
**License Spec format:** **License Spec format:**
``` ```
{ {
"licenses": [ "licenses": [
{ {
"uid": STRING (optional, if not provided a random UUID is generated)
"type": STRING (“trial” | “internal” | “subscription”), "type": STRING (“trial” | “internal” | “subscription”),
"subscription_type": STRING (“none” | “gold” | “silver” | “platinum”), "subscription_type": STRING (“none” | “gold” | “silver” | “platinum”),
"issued_to": STRING, "issued_to": STRING,
@ -83,7 +82,7 @@ $ cat license_spec.json
# generate a signed license according to license_spec.json using the private/public keypair # generate a signed license according to license_spec.json using the private/public keypair
$ bin/license-generator --publicKeyPath ~/.es_temp_license/pub.key --privateKeyPath ~/.es_temp_license/pri.key --keyPass ab --licenseFile license_spec.json > gen_license.json $ bin/license-generator --publicKeyPath ~/.es_temp_license/pub.key --privateKeyPath ~/.es_temp_license/pri.key --licenseFile license_spec.json > gen_license.json
# generated license for license_spec.json # generated license for license_spec.json
@ -117,14 +116,41 @@ One licenses that only retains effective sub-licenses for all the licenses provi
**Options:** **Options:**
`--licensesFiles` - a set of **generated** licenses files separated by `:` `--licensesFiles` - a set of **generated** licenses files separated by `:`
`--licenses` - a **generated** licenses as string (multiple licenses could be inputted by repeating the parameter)
`--publicKeyPath` - path to retrieve the public key `--publicKeyPath` - path to retrieve the public key
`--keyPass` - password for the key pair provided
**Example Usage:** **Example Usage:**
``` ```bash
# the output will be the same as the content of gen_license.json (as all the licenses are valid and not expired) # the output will be the same as the content of gen_license.json (as all the licenses are valid and not expired)
# in order to merge multiple licenses file use --licensesFiles file1.json:file2.json # in order to merge multiple licenses file use --licensesFiles file1.json:file2.json
$ bin/verify-license --publicKeyPath ~/.es_temp_license/pub.key --keyPass ab --licensesFiles gen_license.json $ bin/verify-license --publicKeyPath ~/.es_temp_license/pub.key --licensesFiles gen_license.json
# example using verify-license with multiple licenses json as string
$ bin/verify-license --publicKeyPath ~/.es_temp_license/pub.key --licenses `cat generated_license1.json` --licenses `cat generated_license2.json`
``` ```
## Workflow
A public/private key pair has to be generated before license generation
```bash
# store public/private key pair to PUBLIC_KEY_FILE_PATH and PRIVATE_KEY_FILE_PATH respectively
$ bin/key-pair-generator --publicKeyPath PUBLIC_KEY_FILE_PATH --privateKeyPath PRIVATE_KEY_FILE_PATH
```
### License Generation
```bash
# generate a license for a requested feature for a customer with a LICENSE_SPEC (format shown above)
$ bin/license-generator --publicKeyPath PUBLIC_KEY_FILE_PATH --privateKeyPath PRIVATE_KEY_FILE_PATH --license LICENSE_SPEC > GENERATED_LICENSE
# check any existing valid licenses already issued to the customer from the data store; grab the last generated license file for the customer
# as EXISTING_LICENSE
# use verify-license to generate en EFFECTIVE_LICENSE for the customer for distribution
$ bin/verify-license --publicKeyPath PUBLIC_KEY_FILE_PATH --privateKeyPath PRIVATE_KEY_FILE_PATH --licenses GENERATED_LICENSE_STRING --licenses EXISTING_LICENSE_STRING > EFFECTIVE_LICENSE
```

View File

@ -1,13 +0,0 @@
{
"licenses" : [ {
"uid" : "d8bcf9e8-bcb0-4f72-81ca-8a7537a436c5",
"type" : "internal",
"subscription_type" : "none",
"issued_to" : "issuedTo",
"issue_date" : "2014-09-29",
"expiry_date" : "2015-08-29",
"feature" : "shield",
"max_nodes" : 1,
"signature" : "naPgicfKM2+IJ0AoYgAAAG0AAAAAVGdIQ01qZUtCeEZNbS8wcTF4RU5mYUpiY01hdFlQNEVkdFJhYitoZndrSTI5eVZrY3ZRZ3lYU0s1QWdYb0Y5d1dBQmRUK01leE1aR0RUOHhoRVVhVUE9PaztAAVzcgAxbmV0Lm5pY2hvbGFzd2lsbGlhbXMuamF2YS5saWNlbnNpbmcuU2lnbmVkTGljZW5zZYqE/59+smqEAgACWwAObGljZW5zZUNvbnRlbnR0AAJbQlsAEHNpZ25hdHVyZUNvbnRlbnRxAH4AAXhwdXIAAltCrPMX+AYIVOACAAB4cAAAAMCsH5r77/8FtWY+JxKd9MiBTYQLcXgmXMm+Y83VaNwmlr1lASJ2yf7rWojiuHTWemtUNtOZcXeSrLfs/oKwBzXIfvEZV8X/vPCWnpi7VtU4Hp+OZUFO4c0NQ1PnVdDk1uns16Dqe99/ota3FSvdFrmlzkz2E+2bbx0fwWbKnGDXFXy6eE7OISRJdCqa8gljMo9PA1+RI7MFQ8bSzs9up0cEkSuPzgtafFW5zfyn2vpoPZTxDpJslTBk7S3mdchE0eJ1cQB+AAMAAAEAdikZHpJVMxWMxNsksYnNOD7F+15SK3MCtUWJnQdhYCuVHdKQUE3YxWv59QQuDmKuLbnvi0DsuPGlq3hEx0AXmbpaBOhkwTv3DKZH7V6C0YmXj7RLZobaDTtGY2pwV6Qf5+teq5dV493a1k6YGFiwUoERuWQxqmA36naLdVo2diCSh8QmZ4ihKnhqxwswh2TlnCVuaNN3E7HuGeE0wYgFEfgISJOFlEOnLOItRlrQOTzCq+mhASKbANxx/Z42eMGrgs+GJsxYQZfnBh8K3NQFQk2SjWR1sEgqUPXC+0Z7ungzkkwoSBbrdJfRPKbqXFDthWI1DY9SSZnTbwpUC2XA6Q=="
} ]
}

View File

@ -28,34 +28,28 @@ import static org.elasticsearch.license.core.ESLicenses.ESLicense;
public class ESLicenseSigner { public class ESLicenseSigner {
public static String DEFAULT_PASS_PHRASE = "elasticsearch-license";
private final static int VERSION_START = 0; private final static int VERSION_START = 0;
private final static int VERSION = VERSION_START; private final static int VERSION = VERSION_START;
private final static int MAGIC_LENGTH = 13; private final static int MAGIC_LENGTH = 13;
private final LicenseCreator licenseCreator; private final LicenseCreator licenseCreator;
private final SignerOptions options;
public static class SignerOptions { private final Path publicKeyPath;
final String privateKeyPath;
final String publicKeyPath;
final String password;
public SignerOptions(String privateKeyPath, String publicKeyPath, String password) { public ESLicenseSigner(final String privateKeyPath, final String publicKeyPath) {
this.privateKeyPath = privateKeyPath; this(Paths.get(privateKeyPath), Paths.get(publicKeyPath));
this.publicKeyPath = publicKeyPath;
this.password = password;
}
} }
public ESLicenseSigner(final SignerOptions options) { public ESLicenseSigner(final Path privateKeyPath, final Path publicKeyPath) {
LicenseCreatorProperties.setPrivateKeyDataProvider(new PrivateKeyDataProvider() { LicenseCreatorProperties.setPrivateKeyDataProvider(new PrivateKeyDataProvider() {
@Override @Override
public byte[] getEncryptedPrivateKeyData() throws KeyNotFoundException { public byte[] getEncryptedPrivateKeyData() throws KeyNotFoundException {
Path privateKeyFile = Paths.get(options.privateKeyPath); assert privateKeyPath.toFile().exists();
assert privateKeyFile.toFile().exists();
try { try {
return Files.readAllBytes(privateKeyFile); return Files.readAllBytes(privateKeyPath);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
throw new IllegalStateException(e); throw new IllegalStateException(e);
@ -64,13 +58,14 @@ public class ESLicenseSigner {
} }
}); });
LicenseCreatorProperties.setPrivateKeyPasswordProvider(new PasswordProvider() { LicenseCreatorProperties.setPrivateKeyPasswordProvider(new PasswordProvider() {
@Override @Override
public char[] getPassword() { public char[] getPassword() {
return options.password.toCharArray(); return Hasher.hash(DEFAULT_PASS_PHRASE).toCharArray();
} }
}); });
this.licenseCreator = LicenseCreator.getInstance(); this.licenseCreator = LicenseCreator.getInstance();
this.options = options; this.publicKeyPath = publicKeyPath;
} }
public ESLicenses sign(ESLicenses esLicenses) throws IOException { public ESLicenses sign(ESLicenses esLicenses) throws IOException {
@ -108,7 +103,7 @@ public class ESLicenseSigner {
random.nextBytes(magic); random.nextBytes(magic);
final byte[] licenseSignature = licenseCreator.signAndSerializeLicense(license); final byte[] licenseSignature = licenseCreator.signAndSerializeLicense(license);
final byte[] hash = Hasher.hash(Base64.encodeBase64String( final byte[] hash = Hasher.hash(Base64.encodeBase64String(
Files.readAllBytes(Paths.get(options.publicKeyPath))) Files.readAllBytes(publicKeyPath))
).getBytes(Charset.forName("UTF-8")); ).getBytes(Charset.forName("UTF-8"));
int headerLength = MAGIC_LENGTH + hash.length + 4 + 4; int headerLength = MAGIC_LENGTH + hash.length + 4 + 4;
byte[] bytes = new byte[headerLength + licenseSignature.length]; byte[] bytes = new byte[headerLength + licenseSignature.length];

View File

@ -5,6 +5,7 @@
*/ */
package org.elasticsearch.license.licensor.tools; package org.elasticsearch.license.licensor.tools;
import net.nicholaswilliams.java.licensing.encryption.Hasher;
import net.nicholaswilliams.java.licensing.encryption.RSAKeyPairGenerator; import net.nicholaswilliams.java.licensing.encryption.RSAKeyPairGenerator;
import net.nicholaswilliams.java.licensing.exception.AlgorithmNotSupportedException; import net.nicholaswilliams.java.licensing.exception.AlgorithmNotSupportedException;
import net.nicholaswilliams.java.licensing.exception.InappropriateKeyException; import net.nicholaswilliams.java.licensing.exception.InappropriateKeyException;
@ -16,22 +17,21 @@ import java.security.KeyPair;
public class KeyPairGeneratorTool { public class KeyPairGeneratorTool {
public static String DEFAULT_PASS_PHRASE = "elasticsearch-license";
static class Options { static class Options {
private final String publicKeyFilePath; private final String publicKeyFilePath;
private final String privateKeyFilePath; private final String privateKeyFilePath;
private final String keyPass;
Options(String publicKeyFilePath, String privateKeyFilePath, String keyPass) { Options(String publicKeyFilePath, String privateKeyFilePath) {
this.publicKeyFilePath = publicKeyFilePath; this.publicKeyFilePath = publicKeyFilePath;
this.privateKeyFilePath = privateKeyFilePath; this.privateKeyFilePath = privateKeyFilePath;
this.keyPass = keyPass;
} }
} }
private static Options parse(String[] args) { private static Options parse(String[] args) {
String privateKeyPath = null; String privateKeyPath = null;
String publicKeyPath = null; String publicKeyPath = null;
String keyPass = null;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
String command = args[i]; String command = args[i];
@ -42,9 +42,6 @@ public class KeyPairGeneratorTool {
case "--privateKeyPath": case "--privateKeyPath":
privateKeyPath = args[++i]; privateKeyPath = args[++i];
break; break;
case "--keyPass":
keyPass = args[++i];
break;
} }
} }
@ -54,11 +51,8 @@ public class KeyPairGeneratorTool {
if (privateKeyPath == null) { if (privateKeyPath == null) {
throw new IllegalArgumentException("mandatory option '--privateKeyPath' is missing"); throw new IllegalArgumentException("mandatory option '--privateKeyPath' is missing");
} }
if (keyPass == null) {
throw new IllegalArgumentException("mandatory option '--keyPass' is missing");
}
return new Options(publicKeyPath, privateKeyPath, keyPass); return new Options(publicKeyPath, privateKeyPath);
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
@ -76,7 +70,7 @@ public class KeyPairGeneratorTool {
throw new IllegalArgumentException("public key already exists in " + options.publicKeyFilePath); throw new IllegalArgumentException("public key already exists in " + options.publicKeyFilePath);
} }
KeyPair keyPair = generateKeyPair(options.privateKeyFilePath, options.publicKeyFilePath, options.keyPass); KeyPair keyPair = generateKeyPair(options.privateKeyFilePath, options.publicKeyFilePath);
if (keyPair != null) { if (keyPair != null) {
printStream.println("Successfully generated new keyPair [publicKey: " + options.publicKeyFilePath + ", privateKey: " + options.privateKeyFilePath + "]"); printStream.println("Successfully generated new keyPair [publicKey: " + options.publicKeyFilePath + ", privateKey: " + options.privateKeyFilePath + "]");
printStream.flush(); printStream.flush();
@ -88,7 +82,7 @@ public class KeyPairGeneratorTool {
} }
private static KeyPair generateKeyPair(String privateKeyFileName, String publicKeyFileName, String password) { private static KeyPair generateKeyPair(String privateKeyFileName, String publicKeyFileName) {
RSAKeyPairGenerator generator = new RSAKeyPairGenerator(); RSAKeyPairGenerator generator = new RSAKeyPairGenerator();
KeyPair keyPair; KeyPair keyPair;
@ -99,7 +93,7 @@ public class KeyPairGeneratorTool {
} }
try { try {
generator.saveKeyPairToFiles(keyPair, privateKeyFileName, publicKeyFileName, password.toCharArray()); generator.saveKeyPairToFiles(keyPair, privateKeyFileName, publicKeyFileName, Hasher.hash(DEFAULT_PASS_PHRASE).toCharArray());
} catch (IOException | AlgorithmNotSupportedException | InappropriateKeyException | InappropriateKeySpecificationException e) { } catch (IOException | AlgorithmNotSupportedException | InappropriateKeyException | InappropriateKeySpecificationException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }

View File

@ -21,13 +21,11 @@ public class LicenseGeneratorTool {
private final String licensesInput; private final String licensesInput;
private final String publicKeyFilePath; private final String publicKeyFilePath;
private final String privateKeyFilePath; private final String privateKeyFilePath;
private final String keyPass;
Options(String licensesInput, String publicKeyFilePath, String privateKeyFilePath, String keyPass) { Options(String licensesInput, String publicKeyFilePath, String privateKeyFilePath) {
this.licensesInput = licensesInput; this.licensesInput = licensesInput;
this.publicKeyFilePath = publicKeyFilePath; this.publicKeyFilePath = publicKeyFilePath;
this.privateKeyFilePath = privateKeyFilePath; this.privateKeyFilePath = privateKeyFilePath;
this.keyPass = keyPass;
} }
} }
@ -36,7 +34,6 @@ public class LicenseGeneratorTool {
String licenseFilePath = null; String licenseFilePath = null;
String privateKeyPath = null; String privateKeyPath = null;
String publicKeyPath = null; String publicKeyPath = null;
String keyPass = null;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
String command = args[i].trim(); String command = args[i].trim();
@ -53,9 +50,6 @@ public class LicenseGeneratorTool {
case "--privateKeyPath": case "--privateKeyPath":
privateKeyPath = args[++i]; privateKeyPath = args[++i];
break; break;
case "--keyPass":
keyPass = args[++i];
break;
} }
} }
@ -75,11 +69,8 @@ public class LicenseGeneratorTool {
if (privateKeyPath == null) { if (privateKeyPath == null) {
throw new IllegalArgumentException("mandatory option '--privateKeyPath' is missing"); throw new IllegalArgumentException("mandatory option '--privateKeyPath' is missing");
} }
if (keyPass == null) {
throw new IllegalArgumentException("mandatory option '--keyPass' is missing");
}
return new Options(licenseInput, publicKeyPath, privateKeyPath, keyPass); return new Options(licenseInput, publicKeyPath, privateKeyPath);
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
@ -91,7 +82,7 @@ public class LicenseGeneratorTool {
ESLicenses esLicenses = LicenseUtils.readLicensesFromString(options.licensesInput); ESLicenses esLicenses = LicenseUtils.readLicensesFromString(options.licensesInput);
ESLicenseSigner signer = new ESLicenseSigner(new ESLicenseSigner.SignerOptions(options.privateKeyFilePath, options.publicKeyFilePath, options.keyPass)); ESLicenseSigner signer = new ESLicenseSigner(options.privateKeyFilePath, options.publicKeyFilePath);
ESLicenses signedLicences = signer.sign(esLicenses); ESLicenses signedLicences = signer.sign(esLicenses);
LicenseUtils.dumpLicenseAsJson(signedLicences, out); LicenseUtils.dumpLicenseAsJson(signedLicences, out);

View File

@ -19,35 +19,42 @@ import java.util.Set;
public class LicenseVerificationTool { public class LicenseVerificationTool {
static class Options { static class Options {
private final Set<File> licensesFiles; private final Set<ESLicenses> licenses;
private final String publicKeyFilePath; private final String publicKeyFilePath;
private final String keyPass;
Options(Set<File> licensesFiles, String publicKeyFilePath, String keyPass) { Options(Set<ESLicenses> licenses, String publicKeyFilePath) {
this.licensesFiles = licensesFiles; this.licenses = licenses;
this.publicKeyFilePath = publicKeyFilePath; this.publicKeyFilePath = publicKeyFilePath;
this.keyPass = keyPass;
} }
static Set<File> asFiles(Set<String> filePaths) {
Set<File> files = new HashSet<>(filePaths.size());
for (String filePath : filePaths) {
final File file = new File(filePath);
if (file.exists()) {
files.add(file);
} else {
throw new IllegalArgumentException(file.getAbsolutePath() + " does not exist!");
}
}
return files;
}
} }
private static Options parse(String[] args) { static Set<ESLicenses> asLicensesFromFiles(Set<String> filePaths) throws IOException {
Set<ESLicenses> licenses = new HashSet<>(filePaths.size());
for (String filePath : filePaths) {
final File file = new File(filePath);
if (file.exists()) {
licenses.add(LicenseUtils.readLicenseFile(file));
} else {
throw new IllegalArgumentException(file.getAbsolutePath() + " does not exist!");
}
}
return licenses;
}
static Set<ESLicenses> asLicensesFromStrings(Set<String> fileContents) throws IOException {
Set<ESLicenses> licenses = new HashSet<>(fileContents.size());
for (String fileContent : fileContents) {
licenses.add(LicenseUtils.readLicensesFromString(fileContent));
}
return licenses;
}
private static Options parse(String[] args) throws IOException {
Set<String> licenseFilePaths = null; Set<String> licenseFilePaths = null;
Set<File> licenseFiles = null; Set<String> licensesContents = new HashSet<>();
Set<ESLicenses> licenses = null;
String publicKeyPath = null; String publicKeyPath = null;
String keyPass = null;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
String command = args[i]; String command = args[i];
@ -56,29 +63,28 @@ public class LicenseVerificationTool {
licenseFilePaths = new HashSet<>(); licenseFilePaths = new HashSet<>();
licenseFilePaths.addAll(Arrays.asList(args[++i].split(":"))); licenseFilePaths.addAll(Arrays.asList(args[++i].split(":")));
break; break;
case "--licenses":
licensesContents.add(args[++i]);
break;
case "--publicKeyPath": case "--publicKeyPath":
publicKeyPath = args[++i]; publicKeyPath = args[++i];
break; break;
case "--keyPass":
keyPass = args[++i];
break;
} }
} }
if (licenseFilePaths == null) { if (licenseFilePaths == null && licensesContents.size() == 0) {
throw new IllegalArgumentException("mandatory option '--licensesFiles' is missing"); throw new IllegalArgumentException("mandatory option '--licensesFiles' or '--licenses' is missing");
} else if (licenseFilePaths != null) {
licenses = asLicensesFromFiles(licenseFilePaths);
} else if (licensesContents.size() > 0) {
licenses = asLicensesFromStrings(licensesContents);
} else { } else {
licenseFiles = Options.asFiles(licenseFilePaths); throw new IllegalArgumentException("no licenses could be extracted");
if (licenseFiles.size() == 0) {
throw new IllegalArgumentException("no license file found for provided license files");
}
} }
if (publicKeyPath == null) { if (publicKeyPath == null) {
throw new IllegalArgumentException("mandatory option '--publicKeyPath' is missing"); throw new IllegalArgumentException("mandatory option '--publicKeyPath' is missing");
} }
if (keyPass == null) { assert licenses != null;
throw new IllegalArgumentException("mandatory option '--keyPass' is missing"); return new Options(licenses, publicKeyPath);
}
return new Options(licenseFiles, publicKeyPath, keyPass);
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
@ -88,11 +94,8 @@ public class LicenseVerificationTool {
public static void run(String[] args, OutputStream out) throws IOException { public static void run(String[] args, OutputStream out) throws IOException {
Options options = parse(args); Options options = parse(args);
// read licenses
Set<ESLicenses> esLicensesSet = LicenseUtils.readLicensesFromFiles(options.licensesFiles);
// verify licenses // verify licenses
ESLicenseManager licenseManager = new ESLicenseManager(esLicensesSet, options.publicKeyFilePath, options.keyPass); ESLicenseManager licenseManager = new ESLicenseManager(options.licenses, options.publicKeyFilePath);
licenseManager.verifyLicenses(); licenseManager.verifyLicenses();
// dump effective licences // dump effective licences

View File

@ -41,19 +41,19 @@ public class ESLicenseManager {
private final ESLicenses esLicenses; private final ESLicenses esLicenses;
private final FilePublicKeyDataProvider publicKeyDataProvider; private final FilePublicKeyDataProvider publicKeyDataProvider;
public ESLicenseManager(Set<ESLicenses> esLicensesSet, String publicKeyFile, String password) throws IOException { public ESLicenseManager(Set<ESLicenses> esLicensesSet, String publicKeyFile) throws IOException {
this.publicKeyDataProvider = new FilePublicKeyDataProvider(publicKeyFile); this.publicKeyDataProvider = new FilePublicKeyDataProvider(publicKeyFile);
this.esLicenses = merge(esLicensesSet); this.esLicenses = merge(esLicensesSet);
LicenseManagerProperties.setLicenseProvider(new ESLicenseProvider()); LicenseManagerProperties.setLicenseProvider(new ESLicenseProvider());
LicenseManagerProperties.setPublicKeyDataProvider(publicKeyDataProvider); LicenseManagerProperties.setPublicKeyDataProvider(publicKeyDataProvider);
LicenseManagerProperties.setLicenseValidator(new DefaultLicenseValidator()); LicenseManagerProperties.setLicenseValidator(new DefaultLicenseValidator());
LicenseManagerProperties.setPublicKeyPasswordProvider(new ESPublicKeyPasswordProvider(password)); LicenseManagerProperties.setPublicKeyPasswordProvider(new ESPublicKeyPasswordProvider());
this.licenseManager = LicenseManager.getInstance(); this.licenseManager = LicenseManager.getInstance();
} }
public ESLicenseManager(ESLicenses esLicenses, String publicKeyFile, String password) throws IOException { public ESLicenseManager(ESLicenses esLicenses, String publicKeyFile) throws IOException {
this(Collections.singleton(esLicenses), publicKeyFile, password); this(Collections.singleton(esLicenses), publicKeyFile);
} }
private static ESLicenses merge(Set<ESLicenses> esLicensesSet) { private static ESLicenses merge(Set<ESLicenses> esLicensesSet) {
@ -129,7 +129,7 @@ public class ESLicenseManager {
&& license.getHolder().equals(eslicense.issuedTo()) && license.getHolder().equals(eslicense.issuedTo())
&& license.getIssueDate() == eslicense.issueDate() && license.getIssueDate() == eslicense.issueDate()
&& license.getGoodBeforeDate() == eslicense.expiryDate(); && license.getGoodBeforeDate() == eslicense.expiryDate();
assert license.getFeatures().size() == 4 : "one license should have only four feature"; assert license.getFeatures().size() == 4 : "one license should have only four features";
String maxNodesPrefix = "maxNodes:"; String maxNodesPrefix = "maxNodes:";
String typePrefix = "type:"; String typePrefix = "type:";
String subscriptionTypePrefix = "subscription_type:"; String subscriptionTypePrefix = "subscription_type:";
@ -137,6 +137,7 @@ public class ESLicenseManager {
boolean featureValid = false; boolean featureValid = false;
boolean typeValid = false; boolean typeValid = false;
boolean subscriptionTypeValid = false; boolean subscriptionTypeValid = false;
for (License.Feature feature : license.getFeatures()) { for (License.Feature feature : license.getFeatures()) {
String featureName = feature.getName(); String featureName = feature.getName();
if (featureName.startsWith(maxNodesPrefix)) { if (featureName.startsWith(maxNodesPrefix)) {
@ -151,6 +152,7 @@ public class ESLicenseManager {
} }
} }
if (!licenseValid || !featureValid || !maxNodesValid || !typeValid || !subscriptionTypeValid) { if (!licenseValid || !featureValid || !maxNodesValid || !typeValid || !subscriptionTypeValid) {
//only for debugging
String msg = "licenseValid: " + licenseValid + "\n" + String msg = "licenseValid: " + licenseValid + "\n" +
"featureValid: " + featureValid + "\n" + "featureValid: " + featureValid + "\n" +
"maxNodeValide: " + maxNodesValid + "\n" + "maxNodeValide: " + maxNodesValid + "\n" +
@ -255,16 +257,11 @@ public class ESLicenseManager {
} }
private class ESPublicKeyPasswordProvider implements PasswordProvider { private class ESPublicKeyPasswordProvider implements PasswordProvider {
private final String DEFAULT_PASS_PHRASE = "elasticsearch-license";
private final String pass;
private ESPublicKeyPasswordProvider(String pass) {
this.pass = pass;
}
@Override @Override
public char[] getPassword() { public char[] getPassword() {
return pass.toCharArray(); return Hasher.hash(DEFAULT_PASS_PHRASE).toCharArray();
} }
} }
} }

View File

@ -26,7 +26,6 @@ public class LicenseGenerationTests {
private static String pubKeyPath = null; private static String pubKeyPath = null;
private static String priKeyPath = null; private static String priKeyPath = null;
private static String keyPass = null;
@BeforeClass @BeforeClass
public static void setup() throws IOException { public static void setup() throws IOException {
@ -38,17 +37,13 @@ public class LicenseGenerationTests {
LicenseGenerationTests.priKeyPath = privateKeyFile.getAbsolutePath(); LicenseGenerationTests.priKeyPath = privateKeyFile.getAbsolutePath();
assert privateKeyFile.delete(); assert privateKeyFile.delete();
assert publicKeyFile.delete(); assert publicKeyFile.delete();
String keyPass = "password";
LicenseGenerationTests.keyPass = keyPass;
// Generate keyPair // Generate keyPair
String[] args = new String[6]; String[] args = new String[4];
args[0] = "--publicKeyPath"; args[0] = "--publicKeyPath";
args[1] = LicenseGenerationTests.pubKeyPath; args[1] = LicenseGenerationTests.pubKeyPath;
args[2] = "--privateKeyPath"; args[2] = "--privateKeyPath";
args[3] = LicenseGenerationTests.priKeyPath; args[3] = LicenseGenerationTests.priKeyPath;
args[4] = "--keyPass";
args[5] = LicenseGenerationTests.keyPass;
KeyPairGeneratorTool.main(args); KeyPairGeneratorTool.main(args);
} }
@ -61,15 +56,13 @@ public class LicenseGenerationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
@ -90,15 +83,13 @@ public class LicenseGenerationTests {
map.put(FeatureType.MARVEL, marvelFeatureAttributes); map.put(FeatureType.MARVEL, marvelFeatureAttributes);
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
@ -117,15 +108,13 @@ public class LicenseGenerationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--linse"; args[0] = "--linse";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
try { try {
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
@ -145,15 +134,13 @@ public class LicenseGenerationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
try { try {
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
@ -172,15 +159,13 @@ public class LicenseGenerationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
try { try {
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
@ -200,15 +185,13 @@ public class LicenseGenerationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
try { try {
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);

View File

@ -25,7 +25,6 @@ public class LicenseVerificationToolTests {
private static String pubKeyPath = null; private static String pubKeyPath = null;
private static String priKeyPath = null; private static String priKeyPath = null;
private static String keyPass = null;
@BeforeClass @BeforeClass
public static void setup() throws IOException { public static void setup() throws IOException {
@ -37,16 +36,13 @@ public class LicenseVerificationToolTests {
LicenseVerificationToolTests.priKeyPath = privateKeyFile.getAbsolutePath(); LicenseVerificationToolTests.priKeyPath = privateKeyFile.getAbsolutePath();
assert privateKeyFile.delete(); assert privateKeyFile.delete();
assert publicKeyFile.delete(); assert publicKeyFile.delete();
LicenseVerificationToolTests.keyPass = "password";
// Generate keyPair // Generate keyPair
String[] args = new String[6]; String[] args = new String[4];
args[0] = "--publicKeyPath"; args[0] = "--publicKeyPath";
args[1] = LicenseVerificationToolTests.pubKeyPath; args[1] = LicenseVerificationToolTests.pubKeyPath;
args[2] = "--privateKeyPath"; args[2] = "--privateKeyPath";
args[3] = LicenseVerificationToolTests.priKeyPath; args[3] = LicenseVerificationToolTests.priKeyPath;
args[4] = "--keyPass";
args[5] = LicenseVerificationToolTests.keyPass;
KeyPairGeneratorTool.main(args); KeyPairGeneratorTool.main(args);
} }
@ -67,13 +63,11 @@ public class LicenseVerificationToolTests {
signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map));
String secondLicenseFile = getAsFilePath(signedLicense); String secondLicenseFile = getAsFilePath(signedLicense);
String[] args = new String[6]; String[] args = new String[4];
args[0] = "--licensesFiles"; args[0] = "--licensesFiles";
args[1] = firstLicenseFile + ":" + secondLicenseFile; args[1] = firstLicenseFile + ":" + secondLicenseFile;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--keyPass";
args[5] = keyPass;
String effectiveLicenseStr = runLicenseVerificationTool(args); String effectiveLicenseStr = runLicenseVerificationTool(args);
ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr); ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr);
@ -101,13 +95,11 @@ public class LicenseVerificationToolTests {
signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map));
String secondLicenseFile = getAsFilePath(signedLicense); String secondLicenseFile = getAsFilePath(signedLicense);
String[] args = new String[6]; String[] args = new String[4];
args[0] = "--licensesFiles"; args[0] = "--licensesFiles";
args[1] = firstLicenseFile + ":" + secondLicenseFile; args[1] = firstLicenseFile + ":" + secondLicenseFile;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--keyPass";
args[5] = keyPass;
String effectiveLicenseStr = runLicenseVerificationTool(args); String effectiveLicenseStr = runLicenseVerificationTool(args);
ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr); ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr);
@ -142,13 +134,11 @@ public class LicenseVerificationToolTests {
signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map)); signedLicense = runLicenseGenerationTool(TestUtils.generateESLicenses(map));
String secondLicenseFile = getAsFilePath(signedLicense); String secondLicenseFile = getAsFilePath(signedLicense);
String[] args = new String[6]; String[] args = new String[4];
args[0] = "--licensesFiles"; args[0] = "--licensesFiles";
args[1] = firstLicenseFile + ":" + secondLicenseFile; args[1] = firstLicenseFile + ":" + secondLicenseFile;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--keyPass";
args[5] = keyPass;
String effectiveLicenseStr = runLicenseVerificationTool(args); String effectiveLicenseStr = runLicenseVerificationTool(args);
ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr); ESLicenses effectiveLicense = LicenseUtils.readLicensesFromString(effectiveLicenseStr);
@ -170,16 +160,13 @@ public class LicenseVerificationToolTests {
} }
public static String runLicenseGenerationTool(String licenseInput) throws IOException { public static String runLicenseGenerationTool(String licenseInput) throws IOException {
String args[] = new String[8]; String args[] = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseInput; args[1] = licenseInput;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
return TestUtils.runLicenseGenerationTool(args); return TestUtils.runLicenseGenerationTool(args);
} }

View File

@ -31,7 +31,6 @@ public class LicenseVerificationTests {
private static String pubKeyPath = null; private static String pubKeyPath = null;
private static String priKeyPath = null; private static String priKeyPath = null;
private static String keyPass = null;
@BeforeClass @BeforeClass
public static void setup() throws IOException { public static void setup() throws IOException {
@ -43,16 +42,13 @@ public class LicenseVerificationTests {
LicenseVerificationTests.priKeyPath = privateKeyFile.getAbsolutePath(); LicenseVerificationTests.priKeyPath = privateKeyFile.getAbsolutePath();
assert privateKeyFile.delete(); assert privateKeyFile.delete();
assert publicKeyFile.delete(); assert publicKeyFile.delete();
LicenseVerificationTests.keyPass = "password";
// Generate keyPair // Generate keyPair
String[] args = new String[6]; String[] args = new String[4];
args[0] = "--publicKeyPath"; args[0] = "--publicKeyPath";
args[1] = LicenseVerificationTests.pubKeyPath; args[1] = LicenseVerificationTests.pubKeyPath;
args[2] = "--privateKeyPath"; args[2] = "--privateKeyPath";
args[3] = LicenseVerificationTests.priKeyPath; args[3] = LicenseVerificationTests.priKeyPath;
args[4] = "--keyPass";
args[5] = LicenseVerificationTests.keyPass;
KeyPairGeneratorTool.main(args); KeyPairGeneratorTool.main(args);
} }
@ -68,21 +64,19 @@ public class LicenseVerificationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
ESLicenses esLicensesOutput = readLicensesFromString(licenseOutput); ESLicenses esLicensesOutput = readLicensesFromString(licenseOutput);
ESLicenseManager esLicenseManager = new ESLicenseManager(esLicensesOutput, pubKeyPath, keyPass); ESLicenseManager esLicenseManager = new ESLicenseManager(esLicensesOutput, pubKeyPath);
esLicenseManager.verifyLicenses(); esLicenseManager.verifyLicenses();
@ -105,21 +99,19 @@ public class LicenseVerificationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
ESLicenses esLicensesOutput = readLicensesFromString(licenseOutput); ESLicenses esLicensesOutput = readLicensesFromString(licenseOutput);
ESLicenseManager esLicenseManager = new ESLicenseManager(esLicensesOutput, pubKeyPath, keyPass); ESLicenseManager esLicenseManager = new ESLicenseManager(esLicensesOutput, pubKeyPath);
esLicenseManager.verifyLicenses(); esLicenseManager.verifyLicenses();
@ -145,21 +137,19 @@ public class LicenseVerificationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
ESLicenses esLicensesOutput = readLicensesFromString(licenseOutput); ESLicenses esLicensesOutput = readLicensesFromString(licenseOutput);
ESLicenseManager esLicenseManager = new ESLicenseManager(esLicensesOutput, pubKeyPath, keyPass); ESLicenseManager esLicenseManager = new ESLicenseManager(esLicensesOutput, pubKeyPath);
// All validation for shield license should be normal as expected // All validation for shield license should be normal as expected
verifyLicenseManager(esLicenseManager, Collections.singletonMap(FeatureType.SHIELD, shildFeatureAttributes)); verifyLicenseManager(esLicenseManager, Collections.singletonMap(FeatureType.SHIELD, shildFeatureAttributes));
@ -180,15 +170,13 @@ public class LicenseVerificationTests {
String licenseString = TestUtils.generateESLicenses(map); String licenseString = TestUtils.generateESLicenses(map);
String[] args = new String[8]; String[] args = new String[6];
args[0] = "--license"; args[0] = "--license";
args[1] = licenseString; args[1] = licenseString;
args[2] = "--publicKeyPath"; args[2] = "--publicKeyPath";
args[3] = pubKeyPath; args[3] = pubKeyPath;
args[4] = "--privateKeyPath"; args[4] = "--privateKeyPath";
args[5] = priKeyPath; args[5] = priKeyPath;
args[6] = "--keyPass";
args[7] = keyPass;
String licenseOutput = TestUtils.runLicenseGenerationTool(args); String licenseOutput = TestUtils.runLicenseGenerationTool(args);
@ -208,7 +196,7 @@ public class LicenseVerificationTests {
ESLicenseManager esLicenseManager = null; ESLicenseManager esLicenseManager = null;
try { try {
esLicenseManager = new ESLicenseManager(tamperedLicenses, pubKeyPath, keyPass); esLicenseManager = new ESLicenseManager(tamperedLicenses, pubKeyPath);
assertTrue("License manager should always report the original (signed) expiry date", esLicenseManager.getExpiryDateForLicense(FeatureType.SHIELD) == originalExpiryDate); assertTrue("License manager should always report the original (signed) expiry date", esLicenseManager.getExpiryDateForLicense(FeatureType.SHIELD) == originalExpiryDate);
esLicenseManager.verifyLicenses(); esLicenseManager.verifyLicenses();
fail(); fail();