All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.craftercms.commons.crypto.impl.SecretKeyRepositoryImpl Maven / Gradle / Ivy

There is a newer version: 4.1.8
Show newest version
/*
 * Copyright (C) 2007-2014 Crafter Software Corporation.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.craftercms.commons.crypto.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import javax.annotation.PostConstruct;
import javax.crypto.SecretKey;

import org.apache.commons.io.FileUtils;
import org.craftercms.commons.crypto.CryptoUtils;
import org.craftercms.commons.crypto.CryptoException;
import org.craftercms.commons.crypto.SecretKeyRepository;
import org.craftercms.commons.i10n.I10nLogger;
import org.springframework.beans.factory.annotation.Required;

/**
 * Default implementation of {@link org.craftercms.commons.crypto.SecretKeyRepository}, which uses JCE Key Store.
 *
 * @author avasquez
 */
public class SecretKeyRepositoryImpl implements SecretKeyRepository {

    public static final String KEY_STORE_TYPE = "JCEKS";

    public static final String LOG_KEY_KEY_FOUND = "crypto.keyRepo.keyFound";
    public static final String LOG_KEY_KEY_NOT_FOUND = "crypto.keyRepo.keyNotFound";
    public static final String LOG_KEY_KEY_CREATED = "crypto.keyRepo.keyCreated";
    public static final String LOG_KEY_KEY_SAVED = "crypto.keyRepo.keySaved";
    public static final String LOG_KEY_KEY_STORE_LOADED = "crypto.keyRepo.keyStoreLoaded";
    public static final String LOG_KEY_KEY_STORE_STORED = "crypto.keyRepo.keyStoreStored";
    public static final String ERROR_KEY_KEY_STORE_LOAD_ERROR = "crypto.keyRepo.keyStoreLoadError";
    public static final String ERROR_KEY_KEY_STORE_STORE_ERROR = "crypto.keyRepo.keyStoreStoreError";
    public static final String ERROR_KEY_GET_KEY_ERROR = "crypto.keyRepo.getKeyError";
    public static final String ERROR_KEY_SAVE_KEY_ERROR = "crypto.keyRepo.saveKeyError";

    private static final I10nLogger logger = new I10nLogger(SecretKeyRepositoryImpl.class);

    protected File keyStoreFile;
    protected char[] keyStorePassword;
    protected String defaultKeyAlgorithm;

    protected KeyStore keyStore;

    public SecretKeyRepositoryImpl() {
        defaultKeyAlgorithm = CryptoUtils.AES_CIPHER_ALGORITHM;
    }

    @Required
    public void setKeyStoreFile(File keyStoreFile) {
        this.keyStoreFile = keyStoreFile;
    }

    @Required
    public void setKeyStorePassword(String keyStorePassword) {
        this.keyStorePassword = keyStorePassword.toCharArray();
    }

    public void setDefaultKeyAlgorithm(String defaultKeyAlgorithm) {
        this.defaultKeyAlgorithm = defaultKeyAlgorithm;
    }

    @PostConstruct
    public void init() throws CryptoException {
        loadKeyStore();
    }

    @Override
    public SecretKey getKey(String name, boolean create) throws CryptoException {
        try {
            SecretKey key = (SecretKey) keyStore.getKey(name, keyStorePassword);
            if (key == null) {
                logger.debug(LOG_KEY_KEY_NOT_FOUND, name);

                if (create) {
                    key = CryptoUtils.generateKey(defaultKeyAlgorithm);
                    saveKey(name, key);

                    logger.debug(LOG_KEY_KEY_CREATED, name);
                }
            } else {
                logger.debug(LOG_KEY_KEY_FOUND, name);
            }

            return key;
        } catch (GeneralSecurityException e) {
            throw new CryptoException(ERROR_KEY_GET_KEY_ERROR, e);
        }
    }

    @Override
    public void saveKey(String name, SecretKey key) throws CryptoException {
        KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(keyStorePassword);
        KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(key);

        try {
            keyStore.setEntry(name, entry, protParam);
        } catch (GeneralSecurityException e) {
            throw new CryptoException(ERROR_KEY_SAVE_KEY_ERROR, e);
        }

        logger.debug(LOG_KEY_KEY_SAVED, name);

        storeKeyStore();
    }

    protected void loadKeyStore() throws CryptoException {
        try {
            keyStore = KeyStore.getInstance(KEY_STORE_TYPE);

            if (keyStoreFile.exists()) {
                try (InputStream in = new FileInputStream(keyStoreFile)) {
                    keyStore.load(in, keyStorePassword);
                }

                logger.debug(LOG_KEY_KEY_STORE_LOADED, keyStoreFile);
            } else {
                // Create new empty keystore
                keyStore.load(null, keyStorePassword);
            }
        } catch (GeneralSecurityException | IOException e) {
            throw new CryptoException(ERROR_KEY_KEY_STORE_LOAD_ERROR, e);
        }
    }

    protected void storeKeyStore() throws CryptoException {
        try {
            try (OutputStream out = FileUtils.openOutputStream(keyStoreFile)) {
                keyStore.store(out, keyStorePassword);
            }

            logger.debug(LOG_KEY_KEY_STORE_STORED, keyStoreFile);
        } catch (GeneralSecurityException | IOException e) {
            throw new CryptoException(ERROR_KEY_KEY_STORE_STORE_ERROR, e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy