001/**
002 *
003 * Copyright 2019 Florian Schmaus.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack.util;
018
019import java.lang.reflect.InvocationTargetException;
020import java.security.Provider;
021import java.security.Security;
022
023import org.jxmpp.util.cache.LruCache;
024
025public class SecurityUtil {
026
027    private static final LruCache<Class<? extends Provider>, Void> INSERTED_PROVIDERS_CACHE = new LruCache<>(8);
028
029    public static void ensureProviderAtFirstPosition(Class<? extends Provider> providerClass) {
030        if (INSERTED_PROVIDERS_CACHE.containsKey(providerClass)) {
031            return;
032        }
033
034        Provider provider;
035        try {
036            provider = providerClass.getDeclaredConstructor().newInstance();
037        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
038                | NoSuchMethodException | SecurityException e) {
039            throw new IllegalArgumentException(e);
040        }
041
042        String providerName = provider.getName();
043
044        int installedPosition ;
045        synchronized (Security.class) {
046            Security.removeProvider(providerName);
047            installedPosition = Security.insertProviderAt(provider, 1);
048        }
049        assert installedPosition == 1;
050
051        INSERTED_PROVIDERS_CACHE.put(providerClass, null);
052    }
053}