mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-09 06:28:49 +00:00
Merge
This commit is contained in:
commit
d73e2aa93f
@ -36,6 +36,7 @@ import java.util.logging.Level;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.loading.PrivateClassLoader;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* This class keeps the list of Class Loaders registered in the MBean Server.
|
||||
@ -192,6 +193,7 @@ final class ClassLoaderRepositorySupport
|
||||
final ClassLoader without,
|
||||
final ClassLoader stop)
|
||||
throws ClassNotFoundException {
|
||||
ReflectUtil.checkPackageAccess(className);
|
||||
final int size = list.length;
|
||||
for(int i=0; i<size; i++) {
|
||||
try {
|
||||
|
||||
@ -51,6 +51,7 @@ import javax.management.MBeanPermission;
|
||||
import javax.management.MBeanRegistrationException;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerDelegate;
|
||||
import javax.management.MBeanServerPermission;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
@ -1409,6 +1410,8 @@ public final class JmxMBeanServer
|
||||
// Default is true.
|
||||
final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY;
|
||||
|
||||
checkNewMBeanServerPermission();
|
||||
|
||||
// This constructor happens to disregard the value of the interceptors
|
||||
// flag - that is, it always uses the default value - false.
|
||||
// This is admitedly a bug, but we chose not to fix it for now
|
||||
@ -1494,4 +1497,11 @@ public final class JmxMBeanServer
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNewMBeanServerPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
Permission perm = new MBeanServerPermission("newMBeanServer");
|
||||
sm.checkPermission(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,11 +32,13 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.Permission;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.MBeanException;
|
||||
import javax.management.MBeanPermission;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.OperationsException;
|
||||
@ -44,7 +46,7 @@ import javax.management.ReflectionException;
|
||||
import javax.management.RuntimeErrorException;
|
||||
import javax.management.RuntimeMBeanException;
|
||||
import javax.management.RuntimeOperationsException;
|
||||
|
||||
import sun.reflect.misc.ConstructorUtil;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
@ -56,7 +58,6 @@ import sun.reflect.misc.ReflectUtil;
|
||||
* @since 1.5
|
||||
*/
|
||||
public class MBeanInstantiator {
|
||||
|
||||
private final ModifiableClassLoaderRepository clr;
|
||||
// private MetaData meta = null;
|
||||
|
||||
@ -88,6 +89,7 @@ public class MBeanInstantiator {
|
||||
"Exception occurred during object instantiation");
|
||||
}
|
||||
|
||||
ReflectUtil.checkPackageAccess(className);
|
||||
try {
|
||||
if (clr == null) throw new ClassNotFoundException(className);
|
||||
theClass = clr.loadClass(className);
|
||||
@ -162,6 +164,7 @@ public class MBeanInstantiator {
|
||||
continue;
|
||||
}
|
||||
|
||||
ReflectUtil.checkPackageAccess(signature[i]);
|
||||
// Ok we do not have a primitive type ! We need to build
|
||||
// the signature of the method
|
||||
//
|
||||
@ -205,6 +208,9 @@ public class MBeanInstantiator {
|
||||
*/
|
||||
public Object instantiate(Class<?> theClass)
|
||||
throws ReflectionException, MBeanException {
|
||||
|
||||
checkMBeanPermission(theClass, null, null, "instantiate");
|
||||
|
||||
Object moi;
|
||||
|
||||
|
||||
@ -260,6 +266,9 @@ public class MBeanInstantiator {
|
||||
public Object instantiate(Class<?> theClass, Object params[],
|
||||
String signature[], ClassLoader loader)
|
||||
throws ReflectionException, MBeanException {
|
||||
|
||||
checkMBeanPermission(theClass, null, null, "instantiate");
|
||||
|
||||
// Instantiate the new object
|
||||
|
||||
// ------------------------------
|
||||
@ -407,6 +416,8 @@ public class MBeanInstantiator {
|
||||
throw new RuntimeOperationsException(new
|
||||
IllegalArgumentException(), "Null className passed in parameter");
|
||||
}
|
||||
|
||||
ReflectUtil.checkPackageAccess(className);
|
||||
Class<?> theClass;
|
||||
if (loaderName == null) {
|
||||
// Load the class using the agent class loader
|
||||
@ -619,13 +630,13 @@ public class MBeanInstantiator {
|
||||
**/
|
||||
static Class<?> loadClass(String className, ClassLoader loader)
|
||||
throws ReflectionException {
|
||||
|
||||
Class<?> theClass;
|
||||
if (className == null) {
|
||||
throw new RuntimeOperationsException(new
|
||||
IllegalArgumentException("The class name cannot be null"),
|
||||
"Exception occurred during object instantiation");
|
||||
}
|
||||
ReflectUtil.checkPackageAccess(className);
|
||||
try {
|
||||
if (loader == null)
|
||||
loader = MBeanInstantiator.class.getClassLoader();
|
||||
@ -676,6 +687,7 @@ public class MBeanInstantiator {
|
||||
// We need to load the class through the class
|
||||
// loader of the target object.
|
||||
//
|
||||
ReflectUtil.checkPackageAccess(signature[i]);
|
||||
tab[i] = Class.forName(signature[i], false, aLoader);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -701,7 +713,7 @@ public class MBeanInstantiator {
|
||||
|
||||
private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) {
|
||||
try {
|
||||
return c.getConstructor(params);
|
||||
return ConstructorUtil.getConstructor(c, params);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
@ -715,4 +727,18 @@ public class MBeanInstantiator {
|
||||
char.class, boolean.class})
|
||||
primitiveClasses.put(c.getName(), c);
|
||||
}
|
||||
|
||||
private static void checkMBeanPermission(Class<?> clazz,
|
||||
String member,
|
||||
ObjectName objectName,
|
||||
String actions) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (clazz != null && sm != null) {
|
||||
Permission perm = new MBeanPermission(clazz.getName(),
|
||||
member,
|
||||
objectName,
|
||||
actions);
|
||||
sm.checkPermission(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
import com.sun.jmx.mbeanserver.MXBeanMappingFactory;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Base class for MBeans. There is one instance of this class for
|
||||
@ -131,6 +132,7 @@ public abstract class MBeanSupport<M>
|
||||
" is not an instance of " + mbeanInterfaceType.getName();
|
||||
throw new NotCompliantMBeanException(msg);
|
||||
}
|
||||
ReflectUtil.checkPackageAccess(mbeanInterfaceType);
|
||||
this.resource = resource;
|
||||
MBeanIntrospector<M> introspector = getMBeanIntrospector();
|
||||
this.perInterface = introspector.getPerInterface(mbeanInterfaceType);
|
||||
|
||||
@ -476,6 +476,8 @@ class MethodHandleNatives {
|
||||
case "getProxyClass":
|
||||
case "newProxyInstance":
|
||||
return defc == java.lang.reflect.Proxy.class;
|
||||
case "asInterfaceInstance":
|
||||
return defc == java.lang.invoke.MethodHandleProxies.class;
|
||||
case "getBundle":
|
||||
case "clearCache":
|
||||
return defc == java.util.ResourceBundle.class;
|
||||
|
||||
@ -141,12 +141,15 @@ public class MethodHandleProxies {
|
||||
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
|
||||
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
|
||||
throw new IllegalArgumentException("not a public interface: "+intfc.getName());
|
||||
SecurityManager smgr = System.getSecurityManager();
|
||||
if (smgr != null) {
|
||||
final MethodHandle mh;
|
||||
if (System.getSecurityManager() != null) {
|
||||
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
|
||||
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
|
||||
final ClassLoader ccl = caller.getClassLoader();
|
||||
final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
|
||||
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
|
||||
mh = ccl != null ? bindCaller(target, caller) : target;
|
||||
} else {
|
||||
mh = target;
|
||||
}
|
||||
ClassLoader proxyLoader = intfc.getClassLoader();
|
||||
if (proxyLoader == null) {
|
||||
@ -160,7 +163,7 @@ public class MethodHandleProxies {
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method sm = methods[i];
|
||||
MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
|
||||
MethodHandle checkTarget = target.asType(smMT); // make throw WMT
|
||||
MethodHandle checkTarget = mh.asType(smMT); // make throw WMT
|
||||
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
|
||||
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
|
||||
}
|
||||
@ -183,8 +186,8 @@ public class MethodHandleProxies {
|
||||
}
|
||||
};
|
||||
|
||||
Object proxy;
|
||||
if (smgr != null) {
|
||||
final Object proxy;
|
||||
if (System.getSecurityManager() != null) {
|
||||
// sun.invoke.WrapperInstance is a restricted interface not accessible
|
||||
// by any non-null class loader.
|
||||
final ClassLoader loader = proxyLoader;
|
||||
@ -204,6 +207,16 @@ public class MethodHandleProxies {
|
||||
return intfc.cast(proxy);
|
||||
}
|
||||
|
||||
private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
|
||||
MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
|
||||
if (target.isVarargsCollector()) {
|
||||
MethodType type = cbmh.type();
|
||||
int arity = type.parameterCount();
|
||||
return cbmh.asVarargsCollector(type.parameterType(arity-1));
|
||||
}
|
||||
return cbmh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the given object was produced by a call to {@link #asInterfaceInstance asInterfaceInstance}.
|
||||
* @param x any reference
|
||||
|
||||
@ -802,20 +802,20 @@ public class ManagementFactory {
|
||||
*/
|
||||
private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) {
|
||||
// Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
|
||||
final DynamicMBean dmbean;
|
||||
if (pmo instanceof DynamicMBean) {
|
||||
dmbean = DynamicMBean.class.cast(pmo);
|
||||
} else if (pmo instanceof NotificationEmitter) {
|
||||
dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
|
||||
} else {
|
||||
dmbean = new StandardMBean(pmo, null, true);
|
||||
}
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException,
|
||||
NotCompliantMBeanException {
|
||||
final DynamicMBean dmbean;
|
||||
if (pmo instanceof DynamicMBean) {
|
||||
dmbean = DynamicMBean.class.cast(pmo);
|
||||
} else if (pmo instanceof NotificationEmitter) {
|
||||
dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
|
||||
} else {
|
||||
dmbean = new StandardMBean(pmo, null, true);
|
||||
}
|
||||
|
||||
mbs.registerMBean(dmbean, pmo.getObjectName());
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -609,7 +609,7 @@ public class Proxy implements java.io.Serializable {
|
||||
}
|
||||
|
||||
if (proxyPkg == null) {
|
||||
// if no non-public proxy interfaces, use sun.proxy package
|
||||
// if no non-public proxy interfaces, use com.sun.proxy package
|
||||
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
|
||||
}
|
||||
|
||||
|
||||
@ -395,7 +395,10 @@ public class LogManager {
|
||||
context = userContext;
|
||||
} else {
|
||||
context = new LoggerContext();
|
||||
context.addLocalLogger(manager.rootLogger);
|
||||
// during initialization, rootLogger is null when
|
||||
// instantiating itself RootLogger
|
||||
if (manager.rootLogger != null)
|
||||
context.addLocalLogger(manager.rootLogger);
|
||||
}
|
||||
javaAwtAccess.put(ecx, LoggerContext.class, context);
|
||||
}
|
||||
@ -455,7 +458,40 @@ public class LogManager {
|
||||
}
|
||||
|
||||
Logger demandSystemLogger(String name, String resourceBundleName) {
|
||||
return systemContext.demandLogger(name, resourceBundleName);
|
||||
// Add a system logger in the system context's namespace
|
||||
final Logger sysLogger = systemContext.demandLogger(name, resourceBundleName);
|
||||
|
||||
// Add the system logger to the LogManager's namespace if not exist
|
||||
// so that there is only one single logger of the given name.
|
||||
// System loggers are visible to applications unless a logger of
|
||||
// the same name has been added.
|
||||
Logger logger;
|
||||
do {
|
||||
// First attempt to call addLogger instead of getLogger
|
||||
// This would avoid potential bug in custom LogManager.getLogger
|
||||
// implementation that adds a logger if does not exist
|
||||
if (addLogger(sysLogger)) {
|
||||
// successfully added the new system logger
|
||||
logger = sysLogger;
|
||||
} else {
|
||||
logger = getLogger(name);
|
||||
}
|
||||
} while (logger == null);
|
||||
|
||||
// LogManager will set the sysLogger's handlers via LogManager.addLogger method.
|
||||
if (logger != sysLogger && sysLogger.getHandlers().length == 0) {
|
||||
// if logger already exists but handlers not set
|
||||
final Logger l = logger;
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
for (Handler hdl : l.getHandlers()) {
|
||||
sysLogger.addHandler(hdl);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
return sysLogger;
|
||||
}
|
||||
|
||||
// LoggerContext maintains the logger namespace per context.
|
||||
@ -663,21 +699,6 @@ public class LogManager {
|
||||
}
|
||||
} while (result == null);
|
||||
}
|
||||
// Add the system logger to the LogManager's namespace if not exists
|
||||
// The LogManager will set its handlers via the LogManager.addLogger method.
|
||||
if (!manager.addLogger(result) && result.getHandlers().length == 0) {
|
||||
// if logger already exists but handlers not set
|
||||
final Logger l = manager.getLogger(name);
|
||||
final Logger logger = result;
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
for (Handler hdl : l.getHandlers()) {
|
||||
logger.addHandler(hdl);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,5 +202,7 @@ public final class ReflectUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static final String PROXY_PACKAGE = "sun.proxy";
|
||||
// Note that bytecode instrumentation tools may exclude 'sun.*'
|
||||
// classes but not generated proxy classes and so keep it in com.sun.*
|
||||
public static final String PROXY_PACKAGE = "com.sun.proxy";
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -392,7 +392,8 @@ final class CipherBox {
|
||||
* uniformly use the bad_record_mac alert to hide the specific type of
|
||||
* the error.
|
||||
*/
|
||||
int decrypt(byte[] buf, int offset, int len) throws BadPaddingException {
|
||||
int decrypt(byte[] buf, int offset, int len,
|
||||
int tagLen) throws BadPaddingException {
|
||||
if (cipher == null) {
|
||||
return len;
|
||||
}
|
||||
@ -416,9 +417,10 @@ final class CipherBox {
|
||||
System.out);
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
if (blockSize != 0) {
|
||||
newLen = removePadding(buf, offset, newLen,
|
||||
blockSize, protocolVersion);
|
||||
newLen = removePadding(
|
||||
buf, offset, newLen, tagLen, blockSize, protocolVersion);
|
||||
|
||||
if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
|
||||
if (newLen < blockSize) {
|
||||
@ -448,7 +450,7 @@ final class CipherBox {
|
||||
*
|
||||
* @see decrypt(byte[], int, int)
|
||||
*/
|
||||
int decrypt(ByteBuffer bb) throws BadPaddingException {
|
||||
int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException {
|
||||
|
||||
int len = bb.remaining();
|
||||
|
||||
@ -471,7 +473,6 @@ final class CipherBox {
|
||||
}
|
||||
|
||||
if (debug != null && Debug.isOn("plaintext")) {
|
||||
bb.position(pos);
|
||||
try {
|
||||
HexDumpEncoder hd = new HexDumpEncoder();
|
||||
|
||||
@ -479,7 +480,8 @@ final class CipherBox {
|
||||
"Padded plaintext after DECRYPTION: len = "
|
||||
+ newLen);
|
||||
|
||||
hd.encodeBuffer(bb, System.out);
|
||||
hd.encodeBuffer(
|
||||
(ByteBuffer)bb.duplicate().position(pos), System.out);
|
||||
} catch (IOException e) { }
|
||||
}
|
||||
|
||||
@ -488,7 +490,8 @@ final class CipherBox {
|
||||
*/
|
||||
if (blockSize != 0) {
|
||||
bb.position(pos);
|
||||
newLen = removePadding(bb, blockSize, protocolVersion);
|
||||
newLen = removePadding(
|
||||
bb, tagLen, blockSize, protocolVersion);
|
||||
|
||||
if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
|
||||
if (newLen < blockSize) {
|
||||
@ -590,6 +593,65 @@ final class CipherBox {
|
||||
return newlen;
|
||||
}
|
||||
|
||||
/*
|
||||
* A constant-time check of the padding.
|
||||
*
|
||||
* NOTE that we are checking both the padding and the padLen bytes here.
|
||||
*
|
||||
* The caller MUST ensure that the len parameter is a positive number.
|
||||
*/
|
||||
private static int[] checkPadding(
|
||||
byte[] buf, int offset, int len, byte pad) {
|
||||
|
||||
if (len <= 0) {
|
||||
throw new RuntimeException("padding len must be positive");
|
||||
}
|
||||
|
||||
// An array of hits is used to prevent Hotspot optimization for
|
||||
// the purpose of a constant-time check.
|
||||
int[] results = {0, 0}; // {missed #, matched #}
|
||||
for (int i = 0; i <= 256;) {
|
||||
for (int j = 0; j < len && i <= 256; j++, i++) { // j <= i
|
||||
if (buf[offset + j] != pad) {
|
||||
results[0]++; // mismatched padding data
|
||||
} else {
|
||||
results[1]++; // matched padding data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* A constant-time check of the padding.
|
||||
*
|
||||
* NOTE that we are checking both the padding and the padLen bytes here.
|
||||
*
|
||||
* The caller MUST ensure that the bb parameter has remaining.
|
||||
*/
|
||||
private static int[] checkPadding(ByteBuffer bb, byte pad) {
|
||||
|
||||
if (!bb.hasRemaining()) {
|
||||
throw new RuntimeException("hasRemaining() must be positive");
|
||||
}
|
||||
|
||||
// An array of hits is used to prevent Hotspot optimization for
|
||||
// the purpose of a constant-time check.
|
||||
int[] results = {0, 0}; // {missed #, matched #}
|
||||
bb.mark();
|
||||
for (int i = 0; i <= 256; bb.reset()) {
|
||||
for (; bb.hasRemaining() && i <= 256; i++) {
|
||||
if (bb.get() != pad) {
|
||||
results[0]++; // mismatched padding data
|
||||
} else {
|
||||
results[1]++; // matched padding data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* Typical TLS padding format for a 64 bit block cipher is as follows:
|
||||
@ -602,86 +664,95 @@ final class CipherBox {
|
||||
* as it makes the data a multiple of the block size
|
||||
*/
|
||||
private static int removePadding(byte[] buf, int offset, int len,
|
||||
int blockSize, ProtocolVersion protocolVersion)
|
||||
throws BadPaddingException {
|
||||
int tagLen, int blockSize,
|
||||
ProtocolVersion protocolVersion) throws BadPaddingException {
|
||||
|
||||
// last byte is length byte (i.e. actual padding length - 1)
|
||||
int padOffset = offset + len - 1;
|
||||
int pad = buf[padOffset] & 0x0ff;
|
||||
int padLen = buf[padOffset] & 0xFF;
|
||||
|
||||
int newlen = len - (pad + 1);
|
||||
if (newlen < 0) {
|
||||
throw new BadPaddingException("Padding length invalid: " + pad);
|
||||
int newLen = len - (padLen + 1);
|
||||
if ((newLen - tagLen) < 0) {
|
||||
// If the buffer is not long enough to contain the padding plus
|
||||
// a MAC tag, do a dummy constant-time padding check.
|
||||
//
|
||||
// Note that it is a dummy check, so we won't care about what is
|
||||
// the actual padding data.
|
||||
checkPadding(buf, offset, len, (byte)(padLen & 0xFF));
|
||||
|
||||
throw new BadPaddingException("Invalid Padding length: " + padLen);
|
||||
}
|
||||
|
||||
// The padding data should be filled with the padding length value.
|
||||
int[] results = checkPadding(buf, offset + newLen,
|
||||
padLen + 1, (byte)(padLen & 0xFF));
|
||||
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
|
||||
for (int i = 1; i <= pad; i++) {
|
||||
int val = buf[padOffset - i] & 0xff;
|
||||
if (val != pad) {
|
||||
throw new BadPaddingException
|
||||
("Invalid TLS padding: " + val);
|
||||
}
|
||||
if (results[0] != 0) { // padding data has invalid bytes
|
||||
throw new BadPaddingException("Invalid TLS padding data");
|
||||
}
|
||||
} else { // SSLv3
|
||||
// SSLv3 requires 0 <= length byte < block size
|
||||
// some implementations do 1 <= length byte <= block size,
|
||||
// so accept that as well
|
||||
// v3 does not require any particular value for the other bytes
|
||||
if (pad > blockSize) {
|
||||
throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
|
||||
if (padLen > blockSize) {
|
||||
throw new BadPaddingException("Invalid SSLv3 padding");
|
||||
}
|
||||
}
|
||||
return newlen;
|
||||
return newLen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Position/limit is equal the removed padding.
|
||||
*/
|
||||
private static int removePadding(ByteBuffer bb,
|
||||
int blockSize, ProtocolVersion protocolVersion)
|
||||
throws BadPaddingException {
|
||||
int tagLen, int blockSize,
|
||||
ProtocolVersion protocolVersion) throws BadPaddingException {
|
||||
|
||||
int len = bb.remaining();
|
||||
int offset = bb.position();
|
||||
|
||||
// last byte is length byte (i.e. actual padding length - 1)
|
||||
int padOffset = offset + len - 1;
|
||||
int pad = bb.get(padOffset) & 0x0ff;
|
||||
int padLen = bb.get(padOffset) & 0xFF;
|
||||
|
||||
int newlen = len - (pad + 1);
|
||||
if (newlen < 0) {
|
||||
throw new BadPaddingException("Padding length invalid: " + pad);
|
||||
int newLen = len - (padLen + 1);
|
||||
if ((newLen - tagLen) < 0) {
|
||||
// If the buffer is not long enough to contain the padding plus
|
||||
// a MAC tag, do a dummy constant-time padding check.
|
||||
//
|
||||
// Note that it is a dummy check, so we won't care about what is
|
||||
// the actual padding data.
|
||||
checkPadding(bb.duplicate(), (byte)(padLen & 0xFF));
|
||||
|
||||
throw new BadPaddingException("Invalid Padding length: " + padLen);
|
||||
}
|
||||
|
||||
/*
|
||||
* We could zero the padding area, but not much useful
|
||||
* information there.
|
||||
*/
|
||||
// The padding data should be filled with the padding length value.
|
||||
int[] results = checkPadding(
|
||||
(ByteBuffer)bb.duplicate().position(offset + newLen),
|
||||
(byte)(padLen & 0xFF));
|
||||
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
|
||||
bb.put(padOffset, (byte)0); // zero the padding.
|
||||
for (int i = 1; i <= pad; i++) {
|
||||
int val = bb.get(padOffset - i) & 0xff;
|
||||
if (val != pad) {
|
||||
throw new BadPaddingException
|
||||
("Invalid TLS padding: " + val);
|
||||
}
|
||||
if (results[0] != 0) { // padding data has invalid bytes
|
||||
throw new BadPaddingException("Invalid TLS padding data");
|
||||
}
|
||||
} else { // SSLv3
|
||||
// SSLv3 requires 0 <= length byte < block size
|
||||
// some implementations do 1 <= length byte <= block size,
|
||||
// so accept that as well
|
||||
// v3 does not require any particular value for the other bytes
|
||||
if (pad > blockSize) {
|
||||
throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
|
||||
if (padLen > blockSize) {
|
||||
throw new BadPaddingException("Invalid SSLv3 padding");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset buffer limit to remove padding.
|
||||
*/
|
||||
bb.position(offset + newlen);
|
||||
bb.limit(offset + newlen);
|
||||
bb.position(offset + newLen);
|
||||
bb.limit(offset + newLen);
|
||||
|
||||
return newlen;
|
||||
return newLen;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -708,4 +779,45 @@ final class CipherBox {
|
||||
boolean isCBCMode() {
|
||||
return isCBCMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the cipher null?
|
||||
*
|
||||
* @return true if the cipher is null, false otherwise.
|
||||
*/
|
||||
boolean isNullCipher() {
|
||||
return cipher == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanity check the length of a fragment before decryption.
|
||||
*
|
||||
* In CBC mode, check that the fragment length is one or multiple times
|
||||
* of the block size of the cipher suite, and is at least one (one is the
|
||||
* smallest size of padding in CBC mode) bigger than the tag size of the
|
||||
* MAC algorithm except the explicit IV size for TLS 1.1 or later.
|
||||
*
|
||||
* In non-CBC mode, check that the fragment length is not less than the
|
||||
* tag size of the MAC algorithm.
|
||||
*
|
||||
* @return true if the length of a fragment matches above requirements
|
||||
*/
|
||||
boolean sanityCheck(int tagLen, int fragmentLen) {
|
||||
if (!isCBCMode) {
|
||||
return fragmentLen >= tagLen;
|
||||
}
|
||||
|
||||
if ((fragmentLen % blockSize) == 0) {
|
||||
int minimal = tagLen + 1;
|
||||
minimal = (minimal >= blockSize) ? minimal : blockSize;
|
||||
if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
|
||||
minimal += blockSize; // plus the size of the explicit IV
|
||||
}
|
||||
|
||||
return (fragmentLen >= minimal);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2013, 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
|
||||
@ -549,9 +549,18 @@ final class CipherSuite implements Comparable<CipherSuite> {
|
||||
// size of the MAC value (and MAC key) in bytes
|
||||
final int size;
|
||||
|
||||
MacAlg(String name, int size) {
|
||||
// block size of the underlying hash algorithm
|
||||
final int hashBlockSize;
|
||||
|
||||
// minimal padding size of the underlying hash algorithm
|
||||
final int minimalPaddingSize;
|
||||
|
||||
MacAlg(String name, int size,
|
||||
int hashBlockSize, int minimalPaddingSize) {
|
||||
this.name = name;
|
||||
this.size = size;
|
||||
this.hashBlockSize = hashBlockSize;
|
||||
this.minimalPaddingSize = minimalPaddingSize;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -596,11 +605,11 @@ final class CipherSuite implements Comparable<CipherSuite> {
|
||||
new BulkCipher(CIPHER_AES, 32, 16, true);
|
||||
|
||||
// MACs
|
||||
final static MacAlg M_NULL = new MacAlg("NULL", 0);
|
||||
final static MacAlg M_MD5 = new MacAlg("MD5", 16);
|
||||
final static MacAlg M_SHA = new MacAlg("SHA", 20);
|
||||
final static MacAlg M_SHA256 = new MacAlg("SHA256", 32);
|
||||
final static MacAlg M_SHA384 = new MacAlg("SHA384", 48);
|
||||
final static MacAlg M_NULL = new MacAlg("NULL", 0, 0, 0);
|
||||
final static MacAlg M_MD5 = new MacAlg("MD5", 16, 64, 9);
|
||||
final static MacAlg M_SHA = new MacAlg("SHA", 20, 64, 9);
|
||||
final static MacAlg M_SHA256 = new MacAlg("SHA256", 32, 64, 9);
|
||||
final static MacAlg M_SHA384 = new MacAlg("SHA384", 48, 128, 17);
|
||||
|
||||
/**
|
||||
* PRFs (PseudoRandom Function) from TLS specifications.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, 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
|
||||
@ -177,71 +177,6 @@ final class EngineInputRecord extends InputRecord {
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifies and removes the MAC value. Returns true if
|
||||
* the MAC checks out OK.
|
||||
*
|
||||
* On entry:
|
||||
* position = beginning of app/MAC data
|
||||
* limit = end of MAC data.
|
||||
*
|
||||
* On return:
|
||||
* position = beginning of app data
|
||||
* limit = end of app data
|
||||
*/
|
||||
boolean checkMAC(MAC signer, ByteBuffer bb) {
|
||||
if (internalData) {
|
||||
return checkMAC(signer);
|
||||
}
|
||||
|
||||
int len = signer.MAClen();
|
||||
if (len == 0) { // no mac
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab the original limit
|
||||
*/
|
||||
int lim = bb.limit();
|
||||
|
||||
/*
|
||||
* Delineate the area to apply a MAC on.
|
||||
*/
|
||||
int macData = lim - len;
|
||||
bb.limit(macData);
|
||||
|
||||
byte[] mac = signer.compute(contentType(), bb);
|
||||
|
||||
if (len != mac.length) {
|
||||
throw new RuntimeException("Internal MAC error");
|
||||
}
|
||||
|
||||
/*
|
||||
* Delineate the MAC values, position was already set
|
||||
* by doing the compute above.
|
||||
*
|
||||
* We could zero the MAC area, but not much useful information
|
||||
* there anyway.
|
||||
*/
|
||||
bb.position(macData);
|
||||
bb.limit(lim);
|
||||
|
||||
try {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (bb.get() != mac[i]) { // No BB.equals(byte []); !
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
/*
|
||||
* Position to the data.
|
||||
*/
|
||||
bb.rewind();
|
||||
bb.limit(macData);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass the data down if it's internally cached, otherwise
|
||||
* do it here.
|
||||
@ -251,20 +186,163 @@ final class EngineInputRecord extends InputRecord {
|
||||
* If external data(app), return a new ByteBuffer with data to
|
||||
* process.
|
||||
*/
|
||||
ByteBuffer decrypt(CipherBox box, ByteBuffer bb)
|
||||
throws BadPaddingException {
|
||||
ByteBuffer decrypt(MAC signer,
|
||||
CipherBox box, ByteBuffer bb) throws BadPaddingException {
|
||||
|
||||
if (internalData) {
|
||||
decrypt(box);
|
||||
decrypt(signer, box); // MAC is checked during decryption
|
||||
return tmpBB;
|
||||
}
|
||||
|
||||
box.decrypt(bb);
|
||||
bb.rewind();
|
||||
BadPaddingException reservedBPE = null;
|
||||
int tagLen = signer.MAClen();
|
||||
int cipheredLength = bb.remaining();
|
||||
|
||||
if (!box.isNullCipher()) {
|
||||
// sanity check length of the ciphertext
|
||||
if (!box.sanityCheck(tagLen, cipheredLength)) {
|
||||
throw new BadPaddingException(
|
||||
"ciphertext sanity check failed");
|
||||
}
|
||||
|
||||
try {
|
||||
// Note that the CipherBox.decrypt() does not change
|
||||
// the capacity of the buffer.
|
||||
box.decrypt(bb, tagLen);
|
||||
} catch (BadPaddingException bpe) {
|
||||
// RFC 2246 states that decryption_failed should be used
|
||||
// for this purpose. However, that allows certain attacks,
|
||||
// so we just send bad record MAC. We also need to make
|
||||
// sure to always check the MAC to avoid a timing attack
|
||||
// for the same issue. See paper by Vaudenay et al and the
|
||||
// update in RFC 4346/5246.
|
||||
//
|
||||
// Failover to message authentication code checking.
|
||||
reservedBPE = bpe;
|
||||
} finally {
|
||||
bb.rewind();
|
||||
}
|
||||
}
|
||||
|
||||
if (tagLen != 0) {
|
||||
int macOffset = bb.limit() - tagLen;
|
||||
|
||||
// Note that although it is not necessary, we run the same MAC
|
||||
// computation and comparison on the payload for both stream
|
||||
// cipher and CBC block cipher.
|
||||
if (bb.remaining() < tagLen) {
|
||||
// negative data length, something is wrong
|
||||
if (reservedBPE == null) {
|
||||
reservedBPE = new BadPaddingException("bad record");
|
||||
}
|
||||
|
||||
// set offset of the dummy MAC
|
||||
macOffset = cipheredLength - tagLen;
|
||||
bb.limit(cipheredLength);
|
||||
}
|
||||
|
||||
// Run MAC computation and comparison on the payload.
|
||||
if (checkMacTags(contentType(), bb, signer, false)) {
|
||||
if (reservedBPE == null) {
|
||||
reservedBPE = new BadPaddingException("bad record MAC");
|
||||
}
|
||||
}
|
||||
|
||||
// Run MAC computation and comparison on the remainder.
|
||||
//
|
||||
// It is only necessary for CBC block cipher. It is used to get a
|
||||
// constant time of MAC computation and comparison on each record.
|
||||
if (box.isCBCMode()) {
|
||||
int remainingLen = calculateRemainingLen(
|
||||
signer, cipheredLength, macOffset);
|
||||
|
||||
// NOTE: here we use the InputRecord.buf because I did not find
|
||||
// an effective way to work on ByteBuffer when its capacity is
|
||||
// less than remainingLen.
|
||||
|
||||
// NOTE: remainingLen may be bigger (less than 1 block of the
|
||||
// hash algorithm of the MAC) than the cipheredLength. However,
|
||||
// We won't need to worry about it because we always use a
|
||||
// maximum buffer for every record. We need a change here if
|
||||
// we use small buffer size in the future.
|
||||
if (remainingLen > buf.length) {
|
||||
// unlikely to happen, just a placehold
|
||||
throw new RuntimeException(
|
||||
"Internal buffer capacity error");
|
||||
}
|
||||
|
||||
// Won't need to worry about the result on the remainder. And
|
||||
// then we won't need to worry about what's actual data to
|
||||
// check MAC tag on. We start the check from the header of the
|
||||
// buffer so that we don't need to construct a new byte buffer.
|
||||
checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
|
||||
}
|
||||
|
||||
bb.limit(macOffset);
|
||||
}
|
||||
|
||||
// Is it a failover?
|
||||
if (reservedBPE != null) {
|
||||
throw reservedBPE;
|
||||
}
|
||||
|
||||
return bb.slice();
|
||||
}
|
||||
|
||||
/*
|
||||
* Run MAC computation and comparison
|
||||
*
|
||||
* Please DON'T change the content of the ByteBuffer parameter!
|
||||
*/
|
||||
private static boolean checkMacTags(byte contentType, ByteBuffer bb,
|
||||
MAC signer, boolean isSimulated) {
|
||||
|
||||
int tagLen = signer.MAClen();
|
||||
int lim = bb.limit();
|
||||
int macData = lim - tagLen;
|
||||
|
||||
bb.limit(macData);
|
||||
byte[] hash = signer.compute(contentType, bb, isSimulated);
|
||||
if (hash == null || tagLen != hash.length) {
|
||||
// Something is wrong with MAC implementation.
|
||||
throw new RuntimeException("Internal MAC error");
|
||||
}
|
||||
|
||||
bb.position(macData);
|
||||
bb.limit(lim);
|
||||
try {
|
||||
int[] results = compareMacTags(bb, hash);
|
||||
return (results[0] != 0);
|
||||
} finally {
|
||||
bb.rewind();
|
||||
bb.limit(macData);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A constant-time comparison of the MAC tags.
|
||||
*
|
||||
* Please DON'T change the content of the ByteBuffer parameter!
|
||||
*/
|
||||
private static int[] compareMacTags(ByteBuffer bb, byte[] tag) {
|
||||
|
||||
// An array of hits is used to prevent Hotspot optimization for
|
||||
// the purpose of a constant-time check.
|
||||
int[] results = {0, 0}; // {missed #, matched #}
|
||||
|
||||
// The caller ensures there are enough bytes available in the buffer.
|
||||
// So we won't need to check the remaining of the buffer.
|
||||
for (int i = 0; i < tag.length; i++) {
|
||||
if (bb.get() != tag[i]) {
|
||||
results[0]++; // mismatched bytes
|
||||
} else {
|
||||
results[1]++; // matched bytes
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* Override the actual write below. We do things this way to be
|
||||
* consistent with InputRecord. InputRecord may try to write out
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, 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
|
||||
@ -118,7 +118,7 @@ final class EngineOutputRecord extends OutputRecord {
|
||||
throws IOException {
|
||||
|
||||
if (signer.MAClen() != 0) {
|
||||
byte[] hash = signer.compute(contentType(), bb);
|
||||
byte[] hash = signer.compute(contentType(), bb, false);
|
||||
|
||||
/*
|
||||
* position was advanced to limit in compute above.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -133,43 +133,173 @@ class InputRecord extends ByteArrayInputStream implements Record {
|
||||
return handshakeHash;
|
||||
}
|
||||
|
||||
void decrypt(MAC signer, CipherBox box) throws BadPaddingException {
|
||||
|
||||
BadPaddingException reservedBPE = null;
|
||||
int tagLen = signer.MAClen();
|
||||
int cipheredLength = count - headerSize;
|
||||
|
||||
if (!box.isNullCipher()) {
|
||||
// sanity check length of the ciphertext
|
||||
if (!box.sanityCheck(tagLen, cipheredLength)) {
|
||||
throw new BadPaddingException(
|
||||
"ciphertext sanity check failed");
|
||||
}
|
||||
|
||||
try {
|
||||
// Note that the CipherBox.decrypt() does not change
|
||||
// the capacity of the buffer.
|
||||
count = headerSize +
|
||||
box.decrypt(buf, headerSize, cipheredLength, tagLen);
|
||||
} catch (BadPaddingException bpe) {
|
||||
// RFC 2246 states that decryption_failed should be used
|
||||
// for this purpose. However, that allows certain attacks,
|
||||
// so we just send bad record MAC. We also need to make
|
||||
// sure to always check the MAC to avoid a timing attack
|
||||
// for the same issue. See paper by Vaudenay et al and the
|
||||
// update in RFC 4346/5246.
|
||||
//
|
||||
// Failover to message authentication code checking.
|
||||
reservedBPE = bpe;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagLen != 0) {
|
||||
int macOffset = count - tagLen;
|
||||
int contentLen = macOffset - headerSize;
|
||||
|
||||
// Note that although it is not necessary, we run the same MAC
|
||||
// computation and comparison on the payload for both stream
|
||||
// cipher and CBC block cipher.
|
||||
if (contentLen < 0) {
|
||||
// negative data length, something is wrong
|
||||
if (reservedBPE == null) {
|
||||
reservedBPE = new BadPaddingException("bad record");
|
||||
}
|
||||
|
||||
// set offset of the dummy MAC
|
||||
macOffset = headerSize + cipheredLength - tagLen;
|
||||
contentLen = macOffset - headerSize;
|
||||
}
|
||||
|
||||
count -= tagLen; // Set the count before any MAC checking
|
||||
// exception occurs, so that the following
|
||||
// process can read the actual decrypted
|
||||
// content (minus the MAC) in the fragment
|
||||
// if necessary.
|
||||
|
||||
// Run MAC computation and comparison on the payload.
|
||||
if (checkMacTags(contentType(),
|
||||
buf, headerSize, contentLen, signer, false)) {
|
||||
if (reservedBPE == null) {
|
||||
reservedBPE = new BadPaddingException("bad record MAC");
|
||||
}
|
||||
}
|
||||
|
||||
// Run MAC computation and comparison on the remainder.
|
||||
//
|
||||
// It is only necessary for CBC block cipher. It is used to get a
|
||||
// constant time of MAC computation and comparison on each record.
|
||||
if (box.isCBCMode()) {
|
||||
int remainingLen = calculateRemainingLen(
|
||||
signer, cipheredLength, contentLen);
|
||||
|
||||
// NOTE: remainingLen may be bigger (less than 1 block of the
|
||||
// hash algorithm of the MAC) than the cipheredLength. However,
|
||||
// We won't need to worry about it because we always use a
|
||||
// maximum buffer for every record. We need a change here if
|
||||
// we use small buffer size in the future.
|
||||
if (remainingLen > buf.length) {
|
||||
// unlikely to happen, just a placehold
|
||||
throw new RuntimeException(
|
||||
"Internal buffer capacity error");
|
||||
}
|
||||
|
||||
// Won't need to worry about the result on the remainder. And
|
||||
// then we won't need to worry about what's actual data to
|
||||
// check MAC tag on. We start the check from the header of the
|
||||
// buffer so that we don't need to construct a new byte buffer.
|
||||
checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Is it a failover?
|
||||
if (reservedBPE != null) {
|
||||
throw reservedBPE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify and remove the MAC ... used for all records.
|
||||
* Run MAC computation and comparison
|
||||
*
|
||||
* Please DON'T change the content of the byte buffer parameter!
|
||||
*/
|
||||
boolean checkMAC(MAC signer) {
|
||||
int len = signer.MAClen();
|
||||
if (len == 0) { // no mac
|
||||
return true;
|
||||
}
|
||||
static boolean checkMacTags(byte contentType, byte[] buffer,
|
||||
int offset, int contentLen, MAC signer, boolean isSimulated) {
|
||||
|
||||
int offset = count - len;
|
||||
|
||||
if (offset < headerSize) {
|
||||
// data length would be negative, something is wrong
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] mac = signer.compute(contentType(), buf,
|
||||
headerSize, offset - headerSize);
|
||||
|
||||
if (len != mac.length) {
|
||||
int tagLen = signer.MAClen();
|
||||
byte[] hash = signer.compute(
|
||||
contentType, buffer, offset, contentLen, isSimulated);
|
||||
if (hash == null || tagLen != hash.length) {
|
||||
// Something is wrong with MAC implementation.
|
||||
throw new RuntimeException("Internal MAC error");
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (buf[offset + i] != mac[i]) {
|
||||
return false;
|
||||
int[] results = compareMacTags(buffer, offset + contentLen, hash);
|
||||
return (results[0] != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* A constant-time comparison of the MAC tags.
|
||||
*
|
||||
* Please DON'T change the content of the byte buffer parameter!
|
||||
*/
|
||||
private static int[] compareMacTags(
|
||||
byte[] buffer, int offset, byte[] tag) {
|
||||
|
||||
// An array of hits is used to prevent Hotspot optimization for
|
||||
// the purpose of a constant-time check.
|
||||
int[] results = {0, 0}; // {missed #, matched #}
|
||||
|
||||
// The caller ensures there are enough bytes available in the buffer.
|
||||
// So we won't need to check the length of the buffer.
|
||||
for (int i = 0; i < tag.length; i++) {
|
||||
if (buffer[offset + i] != tag[i]) {
|
||||
results[0]++; // mismatched bytes
|
||||
} else {
|
||||
results[1]++; // matched bytes
|
||||
}
|
||||
}
|
||||
count -= len;
|
||||
return true;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void decrypt(CipherBox box) throws BadPaddingException {
|
||||
int len = count - headerSize;
|
||||
count = headerSize + box.decrypt(buf, headerSize, len);
|
||||
}
|
||||
/*
|
||||
* Calculate the length of a dummy buffer to run MAC computation
|
||||
* and comparison on the remainder.
|
||||
*
|
||||
* The caller MUST ensure that the fullLen is not less than usedLen.
|
||||
*/
|
||||
static int calculateRemainingLen(
|
||||
MAC signer, int fullLen, int usedLen) {
|
||||
|
||||
int blockLen = signer.hashBlockLen();
|
||||
int minimalPaddingLen = signer.minimalPaddingLen();
|
||||
|
||||
// (blockLen - minimalPaddingLen) is the maximum message size of
|
||||
// the last block of hash function operation. See FIPS 180-4, or
|
||||
// MD5 specification.
|
||||
fullLen += 13 - (blockLen - minimalPaddingLen);
|
||||
usedLen += 13 - (blockLen - minimalPaddingLen);
|
||||
|
||||
// Note: fullLen is always not less than usedLen, and blockLen
|
||||
// is always bigger than minimalPaddingLen, so we don't worry
|
||||
// about negative values. 0x01 is added to the result to ensure
|
||||
// that the return value is positive. The extra one byte does
|
||||
// not impact the overall MAC compression function evaluations.
|
||||
return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) -
|
||||
Math.ceil(usedLen/(1.0d * blockLen))) * signer.hashBlockLen();
|
||||
}
|
||||
|
||||
/*
|
||||
* Well ... hello_request messages are _never_ hashed since we can't
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -43,8 +43,8 @@ import static sun.security.ssl.CipherSuite.*;
|
||||
* provide integrity protection for SSL messages. The MAC is actually
|
||||
* one of several keyed hashes, as associated with the cipher suite and
|
||||
* protocol version. (SSL v3.0 uses one construct, TLS uses another.)
|
||||
*
|
||||
* <P>NOTE: MAC computation is the only place in the SSL protocol that the
|
||||
* <P>
|
||||
* NOTE: MAC computation is the only place in the SSL protocol that the
|
||||
* sequence number is used. It's also reset to zero with each change of
|
||||
* a cipher spec, so this is the only place this state is needed.
|
||||
*
|
||||
@ -58,6 +58,9 @@ final class MAC {
|
||||
// Value of the null MAC is fixed
|
||||
private static final byte nullMAC[] = new byte[0];
|
||||
|
||||
// internal identifier for the MAC algorithm
|
||||
private final MacAlg macAlg;
|
||||
|
||||
// stuff defined by the kind of MAC algorithm
|
||||
private final int macSize;
|
||||
|
||||
@ -82,6 +85,7 @@ final class MAC {
|
||||
|
||||
private MAC() {
|
||||
macSize = 0;
|
||||
macAlg = M_NULL;
|
||||
mac = null;
|
||||
block = null;
|
||||
}
|
||||
@ -91,6 +95,7 @@ final class MAC {
|
||||
*/
|
||||
MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key)
|
||||
throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
this.macAlg = macAlg;
|
||||
this.macSize = macAlg.size;
|
||||
|
||||
String algorithm;
|
||||
@ -127,6 +132,20 @@ final class MAC {
|
||||
return macSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash function block length of the MAC alorithm.
|
||||
*/
|
||||
int hashBlockLen() {
|
||||
return macAlg.hashBlockSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash function minimal padding length of the MAC alorithm.
|
||||
*/
|
||||
int minimalPaddingLen() {
|
||||
return macAlg.minimalPaddingSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes and returns the MAC for the data in this byte array.
|
||||
*
|
||||
@ -134,9 +153,11 @@ final class MAC {
|
||||
* @param buf compressed record on which the MAC is computed
|
||||
* @param offset start of compressed record data
|
||||
* @param len the size of the compressed record
|
||||
* @param isSimulated if true, simulate the the MAC computation
|
||||
*/
|
||||
final byte[] compute(byte type, byte buf[], int offset, int len) {
|
||||
return compute(type, null, buf, offset, len);
|
||||
final byte[] compute(byte type, byte buf[],
|
||||
int offset, int len, boolean isSimulated) {
|
||||
return compute(type, null, buf, offset, len, isSimulated);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,9 +170,10 @@ final class MAC {
|
||||
* @param type record type
|
||||
* @param bb a ByteBuffer in which the position and limit
|
||||
* demarcate the data to be MAC'd.
|
||||
* @param isSimulated if true, simulate the the MAC computation
|
||||
*/
|
||||
final byte[] compute(byte type, ByteBuffer bb) {
|
||||
return compute(type, bb, null, 0, bb.remaining());
|
||||
final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
|
||||
return compute(type, bb, null, 0, bb.remaining(), isSimulated);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,18 +226,21 @@ final class MAC {
|
||||
* or buf/offset/len.
|
||||
*/
|
||||
private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
|
||||
int offset, int len) {
|
||||
int offset, int len, boolean isSimulated) {
|
||||
|
||||
if (macSize == 0) {
|
||||
return nullMAC;
|
||||
}
|
||||
|
||||
block[BLOCK_OFFSET_TYPE] = type;
|
||||
block[block.length - 2] = (byte)(len >> 8);
|
||||
block[block.length - 1] = (byte)(len );
|
||||
// MUST NOT increase the sequence number for a simulated computation.
|
||||
if (!isSimulated) {
|
||||
block[BLOCK_OFFSET_TYPE] = type;
|
||||
block[block.length - 2] = (byte)(len >> 8);
|
||||
block[block.length - 1] = (byte)(len );
|
||||
|
||||
mac.update(block);
|
||||
incrementSequenceNumber();
|
||||
mac.update(block);
|
||||
incrementSequenceNumber();
|
||||
}
|
||||
|
||||
// content
|
||||
if (bb != null) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -205,7 +205,7 @@ class OutputRecord extends ByteArrayOutputStream implements Record {
|
||||
}
|
||||
if (signer.MAClen() != 0) {
|
||||
byte[] hash = signer.compute(contentType, buf,
|
||||
headerSize, count - headerSize);
|
||||
headerSize, count - headerSize, false);
|
||||
write(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, 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
|
||||
@ -958,35 +958,15 @@ final public class SSLEngineImpl extends SSLEngine {
|
||||
* throw a fatal alert if the integrity check fails.
|
||||
*/
|
||||
try {
|
||||
decryptedBB = inputRecord.decrypt(readCipher, readBB);
|
||||
decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
|
||||
} catch (BadPaddingException e) {
|
||||
// RFC 2246 states that decryption_failed should be used
|
||||
// for this purpose. However, that allows certain attacks,
|
||||
// so we just send bad record MAC. We also need to make
|
||||
// sure to always check the MAC to avoid a timing attack
|
||||
// for the same issue. See paper by Vaudenay et al.
|
||||
//
|
||||
// rewind the BB if necessary.
|
||||
readBB.rewind();
|
||||
|
||||
inputRecord.checkMAC(readMAC, readBB);
|
||||
|
||||
// use the same alert types as for MAC failure below
|
||||
byte alertType = (inputRecord.contentType() ==
|
||||
Record.ct_handshake) ?
|
||||
Alerts.alert_handshake_failure :
|
||||
Alerts.alert_bad_record_mac;
|
||||
fatal(alertType, "Invalid padding", e);
|
||||
fatal(alertType, e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (!inputRecord.checkMAC(readMAC, decryptedBB)) {
|
||||
if (inputRecord.contentType() == Record.ct_handshake) {
|
||||
fatal(Alerts.alert_handshake_failure,
|
||||
"bad handshake record MAC");
|
||||
} else {
|
||||
fatal(Alerts.alert_bad_record_mac, "bad record MAC");
|
||||
}
|
||||
}
|
||||
|
||||
// if (!inputRecord.decompress(c))
|
||||
// fatal(Alerts.alert_decompression_failure,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -986,29 +986,13 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
* throw a fatal alert if the integrity check fails.
|
||||
*/
|
||||
try {
|
||||
r.decrypt(readCipher);
|
||||
r.decrypt(readMAC, readCipher);
|
||||
} catch (BadPaddingException e) {
|
||||
// RFC 2246 states that decryption_failed should be used
|
||||
// for this purpose. However, that allows certain attacks,
|
||||
// so we just send bad record MAC. We also need to make
|
||||
// sure to always check the MAC to avoid a timing attack
|
||||
// for the same issue. See paper by Vaudenay et al.
|
||||
r.checkMAC(readMAC);
|
||||
// use the same alert types as for MAC failure below
|
||||
byte alertType = (r.contentType() == Record.ct_handshake)
|
||||
? Alerts.alert_handshake_failure
|
||||
: Alerts.alert_bad_record_mac;
|
||||
fatal(alertType, "Invalid padding", e);
|
||||
fatal(alertType, e.getMessage(), e);
|
||||
}
|
||||
if (!r.checkMAC(readMAC)) {
|
||||
if (r.contentType() == Record.ct_handshake) {
|
||||
fatal(Alerts.alert_handshake_failure,
|
||||
"bad handshake record MAC");
|
||||
} else {
|
||||
fatal(Alerts.alert_bad_record_mac, "bad record MAC");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (!r.decompress(c))
|
||||
// fatal(Alerts.alert_decompression_failure,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, 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
|
||||
@ -737,5 +737,111 @@ public final class UntrustedCertificates {
|
||||
"B8WfedLHjFW/TMcnXlEWKz4=\n" +
|
||||
"-----END CERTIFICATE-----");
|
||||
|
||||
//
|
||||
// Revoked DigiCert code signing certificates used to sign malware
|
||||
//
|
||||
|
||||
// Subject: CN=Buster Paper Comercial Ltda,
|
||||
// O=Buster Paper Comercial Ltda,
|
||||
// L=S?o Jos? Dos Campos,
|
||||
// ST=S?o Paulo,
|
||||
// C=BR
|
||||
// Issuer: CN=DigiCert Assured ID Code Signing CA-1,
|
||||
// OU=www.digicert.com,
|
||||
// O=DigiCert Inc,
|
||||
// C=US
|
||||
// Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12
|
||||
add("buster-paper-comercial-ltda-72A67312",
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" +
|
||||
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
|
||||
"d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
|
||||
"ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" +
|
||||
"gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" +
|
||||
"w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" +
|
||||
"cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" +
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" +
|
||||
"HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" +
|
||||
"2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" +
|
||||
"tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" +
|
||||
"mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" +
|
||||
"Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" +
|
||||
"BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" +
|
||||
"HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" +
|
||||
"BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" +
|
||||
"My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" +
|
||||
"Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" +
|
||||
"IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" +
|
||||
"L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" +
|
||||
"AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" +
|
||||
"AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" +
|
||||
"AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" +
|
||||
"AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" +
|
||||
"ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" +
|
||||
"AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" +
|
||||
"AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" +
|
||||
"AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" +
|
||||
"dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" +
|
||||
"cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" +
|
||||
"MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" +
|
||||
"hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" +
|
||||
"jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" +
|
||||
"gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" +
|
||||
"/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" +
|
||||
"BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" +
|
||||
"XMuKLxbh7g==\n" +
|
||||
"-----END CERTIFICATE-----");
|
||||
|
||||
// Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
|
||||
// O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
|
||||
// L=S?o Paulo,
|
||||
// ST=S?o Paulo,
|
||||
// C=BR
|
||||
// Issuer: CN=DigiCert Assured ID Code Signing CA-1,
|
||||
// OU=www.digicert.com,
|
||||
// O=DigiCert Inc,
|
||||
// C=US
|
||||
// Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f
|
||||
add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F",
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" +
|
||||
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
|
||||
"d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
|
||||
"ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" +
|
||||
"gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" +
|
||||
"w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" +
|
||||
"TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" +
|
||||
"IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" +
|
||||
"A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" +
|
||||
"4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" +
|
||||
"JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" +
|
||||
"kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" +
|
||||
"0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" +
|
||||
"NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" +
|
||||
"HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" +
|
||||
"o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" +
|
||||
"MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" +
|
||||
"cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" +
|
||||
"L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" +
|
||||
"hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" +
|
||||
"c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" +
|
||||
"eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" +
|
||||
"ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" +
|
||||
"IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" +
|
||||
"YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" +
|
||||
"cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" +
|
||||
"aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" +
|
||||
"ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" +
|
||||
"BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" +
|
||||
"LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" +
|
||||
"Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" +
|
||||
"MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" +
|
||||
"A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" +
|
||||
"Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" +
|
||||
"XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" +
|
||||
"UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" +
|
||||
"zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
|
||||
"-----END CERTIFICATE-----");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,8 +151,8 @@ package.access=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
@ -175,8 +175,8 @@ package.definition=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
|
||||
@ -152,8 +152,8 @@ package.access=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
@ -177,8 +177,8 @@ package.definition=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
|
||||
@ -153,8 +153,8 @@ package.access=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
@ -177,8 +177,8 @@ package.definition=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
|
||||
@ -152,8 +152,8 @@ package.access=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
@ -176,8 +176,8 @@ package.definition=sun.,\
|
||||
com.sun.xml.internal.ws.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.defaults.,\
|
||||
com.sun.jmx.remote.util.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.org.apache.xerces.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.glassfish.external.,\
|
||||
|
||||
@ -119,9 +119,6 @@ public class SubjectDelegation2Test {
|
||||
System.out.println("Create SimpleStandard MBean");
|
||||
SimpleStandard s = new SimpleStandard("monitorRole");
|
||||
mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
|
||||
// Set Security Manager
|
||||
//
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
// Create Properties containing the username/password entries
|
||||
//
|
||||
Properties props = new Properties();
|
||||
@ -132,6 +129,9 @@ public class SubjectDelegation2Test {
|
||||
HashMap env = new HashMap();
|
||||
env.put("jmx.remote.authenticator",
|
||||
new JMXPluggableAuthenticator(props));
|
||||
// Set Security Manager
|
||||
//
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
// Create an RMI connector server
|
||||
//
|
||||
System.out.println("Create an RMI connector server");
|
||||
|
||||
@ -120,9 +120,6 @@ public class SubjectDelegation3Test {
|
||||
System.out.println("Create SimpleStandard MBean");
|
||||
SimpleStandard s = new SimpleStandard("delegate");
|
||||
mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
|
||||
// Set Security Manager
|
||||
//
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
// Create Properties containing the username/password entries
|
||||
//
|
||||
Properties props = new Properties();
|
||||
@ -133,6 +130,9 @@ public class SubjectDelegation3Test {
|
||||
HashMap env = new HashMap();
|
||||
env.put("jmx.remote.authenticator",
|
||||
new JMXPluggableAuthenticator(props));
|
||||
// Set Security Manager
|
||||
//
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
// Create an RMI connector server
|
||||
//
|
||||
System.out.println("Create an RMI connector server");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user