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

be.atbash.ee.security.octopus.config.JCASupportConfiguration Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017-2022 Rudy De Busscher (https://www.atbash.be)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package be.atbash.ee.security.octopus.config;

import be.atbash.config.AbstractConfiguration;
import be.atbash.config.exception.ConfigurationException;
import be.atbash.config.logging.ConfigEntry;
import be.atbash.config.logging.ModuleConfig;
import be.atbash.config.logging.ModuleConfigName;
import be.atbash.config.logging.StartupLogging;
import be.atbash.ee.security.octopus.nimbus.jose.crypto.bc.BouncyCastleProviderSingleton;
import be.atbash.util.StringUtils;
import be.atbash.util.reflection.CDICheck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ServiceLoader;
import java.util.Timer;
import java.util.TimerTask;

/**
 *
 */

@ModuleConfigName("Octopus JCA Configuration")
//  Java Cryptography Architecture
public class JCASupportConfiguration extends AbstractConfiguration implements ModuleConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(JCASupportConfiguration.class);

    private static final Object SECURE_RANDOM_LOCK = new Object();

    private SecureRandom secureRandom;

    private TimerTask task;

    @ConfigEntry
    public String getSecureRandomAlgorithm() {
        return getOptionalValue("jwt.jca.securerandom.algo", String.class);
    }

    @ConfigEntry
    public SecureRandom getSecureRandom() {
        synchronized (SECURE_RANDOM_LOCK) {
            if (secureRandom == null) {
                tryServiceLoader();
                if (secureRandom == null) {
                    String algo = getSecureRandomAlgorithm();
                    if (StringUtils.isEmpty(algo)) {
                        secureRandom = new SecureRandom();
                    } else {
                        try {
                            secureRandom = SecureRandom.getInstance(algo, BouncyCastleProviderSingleton.getInstance());
                        } catch (NoSuchAlgorithmException e) {
                            throw new ConfigurationException(e.getMessage());
                        }
                    }
                }
            }
            // Do we need to recreate the Secure Random after x seconds of usage?
            Integer secureRandomRecreateSeconds = getSecureRandomRecreateSeconds();
            if (secureRandomRecreateSeconds != 0 && task == null) {
                long recreatePeriod = secureRandomRecreateSeconds * 1000L;
                task = new TimerTask() {
                    public void run() {
                        synchronized (SECURE_RANDOM_LOCK) {
                            // reset variable so that SecureRandom is recreated next time.
                            secureRandom = null;
                        }
                    }
                };
                new Timer("Task to recreate SecureRandom").scheduleAtFixedRate(task, recreatePeriod, recreatePeriod);
            }
        }
        return secureRandom;
    }

    private void tryServiceLoader() {
        ServiceLoader loader = ServiceLoader.load(SecureRandomProvider.class);
        for (SecureRandomProvider provider : loader) {
            if (secureRandom != null) {
                LOGGER.warn("Service loader for 'SecureRandomProvider' returned multiple providers. The selected provider may be different next time.");
                break;
            }
            secureRandom = provider.get();
        }
    }

    @ConfigEntry
    public Integer getSecureRandomRecreateSeconds() {
        return getOptionalValue("jwt.jca.securerandom.recreate", 0, Integer.class);
    }


    // Java SE Support
    private static JCASupportConfiguration INSTANCE;

    public static synchronized JCASupportConfiguration getInstance() {
        // Synchronize methods are not so bad for performance anymore and since only 1 synchronized static there are no side effects
        if (INSTANCE == null) {
            INSTANCE = new JCASupportConfiguration();
            if (!CDICheck.withinContainer()) {
                StartupLogging.logConfiguration(INSTANCE);
            }
        }
        return INSTANCE;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy