This commit is contained in:
J. Duke 2017-07-05 18:22:00 +02:00
commit b614bef576
142 changed files with 4264 additions and 1432 deletions

View File

@ -176,3 +176,4 @@ c97b99424815c43818e3cc3ffcdd1a60f3198b52 jdk8-b49
8d24def5ceb3b8f2e857f2e18b2804fc59eecf8d jdk8-b52 8d24def5ceb3b8f2e857f2e18b2804fc59eecf8d jdk8-b52
febd7ff5280067ca482faaeb9418ae88764c1a35 jdk8-b53 febd7ff5280067ca482faaeb9418ae88764c1a35 jdk8-b53
c1a277c6022affbc6855bdfb039511e73fbe2395 jdk8-b54 c1a277c6022affbc6855bdfb039511e73fbe2395 jdk8-b54
b85b44cced2406792cfb9baab1377ff03e7001d8 jdk8-b55

View File

@ -274,3 +274,4 @@ e3619706a7253540a2d94e9e841acaab8ace7038 jdk8-b49
9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21 9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21
e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54 e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54
09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22 09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22
af0c8a0808516317333dcf9af15567cdd52761ce jdk8-b55

View File

@ -176,3 +176,4 @@ e865efbc71059a414b3b2dd2e0adfcb3d2ab6ff9 jdk8-b51
e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52 e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52
2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53 2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53
70ad0ed1d6cef0e7712690d1bab21e4769708aad jdk8-b54 70ad0ed1d6cef0e7712690d1bab21e4769708aad jdk8-b54
1f3f4b333341873f00da3dee85e4879f0e89c9bb jdk8-b55

View File

@ -542,6 +542,21 @@ CFLAGS_$(VARIANT)/BYFILE = $(CFLAGS_$(VARIANT)/$(@F)) \
CXXFLAGS_$(VARIANT)/BYFILE = $(CXXFLAGS_$(VARIANT)/$(@F)) \ CXXFLAGS_$(VARIANT)/BYFILE = $(CXXFLAGS_$(VARIANT)/$(@F)) \
$(CXXFLAGS_$(VARIANT)$(CXXFLAGS_$(VARIANT)/$(@F))) $(CXXFLAGS_$(VARIANT)$(CXXFLAGS_$(VARIANT)/$(@F)))
# Command line define to provide basename of file being compiled to source.
# The C macro THIS_FILE can replace the use of __FILE__ in the source
# files for the current filename being compiled.
# The value of the __FILE__ macro is unpredictable and can be anything
# from a relative path to a full path, THIS_FILE will be more consistent..
# The THIS_FILE macro will always be just the basename of the file being
# compiled.
# Different string literals in the the object files makes it difficult to
# compare shared libraries from different builds.
#
# NOTE: If the THIS_FILE macro is actually expanded while in an included
# source file, it will not return the name of the included file.
#
CPP_THIS_FILE = -DTHIS_FILE='"$(<F)"'
# #
# Tool flags # Tool flags
# #
@ -551,7 +566,7 @@ ASFLAGS = $(ASFLAGS_$(VARIANT)) $(ASFLAGS_COMMON) $(OTHER_ASFLAGS)
CFLAGS = $(CFLAGS_$(VARIANT)/BYFILE) $(CFLAGS_COMMON) $(OTHER_CFLAGS) $(EXTRA_CFLAGS) CFLAGS = $(CFLAGS_$(VARIANT)/BYFILE) $(CFLAGS_COMMON) $(OTHER_CFLAGS) $(EXTRA_CFLAGS)
CXXFLAGS = $(CXXFLAGS_$(VARIANT)/BYFILE) $(CXXFLAGS_COMMON) $(OTHER_CXXFLAGS) $(EXTRA_CFLAGS) CXXFLAGS = $(CXXFLAGS_$(VARIANT)/BYFILE) $(CXXFLAGS_COMMON) $(OTHER_CXXFLAGS) $(EXTRA_CFLAGS)
CPPFLAGS = $(CPPFLAGS_$(VARIANT)) $(CPPFLAGS_COMMON) $(OTHER_CPPFLAGS) \ CPPFLAGS = $(CPPFLAGS_$(VARIANT)) $(CPPFLAGS_COMMON) $(OTHER_CPPFLAGS) \
$(DEFINES) $(OPTIONS:%=-D%) $(DEFINES) $(OPTIONS:%=-D%) $(CPP_THIS_FILE)
LDFLAGS = $(LDFLAGS_$(VARIANT)) $(LDFLAGS_COMMON) $(OTHER_LDFLAGS) LDFLAGS = $(LDFLAGS_$(VARIANT)) $(LDFLAGS_COMMON) $(OTHER_LDFLAGS)
LDLIBS = $(OTHER_LDLIBS) $(LDLIBS_$(VARIANT)) $(LDLIBS_COMMON) LDLIBS = $(OTHER_LDLIBS) $(LDLIBS_$(VARIANT)) $(LDLIBS_COMMON)
LINTFLAGS = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \ LINTFLAGS = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \

View File

@ -320,10 +320,10 @@ $(DEMO_LIBRARY): $(DEMO_FULL_OBJECTS)
ifeq ($(PLATFORM),windows) ifeq ($(PLATFORM),windows)
$(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE) $(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE)
$(LINK.demo) $(SHARED_LIBRARY_FLAG) -Fe$@ \ $(LINK.demo) $(SHARED_LIBRARY_FLAG) -Fe$@ \
$(DEMO_FULL_OBJECTS) $(LDLIBS.demo) $(sort $(DEMO_FULL_OBJECTS)) $(LDLIBS.demo)
else else
$(LINK.demo) $(SHARED_LIBRARY_FLAG) -o $@ \ $(LINK.demo) $(SHARED_LIBRARY_FLAG) -o $@ \
$(DEMO_FULL_OBJECTS) $(LDLIBS.demo) $(sort $(DEMO_FULL_OBJECTS)) $(LDLIBS.demo)
endif endif
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)

View File

@ -199,7 +199,7 @@ endif # LIBRARY
$(OBJDIR)/$(LIBRARY).lcf: $(OBJDIR)/$(LIBRARY).res $(COMPILE_FILES_o) $(FILES_m) $(OBJDIR)/$(LIBRARY).lcf: $(OBJDIR)/$(LIBRARY).res $(COMPILE_FILES_o) $(FILES_m)
@$(prep-target) @$(prep-target)
@$(MKDIR) -p $(TEMPDIR) @$(MKDIR) -p $(TEMPDIR)
@$(ECHO) $(FILES_o) > $@ @$(ECHO) $(sort $(FILES_o)) > $@
ifndef LOCAL_RESOURCE_FILE ifndef LOCAL_RESOURCE_FILE
@$(ECHO) $(OBJDIR)/$(LIBRARY).res >> $@ @$(ECHO) $(OBJDIR)/$(LIBRARY).res >> $@
endif endif
@ -256,9 +256,9 @@ $(ACTUAL_LIBRARY):: $(COMPILE_FILES_o) $(FILES_m) $(FILES_reorder)
@$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), OPTIMIZATION_LEVEL=$(OPTIMIZATION_LEVEL)" @$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), OPTIMIZATION_LEVEL=$(OPTIMIZATION_LEVEL)"
@$(ECHO) "Rebuilding $@ because of $?" @$(ECHO) "Rebuilding $@ because of $?"
ifeq ($(LIBRARY), fdlibm) ifeq ($(LIBRARY), fdlibm)
$(AR) $(ARFLAGS) $@ $(FILES_o) $(AR) $(ARFLAGS) $@ $(sort $(FILES_o))
else # LIBRARY else # LIBRARY
$(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(FILES_o) $(LDLIBS) $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(sort $(FILES_o)) $(LDLIBS)
@$(call binary_file_verification,$@) @$(call binary_file_verification,$@)
ifeq ($(WRITE_LIBVERSION),true) ifeq ($(WRITE_LIBVERSION),true)
$(MCS) -d -a "$(FULL_VERSION)" $@ $(MCS) -d -a "$(FULL_VERSION)" $@

View File

@ -262,7 +262,7 @@ else
$(ECHO) Rebuilding $@ because of $$1 $$2 $$3 $$4 $$5 $$6 $${7:+...}; $(ECHO) Rebuilding $@ because of $$1 $$2 $$3 $$4 $$5 $$6 $${7:+...};
@$(MKDIR) -p $(TEMPDIR) @$(MKDIR) -p $(TEMPDIR)
$(LINK_PRE_CMD) $(CC) $(CC_OBJECT_OUTPUT_FLAG)$@ $(LDFLAGS) \ $(LINK_PRE_CMD) $(CC) $(CC_OBJECT_OUTPUT_FLAG)$@ $(LDFLAGS) \
$(FILES_o) $(THREADLIBS) $(LDLIBS) $(sort $(FILES_o)) $(THREADLIBS) $(LDLIBS)
ifeq ($(findstring privileged, $(INFO_PLIST_FILE)), privileged) ifeq ($(findstring privileged, $(INFO_PLIST_FILE)), privileged)
-codesign -s openjdk_codesign $@ -codesign -s openjdk_codesign $@
endif endif
@ -392,8 +392,6 @@ VERSION_DEFINES += -DFULL_VERSION='"$(FULL_VERSION)"'
VERSION_DEFINES += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ VERSION_DEFINES += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \
-DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"'
$(OBJDIR)/main.$(OBJECT_SUFFIX): $(LAUNCHER_SHARE_SRC)/bin/main.c $(OBJDIR)/main.$(OBJECT_SUFFIX): $(LAUNCHER_SHARE_SRC)/bin/main.c
@$(prep-target) @$(prep-target)
$(COMPILE.c) $(CC_OBJECT_OUTPUT_FLAG)$(OBJDIR)/main.$(OBJECT_SUFFIX) \ $(COMPILE.c) $(CC_OBJECT_OUTPUT_FLAG)$(OBJDIR)/main.$(OBJECT_SUFFIX) \

View File

@ -73,7 +73,7 @@ ifeq ($(ARCH_DATA_MODEL),64)
else ifeq ($(ARCH),universal) else ifeq ($(ARCH),universal)
MAX_VM_MEMORY = 1024 MAX_VM_MEMORY = 1024
else else
MAX_VM_MEMORY = 612 MAX_VM_MEMORY = 768
endif endif
# List of all possible directories for javadoc to look for sources # List of all possible directories for javadoc to look for sources

View File

@ -128,7 +128,6 @@ AUTO_FILES_JAVA_DIRS = $(PKGDIR)
# Exclude the sources that get built by ../other/Makefile # Exclude the sources that get built by ../other/Makefile
# #
AUTO_JAVA_PRUNE = \ AUTO_JAVA_PRUNE = \
ECKeyFactory.java \
ECParameters.java \ ECParameters.java \
ECPrivateKeyImpl.java \ ECPrivateKeyImpl.java \
ECPublicKeyImpl.java \ ECPublicKeyImpl.java \

View File

@ -53,7 +53,6 @@ AUTO_FILES_JAVA_DIRS = \
# EC classes used by the packages above # EC classes used by the packages above
# #
FILES_java += \ FILES_java += \
sun/security/ec/ECKeyFactory.java \
sun/security/ec/ECParameters.java \ sun/security/ec/ECParameters.java \
sun/security/ec/ECPrivateKeyImpl.java \ sun/security/ec/ECPrivateKeyImpl.java \
sun/security/ec/ECPublicKeyImpl.java \ sun/security/ec/ECPublicKeyImpl.java \

View File

@ -40,6 +40,7 @@ import java.awt.image.VolatileImage;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer; import java.awt.peer.ContainerPeer;
import java.awt.peer.KeyboardFocusManagerPeer;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.security.AccessController; import java.security.AccessController;
@ -894,15 +895,15 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed + ", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
", time= " + time + ", cause=" + cause); ", time= " + time + ", cause=" + cause);
} }
if (LWKeyboardFocusManagerPeer.getInstance(getAppContext()). if (LWKeyboardFocusManagerPeer.processSynchronousLightweightTransfer(
processSynchronousLightweightTransfer(getTarget(), lightweightChild, temporary, getTarget(), lightweightChild, temporary,
focusedWindowChangeAllowed, time)) { focusedWindowChangeAllowed, time)) {
return true; return true;
} }
int result = LWKeyboardFocusManagerPeer.getInstance(getAppContext()). int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
shouldNativelyFocusHeavyweight(getTarget(), lightweightChild, temporary, getTarget(), lightweightChild, temporary,
focusedWindowChangeAllowed, time, cause); focusedWindowChangeAllowed, time, cause);
switch (result) { switch (result) {
case LWKeyboardFocusManagerPeer.SNFH_FAILURE: case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
return false; return false;
@ -951,14 +952,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
return false; return false;
} }
LWComponentPeer focusOwnerPeer = KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
LWKeyboardFocusManagerPeer.getInstance(getAppContext()). Component focusOwner = kfmPeer.getCurrentFocusOwner();
getFocusOwner();
Component focusOwner = (focusOwnerPeer != null) ? focusOwnerPeer.getTarget() : null;
return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild, return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
getTarget(), temporary, getTarget(), temporary,
focusedWindowChangeAllowed, focusedWindowChangeAllowed,
time, cause, focusOwner); time, cause, focusOwner);
case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED: case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
return true; return true;
} }
@ -1251,9 +1251,6 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) { if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT); LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
} else {
// Anyway request focus to the toplevel.
getWindowPeerOrSelf().requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
} }
} }
@ -1263,8 +1260,8 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
protected void handleJavaFocusEvent(FocusEvent e) { protected void handleJavaFocusEvent(FocusEvent e) {
// Note that the peer receives all the FocusEvents from // Note that the peer receives all the FocusEvents from
// its lightweight children as well // its lightweight children as well
LWKeyboardFocusManagerPeer.getInstance(getAppContext()). KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
setFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? this : null); kfmPeer.setCurrentFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? getTarget() : null);
} }
/** /**

View File

@ -26,85 +26,47 @@
package sun.lwawt; package sun.lwawt;
import java.awt.Component; import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.Window; import java.awt.Window;
import java.util.Map;
import java.util.HashMap;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.KeyboardFocusManagerPeerImpl; import sun.awt.KeyboardFocusManagerPeerImpl;
public class LWKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl { public class LWKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
private static final LWKeyboardFocusManagerPeer inst = new LWKeyboardFocusManagerPeer();
private Object lock = new Object(); private Window focusedWindow;
private LWWindowPeer focusedWindow; private Component focusOwner;
private LWComponentPeer focusOwner;
private static Map<KeyboardFocusManager, LWKeyboardFocusManagerPeer> instances = public static LWKeyboardFocusManagerPeer getInstance() {
new HashMap<KeyboardFocusManager, LWKeyboardFocusManagerPeer>(); return inst;
public static synchronized LWKeyboardFocusManagerPeer getInstance(AppContext ctx) {
return getInstance(AWTAccessor.getKeyboardFocusManagerAccessor().
getCurrentKeyboardFocusManager(ctx));
} }
public static synchronized LWKeyboardFocusManagerPeer getInstance(KeyboardFocusManager manager) { private LWKeyboardFocusManagerPeer() {
LWKeyboardFocusManagerPeer instance = instances.get(manager); }
if (instance == null) {
instance = new LWKeyboardFocusManagerPeer(manager); @Override
instances.put(manager, instance); public void setCurrentFocusedWindow(Window win) {
synchronized (this) {
focusedWindow = win;
} }
return instance;
}
public LWKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
super(manager);
} }
@Override @Override
public Window getCurrentFocusedWindow() { public Window getCurrentFocusedWindow() {
synchronized (lock) { synchronized (this) {
return (focusedWindow != null) ? (Window)focusedWindow.getTarget() : null; return focusedWindow;
} }
} }
@Override @Override
public Component getCurrentFocusOwner() { public Component getCurrentFocusOwner() {
synchronized (lock) { synchronized (this) {
return (focusOwner != null) ? focusOwner.getTarget() : null; return focusOwner;
} }
} }
@Override @Override
public void setCurrentFocusOwner(Component comp) { public void setCurrentFocusOwner(Component comp) {
synchronized (lock) { synchronized (this) {
focusOwner = (comp != null) ? (LWComponentPeer)comp.getPeer() : null; focusOwner = comp;
}
}
void setFocusedWindow(LWWindowPeer peer) {
synchronized (lock) {
focusedWindow = peer;
}
}
LWWindowPeer getFocusedWindow() {
synchronized (lock) {
return focusedWindow;
}
}
void setFocusOwner(LWComponentPeer peer) {
synchronized (lock) {
focusOwner = peer;
}
}
LWComponentPeer getFocusOwner() {
synchronized (lock) {
return focusOwner;
} }
} }
} }

View File

@ -415,8 +415,8 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
} }
@Override @Override
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) { public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
return LWKeyboardFocusManagerPeer.getInstance(manager); return LWKeyboardFocusManagerPeer.getInstance();
} }
@Override @Override

View File

@ -88,10 +88,16 @@ public class LWWindowPeer
private volatile int windowState = Frame.NORMAL; private volatile int windowState = Frame.NORMAL;
// A peer where the last mouse event came to. Used to generate // check that the mouse is over the window
// MOUSE_ENTERED/EXITED notifications and by cursor manager to private volatile boolean isMouseOver = false;
// A peer where the last mouse event came to. Used by cursor manager to
// find the component under cursor // find the component under cursor
private static volatile LWComponentPeer lastMouseEventPeer = null; private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
// A peer where the last mouse event came to. Used to generate
// MOUSE_ENTERED/EXITED notifications
private volatile LWComponentPeer lastMouseEventPeer;
// Peers where all dragged/released events should come to, // Peers where all dragged/released events should come to,
// depending on what mouse button is being dragged according to Cocoa // depending on what mouse button is being dragged according to Cocoa
@ -232,8 +238,7 @@ public class LWWindowPeer
// TODO: update graphicsConfig, see 4868278 // TODO: update graphicsConfig, see 4868278
platformWindow.setVisible(visible); platformWindow.setVisible(visible);
if (isSimpleWindow()) { if (isSimpleWindow()) {
LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer. KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
getInstance(getAppContext());
if (visible) { if (visible) {
if (!getTarget().isAutoRequestFocus()) { if (!getTarget().isAutoRequestFocus()) {
@ -242,7 +247,7 @@ public class LWWindowPeer
requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION); requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
} }
// Focus the owner in case this window is focused. // Focus the owner in case this window is focused.
} else if (manager.getCurrentFocusedWindow() == getTarget()) { } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
// Transfer focus to the owner. // Transfer focus to the owner.
LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this); LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
if (owner != null) { if (owner != null) {
@ -707,66 +712,65 @@ public class LWWindowPeer
Rectangle r = getBounds(); Rectangle r = getBounds();
// findPeerAt() expects parent coordinates // findPeerAt() expects parent coordinates
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
LWWindowPeer lastWindowPeer =
(lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
LWWindowPeer curWindowPeer =
(targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
if (id == MouseEvent.MOUSE_EXITED) { if (id == MouseEvent.MOUSE_EXITED) {
// Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched isMouseOver = false;
// to a peer from another window. So we must first check if this peer is if (lastMouseEventPeer != null) {
// the same as lastWindowPeer if (lastMouseEventPeer.isEnabled()) {
if (lastWindowPeer == this) {
if (isEnabled()) {
Point lp = lastMouseEventPeer.windowToLocal(x, y, Point lp = lastMouseEventPeer.windowToLocal(x, y,
lastWindowPeer); this);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(), postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
MouseEvent.MOUSE_EXITED, when, MouseEvent.MOUSE_EXITED, when,
modifiers, lp.x, lp.y, screenX, modifiers, lp.x, lp.y, screenX,
screenY, clickCount, popupTrigger, screenY, clickCount, popupTrigger,
button)); button));
}
// Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
// to a peer from another window. So we must first check if this peer is
// the same as lastWindowPeer
if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
lastCommonMouseEventPeer = null;
} }
lastMouseEventPeer = null; lastMouseEventPeer = null;
} }
} else { } else if(id == MouseEvent.MOUSE_ENTERED) {
if (targetPeer != lastMouseEventPeer) { isMouseOver = true;
if (targetPeer != null) {
if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) { if (targetPeer.isEnabled()) {
// lastMouseEventPeer may be null if mouse was out of Java windows Point lp = targetPeer.windowToLocal(x, y, this);
if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
// Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
// later), in which case lastWindowPeer is another window
if (lastWindowPeer != this) {
Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
// Additionally translate from this to lastWindowPeer coordinates
Rectangle lr = lastWindowPeer.getBounds();
oldp.x += r.x - lr.x;
oldp.y += r.y - lr.y;
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
MouseEvent.MOUSE_EXITED,
when, modifiers,
oldp.x, oldp.y, screenX, screenY,
clickCount, popupTrigger, button));
} else {
Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
MouseEvent.MOUSE_EXITED,
when, modifiers,
oldp.x, oldp.y, screenX, screenY,
clickCount, popupTrigger, button));
}
}
if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
postEvent(new MouseEvent(targetPeer.getTarget(), postEvent(new MouseEvent(targetPeer.getTarget(),
MouseEvent.MOUSE_ENTERED, MouseEvent.MOUSE_ENTERED, when,
when, modifiers, modifiers, lp.x, lp.y, screenX,
newp.x, newp.y, screenX, screenY, screenY, clickCount, popupTrigger,
clickCount, popupTrigger, button)); button));
}
} }
lastCommonMouseEventPeer = targetPeer;
lastMouseEventPeer = targetPeer; lastMouseEventPeer = targetPeer;
} }
} else {
PlatformWindow topmostPlatforWindow =
platformWindow.getTopmostPlatformWindowUnderMouse();
LWWindowPeer topmostWindowPeer =
topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null;
// topmostWindowPeer == null condition is added for the backward
// compatibility with applets. It can be removed when the
// getTopmostPlatformWindowUnderMouse() method will be properly
// implemented in CPlatformEmbeddedFrame class
if (topmostWindowPeer == this || topmostWindowPeer == null) {
generateMouseEnterExitEventsForComponents(when, button, x, y,
screenX, screenY, modifiers, clickCount, popupTrigger,
targetPeer);
} else {
LWComponentPeer topmostTargetPeer =
topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
screenX, screenY, modifiers, clickCount, popupTrigger,
topmostTargetPeer);
}
// TODO: fill "bdata" member of AWTEvent // TODO: fill "bdata" member of AWTEvent
int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0; int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
@ -794,6 +798,14 @@ public class LWWindowPeer
mouseClickButtons |= eventButtonMask; mouseClickButtons |= eventButtonMask;
} }
// The window should be focused on mouse click. If it gets activated by the native platform,
// this request will be no op. It will take effect when:
// 1. A simple not focused window is clicked.
// 2. An active but not focused owner frame/dialog is clicked.
// The mouse event then will trigger a focus request "in window" to the component, so the window
// should gain focus before.
requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
mouseDownTarget[targetIdx] = targetPeer; mouseDownTarget[targetIdx] = targetPeer;
} else if (id == MouseEvent.MOUSE_DRAGGED) { } else if (id == MouseEvent.MOUSE_DRAGGED) {
// Cocoa dragged event has the information about which mouse // Cocoa dragged event has the information about which mouse
@ -816,19 +828,13 @@ public class LWWindowPeer
// mouseClickButtons is updated below, after MOUSE_CLICK is sent // mouseClickButtons is updated below, after MOUSE_CLICK is sent
} }
// check if we receive mouseEvent from outside the window's bounds
// it can be either mouseDragged or mouseReleased
if (curWindowPeer == null) {
//TODO This can happen if this window is invisible. this is correct behavior in this case?
curWindowPeer = this;
}
if (targetPeer == null) { if (targetPeer == null) {
//TODO This can happen if this window is invisible. this is correct behavior in this case? //TODO This can happen if this window is invisible. this is correct behavior in this case?
targetPeer = this; targetPeer = this;
} }
Point lp = targetPeer.windowToLocal(x, y, curWindowPeer); Point lp = targetPeer.windowToLocal(x, y, this);
if (targetPeer.isEnabled()) { if (targetPeer.isEnabled()) {
MouseEvent event = new MouseEvent(targetPeer.getTarget(), id, MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
when, modifiers, lp.x, lp.y, when, modifiers, lp.x, lp.y,
@ -852,6 +858,38 @@ public class LWWindowPeer
notifyUpdateCursor(); notifyUpdateCursor();
} }
private void generateMouseEnterExitEventsForComponents(long when,
int button, int x, int y, int screenX, int screenY,
int modifiers, int clickCount, boolean popupTrigger,
LWComponentPeer targetPeer) {
if (!isMouseOver || targetPeer == lastMouseEventPeer) {
return;
}
// Generate Mouse Exit for components
if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
MouseEvent.MOUSE_EXITED,
when, modifiers,
oldp.x, oldp.y, screenX, screenY,
clickCount, popupTrigger, button));
}
lastCommonMouseEventPeer = targetPeer;
lastMouseEventPeer = targetPeer;
// Generate Mouse Enter for components
if (targetPeer != null && targetPeer.isEnabled()) {
Point newp = targetPeer.windowToLocal(x, y, this);
postEvent(new MouseEvent(targetPeer.getTarget(),
MouseEvent.MOUSE_ENTERED,
when, modifiers,
newp.x, newp.y, screenX, screenY,
clickCount, popupTrigger, button));
}
}
public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers, public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
int scrollType, int scrollAmount, int scrollType, int scrollAmount,
int wheelRotation, double preciseWheelRotation, int wheelRotation, double preciseWheelRotation,
@ -884,20 +922,16 @@ public class LWWindowPeer
public void dispatchKeyEvent(int id, long when, int modifiers, public void dispatchKeyEvent(int id, long when, int modifiers,
int keyCode, char keyChar, int keyLocation) int keyCode, char keyChar, int keyLocation)
{ {
LWComponentPeer focusOwner = LWKeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
LWKeyboardFocusManagerPeer.getInstance(getAppContext()). Component focusOwner = kfmPeer.getCurrentFocusOwner();
getFocusOwner();
// Null focus owner may receive key event when if (focusOwner == null) {
// application hides the focused window upon ESC press focusOwner = kfmPeer.getCurrentFocusedWindow();
// (AWT transfers/clears the focus owner) and pending ESC release if (focusOwner == null) {
// may come to already hidden window. This check eliminates NPE. focusOwner = this.getTarget();
if (focusOwner != null) { }
KeyEvent event =
new KeyEvent(focusOwner.getTarget(), id, when, modifiers,
keyCode, keyChar, keyLocation);
focusOwner.postEvent(event);
} }
postEvent(new KeyEvent(focusOwner, id, when, modifiers, keyCode, keyChar, keyLocation));
} }
@ -1096,11 +1130,11 @@ public class LWWindowPeer
} }
public static LWWindowPeer getWindowUnderCursor() { public static LWWindowPeer getWindowUnderCursor() {
return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null; return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
} }
public static LWComponentPeer<?, ?> getPeerUnderCursor() { public static LWComponentPeer<?, ?> getPeerUnderCursor() {
return lastMouseEventPeer; return lastCommonMouseEventPeer;
} }
/* /*
@ -1213,10 +1247,8 @@ public class LWWindowPeer
} }
} }
LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer. KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
getInstance(getAppContext()); Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
Window oppositeWindow = becomesFocused ? manager.getCurrentFocusedWindow() : null;
// Note, the method is not called: // Note, the method is not called:
// - when the opposite (gaining focus) window is an owned/owner window. // - when the opposite (gaining focus) window is an owned/owner window.
@ -1229,10 +1261,10 @@ public class LWWindowPeer
grabbingWindow.ungrab(); grabbingWindow.ungrab();
} }
manager.setFocusedWindow(becomesFocused ? LWWindowPeer.this : null); kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS; int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
WindowEvent windowEvent = new WindowEvent(getTarget(), eventID, oppositeWindow); WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, oppositeWindow, System.currentTimeMillis());
// TODO: wrap in SequencedEvent // TODO: wrap in SequencedEvent
postEvent(windowEvent); postEvent(windowEvent);

View File

@ -118,6 +118,8 @@ public interface PlatformWindow {
public void setAlwaysOnTop(boolean value); public void setAlwaysOnTop(boolean value);
public PlatformWindow getTopmostPlatformWindowUnderMouse();
public void updateFocusableWindowState(); public void updateFocusableWindowState();
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause); public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);

View File

@ -151,6 +151,10 @@ public class CPlatformEmbeddedFrame implements PlatformWindow {
@Override @Override
public void setAlwaysOnTop(boolean value) {} public void setAlwaysOnTop(boolean value) {}
// This method should be properly implemented for applets.
// It returns null just as a stub.
public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; }
@Override @Override
public void updateFocusableWindowState() {} public void updateFocusableWindowState() {}

View File

@ -61,8 +61,9 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename); private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY); private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled); private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr); private static native void nativeSynthesizeMouseEnteredExitedEvents();
private static native void nativeDispose(long nsWindowPtr); private static native void nativeDispose(long nsWindowPtr);
private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr); private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
@ -588,7 +589,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
} }
} }
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); nativeSynthesizeMouseEnteredExitedEvents();
// Configure stuff #2 // Configure stuff #2
updateFocusabilityForAutoRequestFocus(true); updateFocusabilityForAutoRequestFocus(true);
@ -729,6 +730,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop); setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
} }
public PlatformWindow getTopmostPlatformWindowUnderMouse(){
return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();
}
@Override @Override
public void setOpacity(float opacity) { public void setOpacity(float opacity) {
CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity); CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
@ -803,7 +808,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
throw new RuntimeException("Unknown window state: " + windowState); throw new RuntimeException("Unknown window state: " + windowState);
} }
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); nativeSynthesizeMouseEnteredExitedEvents();
// NOTE: the SWP.windowState field gets updated to the newWindowState // NOTE: the SWP.windowState field gets updated to the newWindowState
// value when the native notification comes to us // value when the native notification comes to us

View File

@ -37,7 +37,11 @@
#import "ThreadUtilities.h" #import "ThreadUtilities.h"
#import "CMenuBar.h" #import "CMenuBar.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
static JNF_CLASS_CACHE(sjc_ScreenMenu, "com/apple/laf/ScreenMenu"); static JNF_CLASS_CACHE(sjc_ScreenMenu, "com/apple/laf/ScreenMenu");
static jint ns2awtModifiers(NSUInteger keyMods) { static jint ns2awtModifiers(NSUInteger keyMods) {
@ -97,7 +101,7 @@ static jint ns2awtMouseButton(NSInteger mouseButton) {
{ {
if (self.javaObjectWrapper == nil) { if (self.javaObjectWrapper == nil) {
#ifdef DEBUG #ifdef DEBUG
NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__); NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif #endif
return; return;
} }
@ -115,7 +119,7 @@ JNF_COCOA_EXIT(env);
{ {
if (self.javaObjectWrapper == nil) { if (self.javaObjectWrapper == nil) {
#ifdef DEBUG #ifdef DEBUG
NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__); NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif #endif
return; return;
} }
@ -133,7 +137,7 @@ JNF_COCOA_EXIT(env);
{ {
if (self.javaObjectWrapper == nil) { if (self.javaObjectWrapper == nil) {
#ifdef DEBUG #ifdef DEBUG
NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__); NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif #endif
return; return;
} }

View File

@ -26,6 +26,11 @@
//#define USE_ERROR //#define USE_ERROR
//#define USE_TRACE //#define USE_TRACE
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#if USE_PLATFORM_MIDI_OUT == TRUE #if USE_PLATFORM_MIDI_OUT == TRUE
#include "PLATFORM_API_MacOSX_MidiUtils.h" #include "PLATFORM_API_MacOSX_MidiUtils.h"
@ -128,7 +133,7 @@ INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT
case 0xF7: case 0xF7:
// System exclusive // System exclusive
fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n", fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n",
__FILE__, __LINE__, data[0]); THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE; byteIsInvalid = TRUE;
break; break;
@ -154,7 +159,7 @@ INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT
default: default:
// Invalid message // Invalid message
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n", fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
__FILE__, __LINE__, data[0]); THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE; byteIsInvalid = TRUE;
break; break;
} }
@ -164,7 +169,7 @@ INT32 MIDI_OUT_SendShortMessage(MidiDeviceHandle* handle, UINT32 packedMsg, UINT
default: default:
// This can't happen, but handle it anyway. // This can't happen, but handle it anyway.
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n", fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
__FILE__, __LINE__, data[0]); THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE; byteIsInvalid = TRUE;
break; break;
} }

View File

@ -42,6 +42,11 @@
//#define USE_ERROR //#define USE_ERROR
//#define USE_TRACE //#define USE_TRACE
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE) #if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)
#include "PLATFORM_API_MacOSX_MidiUtils.h" #include "PLATFORM_API_MacOSX_MidiUtils.h"
@ -317,7 +322,7 @@ static void processMessagesForPacket(const MIDIPacket* packet, MacMidiDeviceHand
packedMsg = pendingMessageStatus | pendingData[0] << 8; packedMsg = pendingMessageStatus | pendingData[0] << 8;
} else { } else {
fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n", fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n",
__FILE__, __LINE__, pendingMessageStatus, pendingDataLength); THIS_FILE, __LINE__, pendingMessageStatus, pendingDataLength);
byteIsInvalid = TRUE; byteIsInvalid = TRUE;
} }
pendingDataLength = 0; pendingDataLength = 0;

View File

@ -33,8 +33,8 @@
@private @private
jobject m_cPlatformView; jobject m_cPlatformView;
// Handler for the tracking rect needed for Enter/Exit events management. // Handler for the tracking area needed for Enter/Exit events management.
NSTrackingRectTag rolloverTrackingRectTag; NSTrackingArea* rolloverTrackingArea;
// TODO: NSMenu *contextualMenu; // TODO: NSMenu *contextualMenu;
@ -61,7 +61,7 @@
- (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer; - (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer;
- (void) deliverJavaMouseEvent: (NSEvent *) event; - (void) deliverJavaMouseEvent: (NSEvent *) event;
- (void) resetTrackingRect; - (void) resetTrackingArea;
- (void) deliverJavaKeyEventHelper: (NSEvent *) event; - (void) deliverJavaKeyEventHelper: (NSEvent *) event;
- (jobject) awtComponent:(JNIEnv *)env; - (jobject) awtComponent:(JNIEnv *)env;

View File

@ -82,6 +82,7 @@ AWT_ASSERT_APPKIT_THREAD;
fPAHNeedsToSelect = NO; fPAHNeedsToSelect = NO;
mouseIsOver = NO; mouseIsOver = NO;
[self resetTrackingArea];
if (windowLayer != nil) { if (windowLayer != nil) {
self.cglLayer = windowLayer; self.cglLayer = windowLayer;
@ -146,7 +147,7 @@ AWT_ASSERT_APPKIT_THREAD;
[[self window] makeFirstResponder: self]; [[self window] makeFirstResponder: self];
}]; }];
if ([self window] != NULL) { if ([self window] != NULL) {
[self resetTrackingRect]; [self resetTrackingArea];
} }
} }
@ -368,30 +369,31 @@ AWT_ASSERT_APPKIT_THREAD;
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
} }
- (void) resetTrackingArea {
- (void) clearTrackingRect { if (rolloverTrackingArea != nil) {
if (rolloverTrackingRectTag > 0) { [self removeTrackingArea:rolloverTrackingArea];
[self removeTrackingRect:rolloverTrackingRectTag]; [rolloverTrackingArea release];
rolloverTrackingRectTag = 0;
} }
}
- (void) resetTrackingRect { int options = (NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited |
[self clearTrackingRect]; NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect]
owner:self rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
userData:NULL options: options
assumeInside:NO]; owner:self
userInfo:nil
];
[self addTrackingArea:rolloverTrackingArea];
} }
- (void)updateTrackingAreas { - (void)updateTrackingAreas {
[super updateTrackingAreas]; [super updateTrackingAreas];
[self resetTrackingRect]; [self resetTrackingArea];
} }
- (void) resetCursorRects { - (void) resetCursorRects {
[super resetCursorRects]; [super resetCursorRects];
[self resetTrackingRect]; [self resetTrackingArea];
} }
-(void) deliverJavaKeyEventHelper: (NSEvent *) event { -(void) deliverJavaKeyEventHelper: (NSEvent *) event {
@ -402,7 +404,7 @@ AWT_ASSERT_APPKIT_THREAD;
} }
[sLastKeyEvent release]; [sLastKeyEvent release];
sLastKeyEvent = [event retain]; sLastKeyEvent = [event retain];
[AWTToolkit eventCountPlusPlus]; [AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];

View File

@ -238,10 +238,12 @@ AWT_ASSERT_APPKIT_THREAD;
return self; return self;
} }
// checks that this window is under the mouse cursor and this point is not overlapped by others windows + (BOOL) isAWTWindow:(NSWindow *)window {
- (BOOL) isTopmostWindowUnderMouse { return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
}
int currentWinID = [self.nsWindow windowNumber]; // returns id for the topmost window under mouse
+ (NSInteger) getTopmostWindowUnderMouseID {
NSRect screenRect = [[NSScreen mainScreen] frame]; NSRect screenRect = [[NSScreen mainScreen] frame];
NSPoint nsMouseLocation = [NSEvent mouseLocation]; NSPoint nsMouseLocation = [NSEvent mouseLocation];
@ -249,53 +251,77 @@ AWT_ASSERT_APPKIT_THREAD;
NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
for (NSDictionary *window in windows) { for (NSDictionary *window in windows) {
int layer = [[window objectForKey:(id)kCGWindowLayer] intValue]; NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
if (layer == 0) { if (layer == 0) {
int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
CGRect rect; CGRect rect;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect); CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
if (CGRectContainsPoint(rect, cgMouseLocation)) { if (CGRectContainsPoint(rect, cgMouseLocation)) {
return currentWinID == winID; return [[window objectForKey:(id)kCGWindowNumber] integerValue];
} else if (currentWinID == winID) {
return NO;
} }
} }
} }
return NO; return -1;
} }
- (void) synthesizeMouseEnteredExitedEvents { // checks that this window is under the mouse cursor and this point is not overlapped by others windows
- (BOOL) isTopmostWindowUnderMouse {
return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
}
int eventType = 0; + (AWTWindow *) getTopmostWindowUnderMouse {
BOOL isUnderMouse = [self isTopmostWindowUnderMouse]; NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver]; NSWindow *window;
if (isUnderMouse && !mouseIsOver) { NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
eventType = NSMouseEntered;
} else if (!isUnderMouse && mouseIsOver) { while ((window = [windowEnumerator nextObject]) != nil) {
eventType = NSMouseExited; if ([window windowNumber] == topmostWindowUnderMouseID) {
} else { BOOL isAWTWindow = [AWTWindow isAWTWindow: window];
return; return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
}
} }
return nil;
}
+ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
NSPoint screenLocation = [NSEvent mouseLocation]; NSPoint screenLocation = [NSEvent mouseLocation];
NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation]; NSPoint windowLocation = [window convertScreenToBase: screenLocation];
int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask; int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
location: windowLocation location: windowLocation
modifierFlags: modifierFlags modifierFlags: modifierFlags
timestamp: 0 timestamp: 0
windowNumber: [self.nsWindow windowNumber] windowNumber: [window windowNumber]
context: nil context: nil
eventNumber: 0 eventNumber: 0
trackingNumber: 0 trackingNumber: 0
userData: nil userData: nil
]; ];
[[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent]; [[window contentView] deliverJavaMouseEvent: mouseEvent];
}
+ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
NSArray *windows = [NSApp windows];
NSWindow *window;
NSEnumerator *windowEnumerator = [windows objectEnumerator];
while ((window = [windowEnumerator nextObject]) != nil) {
if ([AWTWindow isAWTWindow: window]) {
BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);
BOOL mouseIsOver = [[window contentView] mouseIsOver];
if (isUnderMouse && !mouseIsOver) {
[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];
} else if (!isUnderMouse && mouseIsOver) {
[AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];
}
}
}
} }
- (void) dealloc { - (void) dealloc {
@ -825,7 +851,7 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
// (this will also re-enable screen updates, which were disabled above) // (this will also re-enable screen updates, which were disabled above)
// TODO: send PaintEvent // TODO: send PaintEvent
[window synthesizeMouseEnteredExitedEvents]; [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}]; }];
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);
@ -1038,24 +1064,44 @@ AWT_ASSERT_NOT_APPKIT_THREAD;
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);
} }
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeGetTopmostPlatformWindowUnderMouse
* Signature: (J)V
*/
JNIEXPORT jobject
JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
(JNIEnv *env, jclass clazz)
{
jobject topmostWindowUnderMouse = nil;
JNF_COCOA_ENTER(env);
AWT_ASSERT_APPKIT_THREAD;
AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
if (awtWindow != nil) {
topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
}
JNF_COCOA_EXIT(env);
return topmostWindowUnderMouse;
}
/* /*
* Class: sun_lwawt_macosx_CPlatformWindow * Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSynthesizeMouseEnteredExitedEvents * Method: nativeSynthesizeMouseEnteredExitedEvents
* Signature: (J)V * Signature: (J)V
*/ */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
(JNIEnv *env, jclass clazz, jlong windowPtr) (JNIEnv *env, jclass clazz)
{ {
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD; AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD; AWT_ASSERT_APPKIT_THREAD;
[AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
[window synthesizeMouseEnteredExitedEvents];
}]; }];
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);

View File

@ -33,6 +33,11 @@
#import "ThreadUtilities.h" #import "ThreadUtilities.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
NSColor **sColors = nil; NSColor **sColors = nil;
NSColor **appleColors = nil; NSColor **appleColors = nil;
@ -130,7 +135,7 @@ static JNF_STATIC_MEMBER_CACHE(jm_systemColorsChanged, jc_LWCToolkit, "systemCol
result = (useAppleColor ? appleColors : sColors)[colorIndex]; result = (useAppleColor ? appleColors : sColors)[colorIndex];
} }
else { else {
NSLog(@"%s: %s %sColor: %ld not found, returning black.", __FILE__, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex); NSLog(@"%s: %s %sColor: %ld not found, returning black.", THIS_FILE, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex);
result = [NSColor blackColor]; result = [NSColor blackColor];
} }

View File

@ -36,6 +36,10 @@
#import "QuartzSurfaceData.h" #import "QuartzSurfaceData.h"
#include "AWTStrike.h" #include "AWTStrike.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 }; static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
@ -488,7 +492,7 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
if (glyphs == NULL || advances == NULL) if (glyphs == NULL || advances == NULL)
{ {
(*env)->DeleteLocalRef(env, glyphsArray); (*env)->DeleteLocalRef(env, glyphsArray);
[NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__]; [NSException raise:NSMallocException format:@"%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__];
return; return;
} }

View File

@ -41,7 +41,7 @@ void UnlockImagePixels(JNIEnv* env, ImageSDOps* isdo);
// If there is an image present, this is a no-op // If there is an image present, this is a no-op
void makeSureImageIsCreated(ImageSDOps* isdo); void makeSureImageIsCreated(ImageSDOps* isdo);
struct _ContextInfo typedef struct _ContextInfo
{ {
BOOL useWindowContextReference; BOOL useWindowContextReference;
BOOL canUseJavaPixelsAsContext; BOOL canUseJavaPixelsAsContext;
@ -50,10 +50,9 @@ struct _ContextInfo
size_t bytesPerRow; size_t bytesPerRow;
CGImageAlphaInfo alphaInfo; CGImageAlphaInfo alphaInfo;
CGColorSpaceRef colorSpace; CGColorSpaceRef colorSpace;
} } ContextInfo;
typedef ContextInfo;
struct _ImageInfo typedef struct _ImageInfo
{ {
size_t bitsPerComponent; size_t bitsPerComponent;
size_t bitsPerPixel; size_t bitsPerPixel;
@ -61,8 +60,7 @@ struct _ImageInfo
size_t bytesPerRow; size_t bytesPerRow;
CGImageAlphaInfo alphaInfo; CGImageAlphaInfo alphaInfo;
CGColorSpaceRef colorSpace; CGColorSpaceRef colorSpace;
} } ImageInfo;
typedef ImageInfo;
struct _ImageSDOps struct _ImageSDOps
{ {

View File

@ -53,10 +53,6 @@
// for vImage framework headers // for vImage framework headers
#include <Accelerate/Accelerate.h> #include <Accelerate/Accelerate.h>
// private Quartz routines needed here
CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] = static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
{ {
{YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case
@ -942,7 +938,6 @@ PRINT("createContext")
// intitalize the context to match the Java coordinate system // intitalize the context to match the Java coordinate system
// BG, since the context is created above, we can just concat // BG, since the context is created above, we can just concat
//CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height));
CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height)); CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height));
CGContextSaveGState(qsdo->cgRef); // this will make sure we don't go pass device context settings CGContextSaveGState(qsdo->cgRef); // this will make sure we don't go pass device context settings
@ -1114,7 +1109,10 @@ PRINT("syncFromJavaPixels")
if (qsdo->cgRef != NULL) if (qsdo->cgRef != NULL)
{ {
CGContextSaveGState(qsdo->cgRef); CGContextSaveGState(qsdo->cgRef);
CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0)); CGAffineTransform currCTM = CGContextGetCTM(qsdo->cgRef);
CGAffineTransform inverse = CGAffineTransformInvert(currCTM);
CGContextConcatCTM(qsdo->cgRef, inverse);
CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0));
CGContextSetBlendMode(qsdo->cgRef, kCGBlendModeCopy); CGContextSetBlendMode(qsdo->cgRef, kCGBlendModeCopy);
CGContextSetAlpha(qsdo->cgRef, 1.0f); CGContextSetAlpha(qsdo->cgRef, 1.0f);
CGContextDrawImage(qsdo->cgRef, CGRectMake(0, 0, width, height), javaImg); CGContextDrawImage(qsdo->cgRef, CGRectMake(0, 0, width, height), javaImg);

View File

@ -50,9 +50,6 @@
// same value as defined in Sun's own code // same value as defined in Sun's own code
#define XOR_ALPHA_CUTOFF 128 #define XOR_ALPHA_CUTOFF 128
// private Quartz routines needed here
CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
static CGFloat gRoundRectCtrlpts[10][12] = static CGFloat gRoundRectCtrlpts[10][12] =
{ {
@ -536,7 +533,7 @@ QUARTZ_RENDERER_INLINE void doImageCG(JNIEnv *env, CGContextRef cgRef, jobject i
makeSureImageIsCreated(isdo); makeSureImageIsCreated(isdo);
CGAffineTransform ctm = CGContextGetCTM(cgRef); CGContextSaveGState(cgRef);
CGContextConcatCTM(cgRef, CGAffineTransformMake(a, b, c, d, tx, ty)); CGContextConcatCTM(cgRef, CGAffineTransformMake(a, b, c, d, tx, ty));
jint alphaInfo = isdo->contextInfo.alphaInfo & kCGBitmapAlphaInfoMask; jint alphaInfo = isdo->contextInfo.alphaInfo & kCGBitmapAlphaInfoMask;
@ -551,7 +548,7 @@ QUARTZ_RENDERER_INLINE void doImageCG(JNIEnv *env, CGContextRef cgRef, jobject i
CGImageRelease(subImg); CGImageRelease(subImg);
} }
CGContextSetCTM(cgRef, ctm); CGContextRestoreGState(cgRef);
UnlockImage(env, isdo); UnlockImage(env, isdo);
} }

View File

@ -40,9 +40,6 @@
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#import "ThreadUtilities.h" #import "ThreadUtilities.h"
// private Quartz routines needed here
CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
//#define DEBUG //#define DEBUG
#if defined DEBUG #if defined DEBUG
#define PRINT(msg) {fprintf(stderr, "%s\n", msg);} #define PRINT(msg) {fprintf(stderr, "%s\n", msg);}
@ -50,9 +47,6 @@ CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
#define PRINT(msg) {} #define PRINT(msg) {}
#endif #endif
// from CGAffineTransformPrivate.h
extern CGPoint CGPointApplyInverseAffineTransform(CGPoint point, CGAffineTransform t);
#define kOffset (0.5f) #define kOffset (0.5f)
BOOL gAdjustForJavaDrawing; BOOL gAdjustForJavaDrawing;
@ -608,7 +602,8 @@ PRINT(" SetUpCGContext")
// We need to flip both y coefficeints to flip the offset point into the java coordinate system. // We need to flip both y coefficeints to flip the offset point into the java coordinate system.
ctm.b = -ctm.b; ctm.d = -ctm.d; ctm.tx = 0.0f; ctm.ty = 0.0f; ctm.b = -ctm.b; ctm.d = -ctm.d; ctm.tx = 0.0f; ctm.ty = 0.0f;
CGPoint offsets = {kOffset, kOffset}; CGPoint offsets = {kOffset, kOffset};
offsets = CGPointApplyInverseAffineTransform(offsets, ctm); CGAffineTransform inverse = CGAffineTransformInvert(ctm);
offsets = CGPointApplyAffineTransform(offsets, inverse);
qsdo->graphicsStateInfo.offsetX = offsets.x; qsdo->graphicsStateInfo.offsetX = offsets.x;
qsdo->graphicsStateInfo.offsetY = offsets.y; qsdo->graphicsStateInfo.offsetY = offsets.y;
} }

View File

@ -33,6 +33,11 @@
#import "CoreTextSupport.h" #import "CoreTextSupport.h"
//#import "jni_util.h" //#import "jni_util.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
@implementation AWTStrike @implementation AWTStrike
static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 }; static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
@ -102,7 +107,7 @@ static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
#define AWT_FONT_CLEANUP_FINISH \ #define AWT_FONT_CLEANUP_FINISH \
if (_fontThrowJavaException == YES) { \ if (_fontThrowJavaException == YES) { \
char s[512]; \ char s[512]; \
sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \ sprintf(s, "%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__); \
[JNFException raise:env as:kRuntimeException reason:s]; \ [JNFException raise:env as:kRuntimeException reason:s]; \
} }

View File

@ -42,31 +42,36 @@ const char * jvmtiErrorText(jvmtiError);
const char * eventText(int); const char * eventText(int);
const char * jdwpErrorText(jdwpError); const char * jdwpErrorText(jdwpError);
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#define EXIT_ERROR(error,msg) \ #define EXIT_ERROR(error,msg) \
{ \ { \
print_message(stderr, "JDWP exit error ", "\n", \ print_message(stderr, "JDWP exit error ", "\n", \
"%s(%d): %s [%s:%d]", \ "%s(%d): %s [%s:%d]", \
jvmtiErrorText((jvmtiError)error), error, (msg==NULL?"":msg), \ jvmtiErrorText((jvmtiError)error), error, (msg==NULL?"":msg), \
__FILE__, __LINE__); \ THIS_FILE, __LINE__); \
debugInit_exit((jvmtiError)error, msg); \ debugInit_exit((jvmtiError)error, msg); \
} }
#define JDI_ASSERT(expression) \ #define JDI_ASSERT(expression) \
do { \ do { \
if (gdata && gdata->assertOn && !(expression)) { \ if (gdata && gdata->assertOn && !(expression)) { \
jdiAssertionFailed(__FILE__, __LINE__, #expression); \ jdiAssertionFailed(THIS_FILE, __LINE__, #expression); \
} \ } \
} while (0) } while (0)
#define JDI_ASSERT_MSG(expression, msg) \ #define JDI_ASSERT_MSG(expression, msg) \
do { \ do { \
if (gdata && gdata->assertOn && !(expression)) { \ if (gdata && gdata->assertOn && !(expression)) { \
jdiAssertionFailed(__FILE__, __LINE__, msg); \ jdiAssertionFailed(THIS_FILE, __LINE__, msg); \
} \ } \
} while (0) } while (0)
#define JDI_ASSERT_FAILED(msg) \ #define JDI_ASSERT_FAILED(msg) \
jdiAssertionFailed(__FILE__, __LINE__, msg) jdiAssertionFailed(THIS_FILE, __LINE__, msg)
void do_pause(void); void do_pause(void);

View File

@ -33,11 +33,15 @@ void finish_logging(int);
#define LOG_NULL ((void)0) #define LOG_NULL ((void)0)
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#ifdef JDWP_LOGGING #ifdef JDWP_LOGGING
#define _LOG(flavor,args) \ #define _LOG(flavor,args) \
(log_message_begin(flavor,__FILE__,__LINE__), \ (log_message_begin(flavor,THIS_FILE,__LINE__), \
log_message_end args) log_message_end args)
#define LOG_TEST(flag) (gdata->log_flags & (flag)) #define LOG_TEST(flag) (gdata->log_flags & (flag))

View File

@ -68,12 +68,23 @@ int JLI_GetStdArgc();
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3)) #define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
#define JLI_Snprintf _snprintf #define JLI_Snprintf _snprintf
void JLI_CmdToArgs(char *cmdline); void JLI_CmdToArgs(char *cmdline);
#else #define JLI_Lseek _lseeki64
#else /* NIXES */
#include <unistd.h> #include <unistd.h>
#include <strings.h> #include <strings.h>
#define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2)) #define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3)) #define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3))
#define JLI_Snprintf snprintf #define JLI_Snprintf snprintf
#ifdef __solaris__
#define JLI_Lseek llseek
#endif
#ifdef __linux__
#define _LARGFILE64_SOURCE
#define JLI_Lseek lseek64
#endif
#ifdef MACOSX
#define JLI_Lseek lseek
#endif
#endif /* _WIN32 */ #endif /* _WIN32 */
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,8 @@
#define CENSIG 0x02014b50L /* "PK\001\002" */ #define CENSIG 0x02014b50L /* "PK\001\002" */
#define ENDSIG 0x06054b50L /* "PK\005\006" */ #define ENDSIG 0x06054b50L /* "PK\005\006" */
#define ZIP64_ENDSIG 0x06064b50L /* "PK\006\006" */
#define ZIP64_LOCSIG 0x07064b50L /* "PK\006\007" */
/* /*
* Header sizes including signatures * Header sizes including signatures
*/ */
@ -45,12 +47,21 @@
#define CENHDR 46 #define CENHDR 46
#define ENDHDR 22 #define ENDHDR 22
#define ZIP64_ENDHDR 56 // ZIP64 end header size
#define ZIP64_LOCHDR 20 // ZIP64 end loc header size
#define ZIP64_EXTHDR 24 // EXT header size
#define ZIP64_EXTID 1 // Extra field Zip64 header ID
#define ZIP64_MAGICVAL 0xffffffffLL
#define ZIP64_MAGICCOUNT 0xffff
/* /*
* Header field access macros * Header field access macros
*/ */
#define CH(b, n) (((unsigned char *)(b))[n]) #define CH(b, n) (((unsigned char *)(b))[n])
#define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8)) #define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8))
#define LG(b, n) (SH(b, n) | (SH(b, n+2) << 16)) #define LG(b, n) ((SH(b, n) | (SH(b, n+2) << 16)) &0xffffffffUL)
#define LL(b, n) (((jlong)LG(b, n)) | (((jlong)LG(b, n+4)) << 32))
#define GETSIG(b) LG(b, 0) #define GETSIG(b) LG(b, 0)
/* /*
@ -101,6 +112,26 @@
#define ENDOFF(b) LG(b, 16) /* central directory offset */ #define ENDOFF(b) LG(b, 16) /* central directory offset */
#define ENDCOM(b) SH(b, 20) /* size of zip file comment */ #define ENDCOM(b) SH(b, 20) /* size of zip file comment */
/*
* Macros for getting Zip64 end of central directory header fields
*/
#define ZIP64_ENDLEN(b) LL(b, 4) /* size of zip64 end of central dir */
#define ZIP64_ENDVEM(b) SH(b, 12) /* version made by */
#define ZIP64_ENDVER(b) SH(b, 14) /* version needed to extract */
#define ZIP64_ENDNMD(b) LG(b, 16) /* number of this disk */
#define ZIP64_ENDDSK(b) LG(b, 20) /* disk number of start */
#define ZIP64_ENDTOD(b) LL(b, 24) /* total number of entries on this disk */
#define ZIP64_ENDTOT(b) LL(b, 32) /* total number of entries */
#define ZIP64_ENDSIZ(b) LL(b, 40) /* central directory size in bytes */
#define ZIP64_ENDOFF(b) LL(b, 48) /* offset of first CEN header */
/*
* Macros for getting Zip64 end of central directory locator fields
*/
#define ZIP64_LOCDSK(b) LG(b, 4) /* disk number start */
#define ZIP64_LOCOFF(b) LL(b, 8) /* offset of zip64 end */
#define ZIP64_LOCTOT(b) LG(b, 16) /* total number of disks */
/* /*
* A comment of maximum length of 64kb can follow the END record. This * A comment of maximum length of 64kb can follow the END record. This
* is the furthest the END record can be from the end of the file. * is the furthest the END record can be from the end of the file.
@ -119,7 +150,7 @@
typedef struct zentry { /* Zip file entry */ typedef struct zentry { /* Zip file entry */
size_t isize; /* size of inflated data */ size_t isize; /* size of inflated data */
size_t csize; /* size of compressed data (zero if uncompressed) */ size_t csize; /* size of compressed data (zero if uncompressed) */
off_t offset; /* position of compressed data */ jlong offset; /* position of compressed data */
int how; /* compression method (if any) */ int how; /* compression method (if any) */
} zentry; } zentry;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -61,7 +61,7 @@ inflate_file(int fd, zentry *entry, int *size_out)
if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 ) if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 )
return (NULL); return (NULL);
if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0) if (JLI_Lseek(fd, entry->offset, SEEK_SET) < (jlong)0)
return (NULL); return (NULL);
if ((in = malloc(entry->csize + 1)) == NULL) if ((in = malloc(entry->csize + 1)) == NULL)
return (NULL); return (NULL);
@ -110,6 +110,38 @@ inflate_file(int fd, zentry *entry, int *size_out)
return (NULL); return (NULL);
} }
static jboolean zip64_present = JNI_FALSE;
/*
* Checks to see if we have ZIP64 archive, and save
* the check for later use
*/
static int
haveZIP64(Byte *p) {
jlong cenlen, cenoff, centot;
cenlen = ENDSIZ(p);
cenoff = ENDOFF(p);
centot = ENDTOT(p);
zip64_present = (cenlen == ZIP64_MAGICVAL ||
cenoff == ZIP64_MAGICVAL ||
centot == ZIP64_MAGICCOUNT);
return zip64_present;
}
static jlong
find_end64(int fd, Byte *ep, jlong pos)
{
jlong end64pos;
jlong bytes;
if ((end64pos = JLI_Lseek(fd, pos - ZIP64_LOCHDR, SEEK_SET)) < (jlong)0)
return -1;
if ((bytes = read(fd, ep, ZIP64_LOCHDR)) < 0)
return -1;
if (GETSIG(ep) == ZIP64_LOCSIG)
return end64pos;
return -1;
}
/* /*
* A very little used routine to handle the case that zip file has * A very little used routine to handle the case that zip file has
* a comment at the end. Believe it or not, the only way to find the * a comment at the end. Believe it or not, the only way to find the
@ -122,12 +154,12 @@ inflate_file(int fd, zentry *entry, int *size_out)
* Returns the offset of the END record in the file on success, * Returns the offset of the END record in the file on success,
* -1 on failure. * -1 on failure.
*/ */
static off_t static jlong
find_end(int fd, Byte *eb) find_end(int fd, Byte *eb)
{ {
off_t len; jlong len;
off_t pos; jlong pos;
off_t flen; jlong flen;
int bytes; int bytes;
Byte *cp; Byte *cp;
Byte *endpos; Byte *endpos;
@ -136,14 +168,16 @@ find_end(int fd, Byte *eb)
/* /*
* 99.44% (or more) of the time, there will be no comment at the * 99.44% (or more) of the time, there will be no comment at the
* end of the zip file. Try reading just enough to read the END * end of the zip file. Try reading just enough to read the END
* record from the end of the file. * record from the end of the file, at this time we should also
* check to see if we have a ZIP64 archive.
*/ */
if ((pos = lseek(fd, -ENDHDR, SEEK_END)) < (off_t)0) if ((pos = JLI_Lseek(fd, -ENDHDR, SEEK_END)) < (jlong)0)
return (-1); return (-1);
if ((bytes = read(fd, eb, ENDHDR)) < 0) if ((bytes = read(fd, eb, ENDHDR)) < 0)
return (-1); return (-1);
if (GETSIG(eb) == ENDSIG) if (GETSIG(eb) == ENDSIG) {
return (pos); return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos;
}
/* /*
* Shucky-Darn,... There is a comment at the end of the zip file. * Shucky-Darn,... There is a comment at the end of the zip file.
@ -151,10 +185,10 @@ find_end(int fd, Byte *eb)
* Allocate and fill a buffer with enough of the zip file * Allocate and fill a buffer with enough of the zip file
* to meet the specification for a maximal comment length. * to meet the specification for a maximal comment length.
*/ */
if ((flen = lseek(fd, 0, SEEK_END)) < (off_t)0) if ((flen = JLI_Lseek(fd, 0, SEEK_END)) < (jlong)0)
return (-1); return (-1);
len = (flen < END_MAXLEN) ? flen : END_MAXLEN; len = (flen < END_MAXLEN) ? flen : END_MAXLEN;
if (lseek(fd, -len, SEEK_END) < (off_t)0) if (JLI_Lseek(fd, -len, SEEK_END) < (jlong)0)
return (-1); return (-1);
if ((buffer = malloc(END_MAXLEN)) == NULL) if ((buffer = malloc(END_MAXLEN)) == NULL)
return (-1); return (-1);
@ -175,12 +209,92 @@ find_end(int fd, Byte *eb)
(cp + ENDHDR + ENDCOM(cp) == endpos)) { (cp + ENDHDR + ENDCOM(cp) == endpos)) {
(void) memcpy(eb, cp, ENDHDR); (void) memcpy(eb, cp, ENDHDR);
free(buffer); free(buffer);
return (flen - (endpos - cp)); pos = flen - (endpos - cp);
return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos;
} }
free(buffer); free(buffer);
return (-1); return (-1);
} }
#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ)
#define MINREAD 1024
/*
* Computes and positions at the start of the CEN header, ie. the central
* directory, this will also return the offset if there is a zip file comment
* at the end of the archive, for most cases this would be 0.
*/
static jlong
compute_cen(int fd, Byte *bp)
{
int bytes;
Byte *p;
jlong base_offset;
jlong offset;
char buffer[MINREAD];
p = buffer;
/*
* Read the END Header, which is the starting point for ZIP files.
* (Clearly designed to make writing a zip file easier than reading
* one. Now isn't that precious...)
*/
if ((base_offset = find_end(fd, bp)) == -1) {
return (-1);
}
p = bp;
/*
* There is a historical, but undocumented, ability to allow for
* additional "stuff" to be prepended to the zip/jar file. It seems
* that this has been used to prepend an actual java launcher
* executable to the jar on Windows. Although this is just another
* form of statically linking a small piece of the JVM to the
* application, we choose to continue to support it. Note that no
* guarantees have been made (or should be made) to the customer that
* this will continue to work.
*
* Therefore, calculate the base offset of the zip file (within the
* expanded file) by assuming that the central directory is followed
* immediately by the end record.
*/
if (zip64_present) {
if ((offset = ZIP64_LOCOFF(p)) < (jlong)0) {
return -1;
}
if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong) 0) {
return (-1);
}
if ((bytes = read(fd, buffer, MINREAD)) < 0) {
return (-1);
}
if (GETSIG(buffer) != ZIP64_ENDSIG) {
return -1;
}
if ((offset = ZIP64_ENDOFF(buffer)) < (jlong)0) {
return -1;
}
if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong)0) {
return (-1);
}
p = buffer;
base_offset = base_offset - ZIP64_ENDSIZ(p) - ZIP64_ENDOFF(p) - ZIP64_ENDHDR;
} else {
base_offset = base_offset - ENDSIZ(p) - ENDOFF(p);
/*
* The END Header indicates the start of the Central Directory
* Headers. Remember that the desired Central Directory Header (CEN)
* will almost always be the second one and the first one is a small
* directory entry ("META-INF/"). Keep the code optimized for
* that case.
*
* Seek to the beginning of the Central Directory.
*/
if (JLI_Lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (jlong) 0) {
return (-1);
}
}
return base_offset;
}
/* /*
* Locate the manifest file with the zip/jar file. * Locate the manifest file with the zip/jar file.
* *
@ -208,9 +322,6 @@ find_end(int fd, Byte *eb)
* a typical jar file (META-INF and META-INF/MANIFEST.MF). Keep this factoid * a typical jar file (META-INF and META-INF/MANIFEST.MF). Keep this factoid
* in mind when optimizing this code. * in mind when optimizing this code.
*/ */
#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ)
#define MINREAD 1024
static int static int
find_file(int fd, zentry *entry, const char *file_name) find_file(int fd, zentry *entry, const char *file_name)
{ {
@ -218,7 +329,7 @@ find_file(int fd, zentry *entry, const char *file_name)
int res; int res;
int entry_size; int entry_size;
int read_size; int read_size;
int base_offset; jlong base_offset;
Byte *p; Byte *p;
Byte *bp; Byte *bp;
Byte *buffer; Byte *buffer;
@ -228,54 +339,18 @@ find_file(int fd, zentry *entry, const char *file_name)
return(-1); return(-1);
} }
p = buffer;
bp = buffer; bp = buffer;
base_offset = compute_cen(fd, bp);
/* if (base_offset == -1) {
* Read the END Header, which is the starting point for ZIP files.
* (Clearly designed to make writing a zip file easier than reading
* one. Now isn't that precious...)
*/
if ((base_offset = find_end(fd, bp)) == -1) {
free(buffer); free(buffer);
return (-1); return -1;
} }
/*
* There is a historical, but undocumented, ability to allow for
* additional "stuff" to be prepended to the zip/jar file. It seems
* that this has been used to prepend an actual java launcher
* executable to the jar on Windows. Although this is just another
* form of statically linking a small piece of the JVM to the
* application, we choose to continue to support it. Note that no
* guarantees have been made (or should be made) to the customer that
* this will continue to work.
*
* Therefore, calculate the base offset of the zip file (within the
* expanded file) by assuming that the central directory is followed
* immediately by the end record.
*/
base_offset = base_offset - ENDSIZ(p) - ENDOFF(p);
/*
* The END Header indicates the start of the Central Directory
* Headers. Remember that the desired Central Directory Header (CEN)
* will almost always be the second one and the first one is a small
* directory entry ("META-INF/"). Keep the code optimized for
* that case.
*
* Begin by seeking to the beginning of the Central Directory and
* reading in the first buffer full of bits.
*/
if (lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (off_t)0) {
free(buffer);
return (-1);
}
if ((bytes = read(fd, bp, MINREAD)) < 0) { if ((bytes = read(fd, bp, MINREAD)) < 0) {
free(buffer); free(buffer);
return (-1); return (-1);
} }
p = bp;
/* /*
* Loop through the Central Directory Headers. Note that a valid zip/jar * Loop through the Central Directory Headers. Note that a valid zip/jar
* must have an ENDHDR (with ENDSIG) after the Central Directory. * must have an ENDHDR (with ENDSIG) after the Central Directory.
@ -319,7 +394,7 @@ find_file(int fd, zentry *entry, const char *file_name)
*/ */
if ((size_t)CENNAM(p) == JLI_StrLen(file_name) && if ((size_t)CENNAM(p) == JLI_StrLen(file_name) &&
memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) { memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) {
if (lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (off_t)0) { if (JLI_Lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (jlong)0) {
free(buffer); free(buffer);
return (-1); return (-1);
} }
@ -487,6 +562,9 @@ JLI_ParseManifest(char *jarfile, manifest_info *info)
char *splashscreen_name = NULL; char *splashscreen_name = NULL;
if ((fd = open(jarfile, O_RDONLY if ((fd = open(jarfile, O_RDONLY
#ifdef O_LARGEFILE
| O_LARGEFILE /* large file mode on solaris */
#endif
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -47,18 +47,122 @@ import javax.crypto.BadPaddingException;
* @see OutputFeedback * @see OutputFeedback
*/ */
public final class AESCipher extends CipherSpi { abstract class AESCipher extends CipherSpi {
public static final class General extends AESCipher {
public General() {
super(-1);
}
}
abstract static class OidImpl extends AESCipher {
protected OidImpl(int keySize, String mode, String padding) {
super(keySize);
try {
engineSetMode(mode);
engineSetPadding(padding);
} catch (GeneralSecurityException gse) {
// internal error; re-throw as provider exception
ProviderException pe =new ProviderException("Internal Error");
pe.initCause(gse);
throw pe;
}
}
}
public static final class AES128_ECB_NoPadding extends OidImpl {
public AES128_ECB_NoPadding() {
super(16, "ECB", "NOPADDING");
}
}
public static final class AES192_ECB_NoPadding extends OidImpl {
public AES192_ECB_NoPadding() {
super(24, "ECB", "NOPADDING");
}
}
public static final class AES256_ECB_NoPadding extends OidImpl {
public AES256_ECB_NoPadding() {
super(32, "ECB", "NOPADDING");
}
}
public static final class AES128_CBC_NoPadding extends OidImpl {
public AES128_CBC_NoPadding() {
super(16, "CBC", "NOPADDING");
}
}
public static final class AES192_CBC_NoPadding extends OidImpl {
public AES192_CBC_NoPadding() {
super(24, "CBC", "NOPADDING");
}
}
public static final class AES256_CBC_NoPadding extends OidImpl {
public AES256_CBC_NoPadding() {
super(32, "CBC", "NOPADDING");
}
}
public static final class AES128_OFB_NoPadding extends OidImpl {
public AES128_OFB_NoPadding() {
super(16, "OFB", "NOPADDING");
}
}
public static final class AES192_OFB_NoPadding extends OidImpl {
public AES192_OFB_NoPadding() {
super(24, "OFB", "NOPADDING");
}
}
public static final class AES256_OFB_NoPadding extends OidImpl {
public AES256_OFB_NoPadding() {
super(32, "OFB", "NOPADDING");
}
}
public static final class AES128_CFB_NoPadding extends OidImpl {
public AES128_CFB_NoPadding() {
super(16, "CFB", "NOPADDING");
}
}
public static final class AES192_CFB_NoPadding extends OidImpl {
public AES192_CFB_NoPadding() {
super(24, "CFB", "NOPADDING");
}
}
public static final class AES256_CFB_NoPadding extends OidImpl {
public AES256_CFB_NoPadding() {
super(32, "CFB", "NOPADDING");
}
}
// utility method used by AESCipher and AESWrapCipher
static final void checkKeySize(Key key, int fixedKeySize)
throws InvalidKeyException {
if (fixedKeySize != -1) {
if (key == null) {
throw new InvalidKeyException("The key must not be null");
}
byte[] value = key.getEncoded();
if (value == null) {
throw new InvalidKeyException("Key encoding must not be null");
} else if (value.length != fixedKeySize) {
throw new InvalidKeyException("The key must be " +
fixedKeySize*8 + " bits");
}
}
}
/* /*
* internal CipherCore object which does the real work. * internal CipherCore object which does the real work.
*/ */
private CipherCore core = null; private CipherCore core = null;
/*
* needed to support AES oids which associates a fixed key size
* to the cipher object.
*/
private final int fixedKeySize; // in bytes, -1 if no restriction
/** /**
* Creates an instance of AES cipher with default ECB mode and * Creates an instance of AES cipher with default ECB mode and
* PKCS5Padding. * PKCS5Padding.
*/ */
public AESCipher() { protected AESCipher(int keySize) {
core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE); core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE);
fixedKeySize = keySize;
} }
/** /**
@ -183,6 +287,7 @@ public final class AESCipher extends CipherSpi {
*/ */
protected void engineInit(int opmode, Key key, SecureRandom random) protected void engineInit(int opmode, Key key, SecureRandom random)
throws InvalidKeyException { throws InvalidKeyException {
checkKeySize(key, fixedKeySize);
core.init(opmode, key, random); core.init(opmode, key, random);
} }
@ -214,6 +319,7 @@ public final class AESCipher extends CipherSpi {
AlgorithmParameterSpec params, AlgorithmParameterSpec params,
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
checkKeySize(key, fixedKeySize);
core.init(opmode, key, params, random); core.init(opmode, key, params, random);
} }
@ -221,6 +327,7 @@ public final class AESCipher extends CipherSpi {
AlgorithmParameters params, AlgorithmParameters params,
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
checkKeySize(key, fixedKeySize);
core.init(opmode, key, params, random); core.init(opmode, key, params, random);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -43,8 +43,27 @@ import javax.crypto.spec.*;
* *
* @see AESCipher * @see AESCipher
*/ */
public final class AESWrapCipher extends CipherSpi { abstract class AESWrapCipher extends CipherSpi {
public static final class General extends AESWrapCipher {
public General() {
super(-1);
}
}
public static final class AES128 extends AESWrapCipher {
public AES128() {
super(16);
}
}
public static final class AES192 extends AESWrapCipher {
public AES192() {
super(24);
}
}
public static final class AES256 extends AESWrapCipher {
public AES256() {
super(32);
}
}
private static final byte[] IV = { private static final byte[] IV = {
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6,
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6 (byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6
@ -62,12 +81,20 @@ public final class AESWrapCipher extends CipherSpi {
*/ */
private boolean decrypting = false; private boolean decrypting = false;
/*
* needed to support AES oids which associates a fixed key size
* to the cipher object.
*/
private final int fixedKeySize; // in bytes, -1 if no restriction
/** /**
* Creates an instance of AES KeyWrap cipher with default * Creates an instance of AES KeyWrap cipher with default
* mode, i.e. "ECB" and padding scheme, i.e. "NoPadding". * mode, i.e. "ECB" and padding scheme, i.e. "NoPadding".
*/ */
public AESWrapCipher() { public AESWrapCipher(int keySize) {
cipher = new AESCrypt(); cipher = new AESCrypt();
fixedKeySize = keySize;
} }
/** /**
@ -170,6 +197,7 @@ public final class AESWrapCipher extends CipherSpi {
throw new UnsupportedOperationException("This cipher can " + throw new UnsupportedOperationException("This cipher can " +
"only be used for key wrapping and unwrapping"); "only be used for key wrapping and unwrapping");
} }
AESCipher.checkKeySize(key, fixedKeySize);
cipher.init(decrypting, key.getAlgorithm(), key.getEncoded()); cipher.init(decrypting, key.getAlgorithm(), key.getEncoded());
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -80,10 +80,10 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
* @param random the source of randomness * @param random the source of randomness
*/ */
public void initialize(int keysize, SecureRandom random) { public void initialize(int keysize, SecureRandom random) {
if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) { if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
throw new InvalidParameterException("Keysize must be multiple " throw new InvalidParameterException("Keysize must be multiple "
+ "of 64, and can only range " + "of 64, and can only range "
+ "from 512 to 1024 " + "from 512 to 2048 "
+ "(inclusive)"); + "(inclusive)");
} }
this.pSize = keysize; this.pSize = keysize;
@ -115,11 +115,11 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
params = (DHParameterSpec)algParams; params = (DHParameterSpec)algParams;
pSize = params.getP().bitLength(); pSize = params.getP().bitLength();
if ((pSize < 512) || (pSize > 1024) || if ((pSize < 512) || (pSize > 2048) ||
(pSize % 64 != 0)) { (pSize % 64 != 0)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Prime size must be multiple of 64, and can only range " ("Prime size must be multiple of 64, and can only range "
+ "from 512 to 1024 (inclusive)"); + "from 512 to 2048 (inclusive)");
} }
// exponent size is optional, could be 0 // exponent size is optional, could be 0
@ -156,10 +156,11 @@ public final class DHKeyPairGenerator extends KeyPairGeneratorSpi {
BigInteger g = params.getG(); BigInteger g = params.getG();
if (lSize <= 0) { if (lSize <= 0) {
lSize = pSize >> 1;
// use an exponent size of (pSize / 2) but at least 384 bits // use an exponent size of (pSize / 2) but at least 384 bits
lSize = Math.max(384, pSize >> 1); if (lSize < 384) {
// if lSize is larger than pSize, limit by pSize lSize = 384;
lSize = Math.min(lSize, pSize); }
} }
BigInteger x; BigInteger x;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -67,10 +67,10 @@ extends AlgorithmParameterGeneratorSpi {
* @param random the source of randomness * @param random the source of randomness
*/ */
protected void engineInit(int keysize, SecureRandom random) { protected void engineInit(int keysize, SecureRandom random) {
if ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0)) { if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
throw new InvalidParameterException("Keysize must be multiple " throw new InvalidParameterException("Keysize must be multiple "
+ "of 64, and can only range " + "of 64, and can only range "
+ "from 512 to 1024 " + "from 512 to 2048 "
+ "(inclusive)"); + "(inclusive)");
} }
this.primeSize = keysize; this.primeSize = keysize;
@ -99,10 +99,10 @@ extends AlgorithmParameterGeneratorSpi {
DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec;
primeSize = dhParamSpec.getPrimeSize(); primeSize = dhParamSpec.getPrimeSize();
if ((primeSize<512) || (primeSize>1024) || (primeSize%64 != 0)) { if ((primeSize<512) || (primeSize>2048) || (primeSize%64 != 0)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("Modulus size must be multiple of 64, and can only range " ("Modulus size must be multiple of 64, and can only range "
+ "from 512 to 1024 (inclusive)"); + "from 512 to 2048 (inclusive)");
} }
exponentSize = dhParamSpec.getExponentSize(); exponentSize = dhParamSpec.getExponentSize();

View File

@ -167,17 +167,67 @@ public final class SunJCE extends Provider {
put("Cipher.Blowfish SupportedPaddings", BLOCK_PADS); put("Cipher.Blowfish SupportedPaddings", BLOCK_PADS);
put("Cipher.Blowfish SupportedKeyFormats", "RAW"); put("Cipher.Blowfish SupportedKeyFormats", "RAW");
put("Cipher.AES", "com.sun.crypto.provider.AESCipher"); put("Cipher.AES", "com.sun.crypto.provider.AESCipher$General");
put("Alg.Alias.Cipher.Rijndael", "AES"); put("Alg.Alias.Cipher.Rijndael", "AES");
put("Cipher.AES SupportedModes", BLOCK_MODES128); put("Cipher.AES SupportedModes", BLOCK_MODES128);
put("Cipher.AES SupportedPaddings", BLOCK_PADS); put("Cipher.AES SupportedPaddings", BLOCK_PADS);
put("Cipher.AES SupportedKeyFormats", "RAW"); put("Cipher.AES SupportedKeyFormats", "RAW");
put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher"); put("Cipher.AES_128/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.1", "AES_128/ECB/NoPadding");
put("Cipher.AES_128/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.2", "AES_128/CBC/NoPadding");
put("Cipher.AES_128/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.3", "AES_128/OFB/NoPadding");
put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
put("Cipher.AES_192/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.22", "AES_192/CBC/NoPadding");
put("Cipher.AES_192/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.23", "AES_192/OFB/NoPadding");
put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
put("Cipher.AES_256/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.42", "AES_256/CBC/NoPadding");
put("Cipher.AES_256/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.43", "AES_256/OFB/NoPadding");
put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General");
put("Cipher.AESWrap SupportedModes", "ECB"); put("Cipher.AESWrap SupportedModes", "ECB");
put("Cipher.AESWrap SupportedPaddings", "NOPADDING"); put("Cipher.AESWrap SupportedPaddings", "NOPADDING");
put("Cipher.AESWrap SupportedKeyFormats", "RAW"); put("Cipher.AESWrap SupportedKeyFormats", "RAW");
put("Cipher.AESWrap_128", "com.sun.crypto.provider.AESWrapCipher$AES128");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.5", "AESWrap_128");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.5", "AESWrap_128");
put("Cipher.AESWrap_192", "com.sun.crypto.provider.AESWrapCipher$AES192");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.25", "AESWrap_192");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.25", "AESWrap_192");
put("Cipher.AESWrap_256", "com.sun.crypto.provider.AESWrapCipher$AES256");
put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.45", "AESWrap_256");
put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.45", "AESWrap_256");
put("Cipher.RC2", put("Cipher.RC2",
"com.sun.crypto.provider.RC2Cipher"); "com.sun.crypto.provider.RC2Cipher");
put("Cipher.RC2 SupportedModes", BLOCK_MODES); put("Cipher.RC2 SupportedModes", BLOCK_MODES);
@ -192,7 +242,7 @@ public final class SunJCE extends Provider {
put("Cipher.ARCFOUR SupportedKeyFormats", "RAW"); put("Cipher.ARCFOUR SupportedKeyFormats", "RAW");
/* /*
* Key(pair) Generator engines * Key(pair) Generator engines
*/ */
put("KeyGenerator.DES", put("KeyGenerator.DES",
"com.sun.crypto.provider.DESKeyGenerator"); "com.sun.crypto.provider.DESKeyGenerator");
@ -221,6 +271,8 @@ public final class SunJCE extends Provider {
put("KeyGenerator.HmacSHA1", put("KeyGenerator.HmacSHA1",
"com.sun.crypto.provider.HmacSHA1KeyGenerator"); "com.sun.crypto.provider.HmacSHA1KeyGenerator");
put("Alg.Alias.KeyGenerator.OID.1.2.840.113549.2.7", "HmacSHA1");
put("Alg.Alias.KeyGenerator.1.2.840.113549.2.7", "HmacSHA1");
put("KeyGenerator.HmacSHA224", put("KeyGenerator.HmacSHA224",
"com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224"); "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224");
@ -326,14 +378,12 @@ public final class SunJCE extends Provider {
"com.sun.crypto.provider.AESParameters"); "com.sun.crypto.provider.AESParameters");
put("Alg.Alias.AlgorithmParameters.Rijndael", "AES"); put("Alg.Alias.AlgorithmParameters.Rijndael", "AES");
put("AlgorithmParameters.RC2", put("AlgorithmParameters.RC2",
"com.sun.crypto.provider.RC2Parameters"); "com.sun.crypto.provider.RC2Parameters");
put("AlgorithmParameters.OAEP", put("AlgorithmParameters.OAEP",
"com.sun.crypto.provider.OAEPParameters"); "com.sun.crypto.provider.OAEPParameters");
/* /*
* Key factories * Key factories
*/ */
@ -403,6 +453,8 @@ public final class SunJCE extends Provider {
*/ */
put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5"); put("Mac.HmacMD5", "com.sun.crypto.provider.HmacMD5");
put("Mac.HmacSHA1", "com.sun.crypto.provider.HmacSHA1"); put("Mac.HmacSHA1", "com.sun.crypto.provider.HmacSHA1");
put("Alg.Alias.Mac.OID.1.2.840.113549.2.7", "HmacSHA1");
put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
put("Mac.HmacSHA224", put("Mac.HmacSHA224",
"com.sun.crypto.provider.HmacCore$HmacSHA224"); "com.sun.crypto.provider.HmacCore$HmacSHA224");
put("Alg.Alias.Mac.OID.1.2.840.113549.2.8", "HmacSHA224"); put("Alg.Alias.Mac.OID.1.2.840.113549.2.8", "HmacSHA224");

View File

@ -30,6 +30,8 @@ import java.awt.Container;
import java.awt.Event; import java.awt.Event;
import java.awt.KeyEventPostProcessor; import java.awt.KeyEventPostProcessor;
import java.awt.Window; import java.awt.Window;
import java.awt.Toolkit;
import sun.awt.SunToolkit;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
@ -125,7 +127,19 @@ public class WindowsRootPaneUI extends BasicRootPaneUI {
} }
JMenu menu = mbar != null ? mbar.getMenu(0) : null; JMenu menu = mbar != null ? mbar.getMenu(0) : null;
if (menu != null) { // It might happen that the altRelease event is processed
// with a reasonable delay since it has been generated.
// Here we check the last deactivation time of the containing
// window. If this time appears to be greater than the altRelease
// event time the event is skipped to avoid unexpected menu
// activation. See 7121442.
boolean skip = false;
Toolkit tk = Toolkit.getDefaultToolkit();
if (tk instanceof SunToolkit) {
skip = ev.getWhen() <= ((SunToolkit)tk).getWindowDeactivationTime(winAncestor);
}
if (menu != null && !skip) {
MenuElement[] path = new MenuElement[2]; MenuElement[] path = new MenuElement[2];
path[0] = mbar; path[0] = mbar;
path[1] = menu; path[1] = menu;

View File

@ -4710,7 +4710,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
/* /*
* 0. Set timestamp and modifiers of current event. * 0. Set timestamp and modifiers of current event.
*/ */
EventQueue.setCurrentEventAndMostRecentTime(e); if (!(e instanceof KeyEvent)) {
// Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent).
EventQueue.setCurrentEventAndMostRecentTime(e);
}
/* /*
* 1. Pre-dispatchers. Do any necessary retargeting/reordering here * 1. Pre-dispatchers. Do any necessary retargeting/reordering here
@ -7606,13 +7609,33 @@ public abstract class Component implements ImageObserver, MenuContainer,
boolean focusedWindowChangeAllowed, boolean focusedWindowChangeAllowed,
CausedFocusEvent.Cause cause) CausedFocusEvent.Cause cause)
{ {
// 1) Check if the event being dispatched is a system-generated mouse event.
AWTEvent currentEvent = EventQueue.getCurrentEvent();
if (currentEvent instanceof MouseEvent &&
SunToolkit.isSystemGenerated(currentEvent))
{
// 2) Sanity check: if the mouse event component source belongs to the same containing window.
Component source = ((MouseEvent)currentEvent).getComponent();
if (source == null || source.getContainingWindow() == getContainingWindow()) {
focusLog.finest("requesting focus by mouse event \"in window\"");
// If both the conditions are fulfilled the focus request should be strictly
// bounded by the toplevel window. It's assumed that the mouse event activates
// the window (if it wasn't active) and this makes it possible for a focus
// request with a strong in-window requirement to change focus in the bounds
// of the toplevel. If, by any means, due to asynchronous nature of the event
// dispatching mechanism, the window happens to be natively inactive by the time
// this focus request is eventually handled, it should not re-activate the
// toplevel. Otherwise the result may not meet user expectations. See 6981400.
focusedWindowChangeAllowed = false;
}
}
if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) { if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
if (focusLog.isLoggable(PlatformLogger.FINEST)) { if (focusLog.isLoggable(PlatformLogger.FINEST)) {
focusLog.finest("requestFocus is not accepted"); focusLog.finest("requestFocus is not accepted");
} }
return false; return false;
} }
// Update most-recent map // Update most-recent map
KeyboardFocusManager.setMostRecentFocusOwner(this); KeyboardFocusManager.setMostRecentFocusOwner(this);
@ -7645,7 +7668,15 @@ public abstract class Component implements ImageObserver, MenuContainer,
} }
// Focus this Component // Focus this Component
long time = EventQueue.getMostRecentEventTime(); long time = 0;
if (EventQueue.isDispatchThread()) {
time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
} else {
// A focus request made from outside EDT should not be associated with any event
// and so its time stamp is simply set to the current time.
time = System.currentTimeMillis();
}
boolean success = peer.requestFocus boolean success = peer.requestFocus
(this, temporary, focusedWindowChangeAllowed, time, cause); (this, temporary, focusedWindowChangeAllowed, time, cause);
if (!success) { if (!success) {

View File

@ -2863,7 +2863,7 @@ public class Container extends Component {
// keep the KeyEvents from being dispatched // keep the KeyEvents from being dispatched
// until the focus has been transfered // until the focus has been transfered
long time = Toolkit.getEventQueue().getMostRecentEventTime(); long time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
Component predictedFocusOwner = (Component.isInstanceOf(this, "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame)(this)).getMostRecentFocusOwner() : null; Component predictedFocusOwner = (Component.isInstanceOf(this, "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame)(this)).getMostRecentFocusOwner() : null;
if (predictedFocusOwner != null) { if (predictedFocusOwner != null) {
KeyboardFocusManager.getCurrentKeyboardFocusManager(). KeyboardFocusManager.getCurrentKeyboardFocusManager().

View File

@ -41,6 +41,7 @@ import sun.awt.AppContext;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
import sun.awt.CausedFocusEvent; import sun.awt.CausedFocusEvent;
import sun.awt.TimedWindowEvent;
/** /**
* The default KeyboardFocusManager for AWT applications. Focus traversal is * The default KeyboardFocusManager for AWT applications. Focus traversal is
@ -72,8 +73,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR; private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR;
private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR; private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
private int inSendMessage; private int inSendMessage;
private LinkedList enqueuedKeyEvents = new LinkedList(), private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
typeAheadMarkers = new LinkedList(); private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
private boolean consumeNextKeyTyped; private boolean consumeNextKeyTyped;
static { static {
@ -269,6 +270,31 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
return se.dispatched; return se.dispatched;
} }
/*
* Checks if the focus window event follows key events waiting in the type-ahead
* queue (if any). This may happen when a user types ahead in the window, the client
* listeners hang EDT for a while, and the user switches b/w toplevels. In that
* case the focus window events may be dispatched before the type-ahead events
* get handled. This may lead to wrong focus behavior and in order to avoid it,
* the focus window events are reposted to the end of the event queue. See 6981400.
*/
private boolean repostIfFollowsKeyEvents(WindowEvent e) {
if (!(e instanceof TimedWindowEvent)) {
return false;
}
TimedWindowEvent we = (TimedWindowEvent)e;
long time = we.getWhen();
synchronized (this) {
for (KeyEvent ke: enqueuedKeyEvents) {
if (time >= ke.getWhen()) {
SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
return true;
}
}
}
return false;
}
/** /**
* This method is called by the AWT event dispatcher requesting that the * This method is called by the AWT event dispatcher requesting that the
* current KeyboardFocusManager dispatch the specified event on its behalf. * current KeyboardFocusManager dispatch the specified event on its behalf.
@ -287,6 +313,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
if (focusLog.isLoggable(PlatformLogger.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e); if (focusLog.isLoggable(PlatformLogger.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e);
switch (e.getID()) { switch (e.getID()) {
case WindowEvent.WINDOW_GAINED_FOCUS: { case WindowEvent.WINDOW_GAINED_FOCUS: {
if (repostIfFollowsKeyEvents((WindowEvent)e)) {
break;
}
WindowEvent we = (WindowEvent)e; WindowEvent we = (WindowEvent)e;
Window oldFocusedWindow = getGlobalFocusedWindow(); Window oldFocusedWindow = getGlobalFocusedWindow();
Window newFocusedWindow = we.getWindow(); Window newFocusedWindow = we.getWindow();
@ -646,6 +676,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
} }
case WindowEvent.WINDOW_LOST_FOCUS: { case WindowEvent.WINDOW_LOST_FOCUS: {
if (repostIfFollowsKeyEvents((WindowEvent)e)) {
break;
}
WindowEvent we = (WindowEvent)e; WindowEvent we = (WindowEvent)e;
Window currentFocusedWindow = getGlobalFocusedWindow(); Window currentFocusedWindow = getGlobalFocusedWindow();
Window losingFocusWindow = we.getWindow(); Window losingFocusWindow = we.getWindow();
@ -825,10 +859,9 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
ke = null; ke = null;
synchronized (this) { synchronized (this) {
if (enqueuedKeyEvents.size() != 0) { if (enqueuedKeyEvents.size() != 0) {
ke = (KeyEvent)enqueuedKeyEvents.getFirst(); ke = enqueuedKeyEvents.getFirst();
if (typeAheadMarkers.size() != 0) { if (typeAheadMarkers.size() != 0) {
TypeAheadMarker marker = (TypeAheadMarker) TypeAheadMarker marker = typeAheadMarkers.getFirst();
typeAheadMarkers.getFirst();
// Fixed 5064013: may appears that the events have the same time // Fixed 5064013: may appears that the events have the same time
// if (ke.getWhen() >= marker.after) { // if (ke.getWhen() >= marker.after) {
// The fix is rolled out. // The fix is rolled out.
@ -857,9 +890,9 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
focusLog.finest(">>> Markers dump, time: {0}", System.currentTimeMillis()); focusLog.finest(">>> Markers dump, time: {0}", System.currentTimeMillis());
synchronized (this) { synchronized (this) {
if (typeAheadMarkers.size() != 0) { if (typeAheadMarkers.size() != 0) {
Iterator iter = typeAheadMarkers.iterator(); Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
TypeAheadMarker marker = (TypeAheadMarker)iter.next(); TypeAheadMarker marker = iter.next();
focusLog.finest(" {0}", marker); focusLog.finest(" {0}", marker);
} }
} }
@ -881,8 +914,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
KeyEvent ke = (KeyEvent)e; KeyEvent ke = (KeyEvent)e;
synchronized (this) { synchronized (this) {
if (e.isPosted && typeAheadMarkers.size() != 0) { if (e.isPosted && typeAheadMarkers.size() != 0) {
TypeAheadMarker marker = (TypeAheadMarker) TypeAheadMarker marker = typeAheadMarkers.getFirst();
typeAheadMarkers.getFirst();
// Fixed 5064013: may appears that the events have the same time // Fixed 5064013: may appears that the events have the same time
// if (ke.getWhen() >= marker.after) { // if (ke.getWhen() >= marker.after) {
// The fix is rolled out. // The fix is rolled out.
@ -915,12 +947,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
synchronized (this) { synchronized (this) {
boolean found = false; boolean found = false;
if (hasMarker(target)) { if (hasMarker(target)) {
for (Iterator iter = typeAheadMarkers.iterator(); for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
iter.hasNext(); ) iter.hasNext(); )
{ {
if (((TypeAheadMarker)iter.next()).untilFocused == if (iter.next().untilFocused == target) {
target)
{
found = true; found = true;
} else if (found) { } else if (found) {
break; break;
@ -955,8 +985,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
* @since 1.5 * @since 1.5
*/ */
private boolean hasMarker(Component comp) { private boolean hasMarker(Component comp) {
for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) { for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
if (((TypeAheadMarker)iter.next()).untilFocused == comp) { if (iter.next().untilFocused == comp) {
return true; return true;
} }
} }
@ -982,11 +1012,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
return true; return true;
} }
// Explicitly set the current event and most recent timestamp here in // Explicitly set the key event timestamp here (not in Component.dispatchEventImpl):
// addition to the call in Component.dispatchEventImpl. Because // - A key event is anyway passed to this method which starts its actual dispatching.
// KeyEvents can be delivered in response to a FOCUS_GAINED event, the // - If a key event is put to the type ahead queue, its time stamp should not be registered
// current timestamp may be incorrect. We need to set it here so that // until its dispatching actually starts (by this method).
// KeyEventDispatchers will use the correct time.
EventQueue.setCurrentEventAndMostRecentTime(ke); EventQueue.setCurrentEventAndMostRecentTime(ke);
/** /**
@ -1174,10 +1203,10 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
int insertionIndex = 0, int insertionIndex = 0,
i = typeAheadMarkers.size(); i = typeAheadMarkers.size();
ListIterator iter = typeAheadMarkers.listIterator(i); ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator(i);
for (; i > 0; i--) { for (; i > 0; i--) {
TypeAheadMarker marker = (TypeAheadMarker)iter.previous(); TypeAheadMarker marker = iter.previous();
if (marker.after <= after) { if (marker.after <= after) {
insertionIndex = i; insertionIndex = i;
break; break;
@ -1213,12 +1242,12 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
after, untilFocused); after, untilFocused);
TypeAheadMarker marker; TypeAheadMarker marker;
ListIterator iter = typeAheadMarkers.listIterator ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator
((after >= 0) ? typeAheadMarkers.size() : 0); ((after >= 0) ? typeAheadMarkers.size() : 0);
if (after < 0) { if (after < 0) {
while (iter.hasNext()) { while (iter.hasNext()) {
marker = (TypeAheadMarker)iter.next(); marker = iter.next();
if (marker.untilFocused == untilFocused) if (marker.untilFocused == untilFocused)
{ {
iter.remove(); iter.remove();
@ -1227,7 +1256,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
} }
} else { } else {
while (iter.hasPrevious()) { while (iter.hasPrevious()) {
marker = (TypeAheadMarker)iter.previous(); marker = iter.previous();
if (marker.untilFocused == untilFocused && if (marker.untilFocused == untilFocused &&
marker.after == after) marker.after == after)
{ {
@ -1255,8 +1284,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
long start = -1; long start = -1;
for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) { for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
TypeAheadMarker marker = (TypeAheadMarker)iter.next(); TypeAheadMarker marker = iter.next();
Component toTest = marker.untilFocused; Component toTest = marker.untilFocused;
boolean match = (toTest == comp); boolean match = (toTest == comp);
while (!match && toTest != null && !(toTest instanceof Window)) { while (!match && toTest != null && !(toTest instanceof Window)) {
@ -1287,8 +1316,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
return; return;
} }
for (Iterator iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) { for (Iterator<KeyEvent> iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
KeyEvent ke = (KeyEvent)iter.next(); KeyEvent ke = iter.next();
long time = ke.getWhen(); long time = ke.getWhen();
if (start < time && (end < 0 || time <= end)) { if (start < time && (end < 0 || time <= end)) {

View File

@ -924,7 +924,7 @@ public class Dialog extends Window {
isEnabled() && !isModalBlocked()) { isEnabled() && !isModalBlocked()) {
// keep the KeyEvents from being dispatched // keep the KeyEvents from being dispatched
// until the focus has been transfered // until the focus has been transfered
time.set(Toolkit.getEventQueue().getMostRecentEventTimeEx()); time.set(Toolkit.getEventQueue().getMostRecentKeyEventTime());
KeyboardFocusManager.getCurrentKeyboardFocusManager(). KeyboardFocusManager.getCurrentKeyboardFocusManager().
enqueueKeyEvents(time.get(), toFocus); enqueueKeyEvents(time.get(), toFocus);
} }

View File

@ -162,6 +162,11 @@ public class EventQueue {
*/ */
private long mostRecentEventTime = System.currentTimeMillis(); private long mostRecentEventTime = System.currentTimeMillis();
/*
* The time stamp of the last KeyEvent .
*/
private long mostRecentKeyEventTime = System.currentTimeMillis();
/** /**
* The modifiers field of the current event, if the current event is an * The modifiers field of the current event, if the current event is an
* InputEvent or ActionEvent. * InputEvent or ActionEvent.
@ -1142,6 +1147,15 @@ public class EventQueue {
} }
} }
synchronized long getMostRecentKeyEventTime() {
pushPopLock.lock();
try {
return mostRecentKeyEventTime;
} finally {
pushPopLock.unlock();
}
}
static void setCurrentEventAndMostRecentTime(AWTEvent e) { static void setCurrentEventAndMostRecentTime(AWTEvent e) {
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e); Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
} }
@ -1166,6 +1180,9 @@ public class EventQueue {
if (e instanceof InputEvent) { if (e instanceof InputEvent) {
InputEvent ie = (InputEvent)e; InputEvent ie = (InputEvent)e;
mostRecentEventTime2 = ie.getWhen(); mostRecentEventTime2 = ie.getWhen();
if (e instanceof KeyEvent) {
mostRecentKeyEventTime = ie.getWhen();
}
} else if (e instanceof InputMethodEvent) { } else if (e instanceof InputMethodEvent) {
InputMethodEvent ime = (InputMethodEvent)e; InputMethodEvent ime = (InputMethodEvent)e;
mostRecentEventTime2 = ime.getWhen(); mostRecentEventTime2 = ime.getWhen();

View File

@ -445,7 +445,7 @@ public abstract class KeyboardFocusManager
private void initPeer() { private void initPeer() {
Toolkit tk = Toolkit.getDefaultToolkit(); Toolkit tk = Toolkit.getDefaultToolkit();
KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk; KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
peer = peerProvider.createKeyboardFocusManagerPeer(this); peer = peerProvider.getKeyboardFocusManagerPeer();
} }
/** /**

View File

@ -26,6 +26,7 @@
package java.awt; package java.awt;
import java.util.LinkedList; import java.util.LinkedList;
import sun.awt.AWTAccessor;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
@ -54,6 +55,17 @@ class SequencedEvent extends AWTEvent implements ActiveEvent {
private AppContext appContext; private AppContext appContext;
private boolean disposed; private boolean disposed;
static {
AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() {
public AWTEvent getNested(AWTEvent sequencedEvent) {
return ((SequencedEvent)sequencedEvent).nested;
}
public boolean isSequencedEvent(AWTEvent event) {
return event instanceof SequencedEvent;
}
});
}
/** /**
* Constructs a new SequencedEvent which will dispatch the specified * Constructs a new SequencedEvent which will dispatch the specified
* nested event. * nested event.

View File

@ -33,6 +33,14 @@ import java.awt.Window;
*/ */
public interface KeyboardFocusManagerPeer { public interface KeyboardFocusManagerPeer {
/**
* Sets the window that should become the focused window.
*
* @param win the window that should become the focused window
*
*/
void setCurrentFocusedWindow(Window win);
/** /**
* Returns the currently focused window. * Returns the currently focused window.
* *

View File

@ -1460,7 +1460,7 @@ class GenericBeanInfo extends SimpleBeanInfo {
private PropertyDescriptor[] properties; private PropertyDescriptor[] properties;
private int defaultProperty; private int defaultProperty;
private MethodDescriptor[] methods; private MethodDescriptor[] methods;
private final Reference<BeanInfo> targetBeanInfoRef; private Reference<BeanInfo> targetBeanInfoRef;
public GenericBeanInfo(BeanDescriptor beanDescriptor, public GenericBeanInfo(BeanDescriptor beanDescriptor,
EventSetDescriptor[] events, int defaultEvent, EventSetDescriptor[] events, int defaultEvent,
@ -1472,7 +1472,9 @@ class GenericBeanInfo extends SimpleBeanInfo {
this.properties = properties; this.properties = properties;
this.defaultProperty = defaultProperty; this.defaultProperty = defaultProperty;
this.methods = methods; this.methods = methods;
this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo); this.targetBeanInfoRef = (targetBeanInfo != null)
? new SoftReference<>(targetBeanInfo)
: null;
} }
/** /**
@ -1539,10 +1541,25 @@ class GenericBeanInfo extends SimpleBeanInfo {
} }
public java.awt.Image getIcon(int iconKind) { public java.awt.Image getIcon(int iconKind) {
BeanInfo targetBeanInfo = this.targetBeanInfoRef.get(); BeanInfo targetBeanInfo = getTargetBeanInfo();
if (targetBeanInfo != null) { if (targetBeanInfo != null) {
return targetBeanInfo.getIcon(iconKind); return targetBeanInfo.getIcon(iconKind);
} }
return super.getIcon(iconKind); return super.getIcon(iconKind);
} }
private BeanInfo getTargetBeanInfo() {
if (this.targetBeanInfoRef == null) {
return null;
}
BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
if (targetBeanInfo == null) {
targetBeanInfo = ThreadGroupContext.getContext().getBeanInfoFinder()
.find(this.beanDescriptor.getBeanClass());
if (targetBeanInfo != null) {
this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
}
}
return targetBeanInfo;
}
} }

View File

@ -109,6 +109,10 @@ public class PropertyDescriptor extends FeatureDescriptor {
if (writeMethodName != null && getWriteMethod() == null) { if (writeMethodName != null && getWriteMethod() == null) {
throw new IntrospectionException("Method not found: " + writeMethodName); throw new IntrospectionException("Method not found: " + writeMethodName);
} }
boundInitialization(beanClass);
}
private void boundInitialization(Class<?> beanClass) {
// If this class or one of its base classes allow PropertyChangeListener, // If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound". // then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method. // See Introspector.getTargetPropertyInfo() method.
@ -159,6 +163,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
setReadMethod(read); setReadMethod(read);
setWriteMethod(write); setWriteMethod(write);
this.baseName = base; this.baseName = base;
boundInitialization(bean);
} }
/** /**
@ -588,7 +593,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
Method yw = y.getWriteMethod(); Method yw = y.getWriteMethod();
try { try {
if (yw != null && yw.getDeclaringClass() == getClass0()) { if (yw != null) {
setWriteMethod(yw); setWriteMethod(yw);
} else { } else {
setWriteMethod(xw); setWriteMethod(xw);

View File

@ -631,7 +631,12 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
} }
if (d.name != null) { if (d.name != null) {
outputXML(isArgument ? "object" : "void", " idref=" + quote(d.name), value); if (isArgument) {
writeln("<object idref=" + quote(d.name) + "/>");
}
else {
outputXML("void", " idref=" + quote(d.name), value);
}
} }
else if (d.exp != null) { else if (d.exp != null) {
outputStatement(d.exp, outer, isArgument); outputStatement(d.exp, outer, isArgument);
@ -710,12 +715,14 @@ public class XMLEncoder extends Encoder implements AutoCloseable {
} }
else { else {
d.refs = 2; d.refs = 2;
getValueData(target).refs++; if (d.name == null) {
List<Statement> statements = statementList(target); getValueData(target).refs++;
if (!statements.contains(exp)) { List<Statement> statements = statementList(target);
statements.add(exp); if (!statements.contains(exp)) {
statements.add(exp);
}
outputValue(target, outer, false);
} }
outputValue(target, outer, false);
if (expression) { if (expression) {
outputValue(value, outer, isArgument); outputValue(value, outer, isArgument);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -210,21 +210,21 @@ public class ByteArrayOutputStream extends OutputStream {
/** /**
* Converts the buffer's contents into a string by decoding the bytes using * Converts the buffer's contents into a string by decoding the bytes using
* the specified {@link java.nio.charset.Charset charsetName}. The length of * the named {@link java.nio.charset.Charset charset}. The length of the new
* the new <tt>String</tt> is a function of the charset, and hence may not be * <tt>String</tt> is a function of the charset, and hence may not be equal
* equal to the length of the byte array. * to the length of the byte array.
* *
* <p> This method always replaces malformed-input and unmappable-character * <p> This method always replaces malformed-input and unmappable-character
* sequences with this charset's default replacement string. The {@link * sequences with this charset's default replacement string. The {@link
* java.nio.charset.CharsetDecoder} class should be used when more control * java.nio.charset.CharsetDecoder} class should be used when more control
* over the decoding process is required. * over the decoding process is required.
* *
* @param charsetName the name of a supported * @param charsetName the name of a supported
* {@linkplain java.nio.charset.Charset </code>charset<code>} * {@link java.nio.charset.Charset charset}
* @return String decoded from the buffer's contents. * @return String decoded from the buffer's contents.
* @exception UnsupportedEncodingException * @exception UnsupportedEncodingException
* If the named charset is not supported * If the named charset is not supported
* @since JDK1.1 * @since JDK1.1
*/ */
public synchronized String toString(String charsetName) public synchronized String toString(String charsetName)
throws UnsupportedEncodingException throws UnsupportedEncodingException

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -86,7 +86,7 @@ public class InputStreamReader extends Reader {
* *
* @param charsetName * @param charsetName
* The name of a supported * The name of a supported
* {@link java.nio.charset.Charset </code>charset<code>} * {@link java.nio.charset.Charset charset}
* *
* @exception UnsupportedEncodingException * @exception UnsupportedEncodingException
* If the named charset is not supported * If the named charset is not supported

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2012, 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 java.lang.annotation;
/**
* Indicates that an annotation type is a container for repeated
* instances of annotations of the type of the value of the
* {@code ContainerFor}'s value element.
*
* @since 1.8
* @jls 9.6 Annotation Types
* @jls 9.7 Annotations
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface ContainerFor {
/**
* The repeating annotation type that the annotation type
* annotated with this annotation is a container for.
*/
Class<? extends Annotation> value();
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,9 @@ import java.security.*;
* interface is all that is needed when you accept defaults for algorithm-specific * interface is all that is needed when you accept defaults for algorithm-specific
* parameters. * parameters.
* *
* <p>Note: Some earlier implementations of this interface may not support
* larger sizes of DSA parameters such as 2048 and 3072-bit.
*
* @see java.security.KeyPairGenerator * @see java.security.KeyPairGenerator
*/ */
public interface DSAKeyPairGenerator { public interface DSAKeyPairGenerator {
@ -78,7 +81,7 @@ public interface DSAKeyPairGenerator {
* can be null. * can be null.
* *
* @exception InvalidParameterException if the <code>params</code> * @exception InvalidParameterException if the <code>params</code>
* value is invalid or null. * value is invalid, null, or unsupported.
*/ */
public void initialize(DSAParams params, SecureRandom random) public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException; throws InvalidParameterException;
@ -97,7 +100,7 @@ public interface DSAKeyPairGenerator {
* default parameters for modulus lengths of 512 and 1024 bits. * default parameters for modulus lengths of 512 and 1024 bits.
* *
* @param modlen the modulus length in bits. Valid values are any * @param modlen the modulus length in bits. Valid values are any
* multiple of 8 between 512 and 1024, inclusive. * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072.
* *
* @param random the random bit source to use to generate key bits; * @param random the random bit source to use to generate key bits;
* can be null. * can be null.
@ -105,10 +108,9 @@ public interface DSAKeyPairGenerator {
* @param genParams whether or not to generate new parameters for * @param genParams whether or not to generate new parameters for
* the modulus length requested. * the modulus length requested.
* *
* @exception InvalidParameterException if <code>modlen</code> is not * @exception InvalidParameterException if <code>modlen</code> is
* between 512 and 1024, or if <code>genParams</code> is false and * invalid, or unsupported, or if <code>genParams</code> is false and there
* there are no precomputed parameters for the requested modulus * are no precomputed parameters for the requested modulus length.
* length.
*/ */
public void initialize(int modlen, boolean genParams, SecureRandom random) public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException; throws InvalidParameterException;

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2012, 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 java.security.spec;
/**
* This immutable class specifies the set of parameters used for
* generating DSA parameters as specified in
* <a href="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf">FIPS 186-3 Digital Signature Standard (DSS)</a>.
*
* @see AlgorithmParameterSpec
*
* @since 8
*/
public final class DSAGenParameterSpec implements AlgorithmParameterSpec {
private final int pLen;
private final int qLen;
private final int seedLen;
/**
* Creates a domain parameter specification for DSA parameter
* generation using <code>primePLen</code> and <code>subprimeQLen</code>.
* The value of <code>subprimeQLen</code> is also used as the default
* length of the domain parameter seed in bits.
* @param primePLen the desired length of the prime P in bits.
* @param subprimeQLen the desired length of the sub-prime Q in bits.
* @exception IllegalArgumentException if <code>primePLen</code>
* or <code>subprimeQLen</code> is illegal per the specification of
* FIPS 186-3.
*/
public DSAGenParameterSpec(int primePLen, int subprimeQLen) {
this(primePLen, subprimeQLen, subprimeQLen);
}
/**
* Creates a domain parameter specification for DSA parameter
* generation using <code>primePLen</code>, <code>subprimeQLen</code>,
* and <code>seedLen</code>.
* @param primePLen the desired length of the prime P in bits.
* @param subprimeQLen the desired length of the sub-prime Q in bits.
* @param seedLen the desired length of the domain parameter seed in bits,
* shall be equal to or greater than <code>subprimeQLen</code>.
* @exception IllegalArgumentException if <code>primePLenLen</code>,
* <code>subprimeQLen</code>, or <code>seedLen</code> is illegal per the
* specification of FIPS 186-3.
*/
public DSAGenParameterSpec(int primePLen, int subprimeQLen, int seedLen) {
switch (primePLen) {
case 1024:
if (subprimeQLen != 160) {
throw new IllegalArgumentException
("subprimeQLen must be 160 when primePLen=1024");
}
break;
case 2048:
if (subprimeQLen != 224 && subprimeQLen != 256) {
throw new IllegalArgumentException
("subprimeQLen must be 224 or 256 when primePLen=2048");
}
break;
case 3072:
if (subprimeQLen != 256) {
throw new IllegalArgumentException
("subprimeQLen must be 256 when primePLen=3072");
}
break;
default:
throw new IllegalArgumentException
("primePLen must be 1024, 2048, or 3072");
}
if (seedLen < subprimeQLen) {
throw new IllegalArgumentException
("seedLen must be equal to or greater than subprimeQLen");
}
this.pLen = primePLen;
this.qLen = subprimeQLen;
this.seedLen = seedLen;
}
/**
* Returns the desired length of the prime P of the
* to-be-generated DSA domain parameters in bits.
* @return the length of the prime P.
*/
public int getPrimePLength() {
return pLen;
}
/**
* Returns the desired length of the sub-prime Q of the
* to-be-generated DSA domain parameters in bits.
* @return the length of the sub-prime Q.
*/
public int getSubprimeQLength() {
return qLen;
}
/**
* Returns the desired length of the domain parameter seed in bits.
* @return the length of the domain parameter seed.
*/
public int getSeedLength() {
return seedLen;
}
}

View File

@ -510,7 +510,7 @@ public class DriverManager {
public Void run() { public Void run() {
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator driversIterator = loadedDrivers.iterator(); Iterator<Driver> driversIterator = loadedDrivers.iterator();
/* Load these drivers, so that they can be instantiated. /* Load these drivers, so that they can be instantiated.
* It may be the case that the driver class may not be there * It may be the case that the driver class may not be there

View File

@ -666,6 +666,21 @@ public final class AWTAccessor {
public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e); public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e);
} }
/*
* An accessor for the SequencedEventAccessor class
*/
public interface SequencedEventAccessor {
/*
* Returns the nested event.
*/
AWTEvent getNested(AWTEvent sequencedEvent);
/*
* Returns true if the event is an instances of SequencedEvent.
*/
boolean isSequencedEvent(AWTEvent event);
}
/* /*
* Accessor instances are initialized in the static initializers of * Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below. * corresponding AWT classes by using setters defined below.
@ -692,6 +707,7 @@ public final class AWTAccessor {
private static SystemTrayAccessor systemTrayAccessor; private static SystemTrayAccessor systemTrayAccessor;
private static TrayIconAccessor trayIconAccessor; private static TrayIconAccessor trayIconAccessor;
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor; private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
private static SequencedEventAccessor sequencedEventAccessor;
/* /*
* Set an accessor object for the java.awt.Component class. * Set an accessor object for the java.awt.Component class.
@ -1069,4 +1085,20 @@ public final class AWTAccessor {
} }
return defaultKeyboardFocusManagerAccessor; return defaultKeyboardFocusManagerAccessor;
} }
/*
* Set an accessor object for the java.awt.SequencedEvent class.
*/
public static void setSequencedEventAccessor(SequencedEventAccessor sea) {
sequencedEventAccessor = sea;
}
/*
* Get the accessor object for the java.awt.SequencedEvent class.
*/
public static SequencedEventAccessor getSequencedEventAccessor() {
// The class is not public. So we can't ensure it's initialized.
// Null returned value means it's not initialized
// (so not a single instance of the event has been created).
return sequencedEventAccessor;
}
} }

View File

@ -44,6 +44,14 @@ import java.util.Properties;
public class HToolkit extends SunToolkit public class HToolkit extends SunToolkit
implements ComponentFactory { implements ComponentFactory {
private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
public void setCurrentFocusedWindow(Window win) {}
public Window getCurrentFocusedWindow() { return null; }
public void setCurrentFocusOwner(Component comp) {}
public Component getCurrentFocusOwner() { return null; }
public void clearGlobalFocusOwner(Window activeWindow) {}
};
public HToolkit() { public HToolkit() {
} }
@ -152,15 +160,9 @@ public class HToolkit extends SunToolkit
throw new HeadlessException(); throw new HeadlessException();
} }
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) { public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
// See 6833019. // See 6833019.
return return kfmPeer;
new KeyboardFocusManagerPeer() {
public Window getCurrentFocusedWindow() { return null; }
public void setCurrentFocusOwner(Component comp) {}
public Component getCurrentFocusOwner() { return null; }
public void clearGlobalFocusOwner(Window activeWindow) {}
};
} }
public TrayIconPeer createTrayIcon(TrayIcon target) public TrayIconPeer createTrayIcon(TrayIcon target)

View File

@ -30,22 +30,25 @@ import java.awt.dnd.*;
import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.*; import java.awt.event.*;
import java.awt.im.InputMethodHighlight; import java.awt.im.InputMethodHighlight;
import java.awt.im.spi.InputMethodDescriptor;
import java.awt.image.*; import java.awt.image.*;
import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.Clipboard;
import java.awt.peer.*; import java.awt.peer.*;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL; import java.net.URL;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import sun.awt.im.InputContext;
import sun.awt.image.ImageRepresentation;
public class HeadlessToolkit extends Toolkit public class HeadlessToolkit extends Toolkit
implements ComponentFactory, KeyboardFocusManagerPeerProvider { implements ComponentFactory, KeyboardFocusManagerPeerProvider {
private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
public void setCurrentFocusedWindow(Window win) {}
public Window getCurrentFocusedWindow() { return null; }
public void setCurrentFocusOwner(Component comp) {}
public Component getCurrentFocusOwner() { return null; }
public void clearGlobalFocusOwner(Window activeWindow) {}
};
private Toolkit tk; private Toolkit tk;
private ComponentFactory componentFactory; private ComponentFactory componentFactory;
@ -179,15 +182,9 @@ public class HeadlessToolkit extends Toolkit
throw new HeadlessException(); throw new HeadlessException();
} }
public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) { public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
// See 6833019. // See 6833019.
return return kfmPeer;
new KeyboardFocusManagerPeer() {
public Window getCurrentFocusedWindow() { return null; }
public void setCurrentFocusOwner(Component comp) {}
public Component getCurrentFocusOwner() { return null; }
public void clearGlobalFocusOwner(Window activeWindow) {}
};
} }
public TrayIconPeer createTrayIcon(TrayIcon target) public TrayIconPeer createTrayIcon(TrayIcon target)

View File

@ -53,12 +53,6 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
public static final int SNFH_SUCCESS_HANDLED = 1; public static final int SNFH_SUCCESS_HANDLED = 1;
public static final int SNFH_SUCCESS_PROCEED = 2; public static final int SNFH_SUCCESS_PROCEED = 2;
protected KeyboardFocusManager manager;
public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
this.manager = manager;
}
@Override @Override
public void clearGlobalFocusOwner(Window activeWindow) { public void clearGlobalFocusOwner(Window activeWindow) {
if (activeWindow != null) { if (activeWindow != null) {
@ -134,7 +128,7 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
if (focusLog.isLoggable(PlatformLogger.FINER)) if (focusLog.isLoggable(PlatformLogger.FINER))
focusLog.finer("Posting focus event: " + fl); focusLog.finer("Posting focus event: " + fl);
SunToolkit.postPriorityEvent(fl); SunToolkit.postEvent(SunToolkit.targetToAppContext(currentOwner), fl);
} }
FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED, FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
@ -142,7 +136,7 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
if (focusLog.isLoggable(PlatformLogger.FINER)) if (focusLog.isLoggable(PlatformLogger.FINER))
focusLog.finer("Posting focus event: " + fg); focusLog.finer("Posting focus event: " + fg);
SunToolkit.postPriorityEvent(fg); SunToolkit.postEvent(SunToolkit.targetToAppContext(lightweightChild), fg);
return true; return true;
} }

View File

@ -25,20 +25,19 @@
package sun.awt; package sun.awt;
import java.awt.KeyboardFocusManager;
import java.awt.peer.KeyboardFocusManagerPeer; import java.awt.peer.KeyboardFocusManagerPeer;
/** /**
* {@link KeyboardFocusManagerPeerProvider} is required to be implemented by * {@link KeyboardFocusManagerPeerProvider} is required to be implemented by
* the currently used {@link java.awt.Toolkit} instance. In order to initialize * the currently used {@link java.awt.Toolkit} instance. In order to initialize
* {@link java.awt.KeyboardFocusManager}, an instance of {@link KeyboardFocusManagerPeer} * {@link java.awt.KeyboardFocusManager}, a singleton instance of {@link KeyboardFocusManagerPeer}
* is needed. To create that instance, the {@link #createKeyboardFocusManagerPeer} * is needed. To obtain that instance, the {@link #getKeyboardFocusManagerPeer}
* method of the current toolkit is called. * method of the current toolkit is called.
*/ */
public interface KeyboardFocusManagerPeerProvider { public interface KeyboardFocusManagerPeerProvider {
/** /**
* Creates a KeyboardFocusManagerPeer for the specified KeyboardFocusManager. * Gets a singleton KeyboardFocusManagerPeer instance.
*/ */
KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager); KeyboardFocusManagerPeer getKeyboardFocusManagerPeer();
} }

View File

@ -197,7 +197,7 @@ public abstract class SunToolkit extends Toolkit
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen) public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
throws AWTException; throws AWTException;
public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
throws HeadlessException; throws HeadlessException;
/** /**
@ -463,6 +463,19 @@ public abstract class SunToolkit extends Toolkit
if (event == null) { if (event == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor();
if (sea != null && sea.isSequencedEvent(event)) {
AWTEvent nested = sea.getNested(event);
if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS &&
nested instanceof TimedWindowEvent)
{
TimedWindowEvent twe = (TimedWindowEvent)nested;
((SunToolkit)Toolkit.getDefaultToolkit()).
setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen());
}
}
// All events posted via this method are system-generated. // All events posted via this method are system-generated.
// Placing the following call here reduces considerably the // Placing the following call here reduces considerably the
// number of places throughout the toolkit that would // number of places throughout the toolkit that would
@ -1863,6 +1876,28 @@ public abstract class SunToolkit extends Toolkit
return false; return false;
} }
private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object();
public synchronized void setWindowDeactivationTime(Window w, long time) {
AppContext ctx = getAppContext(w);
WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
if (map == null) {
map = new WeakHashMap<Window, Long>();
ctx.put(DEACTIVATION_TIMES_MAP_KEY, map);
}
map.put(w, time);
}
public synchronized long getWindowDeactivationTime(Window w) {
AppContext ctx = getAppContext(w);
WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
if (map == null) {
return -1;
}
Long time = map.get(w);
return time == null ? -1 : time;
}
// Cosntant alpha // Cosntant alpha
public boolean isWindowOpacitySupported() { public boolean isWindowOpacitySupported() {
return false; return false;

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2012, 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 sun.awt;
import java.awt.event.WindowEvent;
import java.awt.Window;
public class TimedWindowEvent extends WindowEvent {
private long time;
public long getWhen() {
return time;
}
public TimedWindowEvent(Window source, int id, Window opposite, long time) {
super(source, id, opposite);
this.time = time;
}
public TimedWindowEvent(Window source, int id, Window opposite,
int oldState, int newState, long time)
{
super(source, id, opposite, oldState, newState);
this.time = time;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,33 +51,21 @@ import java.security.spec.*;
*/ */
public final class ECKeyFactory extends KeyFactorySpi { public final class ECKeyFactory extends KeyFactorySpi {
// Used by translateKey() and the SunPKCS11 provider // Used by translateKey()
public final static KeyFactory INSTANCE; private static KeyFactory instance;
// Internal provider object we can obtain the KeyFactory and private static KeyFactory getInstance() {
// AlgorithmParameters from. Used by ECParameters and AlgorithmId. if (instance == null) {
// This can go away once we have EC always available in the SUN provider. try {
// Used by ECParameters and AlgorithmId. instance = KeyFactory.getInstance("EC", "SunEC");
public final static Provider ecInternalProvider; } catch (NoSuchProviderException e) {
throw new RuntimeException(e);
static { } catch (NoSuchAlgorithmException e) {
final Provider p = new Provider("SunEC-Internal", 1.0d, null) { throw new RuntimeException(e);
private static final long serialVersionUID = 970685700309471261L;
};
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
p.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
p.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
p.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC");
return null;
} }
});
try {
INSTANCE = KeyFactory.getInstance("EC", p);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} }
ecInternalProvider = p;
return instance;
} }
public ECKeyFactory() { public ECKeyFactory() {
@ -102,7 +90,12 @@ public final class ECKeyFactory extends KeyFactorySpi {
checkKey(ecKey); checkKey(ecKey);
return ecKey; return ecKey;
} else { } else {
return (ECKey)INSTANCE.translateKey(key); /*
* We don't call the engineTranslateKey method directly
* because KeyFactory.translateKey adds code to loop through
* all key factories.
*/
return (ECKey)getInstance().translateKey(key);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -276,8 +276,8 @@ public final class ECParameters extends AlgorithmParametersSpi {
static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec) static AlgorithmParameters getAlgorithmParameters(ECParameterSpec spec)
throws InvalidKeyException { throws InvalidKeyException {
try { try {
AlgorithmParameters params = AlgorithmParameters.getInstance AlgorithmParameters params =
("EC", ECKeyFactory.ecInternalProvider); AlgorithmParameters.getInstance("EC", "SunEC");
params.init(spec); params.init(spec);
return params; return params;
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {

View File

@ -96,8 +96,13 @@ public final class ECPublicKeyImpl extends X509Key implements ECPublicKey {
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
protected void parseKeyBits() throws InvalidKeyException { protected void parseKeyBits() throws InvalidKeyException {
AlgorithmParameters algParams = this.algid.getParameters();
if (algParams == null) {
throw new InvalidKeyException("EC domain parameters must be " +
"encoded in the algorithm identifier");
}
try { try {
AlgorithmParameters algParams = this.algid.getParameters();
params = algParams.getParameterSpec(ECParameterSpec.class); params = algParams.getParameterSpec(ECParameterSpec.class);
w = ECParameters.decodePoint(key, params.getCurve()); w = ECParameters.decodePoint(key, params.getCurve());
} catch (IOException e) { } catch (IOException e) {

View File

@ -54,6 +54,7 @@ final class SunECEntries {
*/ */
map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters"); map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC"); map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
map.put("Alg.Alias.AlgorithmParameters.1.2.840.10045.2.1", "EC");
map.put("AlgorithmParameters.EC KeySize", "256"); map.put("AlgorithmParameters.EC KeySize", "256");
@ -133,6 +134,9 @@ final class SunECEntries {
"sun.security.ec.ECDSASignature$Raw"); "sun.security.ec.ECDSASignature$Raw");
map.put("Signature.SHA1withECDSA", map.put("Signature.SHA1withECDSA",
"sun.security.ec.ECDSASignature$SHA1"); "sun.security.ec.ECDSASignature$SHA1");
map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.1", "SHA1withECDSA");
map.put("Alg.Alias.Signature.1.2.840.10045.4.1", "SHA1withECDSA");
map.put("Signature.SHA224withECDSA", map.put("Signature.SHA224withECDSA",
"sun.security.ec.ECDSASignature$SHA224"); "sun.security.ec.ECDSASignature$SHA224");
map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA"); map.put("Alg.Alias.Signature.OID.1.2.840.10045.4.3.1", "SHA224withECDSA");

View File

@ -115,7 +115,12 @@ public class Config {
private static boolean isMacosLionOrBetter() { private static boolean isMacosLionOrBetter() {
// split the "10.x.y" version number // split the "10.x.y" version number
String osVersion = System.getProperty("os.version"); String osname = getProperty("os.name");
if (!osname.contains("OS X")) {
return false;
}
String osVersion = getProperty("os.version");
String[] fragments = osVersion.split("\\."); String[] fragments = osVersion.split("\\.");
// sanity check the "10." part of the version // sanity check the "10." part of the version
@ -140,20 +145,14 @@ public class Config {
/* /*
* If either one system property is specified, we throw exception. * If either one system property is specified, we throw exception.
*/ */
String tmp = String tmp = getProperty("java.security.krb5.kdc");
java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction
("java.security.krb5.kdc"));
if (tmp != null) { if (tmp != null) {
// The user can specify a list of kdc hosts separated by ":" // The user can specify a list of kdc hosts separated by ":"
defaultKDC = tmp.replace(':', ' '); defaultKDC = tmp.replace(':', ' ');
} else { } else {
defaultKDC = null; defaultKDC = null;
} }
defaultRealm = defaultRealm = getProperty("java.security.krb5.realm");
java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction
("java.security.krb5.realm"));
if ((defaultKDC == null && defaultRealm != null) || if ((defaultKDC == null && defaultRealm != null) ||
(defaultRealm == null && defaultKDC != null)) { (defaultRealm == null && defaultKDC != null)) {
throw new KrbException throw new KrbException
@ -165,11 +164,34 @@ public class Config {
// Always read the Kerberos configuration file // Always read the Kerberos configuration file
try { try {
Vector<String> configFile; Vector<String> configFile;
configFile = loadConfigFile(); String fileName = getJavaFileName();
if (configFile == null && isMacosLionOrBetter()) { if (fileName != null) {
stanzaTable = SCDynamicStoreConfig.getConfig(); configFile = loadConfigFile(fileName);
} else {
stanzaTable = parseStanzaTable(configFile); stanzaTable = parseStanzaTable(configFile);
if (DEBUG) {
System.out.println("Loaded from Java config");
}
} else {
boolean found = false;
if (isMacosLionOrBetter()) {
try {
stanzaTable = SCDynamicStoreConfig.getConfig();
if (DEBUG) {
System.out.println("Loaded from SCDynamicStoreConfig");
}
found = true;
} catch (IOException ioe) {
// OK. Will go on with file
}
}
if (!found) {
fileName = getNativeFileName();
configFile = loadConfigFile(fileName);
stanzaTable = parseStanzaTable(configFile);
if (DEBUG) {
System.out.println("Loaded from native config");
}
}
} }
} catch (IOException ioe) { } catch (IOException ioe) {
// No krb5.conf, no problem. We'll use DNS or system property etc. // No krb5.conf, no problem. We'll use DNS or system property etc.
@ -546,10 +568,13 @@ public class Config {
* [domain_realm] * [domain_realm]
* blue.sample.com = TEST.SAMPLE.COM * blue.sample.com = TEST.SAMPLE.COM
* .backup.com = EXAMPLE.COM * .backup.com = EXAMPLE.COM
*
* @params fileName the conf file, cannot be null
* @return the content, null if fileName is empty
* @throws IOException if there is an I/O or format error
*/ */
private Vector<String> loadConfigFile() throws IOException { private Vector<String> loadConfigFile(final String fileName) throws IOException {
try { try {
final String fileName = getFileName();
if (!fileName.equals("")) { if (!fileName.equals("")) {
BufferedReader br = new BufferedReader(new InputStreamReader( BufferedReader br = new BufferedReader(new InputStreamReader(
java.security.AccessController.doPrivileged( java.security.AccessController.doPrivileged(
@ -668,97 +693,106 @@ public class Config {
} }
/** /**
* Gets the default configuration file name. This method will never * Gets the default Java configuration file name.
* return null.
* *
* If the system property "java.security.krb5.conf" is defined, we'll * If the system property "java.security.krb5.conf" is defined, we'll
* use its value, no matter if the file exists or not. Otherwise, * use its value, no matter if the file exists or not. Otherwise, we
* the file will be searched in a list of possible loations in the * will look at $JAVA_HOME/lib/security directory with "krb5.conf" name,
* following order: * and return it if the file exists.
* *
* 1. at Java home lib\security directory with "krb5.conf" name, * The method returns null if it cannot find a Java config file.
* 2. at windows directory with the name of "krb5.ini" for Windows, */
* /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf otherwise. private String getJavaFileName() {
String name = getProperty("java.security.krb5.conf");
if (name == null) {
name = getProperty("java.home") + File.separator +
"lib" + File.separator + "security" +
File.separator + "krb5.conf";
if (!fileExists(name)) {
name = null;
}
}
if (DEBUG) {
System.out.println("Java config name: " + name);
}
return name;
}
/**
* Gets the default native configuration file name.
*
* Depending on the OS type, the method returns the default native
* kerberos config file name, which is at windows directory with
* the name of "krb5.ini" for Windows, /etc/krb5/krb5.conf for Solaris,
* /etc/krb5.conf otherwise. Mac OSX X has a different file name.
* *
* Note: When the Terminal Service is started in Windows (from 2003), * Note: When the Terminal Service is started in Windows (from 2003),
* there are two kinds of Windows directories: A system one (say, * there are two kinds of Windows directories: A system one (say,
* C:\Windows), and a user-private one (say, C:\Users\Me\Windows). * C:\Windows), and a user-private one (say, C:\Users\Me\Windows).
* We will first look for krb5.ini in the user-private one. If not * We will first look for krb5.ini in the user-private one. If not
* found, try the system one instead. * found, try the system one instead.
*
* This method will always return a non-null non-empty file name,
* even if that file does not exist.
*/ */
private String getFileName() { private String getNativeFileName() {
String name = String name = null;
java.security.AccessController.doPrivileged( String osname = getProperty("os.name");
new sun.security.action. if (osname.startsWith("Windows")) {
GetPropertyAction("java.security.krb5.conf")); try {
if (name == null) { Credentials.ensureLoaded();
name = java.security.AccessController.doPrivileged( } catch (Exception e) {
new sun.security.action. // ignore exceptions
GetPropertyAction("java.home")) + File.separator + }
"lib" + File.separator + "security" + if (Credentials.alreadyLoaded) {
File.separator + "krb5.conf"; String path = getWindowsDirectory(false);
if (!fileExists(name)) { if (path != null) {
name = null; if (path.endsWith("\\")) {
String osname = path = path + "krb5.ini";
java.security.AccessController.doPrivileged( } else {
new sun.security.action.GetPropertyAction("os.name")); path = path + "\\krb5.ini";
if (osname.startsWith("Windows")) {
try {
Credentials.ensureLoaded();
} catch (Exception e) {
// ignore exceptions
} }
if (Credentials.alreadyLoaded) { if (fileExists(path)) {
String path = getWindowsDirectory(false); name = path;
if (path != null) { }
if (path.endsWith("\\")) { }
path = path + "krb5.ini"; if (name == null) {
} else { path = getWindowsDirectory(true);
path = path + "\\krb5.ini"; if (path != null) {
} if (path.endsWith("\\")) {
if (fileExists(path)) { path = path + "krb5.ini";
name = path; } else {
} path = path + "\\krb5.ini";
}
if (name == null) {
path = getWindowsDirectory(true);
if (path != null) {
if (path.endsWith("\\")) {
path = path + "krb5.ini";
} else {
path = path + "\\krb5.ini";
}
name = path;
}
} }
name = path;
} }
if (name == null) {
name = "c:\\winnt\\krb5.ini";
}
} else if (osname.startsWith("SunOS")) {
name = "/etc/krb5/krb5.conf";
} else if (osname.contains("OS X")) {
if (isMacosLionOrBetter()) return "";
name = findMacosConfigFile();
} else {
name = "/etc/krb5.conf";
} }
} }
if (name == null) {
name = "c:\\winnt\\krb5.ini";
}
} else if (osname.startsWith("SunOS")) {
name = "/etc/krb5/krb5.conf";
} else if (osname.contains("OS X")) {
name = findMacosConfigFile();
} else {
name = "/etc/krb5.conf";
} }
if (DEBUG) { if (DEBUG) {
System.out.println("Config name: " + name); System.out.println("Native config name: " + name);
} }
return name; return name;
} }
private String getProperty(String property) { private static String getProperty(String property) {
return java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction(property)); return java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(property));
} }
private String findMacosConfigFile() { private String findMacosConfigFile() {
String userHome = getProperty("user.home"); String userHome = getProperty("user.home");
final String PREF_FILE = "/Library/Preferences/edu.mit.Kerberos"; final String PREF_FILE = "/Library/Preferences/edu.mit.Kerberos";
String userPrefs=userHome + PREF_FILE; String userPrefs = userHome + PREF_FILE;
if (fileExists(userPrefs)) { if (fileExists(userPrefs)) {
return userPrefs; return userPrefs;
@ -768,11 +802,7 @@ public class Config {
return PREF_FILE; return PREF_FILE;
} }
if (fileExists("/etc/krb5.conf")) { return "/etc/krb5.conf";
return "/etc/krb5.conf";
}
return "";
} }
private static String trimmed(String s) { private static String trimmed(String s) {
@ -1344,32 +1374,52 @@ public class Config {
} }
} }
// Shows the content of the Config object for debug purpose.
//
// {
// libdefaults = {
// default_realm = R
// }
// realms = {
// R = {
// kdc = [k1,k2]
// }
// }
// }
@Override @Override
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
toStringIndented("", stanzaTable, sb); toStringInternal("", stanzaTable, sb);
return sb.toString(); return sb.toString();
} }
private static void toStringIndented(String prefix, Object obj, private static void toStringInternal(String prefix, Object obj,
StringBuffer sb) { StringBuffer sb) {
if (obj instanceof String) { if (obj instanceof String) {
sb.append(prefix); // A string value, just print it
sb.append(obj); sb.append(obj).append('\n');
sb.append('\n');
} else if (obj instanceof Hashtable) { } else if (obj instanceof Hashtable) {
// A table, start a new sub-section...
Hashtable<?, ?> tab = (Hashtable<?, ?>)obj; Hashtable<?, ?> tab = (Hashtable<?, ?>)obj;
sb.append("{\n");
for (Object o: tab.keySet()) { for (Object o: tab.keySet()) {
sb.append(prefix); // ...indent, print "key = ", and
sb.append(o); sb.append(prefix).append(" ").append(o).append(" = ");
sb.append(" = {\n"); // ...go recursively into value
toStringIndented(prefix + " ", tab.get(o), sb); toStringInternal(prefix + " ", tab.get(o), sb);
sb.append(prefix + "}\n");
} }
sb.append(prefix).append("}\n");
} else if (obj instanceof Vector) { } else if (obj instanceof Vector) {
// A vector of strings, print them inside [ and ]
Vector<?> v = (Vector<?>)obj; Vector<?> v = (Vector<?>)obj;
sb.append("[");
boolean first = true;
for (Object o: v.toArray()) { for (Object o: v.toArray()) {
toStringIndented(prefix + " ", o, sb); if (!first) sb.append(",");
sb.append(o);
first = false;
} }
sb.append("]\n");
} }
} }
} }

View File

@ -164,6 +164,10 @@ final class P11Cipher extends CipherSpi {
// if we do the padding // if we do the padding
private int bytesBuffered; private int bytesBuffered;
// length of key size in bytes; currently only used by AES given its oid
// specification mandates a fixed size of the key
private int fixedKeySize = -1;
P11Cipher(Token token, String algorithm, long mechanism) P11Cipher(Token token, String algorithm, long mechanism)
throws PKCS11Exception, NoSuchAlgorithmException { throws PKCS11Exception, NoSuchAlgorithmException {
super(); super();
@ -172,19 +176,26 @@ final class P11Cipher extends CipherSpi {
this.mechanism = mechanism; this.mechanism = mechanism;
String algoParts[] = algorithm.split("/"); String algoParts[] = algorithm.split("/");
keyAlgorithm = algoParts[0];
if (keyAlgorithm.equals("AES")) { if (algoParts[0].startsWith("AES")) {
blockSize = 16; blockSize = 16;
} else if (keyAlgorithm.equals("RC4") || int index = algoParts[0].indexOf('_');
keyAlgorithm.equals("ARCFOUR")) { if (index != -1) {
blockSize = 0; // should be well-formed since we specify what we support
} else { // DES, DESede, Blowfish fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8;
blockSize = 8; }
} keyAlgorithm = "AES";
this.blockMode = } else {
keyAlgorithm = algoParts[0];
if (keyAlgorithm.equals("RC4") ||
keyAlgorithm.equals("ARCFOUR")) {
blockSize = 0;
} else { // DES, DESede, Blowfish
blockSize = 8;
}
this.blockMode =
(algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB); (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
}
String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding"); String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
String paddingStr = String paddingStr =
(algoParts.length > 2 ? algoParts[2] : defPadding); (algoParts.length > 2 ? algoParts[2] : defPadding);
@ -333,6 +344,9 @@ final class P11Cipher extends CipherSpi {
SecureRandom random) SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
cancelOperation(); cancelOperation();
if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
throw new InvalidKeyException("Key size is invalid");
}
switch (opmode) { switch (opmode) {
case Cipher.ENCRYPT_MODE: case Cipher.ENCRYPT_MODE:
encrypt = true; encrypt = true;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -304,7 +304,7 @@ final class P11ECKeyFactory extends P11KeyFactory {
} }
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException { KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
return sun.security.ec.ECKeyFactory.INSTANCE; return KeyFactory.getInstance("EC", "SunEC");
} }
} }

View File

@ -399,12 +399,8 @@ public final class SunPKCS11 extends AuthProvider {
return System.identityHashCode(this); return System.identityHashCode(this);
} }
private static String[] s(String s1) { private static String[] s(String ...aliases) {
return new String[] {s1}; return aliases;
}
private static String[] s(String s1, String s2) {
return new String[] {s1, s2};
} }
private static final class Descriptor { private static final class Descriptor {
@ -521,7 +517,8 @@ public final class SunPKCS11 extends AuthProvider {
m(CKM_MD2)); m(CKM_MD2));
d(MD, "MD5", P11Digest, d(MD, "MD5", P11Digest,
m(CKM_MD5)); m(CKM_MD5));
d(MD, "SHA1", P11Digest, s("SHA", "SHA-1"), d(MD, "SHA1", P11Digest,
s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
m(CKM_SHA_1)); m(CKM_SHA_1));
d(MD, "SHA-224", P11Digest, d(MD, "SHA-224", P11Digest,
@ -540,6 +537,7 @@ public final class SunPKCS11 extends AuthProvider {
d(MAC, "HmacMD5", P11MAC, d(MAC, "HmacMD5", P11MAC,
m(CKM_MD5_HMAC)); m(CKM_MD5_HMAC));
d(MAC, "HmacSHA1", P11MAC, d(MAC, "HmacSHA1", P11MAC,
s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
m(CKM_SHA_1_HMAC)); m(CKM_SHA_1_HMAC));
d(MAC, "HmacSHA224", P11MAC, d(MAC, "HmacSHA224", P11MAC,
s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"), s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
@ -561,6 +559,7 @@ public final class SunPKCS11 extends AuthProvider {
d(KPG, "RSA", P11KeyPairGenerator, d(KPG, "RSA", P11KeyPairGenerator,
m(CKM_RSA_PKCS_KEY_PAIR_GEN)); m(CKM_RSA_PKCS_KEY_PAIR_GEN));
d(KPG, "DSA", P11KeyPairGenerator, d(KPG, "DSA", P11KeyPairGenerator,
s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
m(CKM_DSA_KEY_PAIR_GEN)); m(CKM_DSA_KEY_PAIR_GEN));
d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"), d(KPG, "DH", P11KeyPairGenerator, s("DiffieHellman"),
m(CKM_DH_PKCS_KEY_PAIR_GEN)); m(CKM_DH_PKCS_KEY_PAIR_GEN));
@ -583,6 +582,7 @@ public final class SunPKCS11 extends AuthProvider {
d(KF, "RSA", P11RSAKeyFactory, d(KF, "RSA", P11RSAKeyFactory,
m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509)); m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
d(KF, "DSA", P11DSAKeyFactory, d(KF, "DSA", P11DSAKeyFactory,
s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1)); m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"), d(KF, "DH", P11DHKeyFactory, s("DiffieHellman"),
m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE)); m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
@ -609,6 +609,7 @@ public final class SunPKCS11 extends AuthProvider {
d(SKF, "DESede", P11SecretKeyFactory, d(SKF, "DESede", P11SecretKeyFactory,
m(CKM_DES3_CBC)); m(CKM_DES3_CBC));
d(SKF, "AES", P11SecretKeyFactory, d(SKF, "AES", P11SecretKeyFactory,
s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
m(CKM_AES_CBC)); m(CKM_AES_CBC));
d(SKF, "Blowfish", P11SecretKeyFactory, d(SKF, "Blowfish", P11SecretKeyFactory,
m(CKM_BLOWFISH_CBC)); m(CKM_BLOWFISH_CBC));
@ -635,10 +636,28 @@ public final class SunPKCS11 extends AuthProvider {
m(CKM_DES3_ECB)); m(CKM_DES3_ECB));
d(CIP, "AES/CBC/NoPadding", P11Cipher, d(CIP, "AES/CBC/NoPadding", P11Cipher,
m(CKM_AES_CBC)); m(CKM_AES_CBC));
d(CIP, "AES_128/CBC/NoPadding", P11Cipher,
s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
m(CKM_AES_CBC));
d(CIP, "AES_192/CBC/NoPadding", P11Cipher,
s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
m(CKM_AES_CBC));
d(CIP, "AES_256/CBC/NoPadding", P11Cipher,
s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
m(CKM_AES_CBC));
d(CIP, "AES/CBC/PKCS5Padding", P11Cipher, d(CIP, "AES/CBC/PKCS5Padding", P11Cipher,
m(CKM_AES_CBC_PAD, CKM_AES_CBC)); m(CKM_AES_CBC_PAD, CKM_AES_CBC));
d(CIP, "AES/ECB/NoPadding", P11Cipher, d(CIP, "AES/ECB/NoPadding", P11Cipher,
m(CKM_AES_ECB)); m(CKM_AES_ECB));
d(CIP, "AES_128/ECB/NoPadding", P11Cipher,
s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
m(CKM_AES_ECB));
d(CIP, "AES_192/ECB/NoPadding", P11Cipher,
s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
m(CKM_AES_ECB));
d(CIP, "AES_256/ECB/NoPadding", P11Cipher,
s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
m(CKM_AES_ECB));
d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"), d(CIP, "AES/ECB/PKCS5Padding", P11Cipher, s("AES"),
m(CKM_AES_ECB)); m(CKM_AES_ECB));
d(CIP, "AES/CTR/NoPadding", P11Cipher, d(CIP, "AES/CTR/NoPadding", P11Cipher,
@ -654,13 +673,16 @@ public final class SunPKCS11 extends AuthProvider {
d(CIP, "RSA/ECB/NoPadding", P11RSACipher, d(CIP, "RSA/ECB/NoPadding", P11RSACipher,
m(CKM_RSA_X_509)); m(CKM_RSA_X_509));
d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"), d(SIG, "RawDSA", P11Signature, s("NONEwithDSA"),
m(CKM_DSA)); m(CKM_DSA));
d(SIG, "DSA", P11Signature, s("SHA1withDSA"), d(SIG, "DSA", P11Signature,
s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
"1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
m(CKM_DSA_SHA1, CKM_DSA)); m(CKM_DSA_SHA1, CKM_DSA));
d(SIG, "NONEwithECDSA", P11Signature, d(SIG, "NONEwithECDSA", P11Signature,
m(CKM_ECDSA)); m(CKM_ECDSA));
d(SIG, "SHA1withECDSA", P11Signature, s("ECDSA"), d(SIG, "SHA1withECDSA", P11Signature,
s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
m(CKM_ECDSA_SHA1, CKM_ECDSA)); m(CKM_ECDSA_SHA1, CKM_ECDSA));
d(SIG, "SHA224withECDSA", P11Signature, d(SIG, "SHA224withECDSA", P11Signature,
s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"), s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
@ -675,10 +697,14 @@ public final class SunPKCS11 extends AuthProvider {
s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"), s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
m(CKM_ECDSA)); m(CKM_ECDSA));
d(SIG, "MD2withRSA", P11Signature, d(SIG, "MD2withRSA", P11Signature,
s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(SIG, "MD5withRSA", P11Signature, d(SIG, "MD5withRSA", P11Signature,
s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(SIG, "SHA1withRSA", P11Signature, d(SIG, "SHA1withRSA", P11Signature,
s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
"1.3.14.3.2.29"),
m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509)); m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
d(SIG, "SHA224withRSA", P11Signature, d(SIG, "SHA224withRSA", P11Signature,
s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"), s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -45,14 +45,15 @@ import sun.security.jca.JCAUtil;
/** /**
* The Digital Signature Standard (using the Digital Signature * The Digital Signature Standard (using the Digital Signature
* Algorithm), as described in fips186 of the National Instute of * Algorithm), as described in fips186-3 of the National Instute of
* Standards and Technology (NIST), using fips180-1 (SHA-1). * Standards and Technology (NIST), using SHA digest algorithms
* from FIPS180-3.
* *
* This file contains both the signature implementation for the * This file contains both the signature implementation for the
* commonly used SHA1withDSA (DSS) as well as RawDSA, used by TLS * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA,
* among others. RawDSA expects the 20 byte SHA-1 digest as input * as well as RawDSA, used by TLS among others. RawDSA expects
* via update rather than the original data like other signature * the 20 byte SHA-1 digest as input via update rather than the
* implementations. * original data like other signature implementations.
* *
* @author Benjamin Renaud * @author Benjamin Renaud
* *
@ -78,129 +79,19 @@ abstract class DSA extends SignatureSpi {
/* The private key, if any */ /* The private key, if any */
private BigInteger presetX; private BigInteger presetX;
/* The random seed used to generate k */
private int[] Kseed;
/* The random seed used to generate k (specified by application) */
private byte[] KseedAsByteArray;
/*
* The random seed used to generate k
* (prevent the same Kseed from being used twice in a row
*/
private int[] previousKseed;
/* The RNG used to output a seed for generating k */ /* The RNG used to output a seed for generating k */
private SecureRandom signingRandom; private SecureRandom signingRandom;
/* The message digest object used */
private final MessageDigest md;
/** /**
* Construct a blank DSA object. It must be * Construct a blank DSA object. It must be
* initialized before being usable for signing or verifying. * initialized before being usable for signing or verifying.
*/ */
DSA() { DSA(MessageDigest md) {
super(); super();
} this.md = md;
/**
* Return the 20 byte hash value and reset the digest.
*/
abstract byte[] getDigest() throws SignatureException;
/**
* Reset the digest.
*/
abstract void resetDigest();
/**
* Standard SHA1withDSA implementation.
*/
public static final class SHA1withDSA extends DSA {
/* The SHA hash for the data */
private final MessageDigest dataSHA;
public SHA1withDSA() throws NoSuchAlgorithmException {
dataSHA = MessageDigest.getInstance("SHA-1");
}
/**
* Update a byte to be signed or verified.
*/
protected void engineUpdate(byte b) {
dataSHA.update(b);
}
/**
* Update an array of bytes to be signed or verified.
*/
protected void engineUpdate(byte[] data, int off, int len) {
dataSHA.update(data, off, len);
}
protected void engineUpdate(ByteBuffer b) {
dataSHA.update(b);
}
byte[] getDigest() {
return dataSHA.digest();
}
void resetDigest() {
dataSHA.reset();
}
}
/**
* RawDSA implementation.
*
* RawDSA requires the data to be exactly 20 bytes long. If it is
* not, a SignatureException is thrown when sign()/verify() is called
* per JCA spec.
*/
public static final class RawDSA extends DSA {
// length of the SHA-1 digest (20 bytes)
private final static int SHA1_LEN = 20;
// 20 byte digest buffer
private final byte[] digestBuffer;
// offset into the buffer
private int ofs;
public RawDSA() {
digestBuffer = new byte[SHA1_LEN];
}
protected void engineUpdate(byte b) {
if (ofs == SHA1_LEN) {
ofs = SHA1_LEN + 1;
return;
}
digestBuffer[ofs++] = b;
}
protected void engineUpdate(byte[] data, int off, int len) {
if (ofs + len > SHA1_LEN) {
ofs = SHA1_LEN + 1;
return;
}
System.arraycopy(data, off, digestBuffer, ofs, len);
ofs += len;
}
byte[] getDigest() throws SignatureException {
if (ofs != SHA1_LEN) {
throw new SignatureException
("Data for RawDSA must be exactly 20 bytes long");
}
ofs = 0;
return digestBuffer;
}
void resetDigest() {
ofs = 0;
}
} }
/** /**
@ -217,13 +108,25 @@ abstract class DSA extends SignatureSpi {
throw new InvalidKeyException("not a DSA private key: " + throw new InvalidKeyException("not a DSA private key: " +
privateKey); privateKey);
} }
java.security.interfaces.DSAPrivateKey priv = java.security.interfaces.DSAPrivateKey priv =
(java.security.interfaces.DSAPrivateKey)privateKey; (java.security.interfaces.DSAPrivateKey)privateKey;
// check for algorithm specific constraints before doing initialization
DSAParams params = priv.getParams();
if (params == null) {
throw new InvalidKeyException("DSA private key lacks parameters");
}
checkKey(params);
this.params = params;
this.presetX = priv.getX(); this.presetX = priv.getX();
this.presetY = null; this.presetY = null;
initialize(priv.getParams()); this.presetP = params.getP();
this.presetQ = params.getQ();
this.presetG = params.getG();
this.md.reset();
} }
/** /**
* Initialize the DSA object with a DSA public key. * Initialize the DSA object with a DSA public key.
* *
@ -240,16 +143,42 @@ abstract class DSA extends SignatureSpi {
} }
java.security.interfaces.DSAPublicKey pub = java.security.interfaces.DSAPublicKey pub =
(java.security.interfaces.DSAPublicKey)publicKey; (java.security.interfaces.DSAPublicKey)publicKey;
// check for algorithm specific constraints before doing initialization
DSAParams params = pub.getParams();
if (params == null) {
throw new InvalidKeyException("DSA public key lacks parameters");
}
checkKey(params);
this.params = params;
this.presetY = pub.getY(); this.presetY = pub.getY();
this.presetX = null; this.presetX = null;
initialize(pub.getParams()); this.presetP = params.getP();
this.presetQ = params.getQ();
this.presetG = params.getG();
this.md.reset();
} }
private void initialize(DSAParams params) throws InvalidKeyException { /**
resetDigest(); * Update a byte to be signed or verified.
setParams(params); */
protected void engineUpdate(byte b) {
md.update(b);
} }
/**
* Update an array of bytes to be signed or verified.
*/
protected void engineUpdate(byte[] data, int off, int len) {
md.update(data, off, len);
}
protected void engineUpdate(ByteBuffer b) {
md.update(b);
}
/** /**
* Sign all the data thus far updated. The signature is formatted * Sign all the data thus far updated. The signature is formatted
* according to the Canonical Encoding Rules, returned as a DER * according to the Canonical Encoding Rules, returned as a DER
@ -352,23 +281,51 @@ abstract class DSA extends SignatureSpi {
} }
} }
@Deprecated
protected void engineSetParameter(String key, Object param) {
throw new InvalidParameterException("No parameter accepted");
}
@Deprecated
protected Object engineGetParameter(String key) {
return null;
}
protected void checkKey(DSAParams params) throws InvalidKeyException {
// FIPS186-3 states in sec4.2 that a hash function which provides
// a lower security strength than the (L, N) pair ordinarily should
// not be used.
int valueN = params.getQ().bitLength();
if (valueN > md.getDigestLength()*8) {
throw new InvalidKeyException("Key is too strong for this signature algorithm");
}
}
private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g, private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,
BigInteger k) { BigInteger k) {
BigInteger temp = g.modPow(k, p); BigInteger temp = g.modPow(k, p);
return temp.remainder(q); return temp.mod(q);
} }
private BigInteger generateS(BigInteger x, BigInteger q, private BigInteger generateS(BigInteger x, BigInteger q,
BigInteger r, BigInteger k) throws SignatureException { BigInteger r, BigInteger k) throws SignatureException {
byte[] s2 = getDigest(); byte[] s2;
BigInteger temp = new BigInteger(1, s2); try {
s2 = md.digest();
} catch (RuntimeException re) {
// Only for RawDSA due to its 20-byte length restriction
throw new SignatureException(re.getMessage());
}
// get the leftmost min(N, outLen) bits of the digest value
int nBytes = q.bitLength()/8;
if (nBytes < s2.length) {
s2 = Arrays.copyOfRange(s2, 0, nBytes);
}
BigInteger z = new BigInteger(1, s2);
BigInteger k1 = k.modInverse(q); BigInteger k1 = k.modInverse(q);
BigInteger s = x.multiply(r); return x.multiply(r).add(z).multiply(k1).mod(q);
s = temp.add(s);
s = k1.multiply(s);
return s.remainder(q);
} }
private BigInteger generateW(BigInteger p, BigInteger q, private BigInteger generateW(BigInteger p, BigInteger q,
@ -380,54 +337,41 @@ abstract class DSA extends SignatureSpi {
BigInteger q, BigInteger g, BigInteger w, BigInteger r) BigInteger q, BigInteger g, BigInteger w, BigInteger r)
throws SignatureException { throws SignatureException {
byte[] s2 = getDigest(); byte[] s2;
BigInteger temp = new BigInteger(1, s2); try {
s2 = md.digest();
} catch (RuntimeException re) {
// Only for RawDSA due to its 20-byte length restriction
throw new SignatureException(re.getMessage());
}
// get the leftmost min(N, outLen) bits of the digest value
int nBytes = q.bitLength()/8;
if (nBytes < s2.length) {
s2 = Arrays.copyOfRange(s2, 0, nBytes);
}
BigInteger z = new BigInteger(1, s2);
temp = temp.multiply(w); BigInteger u1 = z.multiply(w).mod(q);
BigInteger u1 = temp.remainder(q); BigInteger u2 = (r.multiply(w)).mod(q);
BigInteger u2 = (r.multiply(w)).remainder(q);
BigInteger t1 = g.modPow(u1,p); BigInteger t1 = g.modPow(u1,p);
BigInteger t2 = y.modPow(u2,p); BigInteger t2 = y.modPow(u2,p);
BigInteger t3 = t1.multiply(t2); BigInteger t3 = t1.multiply(t2);
BigInteger t5 = t3.remainder(p); BigInteger t5 = t3.mod(p);
return t5.remainder(q); return t5.mod(q);
} }
/* // NOTE: This following impl is defined in FIPS 186-3 AppendixB.2.2.
* Please read bug report 4044247 for an alternative, faster, // Original DSS algos such as SHA1withDSA and RawDSA uses a different
* NON-FIPS approved method to generate K // algorithm defined in FIPS 186-1 Sec3.2, and thus need to override this.
*/ protected BigInteger generateK(BigInteger q) {
private BigInteger generateK(BigInteger q) {
BigInteger k = null;
// The application specified a Kseed for us to use.
// Note that we do not allow usage of the same Kseed twice in a row
if (Kseed != null && !Arrays.equals(Kseed, previousKseed)) {
k = generateK(Kseed, q);
if (k.signum() > 0 && k.compareTo(q) < 0) {
previousKseed = new int [Kseed.length];
System.arraycopy(Kseed, 0, previousKseed, 0, Kseed.length);
return k;
}
}
// The application did not specify a Kseed for us to use.
// We'll generate a new Kseed by getting random bytes from
// a SecureRandom object.
SecureRandom random = getSigningRandom(); SecureRandom random = getSigningRandom();
byte[] kValue = new byte[q.bitLength()/8];
while (true) { while (true) {
int[] seed = new int[5]; random.nextBytes(kValue);
BigInteger k = new BigInteger(1, kValue).mod(q);
for (int i = 0; i < 5; i++)
seed[i] = random.nextInt();
k = generateK(seed, q);
if (k.signum() > 0 && k.compareTo(q) < 0) { if (k.signum() > 0 && k.compareTo(q) < 0) {
previousKseed = new int [seed.length];
System.arraycopy(seed, 0, previousKseed, 0, seed.length);
return k; return k;
} }
} }
@ -435,7 +379,7 @@ abstract class DSA extends SignatureSpi {
// Use the application-specified SecureRandom Object if provided. // Use the application-specified SecureRandom Object if provided.
// Otherwise, use our default SecureRandom Object. // Otherwise, use our default SecureRandom Object.
private SecureRandom getSigningRandom() { protected SecureRandom getSigningRandom() {
if (signingRandom == null) { if (signingRandom == null) {
if (appRandom != null) { if (appRandom != null) {
signingRandom = appRandom; signingRandom = appRandom;
@ -446,171 +390,6 @@ abstract class DSA extends SignatureSpi {
return signingRandom; return signingRandom;
} }
/**
* Compute k for a DSA signature.
*
* @param seed the seed for generating k. This seed should be
* secure. This is what is refered to as the KSEED in the DSA
* specification.
*
* @param g the g parameter from the DSA key pair.
*/
private BigInteger generateK(int[] seed, BigInteger q) {
// check out t in the spec.
int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
0xC3D2E1F0, 0x67452301 };
//
int[] tmp = DSA.SHA_7(seed, t);
byte[] tmpBytes = new byte[tmp.length * 4];
for (int i = 0; i < tmp.length; i++) {
int k = tmp[i];
for (int j = 0; j < 4; j++) {
tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
}
}
BigInteger k = new BigInteger(1, tmpBytes).mod(q);
return k;
}
// Constants for each round
private static final int round1_kt = 0x5a827999;
private static final int round2_kt = 0x6ed9eba1;
private static final int round3_kt = 0x8f1bbcdc;
private static final int round4_kt = 0xca62c1d6;
/**
* Computes set 1 thru 7 of SHA-1 on m1. */
static int[] SHA_7(int[] m1, int[] h) {
int[] W = new int[80];
System.arraycopy(m1,0,W,0,m1.length);
int temp = 0;
for (int t = 16; t <= 79; t++){
temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t] = ((temp << 1) | (temp >>>(32 - 1)));
}
int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
for (int i = 0; i < 20; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
((b&c)|((~b)&d))+ e + W[i] + round1_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 2
for (int i = 20; i < 40; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
(b ^ c ^ d) + e + W[i] + round2_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 3
for (int i = 40; i < 60; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 4
for (int i = 60; i < 80; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
(b ^ c ^ d) + e + W[i] + round4_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
int[] md = new int[5];
md[0] = h[0] + a;
md[1] = h[1] + b;
md[2] = h[2] + c;
md[3] = h[3] + d;
md[4] = h[4] + e;
return md;
}
/**
* This implementation recognizes the following parameter:<dl>
*
* <dt><tt>Kseed</tt>
*
* <dd>a byte array.
*
* </dl>
*
* @deprecated
*/
@Deprecated
protected void engineSetParameter(String key, Object param) {
if (key.equals("KSEED")) {
if (param instanceof byte[]) {
Kseed = byteArray2IntArray((byte[])param);
KseedAsByteArray = (byte[])param;
} else {
debug("unrecognized param: " + key);
throw new InvalidParameterException("Kseed not a byte array");
}
} else {
throw new InvalidParameterException("invalid parameter");
}
}
/**
* Return the value of the requested parameter. Recognized
* parameters are:
*
* <dl>
*
* <dt><tt>Kseed</tt>
*
* <dd>a byte array.
*
* </dl>
*
* @return the value of the requested parameter.
*
* @see java.security.SignatureEngine
*
* @deprecated
*/
@Deprecated
protected Object engineGetParameter(String key) {
if (key.equals("KSEED")) {
return KseedAsByteArray;
} else {
return null;
}
}
/**
* Set the algorithm object.
*/
private void setParams(DSAParams params) throws InvalidKeyException {
if (params == null) {
throw new InvalidKeyException("DSA public key lacks parameters");
}
this.params = params;
this.presetP = params.getP();
this.presetQ = params.getQ();
this.presetG = params.getG();
}
/** /**
* Return a human readable rendition of the engine. * Return a human readable rendition of the engine.
*/ */
@ -632,38 +411,6 @@ abstract class DSA extends SignatureSpi {
return printable; return printable;
} }
/*
* Utility routine for converting a byte array into an int array
*/
private int[] byteArray2IntArray(byte[] byteArray) {
int j = 0;
byte[] newBA;
int mod = byteArray.length % 4;
// guarantee that the incoming byteArray is a multiple of 4
// (pad with 0's)
switch (mod) {
case 3: newBA = new byte[byteArray.length + 1]; break;
case 2: newBA = new byte[byteArray.length + 2]; break;
case 1: newBA = new byte[byteArray.length + 3]; break;
default: newBA = new byte[byteArray.length + 0]; break;
}
System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
// copy each set of 4 bytes in the byte array into an integer
int[] newSeed = new int[newBA.length / 4];
for (int i = 0; i < newBA.length; i += 4) {
newSeed[j] = newBA[i + 3] & 0xFF;
newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
j++;
}
return newSeed;
}
private static void debug(Exception e) { private static void debug(Exception e) {
if (debug) { if (debug) {
e.printStackTrace(); e.printStackTrace();
@ -675,4 +422,325 @@ abstract class DSA extends SignatureSpi {
System.err.println(s); System.err.println(s);
} }
} }
/**
* Standard SHA224withDSA implementation as defined in FIPS186-3.
*/
public static final class SHA224withDSA extends DSA {
public SHA224withDSA() throws NoSuchAlgorithmException {
super(MessageDigest.getInstance("SHA-224"));
}
}
/**
* Standard SHA256withDSA implementation as defined in FIPS186-3.
*/
public static final class SHA256withDSA extends DSA {
public SHA256withDSA() throws NoSuchAlgorithmException {
super(MessageDigest.getInstance("SHA-256"));
}
}
static class LegacyDSA extends DSA {
/* The random seed used to generate k */
private int[] kSeed;
/* The random seed used to generate k (specified by application) */
private byte[] kSeedAsByteArray;
/*
* The random seed used to generate k
* (prevent the same Kseed from being used twice in a row
*/
private int[] kSeedLast;
public LegacyDSA(MessageDigest md) throws NoSuchAlgorithmException {
super(md);
}
@Deprecated
protected void engineSetParameter(String key, Object param) {
if (key.equals("KSEED")) {
if (param instanceof byte[]) {
kSeed = byteArray2IntArray((byte[])param);
kSeedAsByteArray = (byte[])param;
} else {
debug("unrecognized param: " + key);
throw new InvalidParameterException("kSeed not a byte array");
}
} else {
throw new InvalidParameterException("Unsupported parameter");
}
}
@Deprecated
protected Object engineGetParameter(String key) {
if (key.equals("KSEED")) {
return kSeedAsByteArray;
} else {
return null;
}
}
@Override
protected void checkKey(DSAParams params) throws InvalidKeyException {
int valueL = params.getP().bitLength();
if (valueL > 1024) {
throw new InvalidKeyException("Key is too long for this algorithm");
}
}
/*
* Please read bug report 4044247 for an alternative, faster,
* NON-FIPS approved method to generate K
*/
@Override
protected BigInteger generateK(BigInteger q) {
BigInteger k = null;
// The application specified a kSeed for us to use.
// Note: we dis-allow usage of the same Kseed twice in a row
if (kSeed != null && !Arrays.equals(kSeed, kSeedLast)) {
k = generateKUsingKSeed(kSeed, q);
if (k.signum() > 0 && k.compareTo(q) < 0) {
kSeedLast = kSeed.clone();
return k;
}
}
// The application did not specify a Kseed for us to use.
// We'll generate a new Kseed by getting random bytes from
// a SecureRandom object.
SecureRandom random = getSigningRandom();
while (true) {
int[] seed = new int[5];
for (int i = 0; i < 5; i++) seed[i] = random.nextInt();
k = generateKUsingKSeed(seed, q);
if (k.signum() > 0 && k.compareTo(q) < 0) {
kSeedLast = seed;
return k;
}
}
}
/**
* Compute k for the DSA signature as defined in the original DSS,
* i.e. FIPS186.
*
* @param seed the seed for generating k. This seed should be
* secure. This is what is refered to as the KSEED in the DSA
* specification.
*
* @param g the g parameter from the DSA key pair.
*/
private BigInteger generateKUsingKSeed(int[] seed, BigInteger q) {
// check out t in the spec.
int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
0xC3D2E1F0, 0x67452301 };
//
int[] tmp = SHA_7(seed, t);
byte[] tmpBytes = new byte[tmp.length * 4];
for (int i = 0; i < tmp.length; i++) {
int k = tmp[i];
for (int j = 0; j < 4; j++) {
tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
}
}
BigInteger k = new BigInteger(1, tmpBytes).mod(q);
return k;
}
// Constants for each round
private static final int round1_kt = 0x5a827999;
private static final int round2_kt = 0x6ed9eba1;
private static final int round3_kt = 0x8f1bbcdc;
private static final int round4_kt = 0xca62c1d6;
/**
* Computes set 1 thru 7 of SHA-1 on m1. */
static int[] SHA_7(int[] m1, int[] h) {
int[] W = new int[80];
System.arraycopy(m1,0,W,0,m1.length);
int temp = 0;
for (int t = 16; t <= 79; t++){
temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
W[t] = ((temp << 1) | (temp >>>(32 - 1)));
}
int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
for (int i = 0; i < 20; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
((b&c)|((~b)&d))+ e + W[i] + round1_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 2
for (int i = 20; i < 40; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
(b ^ c ^ d) + e + W[i] + round2_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 3
for (int i = 40; i < 60; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 4
for (int i = 60; i < 80; i++) {
temp = ((a<<5) | (a>>>(32-5))) +
(b ^ c ^ d) + e + W[i] + round4_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
int[] md = new int[5];
md[0] = h[0] + a;
md[1] = h[1] + b;
md[2] = h[2] + c;
md[3] = h[3] + d;
md[4] = h[4] + e;
return md;
}
/*
* Utility routine for converting a byte array into an int array
*/
private int[] byteArray2IntArray(byte[] byteArray) {
int j = 0;
byte[] newBA;
int mod = byteArray.length % 4;
// guarantee that the incoming byteArray is a multiple of 4
// (pad with 0's)
switch (mod) {
case 3: newBA = new byte[byteArray.length + 1]; break;
case 2: newBA = new byte[byteArray.length + 2]; break;
case 1: newBA = new byte[byteArray.length + 3]; break;
default: newBA = new byte[byteArray.length + 0]; break;
}
System.arraycopy(byteArray, 0, newBA, 0, byteArray.length);
// copy each set of 4 bytes in the byte array into an integer
int[] newSeed = new int[newBA.length / 4];
for (int i = 0; i < newBA.length; i += 4) {
newSeed[j] = newBA[i + 3] & 0xFF;
newSeed[j] |= (newBA[i + 2] << 8) & 0xFF00;
newSeed[j] |= (newBA[i + 1] << 16) & 0xFF0000;
newSeed[j] |= (newBA[i + 0] << 24) & 0xFF000000;
j++;
}
return newSeed;
}
}
public static final class SHA1withDSA extends LegacyDSA {
public SHA1withDSA() throws NoSuchAlgorithmException {
super(MessageDigest.getInstance("SHA-1"));
}
}
/**
* RawDSA implementation.
*
* RawDSA requires the data to be exactly 20 bytes long. If it is
* not, a SignatureException is thrown when sign()/verify() is called
* per JCA spec.
*/
public static final class RawDSA extends LegacyDSA {
// Internal special-purpose MessageDigest impl for RawDSA
// Only override whatever methods used
// NOTE: no clone support
public static final class NullDigest20 extends MessageDigest {
// 20 byte digest buffer
private final byte[] digestBuffer = new byte[20];
// offset into the buffer; use Integer.MAX_VALUE to indicate
// out-of-bound condition
private int ofs = 0;
protected NullDigest20() {
super("NullDigest20");
}
protected void engineUpdate(byte input) {
if (ofs == digestBuffer.length) {
ofs = Integer.MAX_VALUE;
} else {
digestBuffer[ofs++] = input;
}
}
protected void engineUpdate(byte[] input, int offset, int len) {
if (ofs + len > digestBuffer.length) {
ofs = Integer.MAX_VALUE;
} else {
System.arraycopy(input, offset, digestBuffer, ofs, len);
ofs += len;
}
}
protected final void engineUpdate(ByteBuffer input) {
int inputLen = input.remaining();
if (ofs + inputLen > digestBuffer.length) {
ofs = Integer.MAX_VALUE;
} else {
input.get(digestBuffer, ofs, inputLen);
ofs += inputLen;
}
}
protected byte[] engineDigest() throws RuntimeException {
if (ofs != digestBuffer.length) {
throw new RuntimeException
("Data for RawDSA must be exactly 20 bytes long");
}
reset();
return digestBuffer;
}
protected int engineDigest(byte[] buf, int offset, int len)
throws DigestException {
if (ofs != digestBuffer.length) {
throw new DigestException
("Data for RawDSA must be exactly 20 bytes long");
}
if (len < digestBuffer.length) {
throw new DigestException
("Output buffer too small; must be at least 20 bytes");
}
System.arraycopy(digestBuffer, 0, buf, offset, digestBuffer.length);
reset();
return digestBuffer.length;
}
protected void engineReset() {
ofs = 0;
}
protected final int engineGetDigestLength() {
return digestBuffer.length;
}
}
public RawDSA() throws NoSuchAlgorithmException {
super(new NullDigest20());
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,8 +48,9 @@ import sun.security.jca.JCAUtil;
public class DSAKeyPairGenerator extends KeyPairGenerator public class DSAKeyPairGenerator extends KeyPairGenerator
implements java.security.interfaces.DSAKeyPairGenerator { implements java.security.interfaces.DSAKeyPairGenerator {
/* The modulus length */ /* Length for prime P and subPrime Q in bits */
private int modlen; private int plen;
private int qlen;
/* whether to force new parameters to be generated for each KeyPair */ /* whether to force new parameters to be generated for each KeyPair */
private boolean forceNewParameters; private boolean forceNewParameters;
@ -65,20 +66,23 @@ implements java.security.interfaces.DSAKeyPairGenerator {
initialize(1024, null); initialize(1024, null);
} }
private static void checkStrength(int strength) { private static void checkStrength(int sizeP, int sizeQ) {
if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) { if ((sizeP >= 512) && (sizeP <= 1024) && (sizeP % 64 == 0)
&& sizeQ == 160) {
// traditional - allow for backward compatibility
// L=multiples of 64 and between 512 and 1024 (inclusive)
// N=160
} else if (sizeP == 2048 && (sizeQ == 224 || sizeQ == 256)) {
// L=2048, N=224 or 256
} else {
throw new InvalidParameterException throw new InvalidParameterException
("Modulus size must range from 512 to 1024 " ("Unsupported prime and subprime size combination: " +
+ "and be a multiple of 64"); sizeP + ", " + sizeQ);
} }
} }
public void initialize(int modlen, SecureRandom random) { public void initialize(int modlen, SecureRandom random) {
checkStrength(modlen); initialize(modlen, false, random);
this.random = random;
this.modlen = modlen;
this.params = null;
this.forceNewParameters = false;
} }
/** /**
@ -86,18 +90,27 @@ implements java.security.interfaces.DSAKeyPairGenerator {
* is false, a set of pre-computed parameters is used. * is false, a set of pre-computed parameters is used.
*/ */
public void initialize(int modlen, boolean genParams, SecureRandom random) { public void initialize(int modlen, boolean genParams, SecureRandom random) {
checkStrength(modlen); int subPrimeLen = -1;
if (modlen <= 1024) {
subPrimeLen = 160;
} else if (modlen == 2048) {
subPrimeLen = 224;
}
checkStrength(modlen, subPrimeLen);
if (genParams) { if (genParams) {
params = null; params = null;
} else { } else {
params = ParameterCache.getCachedDSAParameterSpec(modlen); params = ParameterCache.getCachedDSAParameterSpec(modlen,
subPrimeLen);
if (params == null) { if (params == null) {
throw new InvalidParameterException throw new InvalidParameterException
("No precomputed parameters for requested modulus size " ("No precomputed parameters for requested modulus size "
+ "available"); + "available");
} }
} }
this.modlen = modlen; this.plen = modlen;
this.qlen = subPrimeLen;
this.random = random; this.random = random;
this.forceNewParameters = genParams; this.forceNewParameters = genParams;
} }
@ -136,9 +149,11 @@ implements java.security.interfaces.DSAKeyPairGenerator {
} }
private void initialize0(DSAParameterSpec params, SecureRandom random) { private void initialize0(DSAParameterSpec params, SecureRandom random) {
int modlen = params.getP().bitLength(); int sizeP = params.getP().bitLength();
checkStrength(modlen); int sizeQ = params.getQ().bitLength();
this.modlen = modlen; checkStrength(sizeP, sizeQ);
this.plen = sizeP;
this.qlen = sizeQ;
this.params = params; this.params = params;
this.random = random; this.random = random;
this.forceNewParameters = false; this.forceNewParameters = false;
@ -156,11 +171,11 @@ implements java.security.interfaces.DSAKeyPairGenerator {
try { try {
if (forceNewParameters) { if (forceNewParameters) {
// generate new parameters each time // generate new parameters each time
spec = ParameterCache.getNewDSAParameterSpec(modlen, random); spec = ParameterCache.getNewDSAParameterSpec(plen, qlen, random);
} else { } else {
if (params == null) { if (params == null) {
params = params =
ParameterCache.getDSAParameterSpec(modlen, random); ParameterCache.getDSAParameterSpec(plen, qlen, random);
} }
spec = params; spec = params;
} }
@ -203,43 +218,14 @@ implements java.security.interfaces.DSAKeyPairGenerator {
*/ */
private BigInteger generateX(SecureRandom random, BigInteger q) { private BigInteger generateX(SecureRandom random, BigInteger q) {
BigInteger x = null; BigInteger x = null;
byte[] temp = new byte[qlen];
while (true) { while (true) {
int[] seed = new int[5]; random.nextBytes(temp);
for (int i = 0; i < 5; i++) { x = new BigInteger(1, temp).mod(q);
seed[i] = random.nextInt();
}
x = generateX(seed, q);
if (x.signum() > 0 && (x.compareTo(q) < 0)) { if (x.signum() > 0 && (x.compareTo(q) < 0)) {
break; return x;
} }
} }
return x;
}
/**
* Given a seed, generate the private key component of the key
* pair. In the terminology used in the DSA specification
* (FIPS-186) seed is the XSEED quantity.
*
* @param seed the seed to use to generate the private key.
*/
BigInteger generateX(int[] seed, BigInteger q) {
// check out t in the spec.
int[] t = { 0x67452301, 0xEFCDAB89, 0x98BADCFE,
0x10325476, 0xC3D2E1F0 };
//
int[] tmp = DSA.SHA_7(seed, t);
byte[] tmpBytes = new byte[tmp.length * 4];
for (int i = 0; i < tmp.length; i++) {
int k = tmp[i];
for (int j = 0; j < 4; j++) {
tmpBytes[(i * 4) + j] = (byte) (k >>> (24 - (j * 8)));
}
}
BigInteger x = new BigInteger(1, tmpBytes).mod(q);
return x;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,10 +32,12 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.InvalidParameterException; import java.security.InvalidParameterException;
import java.security.MessageDigest;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException; import java.security.spec.InvalidParameterSpecException;
import java.security.spec.DSAParameterSpec; import java.security.spec.DSAParameterSpec;
import java.security.spec.DSAGenParameterSpec;
/** /**
* This class generates parameters for the DSA algorithm. It uses a default * This class generates parameters for the DSA algorithm. It uses a default
@ -54,8 +56,14 @@ import java.security.spec.DSAParameterSpec;
public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi { public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
// the modulus length // the default parameters
private int modLen = 1024; // default private static final DSAGenParameterSpec DEFAULTS =
new DSAGenParameterSpec(1024, 160, 160);
// the length of prime P, subPrime Q, and seed in bits
private int valueL = -1;
private int valueN = -1;
private int seedLen = -1;
// the source of randomness // the source of randomness
private SecureRandom random; private SecureRandom random;
@ -65,11 +73,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
private static final BigInteger ONE = BigInteger.valueOf(1); private static final BigInteger ONE = BigInteger.valueOf(1);
private static final BigInteger TWO = BigInteger.valueOf(2); private static final BigInteger TWO = BigInteger.valueOf(2);
// Make a SHA-1 hash function
private SHA sha;
public DSAParameterGenerator() { public DSAParameterGenerator() {
this.sha = new SHA();
} }
/** /**
@ -80,19 +84,18 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
* @param random the source of randomness * @param random the source of randomness
*/ */
protected void engineInit(int strength, SecureRandom random) { protected void engineInit(int strength, SecureRandom random) {
/* if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
* Bruce Schneier, "Applied Cryptography", 2nd Edition, this.valueN = 160;
* Description of DSA: } else if (strength == 2048) {
* [...] The algorithm uses the following parameter: this.valueN = 224;
* p=a prime number L bits long, when L ranges from 512 to 1024 and is // } else if (strength == 3072) {
* a multiple of 64. [...] // this.valueN = 256;
*/ } else {
if ((strength < 512) || (strength > 1024) || (strength % 64 != 0)) {
throw new InvalidParameterException throw new InvalidParameterException
("Prime size must range from 512 to 1024 " ("Prime size should be 512 - 1024, or 2048");
+ "and be a multiple of 64");
} }
this.modLen = strength; this.valueL = strength;
this.seedLen = valueN;
this.random = random; this.random = random;
} }
@ -100,7 +103,7 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
* Initializes this parameter generator with a set of * Initializes this parameter generator with a set of
* algorithm-specific parameter generation values. * algorithm-specific parameter generation values.
* *
* @param params the set of algorithm-specific parameter generation values * @param genParamSpec the set of algorithm-specific parameter generation values
* @param random the source of randomness * @param random the source of randomness
* *
* @exception InvalidAlgorithmParameterException if the given parameter * @exception InvalidAlgorithmParameterException if the given parameter
@ -109,7 +112,19 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
protected void engineInit(AlgorithmParameterSpec genParamSpec, protected void engineInit(AlgorithmParameterSpec genParamSpec,
SecureRandom random) SecureRandom random)
throws InvalidAlgorithmParameterException { throws InvalidAlgorithmParameterException {
if (!(genParamSpec instanceof DSAGenParameterSpec)) {
throw new InvalidAlgorithmParameterException("Invalid parameter"); throw new InvalidAlgorithmParameterException("Invalid parameter");
}
DSAGenParameterSpec dsaGenParams = (DSAGenParameterSpec) genParamSpec;
if (dsaGenParams.getPrimePLength() > 2048) {
throw new InvalidParameterException
("Prime size should be 512 - 1024, or 2048");
}
// directly initialize using the already validated values
this.valueL = dsaGenParams.getPrimePLength();
this.valueN = dsaGenParams.getSubprimeQLength();
this.seedLen = dsaGenParams.getSeedLength();
this.random = random;
} }
/** /**
@ -123,15 +138,21 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
if (this.random == null) { if (this.random == null) {
this.random = new SecureRandom(); this.random = new SecureRandom();
} }
if (valueL == -1) {
BigInteger[] pAndQ = generatePandQ(this.random, this.modLen); try {
engineInit(DEFAULTS, this.random);
} catch (InvalidAlgorithmParameterException iape) {
// should never happen
}
}
BigInteger[] pAndQ = generatePandQ(this.random, valueL,
valueN, seedLen);
BigInteger paramP = pAndQ[0]; BigInteger paramP = pAndQ[0];
BigInteger paramQ = pAndQ[1]; BigInteger paramQ = pAndQ[1];
BigInteger paramG = generateG(paramP, paramQ); BigInteger paramG = generateG(paramP, paramQ);
DSAParameterSpec dsaParamSpec = new DSAParameterSpec(paramP, DSAParameterSpec dsaParamSpec =
paramQ, new DSAParameterSpec(paramP, paramQ, paramG);
paramG);
algParams = AlgorithmParameters.getInstance("DSA", "SUN"); algParams = AlgorithmParameters.getInstance("DSA", "SUN");
algParams.init(dsaParamSpec); algParams.init(dsaParamSpec);
} catch (InvalidParameterSpecException e) { } catch (InvalidParameterSpecException e) {
@ -156,102 +177,98 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
* *
* @param random the source of randomness to generate the * @param random the source of randomness to generate the
* seed * seed
* @param L the size of <code>p</code>, in bits. * @param valueL the size of <code>p</code>, in bits.
* @param valueN the size of <code>q</code>, in bits.
* @param seedLen the length of <code>seed</code>, in bits.
* *
* @return an array of BigInteger, with <code>p</code> at index 0 and * @return an array of BigInteger, with <code>p</code> at index 0 and
* <code>q</code> at index 1.
*/
BigInteger[] generatePandQ(SecureRandom random, int L) {
BigInteger[] result = null;
byte[] seed = new byte[20];
while(result == null) {
for (int i = 0; i < 20; i++) {
seed[i] = (byte)random.nextInt();
}
result = generatePandQ(seed, L);
}
return result;
}
/*
* Generates the prime and subprime parameters for DSA.
*
* <p>The seed parameter corresponds to the <code>SEED</code> parameter
* referenced in the FIPS specification of the DSA algorithm,
* and L is the size of <code>p</code>, in bits.
*
* @param seed the seed to generate the parameters
* @param L the size of <code>p</code>, in bits.
*
* @return an array of BigInteger, with <code>p</code> at index 0,
* <code>q</code> at index 1, the seed at index 2, and the counter value * <code>q</code> at index 1, the seed at index 2, and the counter value
* at index 3, or null if the seed does not yield suitable numbers. * at index 3.
*/ */
BigInteger[] generatePandQ(byte[] seed, int L) { private static BigInteger[] generatePandQ(SecureRandom random, int valueL,
int valueN, int seedLen) {
String hashAlg = null;
if (valueN == 160) {
hashAlg = "SHA";
} else if (valueN == 224) {
hashAlg = "SHA-224";
} else if (valueN == 256) {
hashAlg = "SHA-256";
}
MessageDigest hashObj = null;
try {
hashObj = MessageDigest.getInstance(hashAlg);
} catch (NoSuchAlgorithmException nsae) {
// should never happen
nsae.printStackTrace();
}
/* Useful variables */ /* Step 3, 4: Useful variables */
int g = seed.length * 8; int outLen = hashObj.getDigestLength()*8;
int n = (L - 1) / 160; int n = (valueL - 1) / outLen;
int b = (L - 1) % 160; int b = (valueL - 1) % outLen;
byte[] seedBytes = new byte[seedLen/8];
BigInteger twoSl = TWO.pow(seedLen);
int primeCertainty = 80; // for 1024-bit prime P
if (valueL == 2048) {
primeCertainty = 112;
//} else if (valueL == 3072) {
// primeCertainty = 128;
}
BigInteger SEED = new BigInteger(1, seed); BigInteger resultP, resultQ, seed = null;
BigInteger TWOG = TWO.pow(2 * g); int counter;
while (true) {
do {
/* Step 5 */
random.nextBytes(seedBytes);
seed = new BigInteger(1, seedBytes);
/* Step 2 (Step 1 is getting seed). */ /* Step 6 */
byte[] U1 = SHA(seed); BigInteger U = new BigInteger(1, hashObj.digest(seedBytes)).
byte[] U2 = SHA(toByteArray((SEED.add(ONE)).mod(TWOG))); mod(TWO.pow(valueN - 1));
xor(U1, U2); /* Step 7 */
byte[] U = U1; resultQ = TWO.pow(valueN - 1).add(U).add(ONE). subtract(U.mod(TWO));
} while (!resultQ.isProbablePrime(primeCertainty));
/* Step 3: For q by setting the msb and lsb to 1 */ /* Step 10 */
U[0] |= 0x80; BigInteger offset = ONE;
U[19] |= 1; /* Step 11 */
BigInteger q = new BigInteger(1, U); for (counter = 0; counter < 4*valueL; counter++) {
BigInteger V[] = new BigInteger[n + 1];
/* Step 5 */ /* Step 11.1 */
if (!q.isProbablePrime(80)) { for (int j = 0; j <= n; j++) {
return null; BigInteger J = BigInteger.valueOf(j);
BigInteger tmp = (seed.add(offset).add(J)).mod(twoSl);
} else { byte[] vjBytes = hashObj.digest(toByteArray(tmp));
BigInteger V[] = new BigInteger[n + 1]; V[j] = new BigInteger(1, vjBytes);
BigInteger offset = TWO; }
/* Step 11.2 */
/* Step 6 */ BigInteger W = V[0];
for (int counter = 0; counter < 4096; counter++) { for (int i = 1; i < n; i++) {
W = W.add(V[i].multiply(TWO.pow(i * outLen)));
/* Step 7 */ }
for (int k = 0; k <= n; k++) { W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * outLen)));
BigInteger K = BigInteger.valueOf(k); /* Step 11.3 */
BigInteger tmp = (SEED.add(offset).add(K)).mod(TWOG); BigInteger twoLm1 = TWO.pow(valueL - 1);
V[k] = new BigInteger(1, SHA(toByteArray(tmp))); BigInteger X = W.add(twoLm1);
} /* Step 11.4, 11.5 */
BigInteger c = X.mod(resultQ.multiply(TWO));
/* Step 8 */ resultP = X.subtract(c.subtract(ONE));
BigInteger W = V[0]; /* Step 11.6, 11.7 */
for (int i = 1; i < n; i++) { if (resultP.compareTo(twoLm1) > -1
W = W.add(V[i].multiply(TWO.pow(i * 160))); && resultP.isProbablePrime(primeCertainty)) {
} /* Step 11.8 */
W = W.add((V[n].mod(TWO.pow(b))).multiply(TWO.pow(n * 160))); BigInteger[] result = {resultP, resultQ, seed,
BigInteger.valueOf(counter)};
BigInteger TWOLm1 = TWO.pow(L - 1); return result;
BigInteger X = W.add(TWOLm1); }
/* Step 11.9 */
/* Step 9 */ offset = offset.add(BigInteger.valueOf(n)).add(ONE);
BigInteger c = X.mod(q.multiply(TWO));
BigInteger p = X.subtract(c.subtract(ONE));
/* Step 10 - 13 */
if (p.compareTo(TWOLm1) > -1 && p.isProbablePrime(80)) {
BigInteger[] result = {p, q, SEED,
BigInteger.valueOf(counter)};
return result;
}
offset = offset.add(BigInteger.valueOf(n)).add(ONE);
} }
return null; }
}
} }
/* /*
@ -262,31 +279,24 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
* *
* @param the <code>g</code> * @param the <code>g</code>
*/ */
BigInteger generateG(BigInteger p, BigInteger q) { private static BigInteger generateG(BigInteger p, BigInteger q) {
BigInteger h = ONE; BigInteger h = ONE;
/* Step 1 */
BigInteger pMinusOneOverQ = (p.subtract(ONE)).divide(q); BigInteger pMinusOneOverQ = (p.subtract(ONE)).divide(q);
BigInteger g = ONE; BigInteger resultG = ONE;
while (g.compareTo(TWO) < 0) { while (resultG.compareTo(TWO) < 0) {
g = h.modPow(pMinusOneOverQ, p); /* Step 3 */
resultG = h.modPow(pMinusOneOverQ, p);
h = h.add(ONE); h = h.add(ONE);
} }
return g; return resultG;
}
/*
* Returns the SHA-1 digest of some data
*/
private byte[] SHA(byte[] array) {
sha.engineReset();
sha.engineUpdate(array, 0, array.length);
return sha.engineDigest();
} }
/* /*
* Converts the result of a BigInteger.toByteArray call to an exact * Converts the result of a BigInteger.toByteArray call to an exact
* signed magnitude representation for any positive number. * signed magnitude representation for any positive number.
*/ */
private byte[] toByteArray(BigInteger bigInt) { private static byte[] toByteArray(BigInteger bigInt) {
byte[] result = bigInt.toByteArray(); byte[] result = bigInt.toByteArray();
if (result[0] == 0) { if (result[0] == 0) {
byte[] tmp = new byte[result.length - 1]; byte[] tmp = new byte[result.length - 1];
@ -295,13 +305,4 @@ public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
} }
return result; return result;
} }
/*
* XORs U2 into U1
*/
private void xor(byte[] U1, byte[] U2) {
for (int i = 0; i < U1.length; i++) {
U1[i] ^= U2[i];
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package sun.security.provider; package sun.security.provider;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.*; import java.security.*;
@ -55,11 +56,17 @@ public final class ParameterCache {
private final static Map<Integer,DHParameterSpec> dhCache; private final static Map<Integer,DHParameterSpec> dhCache;
/** /**
* Return cached DSA parameters for the given keylength, or null if none * Return cached DSA parameters for the given length combination of
* are available in the cache. * prime and subprime, or null if none are available in the cache.
*/ */
public static DSAParameterSpec getCachedDSAParameterSpec(int keyLength) { public static DSAParameterSpec getCachedDSAParameterSpec(int primeLen,
return dsaCache.get(Integer.valueOf(keyLength)); int subprimeLen) {
// ensure the sum is unique in all cases, i.e.
// case#1: (512 <= p <= 1024) AND q=160
// case#2: p=2048 AND q=224
// case#3: p=2048 AND q=256
// (NOT-YET-SUPPORTED)case#4: p=3072 AND q=256
return dsaCache.get(Integer.valueOf(primeLen+subprimeLen));
} }
/** /**
@ -71,18 +78,39 @@ public final class ParameterCache {
} }
/** /**
* Return DSA parameters for the given keylength. Uses cache if possible, * Return DSA parameters for the given primeLen. Uses cache if
* generates new parameters and adds them to the cache otherwise. * possible, generates new parameters and adds them to the cache
* otherwise.
*/ */
public static DSAParameterSpec getDSAParameterSpec(int keyLength, public static DSAParameterSpec getDSAParameterSpec(int primeLen,
SecureRandom random) SecureRandom random)
throws NoSuchAlgorithmException, InvalidParameterSpecException { throws NoSuchAlgorithmException, InvalidParameterSpecException,
DSAParameterSpec spec = getCachedDSAParameterSpec(keyLength); InvalidAlgorithmParameterException {
if (primeLen <= 1024) {
return getDSAParameterSpec(primeLen, 160, random);
} else if (primeLen == 2048) {
return getDSAParameterSpec(primeLen, 224, random);
} else {
return null;
}
}
/**
* Return DSA parameters for the given primeLen and subprimeLen.
* Uses cache if possible, generates new parameters and adds them to the
* cache otherwise.
*/
public static DSAParameterSpec getDSAParameterSpec(int primeLen,
int subprimeLen, SecureRandom random)
throws NoSuchAlgorithmException, InvalidParameterSpecException,
InvalidAlgorithmParameterException {
DSAParameterSpec spec =
getCachedDSAParameterSpec(primeLen, subprimeLen);
if (spec != null) { if (spec != null) {
return spec; return spec;
} }
spec = getNewDSAParameterSpec(keyLength, random); spec = getNewDSAParameterSpec(primeLen, subprimeLen, random);
dsaCache.put(Integer.valueOf(keyLength), spec); dsaCache.put(Integer.valueOf(primeLen + subprimeLen), spec);
return spec; return spec;
} }
@ -107,28 +135,28 @@ public final class ParameterCache {
} }
/** /**
* Return new DSA parameters for the given keylength. Do not lookup in * Return new DSA parameters for the given length combination of prime and
* cache and do not cache the newly generated parameters. This method * sub prime. Do not lookup in cache and do not cache the newly generated
* really only exists for the legacy method * parameters. This method really only exists for the legacy method
* DSAKeyPairGenerator.initialize(int, boolean, SecureRandom). * DSAKeyPairGenerator.initialize(int, boolean, SecureRandom).
*/ */
public static DSAParameterSpec getNewDSAParameterSpec(int keyLength, public static DSAParameterSpec getNewDSAParameterSpec(int primeLen,
SecureRandom random) int subprimeLen, SecureRandom random)
throws NoSuchAlgorithmException, InvalidParameterSpecException { throws NoSuchAlgorithmException, InvalidParameterSpecException,
InvalidAlgorithmParameterException {
AlgorithmParameterGenerator gen = AlgorithmParameterGenerator gen =
AlgorithmParameterGenerator.getInstance("DSA"); AlgorithmParameterGenerator.getInstance("DSA");
gen.init(keyLength, random); DSAGenParameterSpec genParams =
new DSAGenParameterSpec(primeLen, subprimeLen);
gen.init(genParams, random);
AlgorithmParameters params = gen.generateParameters(); AlgorithmParameters params = gen.generateParameters();
DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class); DSAParameterSpec spec = params.getParameterSpec(DSAParameterSpec.class);
return spec; return spec;
} }
static { static {
// XXX change to ConcurrentHashMap once available dhCache = new ConcurrentHashMap<Integer,DHParameterSpec>();
dhCache = Collections.synchronizedMap dsaCache = new ConcurrentHashMap<Integer,DSAParameterSpec>();
(new HashMap<Integer,DHParameterSpec>());
dsaCache = Collections.synchronizedMap
(new HashMap<Integer,DSAParameterSpec>());
/* /*
* We support precomputed parameter for 512, 768 and 1024 bit * We support precomputed parameter for 512, 768 and 1024 bit
@ -210,17 +238,99 @@ public final class ParameterCache {
"83dfe15ae59f06928b665e807b552564014c3bfecf" + "83dfe15ae59f06928b665e807b552564014c3bfecf" +
"492a", 16); "492a", 16);
dsaCache.put(Integer.valueOf(512), dsaCache.put(Integer.valueOf(512+160),
new DSAParameterSpec(p512, q512, g512)); new DSAParameterSpec(p512, q512, g512));
dsaCache.put(Integer.valueOf(768), dsaCache.put(Integer.valueOf(768+160),
new DSAParameterSpec(p768, q768, g768)); new DSAParameterSpec(p768, q768, g768));
dsaCache.put(Integer.valueOf(1024), dsaCache.put(Integer.valueOf(1024+160),
new DSAParameterSpec(p1024, q1024, g1024)); new DSAParameterSpec(p1024, q1024, g1024));
/*
* L = 2048, N = 224
* SEED = 584236080cfa43c09b02354135f4cc5198a19efada08bd866d601ba4
* counter = 2666
*/
BigInteger p2048_224 =
new BigInteger("8f7935d9b9aae9bfabed887acf4951b6f32ec59e3b" +
"af3718e8eac4961f3efd3606e74351a9c4183339b8" +
"09e7c2ae1c539ba7475b85d011adb8b47987754984" +
"695cac0e8f14b3360828a22ffa27110a3d62a99345" +
"3409a0fe696c4658f84bdd20819c3709a01057b195" +
"adcd00233dba5484b6291f9d648ef883448677979c" +
"ec04b434a6ac2e75e9985de23db0292fc1118c9ffa" +
"9d8181e7338db792b730d7b9e349592f6809987215" +
"3915ea3d6b8b4653c633458f803b32a4c2e0f27290" +
"256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea1" +
"43de4b66ff04903ed5cf1623e158d487c608e97f21" +
"1cd81dca23cb6e380765f822e342be484c05763939" +
"601cd667", 16);
BigInteger q2048_224 =
new BigInteger("baf696a68578f7dfdee7fa67c977c785ef32b233ba" +
"e580c0bcd5695d", 16);
BigInteger g2048_224 =
new BigInteger("16a65c58204850704e7502a39757040d34da3a3478" +
"c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f" +
"37eeb1e09f3182d23c9043cb642f88004160edf9ca" +
"09b32076a79c32a627f2473e91879ba2c4e744bd20" +
"81544cb55b802c368d1fa83ed489e94e0fa0688e32" +
"428a5c78c478c68d0527b71c9a3abb0b0be12c4468" +
"9639e7d3ce74db101a65aa2b87f64c6826db3ec72f" +
"4b5599834bb4edb02f7c90e9a496d3a55d535bebfc" +
"45d4f619f63f3dedbb873925c2f224e07731296da8" +
"87ec1e4748f87efb5fdeb75484316b2232dee553dd" +
"af02112b0d1f02da30973224fe27aeda8b9d4b2922" +
"d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1" +
"ef17dbde", 16);
dsaCache.put(Integer.valueOf(2048+224),
new DSAParameterSpec(p2048_224, q2048_224, g2048_224));
/*
* L = 2048, N = 256
* SEED = b0b4417601b59cbc9d8ac8f935cadaec4f5fbb2f23785609ae466748d9b5a536
* counter = 497
*/
BigInteger p2048_256 =
new BigInteger("95475cf5d93e596c3fcd1d902add02f427f5f3c721" +
"0313bb45fb4d5bb2e5fe1cbd678cd4bbdd84c9836b" +
"e1f31c0777725aeb6c2fc38b85f48076fa76bcd814" +
"6cc89a6fb2f706dd719898c2083dc8d896f84062e2" +
"c9c94d137b054a8d8096adb8d51952398eeca852a0" +
"af12df83e475aa65d4ec0c38a9560d5661186ff98b" +
"9fc9eb60eee8b030376b236bc73be3acdbd74fd61c" +
"1d2475fa3077b8f080467881ff7e1ca56fee066d79" +
"506ade51edbb5443a563927dbc4ba520086746175c" +
"8885925ebc64c6147906773496990cb714ec667304" +
"e261faee33b3cbdf008e0c3fa90650d97d3909c927" +
"5bf4ac86ffcb3d03e6dfc8ada5934242dd6d3bcca2" +
"a406cb0b", 16);
BigInteger q2048_256 =
new BigInteger("f8183668ba5fc5bb06b5981e6d8b795d30b8978d43" +
"ca0ec572e37e09939a9773", 16);
BigInteger g2048_256 =
new BigInteger("42debb9da5b3d88cc956e08787ec3f3a09bba5f48b" +
"889a74aaf53174aa0fbe7e3c5b8fcd7a53bef563b0" +
"e98560328960a9517f4014d3325fc7962bf1e04937" +
"0d76d1314a76137e792f3f0db859d095e4a5b93202" +
"4f079ecf2ef09c797452b0770e1350782ed57ddf79" +
"4979dcef23cb96f183061965c4ebc93c9c71c56b92" +
"5955a75f94cccf1449ac43d586d0beee43251b0b22" +
"87349d68de0d144403f13e802f4146d882e057af19" +
"b6f6275c6676c8fa0e3ca2713a3257fd1b27d0639f" +
"695e347d8d1cf9ac819a26ca9b04cb0eb9b7b03598" +
"8d15bbac65212a55239cfc7e58fae38d7250ab9991" +
"ffbc97134025fe8ce04c4399ad96569be91a546f49" +
"78693c7a", 16);
dsaCache.put(Integer.valueOf(2048+256),
new DSAParameterSpec(p2048_256, q2048_256, g2048_256));
// use DSA parameters for DH as well // use DSA parameters for DH as well
dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512)); dhCache.put(Integer.valueOf(512), new DHParameterSpec(p512, g512));
dhCache.put(Integer.valueOf(768), new DHParameterSpec(p768, g768)); dhCache.put(Integer.valueOf(768), new DHParameterSpec(p768, g768));
dhCache.put(Integer.valueOf(1024), new DHParameterSpec(p1024, g1024)); dhCache.put(Integer.valueOf(1024), new DHParameterSpec(p1024, g1024));
dhCache.put(Integer.valueOf(2048), new DHParameterSpec(p2048_224, g2048_224));
} }
} }

View File

@ -47,6 +47,10 @@ import java.security.*;
* SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384, * SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384,
* and SHA-512. * and SHA-512.
* *
* - SHA-224withDSA/SHA-256withDSA are the signature schemes
* described in FIPS 186-3. The associated object identifiers are
* "OID.2.16.840.1.101.3.4.3.1", and "OID.2.16.840.1.101.3.4.3.2".
* - DSA is the key generation scheme as described in FIPS 186. * - DSA is the key generation scheme as described in FIPS 186.
* Aliases for DSA include the OID strings "OID.1.3.14.3.2.12" * Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
* and "OID.1.2.840.10040.4.1". * and "OID.1.2.840.10040.4.1".
@ -106,11 +110,15 @@ final class SunEntries {
map.put("Signature.SHA1withDSA", "sun.security.provider.DSA$SHA1withDSA"); map.put("Signature.SHA1withDSA", "sun.security.provider.DSA$SHA1withDSA");
map.put("Signature.NONEwithDSA", "sun.security.provider.DSA$RawDSA"); map.put("Signature.NONEwithDSA", "sun.security.provider.DSA$RawDSA");
map.put("Alg.Alias.Signature.RawDSA", "NONEwithDSA"); map.put("Alg.Alias.Signature.RawDSA", "NONEwithDSA");
map.put("Signature.SHA224withDSA", "sun.security.provider.DSA$SHA224withDSA");
map.put("Signature.SHA256withDSA", "sun.security.provider.DSA$SHA256withDSA");
String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" + String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" +
"|java.security.interfaces.DSAPrivateKey"; "|java.security.interfaces.DSAPrivateKey";
map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses); map.put("Signature.SHA1withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.NONEwithDSA SupportedKeyClasses", dsaKeyClasses); map.put("Signature.NONEwithDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.SHA224withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Signature.SHA256withDSA SupportedKeyClasses", dsaKeyClasses);
map.put("Alg.Alias.Signature.DSA", "SHA1withDSA"); map.put("Alg.Alias.Signature.DSA", "SHA1withDSA");
map.put("Alg.Alias.Signature.DSS", "SHA1withDSA"); map.put("Alg.Alias.Signature.DSS", "SHA1withDSA");
@ -124,6 +132,10 @@ final class SunEntries {
map.put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA"); map.put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA"); map.put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
map.put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA"); map.put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.1", "SHA224withDSA");
map.put("Alg.Alias.Signature.OID.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
map.put("Alg.Alias.Signature.2.16.840.1.101.3.4.3.2", "SHA256withDSA");
/* /*
* Key Pair Generator engines * Key Pair Generator engines
@ -143,6 +155,8 @@ final class SunEntries {
map.put("Alg.Alias.MessageDigest.SHA-1", "SHA"); map.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
map.put("Alg.Alias.MessageDigest.SHA1", "SHA"); map.put("Alg.Alias.MessageDigest.SHA1", "SHA");
map.put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA");
map.put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA");
map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224"); map.put("MessageDigest.SHA-224", "sun.security.provider.SHA2$SHA224");
map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224"); map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.4", "SHA-224");
@ -169,15 +183,17 @@ final class SunEntries {
*/ */
map.put("AlgorithmParameters.DSA", map.put("AlgorithmParameters.DSA",
"sun.security.provider.DSAParameters"); "sun.security.provider.DSAParameters");
map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA"); map.put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA"); map.put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.AlgorithmParameters.1.3.14.3.2.12", "DSA");
/* /*
* Key factories * Key factories
*/ */
map.put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory"); map.put("KeyFactory.DSA", "sun.security.provider.DSAKeyFactory");
map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); map.put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); map.put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
map.put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
/* /*
* Certificates * Certificates
@ -234,9 +250,13 @@ final class SunEntries {
/* /*
* KeySize * KeySize
*/ */
map.put("Signature.NONEwithDSA KeySize", "1024");
map.put("Signature.SHA1withDSA KeySize", "1024"); map.put("Signature.SHA1withDSA KeySize", "1024");
map.put("KeyPairGenerator.DSA KeySize", "1024"); map.put("Signature.SHA224withDSA KeySize", "2048");
map.put("AlgorithmParameterGenerator.DSA KeySize", "1024"); map.put("Signature.SHA256withDSA KeySize", "2048");
map.put("KeyPairGenerator.DSA KeySize", "2048");
map.put("AlgorithmParameterGenerator.DSA KeySize", "2048");
/* /*
* Implementation type: software or hardware * Implementation type: software or hardware

View File

@ -120,21 +120,14 @@ public class AlgorithmId implements Serializable, DerEncoder {
try { try {
algParams = AlgorithmParameters.getInstance(algidString); algParams = AlgorithmParameters.getInstance(algidString);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
try { /*
// Try the internal EC code so that we can fully parse EC * This algorithm parameter type is not supported, so we cannot
// keys even if the provider is not registered. * parse the parameters.
// This code can go away once we have EC in the SUN provider. */
algParams = AlgorithmParameters.getInstance(algidString, algParams = null;
sun.security.ec.ECKeyFactory.ecInternalProvider); return;
} catch (NoSuchAlgorithmException ee) {
/*
* This algorithm parameter type is not supported, so we cannot
* parse the parameters.
*/
algParams = null;
return;
}
} }
// Decode (parse) the parameters // Decode (parse) the parameters
algParams.init(params.toByteArray()); algParams.init(params.toByteArray());
} }
@ -505,6 +498,9 @@ public class AlgorithmId implements Serializable, DerEncoder {
if (name.equalsIgnoreCase("EC")) { if (name.equalsIgnoreCase("EC")) {
return EC_oid; return EC_oid;
} }
if (name.equalsIgnoreCase("ECDH")) {
return AlgorithmId.ECDH_oid;
}
// Common signature types // Common signature types
if (name.equalsIgnoreCase("MD5withRSA") if (name.equalsIgnoreCase("MD5withRSA")
@ -524,6 +520,12 @@ public class AlgorithmId implements Serializable, DerEncoder {
|| name.equalsIgnoreCase("SHA-1/DSA")) { || name.equalsIgnoreCase("SHA-1/DSA")) {
return AlgorithmId.sha1WithDSA_oid; return AlgorithmId.sha1WithDSA_oid;
} }
if (name.equalsIgnoreCase("SHA224WithDSA")) {
return AlgorithmId.sha224WithDSA_oid;
}
if (name.equalsIgnoreCase("SHA256WithDSA")) {
return AlgorithmId.sha256WithDSA_oid;
}
if (name.equalsIgnoreCase("SHA1WithRSA") if (name.equalsIgnoreCase("SHA1WithRSA")
|| name.equalsIgnoreCase("SHA1/RSA")) { || name.equalsIgnoreCase("SHA1/RSA")) {
return AlgorithmId.sha1WithRSAEncryption_oid; return AlgorithmId.sha1WithRSAEncryption_oid;
@ -654,6 +656,7 @@ public class AlgorithmId implements Serializable, DerEncoder {
public static final ObjectIdentifier DSA_oid; public static final ObjectIdentifier DSA_oid;
public static final ObjectIdentifier DSA_OIW_oid; public static final ObjectIdentifier DSA_OIW_oid;
public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1); public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1);
public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12);
public static final ObjectIdentifier RSA_oid; public static final ObjectIdentifier RSA_oid;
public static final ObjectIdentifier RSAEncryption_oid; public static final ObjectIdentifier RSAEncryption_oid;
@ -694,6 +697,10 @@ public class AlgorithmId implements Serializable, DerEncoder {
public static final ObjectIdentifier shaWithDSA_OIW_oid; public static final ObjectIdentifier shaWithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_OIW_oid; public static final ObjectIdentifier sha1WithDSA_OIW_oid;
public static final ObjectIdentifier sha1WithDSA_oid; public static final ObjectIdentifier sha1WithDSA_oid;
public static final ObjectIdentifier sha224WithDSA_oid =
oid(2, 16, 840, 1, 101, 3, 4, 3, 1);
public static final ObjectIdentifier sha256WithDSA_oid =
oid(2, 16, 840, 1, 101, 3, 4, 3, 2);
public static final ObjectIdentifier sha1WithECDSA_oid = public static final ObjectIdentifier sha1WithECDSA_oid =
oid(1, 2, 840, 10045, 4, 1); oid(1, 2, 840, 10045, 4, 1);
@ -725,7 +732,6 @@ public class AlgorithmId implements Serializable, DerEncoder {
public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid = public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid =
ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6}); ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6});
static { static {
/* /*
* Note the preferred OIDs are named simply with no "OIW" or * Note the preferred OIDs are named simply with no "OIW" or
@ -885,6 +891,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
nameTable.put(DSA_oid, "DSA"); nameTable.put(DSA_oid, "DSA");
nameTable.put(DSA_OIW_oid, "DSA"); nameTable.put(DSA_OIW_oid, "DSA");
nameTable.put(EC_oid, "EC"); nameTable.put(EC_oid, "EC");
nameTable.put(ECDH_oid, "ECDH");
nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA"); nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA");
nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA"); nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA");
nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA"); nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA");
@ -895,6 +903,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
nameTable.put(sha1WithDSA_oid, "SHA1withDSA"); nameTable.put(sha1WithDSA_oid, "SHA1withDSA");
nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA"); nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA"); nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA");
nameTable.put(sha224WithDSA_oid, "SHA224withDSA");
nameTable.put(sha256WithDSA_oid, "SHA256withDSA");
nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA"); nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA");
nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA"); nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA");
nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA"); nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA");

View File

@ -5,7 +5,7 @@
<body> <body>
<h1>Card Test (1.1)</h1> <h1>Card Test (1.1)</h1>
<hr> <hr>
<applet code=CardTest.class width=400 height=300> <applet code=CardTest.class width=455 height=300>
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason." alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag! Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet> </applet>

View File

@ -5,7 +5,7 @@
<body> <body>
<h1>Dither Test (1.1)</h1> <h1>Dither Test (1.1)</h1>
<hr> <hr>
<applet code=DitherTest.class width=425 height=400> <applet code=DitherTest.class width=455 height=400>
alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason." alt="Your browser understands the &lt;APPLET&gt; tag but isn't running the applet, for some reason."
Your browser is completely ignoring the &lt;APPLET&gt; tag! Your browser is completely ignoring the &lt;APPLET&gt; tag!
</applet> </applet>

View File

@ -59,6 +59,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
/* The real functions behind the macro curtains. */ /* The real functions behind the macro curtains. */
void *debug_malloc(size_t, const char *, int); void *debug_malloc(size_t, const char *, int);
@ -71,10 +76,10 @@ void debug_free(void *, const char *, int);
void debug_malloc_verify(const char*, int); void debug_malloc_verify(const char*, int);
#undef malloc_verify #undef malloc_verify
#define malloc_verify() debug_malloc_verify(__FILE__, __LINE__) #define malloc_verify() debug_malloc_verify(THIS_FILE, __LINE__)
void debug_malloc_police(const char*, int); void debug_malloc_police(const char*, int);
#undef malloc_police #undef malloc_police
#define malloc_police() debug_malloc_police(__FILE__, __LINE__) #define malloc_police() debug_malloc_police(THIS_FILE, __LINE__)
#endif #endif

View File

@ -41,20 +41,25 @@
#ifndef HPROF_ERROR_H #ifndef HPROF_ERROR_H
#define HPROF_ERROR_H #define HPROF_ERROR_H
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
/* Macros over assert and error functions so we can capture the source loc. */ /* Macros over assert and error functions so we can capture the source loc. */
#define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE)) #define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE))
#define HPROF_ERROR(fatal,msg) \ #define HPROF_ERROR(fatal,msg) \
error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, __FILE__, __LINE__) error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, THIS_FILE, __LINE__)
#define HPROF_JVMTI_ERROR(error,msg) \ #define HPROF_JVMTI_ERROR(error,msg) \
error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \ error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \
error, msg, __FILE__, __LINE__) error, msg, THIS_FILE, __LINE__)
#if defined(DEBUG) || !defined(NDEBUG) #if defined(DEBUG) || !defined(NDEBUG)
#define HPROF_ASSERT(cond) \ #define HPROF_ASSERT(cond) \
(((int)(cond))?(void)0:error_assert(#cond, __FILE__, __LINE__)) (((int)(cond))?(void)0:error_assert(#cond, THIS_FILE, __LINE__))
#else #else
#define HPROF_ASSERT(cond) #define HPROF_ASSERT(cond)
#endif #endif
@ -77,11 +82,11 @@
#define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n" #define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n"
#define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \ #define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \
str1, __FILE__, __LINE__ )) str1, THIS_FILE, __LINE__ ))
#define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \ #define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \
str1, str2, __FILE__, __LINE__ )) str1, str2, THIS_FILE, __LINE__ ))
#define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \ #define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \
str1, str2, num, __FILE__, __LINE__ )) str1, str2, num, THIS_FILE, __LINE__ ))
#define LOG(str) LOG1(str) #define LOG(str) LOG1(str)

View File

@ -41,6 +41,11 @@
#ifndef HPROF_UTIL_H #ifndef HPROF_UTIL_H
#define HPROF_UTIL_H #define HPROF_UTIL_H
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
/* Macros that protect code from accidently using a local ref improperly */ /* Macros that protect code from accidently using a local ref improperly */
#define WITH_LOCAL_REFS(env, number) \ #define WITH_LOCAL_REFS(env, number) \
{ \ { \
@ -184,8 +189,8 @@ void hprof_free(void *ptr);
#ifdef DEBUG #ifdef DEBUG
void * hprof_debug_malloc(int size, char *file, int line); void * hprof_debug_malloc(int size, char *file, int line);
void hprof_debug_free(void *ptr, char *file, int line); void hprof_debug_free(void *ptr, char *file, int line);
#define HPROF_MALLOC(size) hprof_debug_malloc(size, __FILE__, __LINE__) #define HPROF_MALLOC(size) hprof_debug_malloc(size, THIS_FILE, __LINE__)
#define HPROF_FREE(ptr) hprof_debug_free(ptr, __FILE__, __LINE__) #define HPROF_FREE(ptr) hprof_debug_free(ptr, THIS_FILE, __LINE__)
#else #else
#define HPROF_MALLOC(size) hprof_malloc(size) #define HPROF_MALLOC(size) hprof_malloc(size)
#define HPROF_FREE(ptr) hprof_free(ptr) #define HPROF_FREE(ptr) hprof_free(ptr)

View File

@ -70,12 +70,20 @@
/* Macros over error functions to capture line numbers */ /* Macros over error functions to capture line numbers */
#define CRW_FATAL(ci, message) fatal_error(ci, message, __FILE__, __LINE__) /* Fatal error used in all builds. */
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE "java_crw.demo.c" /* Never use __FILE__ */
#endif
#define CRW_FATAL(ci, message) fatal_error(ci, message, THIS_FILE, __LINE__)
#if defined(DEBUG) || !defined(NDEBUG) #if defined(DEBUG) || !defined(NDEBUG)
/* This assert macro is only used in the debug builds. */
#define CRW_ASSERT(ci, cond) \ #define CRW_ASSERT(ci, cond) \
((cond)?(void)0:assert_error(ci, #cond, __FILE__, __LINE__)) ((cond)?(void)0:assert_error(ci, #cond, THIS_FILE, __LINE__))
#else #else

View File

@ -49,10 +49,14 @@ extern "C" {
#define JPLISASSERT_ENABLEASSERTIONS (0) #define JPLISASSERT_ENABLEASSERTIONS (0)
#endif #endif
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#if JPLISASSERT_ENABLEASSERTIONS #if JPLISASSERT_ENABLEASSERTIONS
#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, __FILE__, __LINE__) #define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, THIS_FILE, __LINE__)
#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, __FILE__, __LINE__) #define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, THIS_FILE, __LINE__)
#else #else
#define jplis_assert(x) #define jplis_assert(x)
#define jplis_assert_msg(x, msg) #define jplis_assert_msg(x, msg)

View File

@ -32,17 +32,22 @@ extern "C" {
#include "debug_util.h" #include "debug_util.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#if defined(DEBUG) #if defined(DEBUG)
#define DASSERT(_expr) \ #define DASSERT(_expr) \
if ( !(_expr) ) { \ if ( !(_expr) ) { \
DAssert_Impl( #_expr, __FILE__, __LINE__); \ DAssert_Impl( #_expr, THIS_FILE, __LINE__); \
} else { \ } else { \
} }
#define DASSERTMSG(_expr, _msg) \ #define DASSERTMSG(_expr, _msg) \
if ( !(_expr) ) { \ if ( !(_expr) ) { \
DAssert_Impl( (_msg), __FILE__, __LINE__); \ DAssert_Impl( (_msg), THIS_FILE, __LINE__); \
} else { \ } else { \
} }

View File

@ -27,6 +27,11 @@
#include "debug_util.h" #include "debug_util.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#define DMEM_MIN(a,b) (a) < (b) ? (a) : (b) #define DMEM_MIN(a,b) (a) < (b) ? (a) : (b)
#define DMEM_MAX(a,b) (a) > (b) ? (a) : (b) #define DMEM_MAX(a,b) (a) > (b) ? (a) : (b)
@ -291,7 +296,7 @@ void DMem_ReportLeaks() {
DMutex_Enter(DMemMutex); DMutex_Enter(DMemMutex);
/* Force memory leaks to be output regardless of trace settings */ /* Force memory leaks to be output regardless of trace settings */
DTrace_EnableFile(__FILE__, TRUE); DTrace_EnableFile(THIS_FILE, TRUE);
DTRACE_PRINTLN("--------------------------"); DTRACE_PRINTLN("--------------------------");
DTRACE_PRINTLN("Debug Memory Manager Leaks"); DTRACE_PRINTLN("Debug Memory Manager Leaks");
DTRACE_PRINTLN("--------------------------"); DTRACE_PRINTLN("--------------------------");

View File

@ -34,6 +34,11 @@ extern "C" {
#include "debug_util.h" #include "debug_util.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
typedef int dtrace_id; typedef int dtrace_id;
enum { enum {
UNDEFINED_TRACE_ID = -1 /* indicates trace point has not been registered yet */ UNDEFINED_TRACE_ID = -1 /* indicates trace point has not been registered yet */
@ -69,7 +74,7 @@ static dtrace_id _Dt_FileTraceId = UNDEFINED_TRACE_ID;
#define _DTrace_Template(_func, _ac, _f, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) \ #define _DTrace_Template(_func, _ac, _f, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) \
{ \ { \
static dtrace_id _dt_lineid_ = UNDEFINED_TRACE_ID; \ static dtrace_id _dt_lineid_ = UNDEFINED_TRACE_ID; \
DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, __FILE__, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \ DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, THIS_FILE, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \
} }
/* printf style trace macros */ /* printf style trace macros */

View File

@ -452,7 +452,12 @@ extern CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
void *p11malloc(size_t c, char *file, int line); void *p11malloc(size_t c, char *file, int line);
void p11free(void *p, char *file, int line); void p11free(void *p, char *file, int line);
#define malloc(c) (p11malloc((c), __FILE__, __LINE__)) /* Use THIS_FILE when it is available. */
#define free(c) (p11free((c), __FILE__, __LINE__)) #ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#define malloc(c) (p11malloc((c), THIS_FILE, __LINE__))
#define free(c) (p11free((c), THIS_FILE, __LINE__))
#endif #endif

View File

@ -33,8 +33,13 @@
#include "jni.h" #include "jni.h"
#include "utf_md.h" #include "utf_md.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
/* Error and assert macros */ /* Error and assert macros */
#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m) #define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m)
#define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 ) #define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 )
void utfError(char *file, int line, char *message); void utfError(char *file, int line, char *message);

View File

@ -49,11 +49,16 @@ jint shmemBase_receivePacket(SharedMemoryConnection *, jdwpPacket *packet);
jint shmemBase_name(SharedMemoryTransport *, char **name); jint shmemBase_name(SharedMemoryTransport *, char **name);
jint shmemBase_getlasterror(char *msg, jint size); jint shmemBase_getlasterror(char *msg, jint size);
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#ifdef DEBUG #ifdef DEBUG
#define SHMEM_ASSERT(expression) \ #define SHMEM_ASSERT(expression) \
do { \ do { \
if (!(expression)) { \ if (!(expression)) { \
exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \ exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \
} \ } \
} while (0) } while (0)
#else #else
@ -63,7 +68,7 @@ do { \
#define SHMEM_GUARANTEE(expression) \ #define SHMEM_GUARANTEE(expression) \
do { \ do { \
if (!(expression)) { \ if (!(expression)) { \
exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \ exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \
} \ } \
} while (0) } while (0)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -80,6 +80,7 @@
# include <sys/types.h> # include <sys/types.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <fcntl.h> # include <fcntl.h>
# include "jni.h"
# include "manifest_info.h" # include "manifest_info.h"
#endif #endif

View File

@ -1001,6 +1001,13 @@ public class XBaseWindow {
switch (xev.get_type()) { switch (xev.get_type()) {
case XConstants.ButtonPress: case XConstants.ButtonPress:
if (buttonState == 0) { if (buttonState == 0) {
XWindowPeer parent = getToplevelXWindow();
// See 6385277, 6981400.
if (parent != null && parent.isFocusableWindow()) {
// A click in a client area drops the actual focused window retaining.
parent.setActualFocusedWindow(null);
parent.requestWindowFocus(xbe.get_time(), true);
}
XAwtState.setAutoGrabWindow(this); XAwtState.setAutoGrabWindow(this);
} }
break; break;

View File

@ -588,33 +588,6 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
} }
public void handleButtonPressRelease(XEvent xev) {
/*
* Fix for 6385277.
* We request focus on simple Window by click in order
* to make it behave like Frame/Dialog in this case and also to unify
* the behaviour with what we have on MS Windows.
* handleJavaMouseEvent() would be more suitable place to do this
* but we want Swing to have this functionality also.
*/
if (xev.get_type() == XConstants.ButtonPress) {
final XWindowPeer parentXWindow = getParentTopLevel();
Window parentWindow = (Window)parentXWindow.getTarget();
if (parentXWindow.isFocusableWindow() && parentXWindow.isSimpleWindow() &&
XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() != parentWindow)
{
postEvent(new InvocationEvent(parentWindow, new Runnable() {
public void run() {
// Request focus on the EDT of 'parentWindow' because
// XDecoratedPeer.requestWindowFocus() calls client code.
parentXWindow.requestXFocus();
}
}));
}
}
super.handleButtonPressRelease(xev);
}
public Dimension getMinimumSize() { public Dimension getMinimumSize() {
return target.getSize(); return target.getSize();
} }

View File

@ -1108,7 +1108,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
focusLog.fine("Request for decorated window focus"); focusLog.fine("Request for decorated window focus");
// If this is Frame or Dialog we can't assure focus request success - but we still can try // If this is Frame or Dialog we can't assure focus request success - but we still can try
// If this is Window and its owner Frame is active we can be sure request succedded. // If this is Window and its owner Frame is active we can be sure request succedded.
Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow(); Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow); Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
focusLog.finer("Current window is: active={0}, focused={1}", focusLog.finer("Current window is: active={0}, focused={1}",
@ -1201,7 +1201,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
public void handleWindowFocusOut(Window oppositeWindow, long serial) { public void handleWindowFocusOut(Window oppositeWindow, long serial) {
Window actualFocusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow(); Window actualFocusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
// If the actual focused window is not this decorated window then retain it. // If the actual focused window is not this decorated window then retain it.
if (actualFocusedWindow != null && actualFocusedWindow != target) { if (actualFocusedWindow != null && actualFocusedWindow != target) {

View File

@ -135,7 +135,7 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer {
* Thus we don't have to perform any transitive (a blocker of a blocker) checks. * Thus we don't have to perform any transitive (a blocker of a blocker) checks.
*/ */
boolean isFocusedWindowModalBlocker() { boolean isFocusedWindowModalBlocker() {
Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow(); Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
XWindowPeer focusedWindowPeer = null; XWindowPeer focusedWindowPeer = null;
if (focusedWindow != null) { if (focusedWindow != null) {

View File

@ -96,11 +96,11 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
public void handleEvent(AWTEvent e) { public void handleEvent(AWTEvent e) {
switch (e.getID()) { switch (e.getID()) {
case FocusEvent.FOCUS_GAINED: case FocusEvent.FOCUS_GAINED:
XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(proxy); XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(proxy);
container.focusGained(handle); container.focusGained(handle);
break; break;
case FocusEvent.FOCUS_LOST: case FocusEvent.FOCUS_LOST:
XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null); XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
container.focusLost(handle); container.focusLost(handle);
break; break;
case KeyEvent.KEY_PRESSED: case KeyEvent.KEY_PRESSED:
@ -172,7 +172,7 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
if (lightweightChild == null) { if (lightweightChild == null) {
lightweightChild = (Component)proxy; lightweightChild = (Component)proxy;
} }
Component currentOwner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner(); Component currentOwner = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
if (currentOwner != null && currentOwner.getPeer() == null) { if (currentOwner != null && currentOwner.getPeer() == null) {
currentOwner = null; currentOwner = null;
} }
@ -224,7 +224,8 @@ public class XEmbedChildProxyPeer implements ComponentPeer, XEventDispatcher{
if (parent != null) { if (parent != null) {
Window parentWindow = (Window)parent; Window parentWindow = (Window)parent;
// and check that it is focused // and check that it is focused
if (!parentWindow.isFocused() && XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == parentWindow) { if (!parentWindow.isFocused() &&
XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == parentWindow) {
// if it is not - skip requesting focus on Solaris // if it is not - skip requesting focus on Solaris
// but return true for compatibility. // but return true for compatibility.
return true; return true;

View File

@ -204,7 +204,7 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
// XEMBED_FOCUS_OUT client messages), so we first need to check if // XEMBED_FOCUS_OUT client messages), so we first need to check if
// embedded is an active window before sending WINDOW_LOST_FOCUS // embedded is an active window before sending WINDOW_LOST_FOCUS
// to shared code // to shared code
if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) { if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == embedded.target) {
embedded.handleWindowFocusOut(null, 0); embedded.handleWindowFocusOut(null, 0);
} }
} }

View File

@ -25,66 +25,48 @@
package sun.awt.X11; package sun.awt.X11;
import java.awt.Component; import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.awt.Window; import java.awt.Window;
import java.awt.event.FocusEvent;
import java.awt.peer.KeyboardFocusManagerPeer;
import java.awt.peer.ComponentPeer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
import sun.awt.CausedFocusEvent; import sun.awt.CausedFocusEvent;
import sun.awt.SunToolkit;
import sun.awt.KeyboardFocusManagerPeerImpl; import sun.awt.KeyboardFocusManagerPeerImpl;
public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl { public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer"); private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer");
private static final XKeyboardFocusManagerPeer inst = new XKeyboardFocusManagerPeer();
private static Object lock = new Object() {}; private Component currentFocusOwner;
private static Component currentFocusOwner; private Window currentFocusedWindow;
private static Window currentFocusedWindow;
XKeyboardFocusManagerPeer(KeyboardFocusManager manager) { public static XKeyboardFocusManagerPeer getInstance() {
super(manager); return inst;
}
private XKeyboardFocusManagerPeer() {
} }
@Override @Override
public void setCurrentFocusOwner(Component comp) { public void setCurrentFocusOwner(Component comp) {
setCurrentNativeFocusOwner(comp); synchronized (this) {
}
@Override
public Component getCurrentFocusOwner() {
return getCurrentNativeFocusOwner();
}
@Override
public Window getCurrentFocusedWindow() {
return getCurrentNativeFocusedWindow();
}
public static void setCurrentNativeFocusOwner(Component comp) {
synchronized (lock) {
currentFocusOwner = comp; currentFocusOwner = comp;
} }
} }
public static Component getCurrentNativeFocusOwner() { @Override
synchronized(lock) { public Component getCurrentFocusOwner() {
synchronized(this) {
return currentFocusOwner; return currentFocusOwner;
} }
} }
public static void setCurrentNativeFocusedWindow(Window win) { @Override
if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Setting current native focused window " + win); public void setCurrentFocusedWindow(Window win) {
if (focusLog.isLoggable(PlatformLogger.FINER)) {
focusLog.finer("Setting current focused window " + win);
}
XWindowPeer from = null, to = null; XWindowPeer from = null, to = null;
synchronized(lock) { synchronized(this) {
if (currentFocusedWindow != null) { if (currentFocusedWindow != null) {
from = (XWindowPeer)currentFocusedWindow.getPeer(); from = (XWindowPeer)currentFocusedWindow.getPeer();
} }
@ -104,8 +86,9 @@ public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
} }
} }
public static Window getCurrentNativeFocusedWindow() { @Override
synchronized(lock) { public Window getCurrentFocusedWindow() {
synchronized(this) {
return currentFocusedWindow; return currentFocusedWindow;
} }
} }
@ -124,6 +107,6 @@ public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
focusedWindowChangeAllowed, focusedWindowChangeAllowed,
time, time,
cause, cause,
getCurrentNativeFocusOwner()); getInstance().getCurrentFocusOwner());
} }
} }

Some files were not shown because too many files have changed in this diff Show More