eu.optimis.trustedinstance.TrustedInstanceImpl.java Source code

Java tutorial

Introduction

Here is the source code for eu.optimis.trustedinstance.TrustedInstanceImpl.java

Source

/* 
 * Copyright (c) 2007, Fraunhofer-Gesellschaft
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * (1) Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the disclaimer at the end.
 *     Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 * 
 * (2) Neither the name of Fraunhofer nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 * 
 * DISCLAIMER
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *  
 */
package eu.optimis.trustedinstance;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import eu.elasticlm.schemas.x2009.x05.license.token.LicenseTokenDocument;
import eu.elasticlm.schemas.x2009.x05.license.token.secure.LicenseTokenSecureDocument;
import eu.elasticlm.schemas.x2009.x05.license.token.secure.LicenseTokenSecureType;
import eu.elasticlm.schemas.x2009.x05.license.token.secure.ProviderHashType;
import eu.elasticlm.schemas.x2009.x05.license.token.secure.ProviderInfoType;
import eu.elasticlm.schemas.x2009.x07.security.user.token.authorization.UserTokenAuthorizationDocument;
import eu.elasticlm.security.tokens.TokenSigner;
import eu.optimis.providerinfo.client.InfoServiceClient;
import eu.optimis.trustedinstance.exceptions.ResourceInvalid;
import eu.optimis.trustedinstance.exceptions.ResourceNotFound;
import eu.optimis.trustedinstance.exceptions.ResourceTypeUnknown;

import eu.optimis.trustedinstance.exceptions.TrustedInstanceException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.util.Base64;

/**
 * @author hrasheed
 * 
 */
public class TrustedInstanceImpl implements TrustedInstance {

    private static final Logger LOG = Logger.getLogger(TrustedInstanceImpl.class);

    private DBStorage storage = null;

    private static TrustedInstanceImpl trustedInstance = null;

    private InputStream keyStore_input_stream = null;

    private char[] ti_keyStorePass = null;

    private String ti_keyStoreAlias = null;

    private InputStream publicCert_input_stream = null;

    private DBStorage dbStorage = null;

    private String infoServiceUrl = null;

    private String infoServiceName = null;

    private X509Certificate ti_certificate = null;

    private KeyStore ti_ks = null;

    private synchronized void initialize() {
        //storage = new DBStorage();

        String keystore = ComponentConfigurationProvider.getString("trusted.instance.keystore"); //$NON-NLS-1$
        String password = ComponentConfigurationProvider.getString("trusted.instance.keystore.password"); //$NON-NLS-1$
        String alias = ComponentConfigurationProvider.getString("trusted.instance.keystore.alias"); //$NON-NLS-1$
        String publicCert = ComponentConfigurationProvider.getString("trusted.instance.keystore.public.cert"); //$NON-NLS-1$
        infoServiceName = ComponentConfigurationProvider.getString("trusted.instance.infoservice.client.name");
        infoServiceUrl = ComponentConfigurationProvider.getString("trusted.instance.infoservice.client.url");

        try {

            keyStore_input_stream = getClass().getResourceAsStream(keystore);

            if (keyStore_input_stream == null) {
                throw new Exception("unable to load keystore of the trusted instance");
            }

            if (password == null) {
                throw new Exception("unable to load passowrd of the keystore");
            }

            ti_keyStorePass = password.toCharArray();

            if (alias == null) {
                throw new Exception("unable to load alias of the keystore");
            }

            ti_keyStoreAlias = alias;

            publicCert_input_stream = getClass().getResourceAsStream(publicCert);

            if (publicCert_input_stream == null) {
                throw new Exception("unable to load public certificate of the trusted instance");
            }

            CertificateFactory ti_cf = CertificateFactory.getInstance("X.509");
            ti_certificate = (X509Certificate) ti_cf.generateCertificate(publicCert_input_stream);

            ti_ks = KeyStore.getInstance("JKS");
            ti_ks.load(keyStore_input_stream, ti_keyStorePass);

            if (infoServiceName == null) {
                throw new Exception("unable to find name for ProviderInfoService");
            }

            if (infoServiceUrl == null) {
                throw new Exception("unable to find URL for ProviderInfoService");
            }

        } catch (Exception e) {
            System.out.println("ERROR: " + e.getMessage());
        }
    }

    public TrustedInstanceImpl() {
        dbStorage = new DBStorage();
        initialize();
    }

    public static synchronized TrustedInstanceImpl getInstance() {
        if (trustedInstance == null) {
            trustedInstance = new TrustedInstanceImpl();
        }

        return trustedInstance;
    }

    @Override
    public LicenseTokenSecureDocument getToken(UserTokenAuthorizationDocument userTokenAuthorizationDoc)
            throws ResourceNotFound, ResourceInvalid, TrustedInstanceException {
        if (userTokenAuthorizationDoc == null)
            throw new ResourceInvalid("Resource is null");

        // TODO validate timestamps and signature of userTokenAuthorizationDoc?
        // TODO get tokenID from UserTokenAuthorizationDocument or LicenseDescription?
        String tokenId = userTokenAuthorizationDoc.getUserTokenAuthorization().getTokenID();

        if (tokenId == null || tokenId.equals(""))
            throw new ResourceInvalid("UserTokenAuthorization is missing TokenID");

        DBStorageEntry receivedEntry = null;
        try {
            receivedEntry = getStorageEntry(tokenId);
        } catch (Exception e) {
            throw new TrustedInstanceException(e.getMessage(), e);
        }

        LicenseTokenSecureDocument licenseTokenSecureDocument;
        try {
            LicenseTokenDocument licenseToken = receivedEntry.getLicenseToken();

            LicenseTokenSecureDocument tokenSecDoc = LicenseTokenSecureDocument.Factory.newInstance();
            LicenseTokenSecureType tokenSecType = tokenSecDoc.addNewLicenseTokenSecure();

            ByteArrayOutputStream token_bos = new ByteArrayOutputStream();
            licenseToken.save(token_bos);
            byte[] token_encoded = Base64.encode(token_bos.toByteArray());

            tokenSecType.setLicenseToken(token_encoded);

            ProviderInfoType providerInfo = tokenSecType.addNewProviderInfo();
            String providerInfoString = getProviderInfo(infoServiceUrl);
            providerInfo.setName(infoServiceName);
            ProviderHashType hashType = providerInfo.addNewProviderHash();
            hashType.setHashAlgorithm("sha1");
            hashType.setStringValue(DigestUtils.shaHex(providerInfoString));
            providerInfo.setInfoServiceURL(infoServiceUrl);

            // server private key
            PrivateKey tiPrivateKey = (PrivateKey) ti_ks.getKey(ti_keyStoreAlias, ti_keyStorePass);

            TokenSigner ts_secure = new TokenSigner(ti_certificate, tiPrivateKey);

            licenseTokenSecureDocument = ts_secure.getSignedToken(tokenSecDoc);

            if (!licenseTokenSecureDocument.validate()) {
                throw new ResourceInvalid("invalid trusted instance token authorization.");
            }
        } catch (XmlException e) {
            // TODO add throws TrustedInstanceException?
            throw new ResourceNotFound("Unable to parse LicenseToken", e);
        } catch (Exception e) {
            throw new TrustedInstanceException(e.getMessage(), e);
        }

        return licenseTokenSecureDocument;
    }

    private String getProviderInfo(String URL) throws TrustedInstanceException {
        InfoServiceClient infoServiceClient = getInfoServiceClient(URL);
        String info = infoServiceClient.getInfo();
        if (info == null || info.equals(""))
            throw new TrustedInstanceException("InfoServiceClient does not return Info-String.");
        return info;
    }

    protected InfoServiceClient getInfoServiceClient(String url) {
        return InfoServiceClient.getInstance(url);
    }

    @Override
    public boolean storeToken(LicenseTokenDocument resource)
            throws ResourceTypeUnknown, ResourceInvalid, TrustedInstanceException {
        String id = getIdFromToken(resource);
        try {
            if (dbStorage.get(id) != null) {
                LOG.error("Token with ID=" + id + " already in store");
                throw new TrustedInstanceException("Token already in store");
            }
        } catch (Exception e) {
            throw new TrustedInstanceException(e.getMessage(), e);
        }

        DBStorageEntry dbStorageEntry;
        try {
            dbStorageEntry = new DBStorageEntry(id, resource);
        } catch (IOException e) {
            throw new TrustedInstanceException("Unable to store resource", e);
        }

        try {
            return dbStorage.store(dbStorageEntry);
        } catch (Exception e) {
            throw new TrustedInstanceException("Unable to store", e);
        }
    }

    @Override
    public boolean removeToken(LicenseTokenDocument tokenDoc)
            throws ResourceNotFound, ResourceTypeUnknown, ResourceInvalid, TrustedInstanceException {
        String id = getIdFromToken(tokenDoc);
        try {
            getStorageEntry(id);
            return dbStorage.delete(id);
        } catch (Exception e) {
            throw new TrustedInstanceException(e.getMessage(), e);
        }
    }

    private DBStorageEntry getStorageEntry(String id) throws ResourceNotFound, Exception {
        DBStorageEntry dbStorageEntry = dbStorage.get(id);
        if (dbStorageEntry == null)
            throw new ResourceNotFound("Token not present in Storage");
        return dbStorageEntry;
    }

    private String getIdFromToken(LicenseTokenDocument token) throws ResourceInvalid {
        // check license
        if (!token.validate())
            throw new ResourceInvalid("Token can not be validated");

        // check if license has a TokenID
        String id = token.getLicenseToken().getTokenId();
        if (id == null || id.equals("")) {
            throw new ResourceInvalid("ID missing in Token");
        }
        return id;
    }
}