/*
 * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.crypto;

import java.security.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.lang.StackWalker.*;

/**
 * The JCE security manager.
 *
 * <p>The JCE security manager is responsible for determining the maximum
 * allowable cryptographic strength for a given application, for a given
 * algorithm, by consulting the configured jurisdiction policy files and
 * the cryptographic permissions bundled with the application.
 *
 * @author Jan Luehe
 *
 * @since 1.4
 */
final class JceSecurityManager {

    private static final CryptoPermissions defaultPolicy;
    private static final CryptoPermissions exemptPolicy;
    private static final CryptoAllPermission allPerm;
    private static final Vector<Class<?>> TrustedCallersCache =
            new Vector<>(2);
    private static final ConcurrentMap<URL,CryptoPermissions> exemptCache =
            new ConcurrentHashMap<>();
    private static final CryptoPermissions CACHE_NULL_MARK =
            new CryptoPermissions();

    // singleton instance
    static final JceSecurityManager INSTANCE;
    static final StackWalker WALKER;

    static {
        defaultPolicy = JceSecurity.getDefaultPolicy();
        exemptPolicy = JceSecurity.getExemptPolicy();
        allPerm = CryptoAllPermission.INSTANCE;

        INSTANCE = new JceSecurityManager();

        WALKER = StackWalker.getInstance(
                Set.of(Option.DROP_METHOD_INFO, Option.RETAIN_CLASS_REFERENCE));
    }

    private JceSecurityManager() {
        // empty
    }

    /**
     * Returns the maximum allowable crypto strength for the given
     * application, for the given algorithm.
     */
    CryptoPermission getCryptoPermission(String theAlg) {

        // Need to convert to uppercase since the crypto perm
        // lookup is case-sensitive.
        final String alg = theAlg.toUpperCase(Locale.ENGLISH);

        // If CryptoAllPermission is granted by default, we return that.
        // Otherwise, this will be the permission we return if anything goes
        // wrong.
        CryptoPermission defaultPerm = getDefaultPermission(alg);
        if (defaultPerm == CryptoAllPermission.INSTANCE) {
            return defaultPerm;
        }

        // Determine the codebase of the caller of the JCE API.
        // This is the codebase of the first class which is not in
        // javax.crypto.* packages.
        // NOTE: javax.crypto.* package maybe subject to package
        // insertion, so need to check its classloader as well.
        return WALKER.walk(s -> s.map(StackFrame::getDeclaringClass)
                .filter(c -> !c.getPackageName().equals("javax.crypto"))
                .map(cls -> {
                    URL callerCodeBase = JceSecurity.getCodeBase(cls);
                    return (callerCodeBase != null) ?
                            getCryptoPermissionFromURL(callerCodeBase,
                                    alg, defaultPerm) : defaultPerm;})
                .findFirst().get()         // nulls not possible for Optional
        );
    }

    CryptoPermission getCryptoPermissionFromURL(URL callerCodeBase,
            String alg, CryptoPermission defaultPerm) {
        CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
        if (appPerms == null) {
            // no match found in cache
            synchronized (this.getClass()) {
                appPerms = exemptCache.get(callerCodeBase);
                if (appPerms == null) {
                    appPerms = getAppPermissions(callerCodeBase);
                    exemptCache.putIfAbsent(callerCodeBase,
                        (appPerms == null? CACHE_NULL_MARK:appPerms));
                }
            }
        }
        if (appPerms == null || appPerms == CACHE_NULL_MARK) {
            return defaultPerm;
        }

        // If the app was granted the special CryptoAllPermission, return that.
        if (appPerms.implies(allPerm)) {
            return allPerm;
        }

        // Check if the crypto permissions granted to the app contain a
        // crypto permission for the requested algorithm that does not require
        // any exemption mechanism to be enforced.
        // Return that permission, if present.
        PermissionCollection appPc = appPerms.getPermissionCollection(alg);
        if (appPc == null) {
            return defaultPerm;
        }
        Enumeration<Permission> enum_ = appPc.elements();
        while (enum_.hasMoreElements()) {
            CryptoPermission cp = (CryptoPermission)enum_.nextElement();
            if (cp.getExemptionMechanism() == null) {
                return cp;
            }
        }

        // Check if the jurisdiction file for exempt applications contains
        // any entries for the requested algorithm.
        // If not, return the default permission.
        PermissionCollection exemptPc =
            exemptPolicy.getPermissionCollection(alg);
        if (exemptPc == null) {
            return defaultPerm;
        }

        // In the jurisdiction file for exempt applications, go through the
        // list of CryptoPermission entries for the requested algorithm, and
        // stop at the first entry:
        //  - that is implied by the collection of crypto permissions granted
        //    to the app, and
        //  - whose exemption mechanism is available from one of the
        //    registered CSPs
        enum_ = exemptPc.elements();
        while (enum_.hasMoreElements()) {
            CryptoPermission cp = (CryptoPermission)enum_.nextElement();
            try {
                ExemptionMechanism.getInstance(cp.getExemptionMechanism());
                if (cp.getAlgorithm().equals(
                                      CryptoPermission.ALG_NAME_WILDCARD)) {
                    CryptoPermission newCp;
                    if (cp.getCheckParam()) {
                        newCp = new CryptoPermission(
                                alg, cp.getMaxKeySize(),
                                cp.getAlgorithmParameterSpec(),
                                cp.getExemptionMechanism());
                    } else {
                        newCp = new CryptoPermission(
                                alg, cp.getMaxKeySize(),
                                cp.getExemptionMechanism());
                    }
                    if (appPerms.implies(newCp)) {
                        return newCp;
                    }
                }

                if (appPerms.implies(cp)) {
                    return cp;
                }
            } catch (Exception e) {
            }
        }
        return defaultPerm;
    }

    private static CryptoPermissions getAppPermissions(URL callerCodeBase) {
        // Check if app is exempt, and retrieve the permissions bundled with it
        try {
            return JceSecurity.verifyExemptJar(callerCodeBase);
        } catch (Exception e) {
            // Jar verification fails
            return null;
        }

    }

    /**
     * Returns the default permission for the given algorithm.
     */
    private CryptoPermission getDefaultPermission(String alg) {
        Enumeration<Permission> enum_ =
            defaultPolicy.getPermissionCollection(alg).elements();
        return (CryptoPermission)enum_.nextElement();
    }

    // Only used by javax.crypto.Cipher constructor to disallow Cipher
    // objects being constructed by untrusted code (See bug 4341369 &
    // 4334690 for more info).
    boolean isCallerTrusted(Class<?> caller, Provider provider) {
        // Get the caller and its codebase.
        if (caller != null) {
            URL callerCodeBase = JceSecurity.getCodeBase(caller);
            if (callerCodeBase == null) {
                return true;
            }
            // The caller has been verified.
            if (TrustedCallersCache.contains(caller)) {
                return true;
            }

            // Check the association between caller and provider
            Class<?> pCls = provider.getClass();
            Module pMod = pCls.getModule();
            // If they are in the same named module or share
            // the same codebase, then they are associated
            boolean sameOrigin = (pMod.isNamed()?
                caller.getModule().equals(pMod) :
                callerCodeBase.equals(JceSecurity.getCodeBase(pCls)));
            if (sameOrigin) {
                // The caller is from trusted provider
                if (ProviderVerifier.isTrustedCryptoProvider(provider)) {
                    TrustedCallersCache.addElement(caller);
                    return true;
                }
            } else {
                // Don't include the provider in the subsequent
                // JceSecurity.verifyProvider(...) call
                provider = null;
            }

            // Check whether the caller is a trusted provider.
            try {
                JceSecurity.verifyProvider(callerCodeBase, provider);
            } catch (Exception e2) {
                return false;
            }
            TrustedCallersCache.addElement(caller);
            return true;
        }
        return false;
    }
}
