com.POLIS.licensing.common.license.AbstractSerializationBasedLicenseFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.POLIS.licensing.common.license.AbstractSerializationBasedLicenseFactory.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.POLIS.licensing.common.license;

import com.POLIS.licensing.common.exception.BadLicenseException;
import com.POLIS.licensing.common.exception.OperationException;
import com.POLIS.licensing.common.exception.SystemStateException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

/**
 *
 * @author Martin
 */
public abstract class AbstractSerializationBasedLicenseFactory<T extends AbstractSerializationBasedLicense>
        implements LicenseFactory<T> {
    private static int symkeySize = 128;

    @Override
    public T loadLicense(String data, PrivateKey senderEncryptionKey, PublicKey senderSignatureKey)
            throws BadLicenseException, SystemStateException, OperationException {
        byte[] decodedLicense;

        decodedLicense = Base64.decodeBase64(data);

        byte[] encryptedSymKey = new byte[symkeySize];
        byte[] encryptedLicense = new byte[decodedLicense.length - symkeySize];
        byte[] decryptedSymKey;
        byte[] decryptedLicense;
        Key symkey;

        System.arraycopy(decodedLicense, 0, encryptedSymKey, 0, symkeySize);
        System.arraycopy(decodedLicense, symkeySize, encryptedLicense, 0, decodedLicense.length - symkeySize);

        Cipher asymetriccipher;
        try {
            asymetriccipher = Cipher.getInstance(AbstractSerializationBasedLicense.asymmetricEncoding,
                    AbstractSerializationBasedLicense.provider);
            asymetriccipher.init(Cipher.DECRYPT_MODE, senderEncryptionKey);
        } catch (NoSuchAlgorithmException | NoSuchProviderException
                | /*InvalidKeySpecException |*/ NoSuchPaddingException | InvalidKeyException ex) {
            throw new SystemStateException("The specified encryption provider or algorithm was not found", ex);
        }

        try {
            decryptedSymKey = asymetriccipher.doFinal(encryptedSymKey);
            symkey = new SecretKeySpec(decryptedSymKey, "AES");
        } catch (IllegalBlockSizeException | BadPaddingException ex) {
            throw new SystemStateException("Could not decode the symkey for the license", ex);
        }

        Cipher symmetriccipher;
        try {
            symmetriccipher = Cipher.getInstance(AbstractSerializationBasedLicense.symmetricEncoding,
                    AbstractSerializationBasedLicense.provider);
            symmetriccipher.init(Cipher.DECRYPT_MODE, symkey);
        } catch (NoSuchAlgorithmException | NoSuchProviderException
                | /*InvalidKeySpecException |*/ NoSuchPaddingException | InvalidKeyException ex) {
            throw new SystemStateException("The specified encryption provider or algorithm was not found", ex);
        }

        try {
            decryptedLicense = symmetriccipher.doFinal(encryptedLicense);
        } catch (IllegalBlockSizeException | BadPaddingException ex) {
            throw new SystemStateException("Could not encode to base64", ex);
        }
        T license;
        try {
            license = getDeserializedObject(decryptedLicense);
        } catch (IOException | ClassNotFoundException ex) {
            throw new SystemStateException("An error occurred while reading the license from the input byte array.",
                    ex);
        }
        if (license.verifyLicense(senderSignatureKey)) {
            return license;
        } else
            throw new BadLicenseException(license,
                    "The license could not be verified with the specified signature decryption key");

    }

    protected abstract T getDeserializedObject(byte[] objectAsBytes)
            throws IOException, ClassNotFoundException, SystemStateException;

    protected AbstractSerializationBasedLicense defaultGetDeserializedObject(byte[] objectAsBytes)
            throws IOException, ClassNotFoundException, SystemStateException {
        AbstractSerializationBasedLicense license;
        try (ByteArrayInputStream bis = new ByteArrayInputStream(objectAsBytes);
                ObjectInput in = new ObjectInputStream(bis)) {
            Object likelyLicense = in.readObject();
            try {
                license = (AbstractSerializationBasedLicense) likelyLicense;
            } catch (ClassCastException ex) {
                throw new SystemStateException("Could not cast " + likelyLicense.getClass().getCanonicalName()
                        + ", expected a subclass of " + AbstractSerializationBasedLicense.class.getCanonicalName(),
                        ex);
            }
        }
        return license;
    }

}