package com.orange.clara.cloud.servicedbdumper.task.boot.sequences;

import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Copyright (C) 2015 Orange
 * <p>
 * This software is distributed under the terms and conditions of the 'Apache-2.0'
 * license which can be found in the file 'LICENSE' in this package distribution
 * or at 'https://opensource.org/licenses/Apache-2.0'.
 * <p>
 * Author: Arthur Halet
 * Date: 09/12/2015
 */
@Component
@Order(1)
public class BootSequenceSecurity implements BootSequence {

    @Value("${encryption.key:MySuperSecretKey}")
    protected String encryptionKey;

    @Value("classpath:properties/encryption_key.txt")
    protected File encryptionKeyFile;

    public void fillEncryptionKeyFile() throws IOException, NoSuchAlgorithmException {
        //force to have always a 32 bytes key (to use AES encryption with 256 bits key length)
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(encryptionKey.getBytes(Charsets.UTF_8));
        byte[] key = md.digest();

        Files.write(key, encryptionKeyFile);
    }

    public void removeEncryptionRestriction() {
        try {
            Field field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
            field.setAccessible(true);
            field.set(null, java.lang.Boolean.FALSE);
        } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void runSequence() {
        this.removeEncryptionRestriction();
        try {
            this.fillEncryptionKeyFile();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

@@ -137,16 +137,73 @@
 .Files;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -434,16 +434,51 @@
 .Field;%0A
+import java.lang.reflect.Modifier;%0A
 import j
@@ -551,16 +551,114 @@
 ception;
+%0Aimport java.security.Permission;%0Aimport java.security.PermissionCollection;%0Aimport java.util.Map;
 %0A%0A/**%0A *
@@ -1046,17 +1046,16 @@
 uence %7B%0A
-%0A
     @Val
@@ -1131,17 +1131,16 @@
 ionKey;%0A
-%0A
     @Val
@@ -1222,16 +1222,322 @@
 KeyFile;
+%0A    private Logger logger = LoggerFactory.getLogger(BootSequenceSecurity.class);%0A%0A    private static boolean isRestrictedCryptography() %7B%0A        // This simply matches the Oracle JRE, but not OpenJDK.%0A        return %22Java(TM) SE Runtime Environment%22.equals(System.getProperty(%22java.runtime.name%22));%0A    %7D
 %0A%0A    pu
@@ -1983,81 +1983,773 @@
     
-try %7B%0A            Field field = Class.forName(%22javax.crypto.JceSecurity%22)
+if (!isRestrictedCryptography()) %7B%0A            logger.info(%22Cryptography restrictions removal not needed%22);%0A            return;%0A        %7D%0A        try %7B%0A        /*%0A         * Do the following, but with reflection to bypass access checks:%0A         *%0A         * JceSecurity.isRestricted = false;%0A         * JceSecurity.defaultPolicy.perms.clear();%0A         * JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE);%0A         */%0A            final Class%3C?%3E jceSecurity = Class.forName(%22javax.crypto.JceSecurity%22);%0A            final Class%3C?%3E cryptoPermissions = Class.forName(%22javax.crypto.CryptoPermissions%22);%0A            final Class%3C?%3E cryptoAllPermission = Class.forName(%22javax.crypto.CryptoAllPermission%22);%0A%0A            final Field isRestrictedField = jceSecurity
 .get
@@ -2783,33 +2783,45 @@
 %22);%0A            
-f
+isRestrictedF
 ield.setAccessib
@@ -2848,227 +2848,1086 @@
   fi
-eld.set(null, java.lang.Boolean.FALSE);%0A        %7D catch (ClassNotFoundException %7C NoSuchFieldException %7C SecurityException %7C IllegalArgumentException %7C IllegalAccessException e) %7B%0A            throw new RuntimeException(
+nal Field modifiersField = Field.class.getDeclaredField(%22modifiers%22);%0A            modifiersField.setAccessible(true);%0A            modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL);%0A            isRestrictedField.set(null, false);%0A%0A            final Field defaultPolicyField = jceSecurity.getDeclaredField(%22defaultPolicy%22);%0A            defaultPolicyField.setAccessible(true);%0A            final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null);%0A%0A            final Field perms = cryptoPermissions.getDeclaredField(%22perms%22);%0A            perms.setAccessible(true);%0A            ((Map%3C?, ?%3E) perms.get(defaultPolicy)).clear();%0A%0A            final Field instance = cryptoAllPermission.getDeclaredField(%22INSTANCE%22);%0A            instance.setAccessible(true);%0A            defaultPolicy.add((Permission) instance.get(null));%0A%0A            logger.info(%22Successfully removed cryptography restrictions%22);%0A        %7D catch (final Exception e) %7B%0A            logger.warn(%22Failed to remove cryptography restrictions%22, 
 e);%0A

change the way to bypass jce