net.java.truelicense.core.LicenseConsumerContext Maven / Gradle / Ivy
Show all versions of truelicense-core Show documentation
/*
* Copyright (C) 2005-2013 Schlichtherle IT Services.
* All rights reserved. Use is subject to license terms.
*/
package net.java.truelicense.core;
import java.io.File;
import javax.annotation.CheckForNull;
import net.java.truelicense.core.auth.Authentication;
import net.java.truelicense.core.auth.AuthenticationParameters;
import net.java.truelicense.core.crypto.Encryption;
import net.java.truelicense.core.io.*;
import net.java.truelicense.core.util.*;
import net.java.truelicense.obfuscate.*;
/**
* A derived context for license consumer applications.
* Use this context to configure a {@link LicenseConsumerManager} with the
* required parameters.
*
* Here's an example of a licensing schema for consuming MyApp 1.X license keys
* with a Free Trial Period (FTP) of thirty calendar days:
*
public final class LicensingSchema {
/** Returns the license consumer context. *{@literal}/
public static LicenseConsumerContext context() { return Lazy.context; }
/** Returns the license consumer manager. *{@literal}/
public static LicenseConsumerManager manager() { return Lazy.manager; }
private static class Lazy {
@Obfuscate
static final String SUBJECT = "MyApp 1.X";
@Obfuscate
static final String PUBLIC_KEY_STORE_NAME = "public.ks";
static final ObfuscatedString PUBLIC_KEY_STORE_PASSWORD =
new ObfuscatedString(new long[] {
0x66c1016da18a6ffdl, 0xbda53ccf9e30c9efl }); /* => "test1234" *{@literal}/
@Obfuscate
static final String PUBLIC_CERT_ENTRY_ALIAS = "mykey";
static final ObfuscatedString PBE_PASSWORD =
new ObfuscatedString(new long[] {
0xc9c00fc60c9db6b8l, 0x4a19910b12cd00c4l }); /* => "test1234" *{@literal}/
@Obfuscate
static final String FTP_KEY_STORE_NAME = "ftp.ks";
static final ObfuscatedString FTP_KEY_STORE_PASSWORD =
new ObfuscatedString(new long[] {
0x7b4abf4aed98b47al, 0xb1e13b4bc0854bccl }); /* => "test1234" *{@literal}/
@Obfuscate
static final String FTP_KEY_ENTRY_ALIAS = "mykey";
static final ObfuscatedString FTP_KEY_ENTRY_PASSWORD =
new ObfuscatedString(new long[] {
0x149d045402a96977l, 0xa448f2162811f378l }); /* => "test1234" *{@literal}/
static final int FTP_CALENDAR_DAYS = 30;
static final LicenseConsumerContext context;
static final LicenseConsumerManager manager;
static {
context = new V2LicenseManagementContext(SUBJECT).consumer();
manager = context.ftpManager(
context.manager(
context.keyStore(
context.resource(PUBLIC_KEY_STORE_NAME),
null,
PUBLIC_KEY_STORE_PASSWORD,
PUBLIC_CERT_ENTRY_ALIAS),
context.pbe(null, PBE_PASSWORD),
context.userNodeStore(Main.class)),
context.ftpKeyStore(
context.resource(FTP_KEY_STORE_NAME),
null,
FTP_KEY_STORE_PASSWORD,
FTP_KEY_ENTRY_ALIAS,
FTP_KEY_ENTRY_PASSWORD),
context.userNodeStore(TopSecret.class),
FTP_CALENDAR_DAYS);
}
}
}
*
*
* If you prefer a fluent API programming style, then you can substitute the
* static initializer in the previous example with this:
*
static {
context = new V2LicenseManagementContext(SUBJECT).consumer();
manager = context
.manager()
.parent()
.keyStore()
.loadFromResource(PUBLIC_KEY_STORE_NAME)
.storePassword(PUBLIC_KEY_STORE_PASSWORD)
.alias(PUBLIC_CERT_ENTRY_ALIAS)
.inject()
.pbe()
.password(PBE_PASSWORD)
.inject()
.storeInUserNode(Main.class)
.inject()
.keyStore()
.loadFromResource(FTP_KEY_STORE_NAME)
.storePassword(FTP_KEY_STORE_PASSWORD)
.alias(FTP_KEY_ENTRY_ALIAS)
.keyPassword(FTP_KEY_ENTRY_PASSWORD)
.inject()
.storeInUserNode(TopSecret.class)
.ftpDays(FTP_CALENDAR_DAYS)
.build();
}
*
*
* Do not copy-paste this code!
* Instead, use the TrueLicense Maven Archetype to generate a fully populated
* template project for you.
*
* Applications have no need to implement this interface and should not do so
* because it may be subject to expansion in future versions.
*
* @author Christian Schlichtherle
*/
public interface LicenseConsumerContext
extends LicenseApplicationContext {
/**
* Configures a license consumer manager
* for use with regular license keys.
*
* The returned manager assumes that it has exclusive access to the given
* store and can use it to
* {@linkplain LicenseConsumerManager#install install} and
* {@linkplain LicenseConsumerManager#uninstall uninstall} a license key.
*
* @param authentication the authentication for regular license keys.
* @param encryption the encryption.
* @param store the store for the regular license key.
* @return A license consumer manager for use with regular license keys.
* @throws IllegalArgumentException if the authentication parameters define
* a private key password.
*/
LicenseConsumerManager manager(Authentication authentication, Encryption encryption, Store store);
/**
* Configures a license consumer manager
* for use with automatically created license keys.
* Use this method to support a Free Trial Period (FTP).
*
* The returned manager assumes that it has exclusive access to the given
* secret store and can use it to automatically install an FTP license key
* when calling {@link LicenseConsumerManager#verify} or
* {@link LicenseConsumerManager#view}.
* Calls to the methods {@link LicenseConsumerManager#install} and
* {@link LicenseConsumerManager#uninstall} get forwarded to the parent
* manager.
*
*
* NOTE THAT THE SECRET STORE MUST BE HIDDEN OR OTHERWISE PROTECTED SO THAT
* USERS CANNOT JUST DELETE THE INSTALLED LICENSE KEY TO MAKE THEM ELIGIBLE
* FOR A NEW FTP AGAIN!
*
*
* @param parent the parent manager.
* @param authentication the authentication for FTP license keys.
* These have to be created with {@link #ftpKeyStore}.
* @param encryption the nullable encryption.
* If this is {@code null}, then it will get inherited from the
* parent manager.
* @param secret the secret store for the FTP license key.
* @param days the FTP in days (the 24 hour equivalent).
* A minimum of one day is required.
* @return A license consumer manager for use with FTP license keys.
* @throws IllegalArgumentException if the authentication parameters define
* no private key password or if the FTP is less than one calendar
* day.
*/
LicenseConsumerManager ftpManager(LicenseConsumerManager parent, Authentication authentication, @CheckForNull Encryption encryption, Store secret, int days);
/**
* Configures a chained license consumer manager
* for use with regular license keys.
* Use this method to unlock application features based on the purchased
* license key.
* For best results, the two managers need to have different authentication
* parameters.
* The returned manager should then get used to verify acces to a sub set
* of the features which are controlled by the parent manager.
*
* The returned manager assumes that it has exclusive access to the given
* store and can use it to
* {@linkplain LicenseConsumerManager#install install} and
* {@linkplain LicenseConsumerManager#uninstall uninstall} a license key.
*
* All life cycle methods first try to use the parent manager.
* If this fails for any reason then they try to use the returned manager.
*
* @param parent the parent manager.
* @param authentication the authentication for regular license keys.
* @param encryption the encryption.
* If this is {@code null}, then it will get inherited from the
* parent manager.
* @param store the secret store for the FTP license key.
* @return A license consumer manager for use with FTP license keys.
* @throws IllegalArgumentException if the authentication parameters define
* a private key password.
*/
LicenseConsumerManager chainedManager(LicenseConsumerManager parent, Authentication authentication, @CheckForNull Encryption encryption, Store store);
/**
* Configures a key store based authentication
* for use with regular license keys.
* The provided strings should be computed on demand from an obfuscated form,
* e.g. by annotating a constant string value with the @{@link Obfuscate}
* annotation and processing it with the TrueLicense Maven Plugin.
*
* Applications should select a key store type with a strong encryption
* algorithm for the private key entry, e.g. {@code JCEKS}.
* If you choose a different key store type then you need to make sure that
* it's supported by a security provider on all platforms, see
* Java Cryptography Architeture Sun Providers Documentation.
*
* @param source the nullable source for the key store.
* May be {@code null} if and only if the key store type does not
* require loading from an input stream.
* @param storeType the nullable type of the key store.
* If this is {@code null}, then it defaults to a value as if
* computed by the expression
* {@link #context()}.{@link LicenseManagementContext#storeType() storeType()}
.
* @param storePassword the password for the key store.
* @param alias the alias of the trusted certificate entry in the key
* store.
* @return A key store based authentication
* for use with regular license keys.
*/
Authentication keyStore(@CheckForNull Source source, @CheckForNull String storeType, ObfuscatedString storePassword, String alias);
/**
* Configures a key store based authentication
* for use with Free Trial Period (FTP) license keys.
* The provided strings should be computed on demand from an obfuscated form,
* e.g. by annotating a constant string value with the @{@link Obfuscate}
* annotation and processing it with the TrueLicense Maven Plugin.
*
* Applications should select a key store type with a strong encryption
* algorithm for the private key entry, e.g. {@code JCEKS}.
* If you choose a different key store type then you need to make sure that
* it's supported by a security provider on all platforms, see
* Java Cryptography Architeture Sun Providers Documentation.
*
* @param source the nullable source for the key store.
* May be {@code null} if and only if the key store type does not
* require loading from an input stream.
* @param storeType the nullable type of the key store.
* If this is {@code null}, then it defaults to a value as if
* computed by the expression
* {@link #context()}.{@link LicenseManagementContext#storeType() storeType()}
.
* @param storePassword the password for the key store.
* @param alias the alias of the private key entry in the key store.
* @param keyPassword the password for the private key in the entry.
* @return A key store based authentication
* for use with FTP license keys.
* @throws IllegalArgumentException if a password is considered to be too
* weak.
*/
Authentication ftpKeyStore(@CheckForNull Source source, @CheckForNull String storeType, ObfuscatedString storePassword, String alias, ObfuscatedString keyPassword);
/**
* Returns a builder (and a self-injection) for
* {@linkplain LicenseConsumerManager license consumer managers}.
* Call its {@link ManagerBuilder#build} method to build and return a
* configured license consumer manager.
*
* Use this method if you prefer a fluent API programming style.
*/
ManagerBuilder manager();
/**
* A builder (and a self injection) for a
* {@linkplain LicenseConsumerManager license consumer manager}.
* Call {@link #build} to obtain a configured license consumer manager.
*
* Use this interface if you prefer a fluent API programming style.
*
* @author Christian Schlichtherle
*/
interface ManagerBuilder
extends Builder, Injection {
/**
* Sets the parent license consumer manager.
* A parent license consumer manager is required to configure a
* non-zero {@link #ftpDays FTP}.
* The parent license consumer manager will be tried first whenever a
* {@linkplain LicenseConsumerManager life cycle management method}
* is executed, e.g. when verifying a license key.
*
* @return {@code this}.
*/
ManagerBuilder parent(LicenseConsumerManager parent);
/**
* Returns a builder for the parent license consumer manager.
* Call its {@link ManagerBuilder#inject} method to build and inject
* the configured parent license consumer manager into this builder and
* return it.
*
* A parent license consumer manager is required to configure a
* non-zero {@link #ftpDays FTP}.
* The parent license consumer manager will be tried first whenever a
* {@linkplain LicenseConsumerManager life cycle management method}
* is executed, e.g. when verifying a license key.
*/
ManagerBuilder parent();
/**
* Sets the FTP period in days (the 24 hour equivalent).
* If this is zero, then no FTP is configured.
* Otherwise, the {@linkplain #keyStore key store} needs to have a
* password configured for the private key entry and a
* {@linkplain #parent parent license consumer manager}
* needs to be configured for the regular license keys.
*
* @return {@code this}.
*/
ManagerBuilder ftpDays(int days);
/**
* Sets the authentication.
* The authentication parameters need to be configured
* {@linkplain AuthenticationParameters#forSigning for signing} if and
* only if the license consumer manager to build defines a non-zero
* {@link #ftpDays FTP}.
*
* @return {@code this}.
*/
ManagerBuilder authentication(Authentication authentication);
/**
* Returns an injection for a key store based authentication.
* Call its {@link Injection#inject} method to build and inject the
* configured authentication into this builder and return it.
*
* The keystore needs to have a key password configured if and only if
* the license consumer manager to build defines a non-zero
* {@link #ftpDays FTP}.
*/
KsbaInjection keyStore();
/**
* Sets the encryption.
* An encryption needs to be configured if no
* {@linkplain #parent parent license consumer manager} is configured.
* Otherwise, the encryption can get inherited from the parent license
* consumer manager.
*
* @return {@code this}.
*/
ManagerBuilder encryption(Encryption encryption);
/**
* Returns an injection for a Password Based {@link Encryption} (PBE).
* Call its {@link Injection#inject} method to build and inject the
* configured encryption into this builder and return it.
*
* PBE parameters need to be configured if no
* {@linkplain #parent parent license consumer manager} is configured.
* Otherwise, the PBE parameters will get inherited from the parent
* license consumer manager.
*/
PbeInjection pbe();
/**
* Stores the license key in the given store.
* If a non-zero {@link #ftpDays FTP} is configured, then the store
* will be used for the auto-generated FTP license keys and
* MUST BE KEPT SECRET!
*
* @return {@code this}.
*/
ManagerBuilder storeIn(Store store);
/**
* Stores the license key in the given file.
* If a non-zero {@link #ftpDays FTP} is configured, then the store
* will be used for the auto-generated FTP license keys and
* MUST BE KEPT SECRET!
*
* @return {@code this}.
*/
ManagerBuilder storeInFile(File file);
/**
* Stores the license key in the system preferences node for the
* package of the given class.
* If a non-zero {@link #ftpDays FTP} is configured, then the store
* will be used for the auto-generated FTP license keys and
* MUST BE KEPT SECRET!
*
* @return {@code this}.
*/
ManagerBuilder storeInSystemNode(Class> classInPackage);
/**
* Stores the license keys in the user preferences node for the
* package of the given class.
* If a non-zero {@link #ftpDays FTP} is configured, then the store
* will be used for the auto-generated FTP license keys and
* MUST BE KEPT SECRET!
*
* @return {@code this}.
*/
ManagerBuilder storeInUserNode(Class> classInPackage);
}
}