// Path: pie-core/src/main/java/com/coverity/security/pie/core/PolicyConfig.java
// public class PolicyConfig {
//     private final String name;
//     private final PieConfig pieConfig;
//     
//     public PolicyConfig(String name, PieConfig pieConfig) {
//         this.name = name;
//         this.pieConfig = pieConfig;
//     }
//     
//     public boolean isEnabled() {
//         return getBoolean("isEnabled", true);
//     }
//     
//     public boolean isReportOnlyMode() {
//         return getBoolean("isReportOnlyMode", true);
//     }
// 
//     public boolean isCollapseEnabled() {
//         return getBoolean("isCollapseEnabled", true);
//     }
//     
//     public URL getPolicyFile() {
//         String policyFile = getProperty("policyFile");
//         if (policyFile != null) {
//             try {
//                 return new URL(policyFile);
//             } catch (MalformedURLException e) {
//                 throw new IllegalStateException("Invalid policy URL: " + policyFile);
//             }
//         }
//         URL resource = this.getClass().getClassLoader().getResource(name + ".policy");
//         if (resource != null) {
//             return resource;
//         }
//         String catalinaHome = System.getProperty("catalina.home");
//         if (catalinaHome != null) {
//             try {
//                 return new File(catalinaHome + File.separatorChar + "conf" + File.separatorChar + name + ".policy").toURI().toURL();
//             } catch (MalformedURLException e) {
//                 throw new IllegalStateException("Could not build default policy file path.");
//             }
//         }
//         
//         // Default to file in the CWD
//         try {
//             return new File(name + ".policy").toURI().toURL();
//         } catch (MalformedURLException e) {
//             throw new RuntimeException(e);
//         }
//     }
//     
//     public boolean getBoolean(String prop, boolean defaultValue) {
//         String v = getProperty(prop);
//         if (v == null) {
//             return defaultValue;
//         }
//         return Boolean.parseBoolean(v);
//     }
//     public int getInteger(String prop, int defaultValue) {
//         String v = getProperty(prop);
//         if (v == null) {
//             return defaultValue;
//         }
//         return Integer.parseInt(v);
//     }
//     
//     
//     public String getProperty(String name) {
//         return pieConfig.getProperties().getProperty(this.name + "." + name);
//     }
// }
// 
// Path: pie-core/src/main/java/com/coverity/security/pie/util/IOUtil.java
// public class IOUtil {
//     public static void closeSilently(Closeable closeable) {
//         if (closeable != null) {
//             try {
//                 closeable.close();
//             } catch (IOException e) {
//                 // Do nothing
//             }
//         }
//     }
//     
//     public static String readFile(File file) throws IOException {
//         return toString(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
//     }
//     public static String readFile(String file) throws IOException {
//         return toString(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
//     }
//     public static String readFile(URL file) throws IOException {
//         return toString(file.openStream());
//     }
//     
//     public static String toString(InputStream is) throws IOException {
//         try {
//             return toString(new InputStreamReader(is, StandardCharsets.UTF_8));
//         } finally {
//             closeSilently(is);
//         }
//     }
//     public static String toString(Reader reader) throws IOException {
//         StringBuilder sb = new StringBuilder();
//         try {
//             char buffer[] = new char[4096];
//             int n;
//             while ((n = reader.read(buffer)) > 0) {
//                 sb.append(buffer, 0, n);
//             }
//             reader.close();
//         } catch (IOException e) {
//             closeSilently(reader);
//             throw e;
//         }
//         return sb.toString();
//     }
//     
//     
//     public static void writeFile(File file, String content) throws IOException {
//         writeFile(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8), content);
//     }
//     private static void writeFile(Writer fw, String content) throws IOException {
//         try {
//             fw.write(content);
//             fw.close();
//         } catch (IOException e) {
//             closeSilently(fw);
//             throw e;
//         }
//     }
//     
// }


import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Permission;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Collection;
import com.coverity.security.pie.core.PolicyConfig;
import com.coverity.security.pie.util.IOUtil;
package com.coverity.security.pie.policy.securitymanager;



/**
 * An implementation of the Java SecurityManager Policy class, which delegates policy decisions to the PIE policy.
 * Whitelists permissions for PIE classes based on their certificate signature.
 */
public class DynamicJavaPolicy extends Policy {
    
    private final Collection<Policy> parentPolicies;
    private final PublicKey coverityPublicKey;
    
    private final SecurityManagerPolicy policy;
    private final PolicyConfig policyConfig;
    
    public DynamicJavaPolicy(Policy parentPolicy, SecurityManagerPolicy policy, PolicyConfig policyConfig) {
        this.parentPolicies = new ArrayList<Policy>();
        if (parentPolicy != null) {
            this.parentPolicies.add(parentPolicy);
        }
        
        this.policy = policy;
        this.policyConfig = policyConfig;

        try {
            coverityPublicKey = loadPublicX509("/coverity.crt").getPublicKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private Certificate loadPublicX509(String fileName) throws GeneralSecurityException, IOException {
        InputStream is = null;
// Path: pie-core/src/main/java/com/coverity/security/pie/core/PolicyConfig.java
// public class PolicyConfig {
//     private final String name;
//     private final PieConfig pieConfig;
//     
//     public PolicyConfig(String name, PieConfig pieConfig) {
//         this.name = name;
//         this.pieConfig = pieConfig;
//     }
//     
//     public boolean isEnabled() {
//         return getBoolean("isEnabled", true);
//     }
//     
//     public boolean isReportOnlyMode() {
//         return getBoolean("isReportOnlyMode", true);
//     }
// 
//     public boolean isCollapseEnabled() {
//         return getBoolean("isCollapseEnabled", true);
//     }
//     
//     public URL getPolicyFile() {
//         String policyFile = getProperty("policyFile");
//         if (policyFile != null) {
//             try {
//                 return new URL(policyFile);
//             } catch (MalformedURLException e) {
//                 throw new IllegalStateException("Invalid policy URL: " + policyFile);
//             }
//         }
//         URL resource = this.getClass().getClassLoader().getResource(name + ".policy");
//         if (resource != null) {
//             return resource;
//         }
//         String catalinaHome = System.getProperty("catalina.home");
//         if (catalinaHome != null) {
//             try {
//                 return new File(catalinaHome + File.separatorChar + "conf" + File.separatorChar + name + ".policy").toURI().toURL();
//             } catch (MalformedURLException e) {
//                 throw new IllegalStateException("Could not build default policy file path.");
//             }
//         }
//         
//         // Default to file in the CWD
//         try {
//             return new File(name + ".policy").toURI().toURL();
//         } catch (MalformedURLException e) {
//             throw new RuntimeException(e);
//         }
//     }
//     
//     public boolean getBoolean(String prop, boolean defaultValue) {
//         String v = getProperty(prop);
//         if (v == null) {
//             return defaultValue;
//         }
//         return Boolean.parseBoolean(v);
//     }
//     public int getInteger(String prop, int defaultValue) {
//         String v = getProperty(prop);
//         if (v == null) {
//             return defaultValue;
//         }
//         return Integer.parseInt(v);
//     }
//     
//     
//     public String getProperty(String name) {
//         return pieConfig.getProperties().getProperty(this.name + "." + name);
//     }
// }
// 
// Path: pie-core/src/main/java/com/coverity/security/pie/util/IOUtil.java
// public class IOUtil {
//     public static void closeSilently(Closeable closeable) {
//         if (closeable != null) {
//             try {
//                 closeable.close();
//             } catch (IOException e) {
//                 // Do nothing
//             }
//         }
//     }
//     
//     public static String readFile(File file) throws IOException {
//         return toString(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
//     }
//     public static String readFile(String file) throws IOException {
//         return toString(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
//     }
//     public static String readFile(URL file) throws IOException {
//         return toString(file.openStream());
//     }
//     
//     public static String toString(InputStream is) throws IOException {
//         try {
//             return toString(new InputStreamReader(is, StandardCharsets.UTF_8));
//         } finally {
//             closeSilently(is);
//         }
//     }
//     public static String toString(Reader reader) throws IOException {
//         StringBuilder sb = new StringBuilder();
//         try {
//             char buffer[] = new char[4096];
//             int n;
//             while ((n = reader.read(buffer)) > 0) {
//                 sb.append(buffer, 0, n);
//             }
//             reader.close();
//         } catch (IOException e) {
//             closeSilently(reader);
//             throw e;
//         }
//         return sb.toString();
//     }
//     
//     
//     public static void writeFile(File file, String content) throws IOException {
//         writeFile(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8), content);
//     }
//     private static void writeFile(Writer fw, String content) throws IOException {
//         try {
//             fw.write(content);
//             fw.close();
//         } catch (IOException e) {
//             closeSilently(fw);
//             throw e;
//         }
//     }
//     
// }


// Path: pie-sm/src/main/java/com/coverity/security/pie/policy/securitymanager/DynamicJavaPolicy.java
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Permission;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Collection;
import com.coverity.security.pie.core.PolicyConfig;
import com.coverity.security.pie.util.IOUtil;

package com.coverity.security.pie.policy.securitymanager;



/**
 * An implementation of the Java SecurityManager Policy class, which delegates policy decisions to the PIE policy.
 * Whitelists permissions for PIE classes based on their certificate signature.
 */
public class DynamicJavaPolicy extends Policy {
    
    private final Collection<Policy> parentPolicies;
    private final PublicKey coverityPublicKey;
    
    private final SecurityManagerPolicy policy;
    private final PolicyConfig policyConfig;
    
    public DynamicJavaPolicy(Policy parentPolicy, SecurityManagerPolicy policy, PolicyConfig policyConfig) {
        this.parentPolicies = new ArrayList<Policy>();
        if (parentPolicy != null) {
            this.parentPolicies.add(parentPolicy);
        }
        
        this.policy = policy;
        this.policyConfig = policyConfig;

        try {
            coverityPublicKey = loadPublicX509("/coverity.crt").getPublicKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private Certificate loadPublicX509(String fileName) throws GeneralSecurityException, IOException {
        InputStream is = null;
        try {