/***** BEGIN LICENSE BLOCK *****
* Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Eclipse Public
* License Version 1.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.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* Copyright (C) 2017 Karol Bucek <self@kares.org>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
package org.jruby.ext.openssl.util;
import org.jruby.ext.openssl.OpenSSL;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Security;
/**
* JCE security helper for disabling (default) imposed cryptographic restrictions.
*
* Using this class might be in **contrast with the license agreement** that came with your JRE.
*
* It's preferable to install:
*
* "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files"
*
* specific to your Java version!
*
* @see http://www.oracle.com/technetwork/java/javase/downloads/index.html
*/
public final class CryptoSecurity {
private CryptoSecurity() { /* no instances */ }
public static void disableJceRestrictions() {
unrestrictSecurity();
setAllPermissionPolicy();
}
public static Boolean setAllPermissionPolicy() {
if ( ! OpenSSL.javaHotSpot() ) return false;
try {
final Class JceSecurity = Class.forName("javax.crypto.JceSecurity");
final Class CryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
final Class CryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");
Field defaultPolicy = JceSecurity.getDeclaredField("defaultPolicy");
defaultPolicy.setAccessible(true);
Field perms = CryptoPermissions.getDeclaredField("perms");
perms.setAccessible(true);
Field INSTANCE = CryptoAllPermission.getDeclaredField("INSTANCE");
INSTANCE.setAccessible(true);
synchronized (Security.class) {
final PermissionCollection defPolicy = (PermissionCollection) defaultPolicy.get(null);
final java.util.Map permsMap = (java.util.Map) perms.get(defPolicy);
if ( ! permsMap.isEmpty() ) {
permsMap.clear();
defPolicy.add((Permission) INSTANCE.get(null));
return true;
}
return false;
}
}
catch (ClassNotFoundException e) {
OpenSSL.debug("unable un-restrict jce security: ", e);
return null;
}
catch (Exception e) {
OpenSSL.debug("unable un-restrict jce security: ");
OpenSSL.debugStackTrace(e);
return null;
}
}
public static Boolean unrestrictSecurity() {
if ( ! OpenSSL.javaHotSpot() ) return false;
if ( javaVersion9() ) {
return unrestrictJceSecurity9();
}
return unrestrictJceSecurity8();
}
static Boolean unrestrictJceSecurity9() {
try {
if (Security.getProperty("crypto.policy") == null) {
Security.setProperty("crypto.policy", "unlimited");
return true;
}
return false;
}
catch (Exception e) {
OpenSSL.debug("unable un-restrict jce security: ", e);
return null;
}
}
static Boolean unrestrictJceSecurity8() {
try {
final Class JceSecurity = Class.forName("javax.crypto.JceSecurity");
Field isRestricted = JceSecurity.getDeclaredField("isRestricted");
if ( Modifier.isFinal(isRestricted.getModifiers()) ) {
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(isRestricted, isRestricted.getModifiers() & ~Modifier.FINAL);
}
isRestricted.setAccessible(true);
if (isRestricted.getBoolean(null) == false) {
isRestricted.setBoolean(null, false); // isRestricted = false;
return true;
}
return false;
}
catch (ClassNotFoundException e) {
OpenSSL.debug("unable un-restrict jce security: ", e);
return null;
}
catch (Exception e) {
OpenSSL.debug("unable un-restrict jce security: ");
OpenSSL.debugStackTrace(e);
return null;
}
}
private static boolean javaVersion9() {
final int gt = "1.8".compareTo( OpenSSL.javaVersion("0.0").substring(0, 3) );
return gt <= 0;
}
}