package net.curisit.securis; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.util.Date; import java.util.Map; import net.curisit.securis.beans.LicenseBean; import net.curisit.securis.beans.RequestBean; import net.curisit.securis.beans.SignedLicenseBean; import net.curisit.securis.utils.JsonUtils; import net.curisit.securis.utils.SignatureHelper; import org.apache.commons.codec.binary.Base64; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * License generator and signer * * @author roberto */ @javax.inject.Singleton public class LicenseGenerator { private static final Logger LOG = LogManager.getLogger(LicenseGenerator.class); private static LicenseGenerator singleton = new LicenseGenerator(); public static LicenseGenerator getInstance() { return singleton; } /** * Generate a license bean with the specified data * * @param req * @param licCode * @param metadata * @param expirationDate * @param licenseCode * @param appName * @return * @throws SeCurisException */ public LicenseBean generateLicense(RequestBean req, Map metadata, Date expirationDate, String licenseCode, String appName) throws SeCurisException { LOG.debug("Generating license: MAC: {}, Customer code: {}, AppName: {}", req.getMacAddresses(), req.getCustomerCode(), appName); LicenseBean license = new LicenseBean(req); license.setAppName(appName); license.setLicenseCode(licenseCode); license.setExpirationDate(expirationDate); license.setMetadata(metadata); sign(license); return license; } /** * Generate a license file using a {@link LicenseBean} * * @param license * @param file * @throws SeCurisException */ public void save(LicenseBean license, File file) throws SeCurisException { SignedLicenseBean signedLic = new SignedLicenseBean(license); byte[] json; try { json = JsonUtils.toPrettyJSON(signedLic).getBytes("utf-8"); Files.write(Paths.get(file.toURI()), json, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } catch (UnsupportedEncodingException e) { LOG.error("Error creating json doc from license: " + license, e); throw new SeCurisException("Error creating json doc from license: " + license, e); } catch (IOException e) { LOG.error("Error creating license file: " + file, e); throw new SeCurisException("Error creating json doc from license: " + license, e); } LOG.info("License saved in {}", file); } /** * * @param licBean * @return * @throws NoSuchAlgorithmException * @throws IOException * @throws InvalidKeySpecException * @throws InvalidKeyException * @throws SignatureException */ public String sign(LicenseBean licBean) throws SeCurisException { SignatureHelper sh = SignatureHelper.getInstance(); Signature signature; try { signature = Signature.getInstance(SignatureHelper.SIGNATURE_GENERATION_ALGORITHM); signature.initSign(sh.generatePrivateKey(new File(System.getProperty("user.home") + File.separator + ".SeCuris" + File.separator + "keys" + File.separator + "securis_private_key.pkcs8"))); sh.prepareSignature(signature, licBean); byte[] signatureData = signature.sign(); licBean.setSignature(Base64.encodeBase64String(signatureData)); return licBean.getSignature(); } catch (NoSuchAlgorithmException e) { LOG.error("Error signing license for " + licBean, e); } catch (InvalidKeyException e) { LOG.error("Error signing license for " + licBean, e); } catch (InvalidKeySpecException e) { LOG.error("Error signing license for " + licBean, e); } catch (IOException e) { LOG.error("Error signing license for " + licBean, e); } catch (SignatureException e) { LOG.error("Error signing license for " + licBean, e); } throw new SeCurisException("License could not be generated"); } }